Стратегии
Моментум по месячному рангу максимальной просадки на Binance Spot: держать 5 активов с наименьшим значением-30-дневного-MDD из актуального на дату отбора топ--20 по ликвидности; только длинные позиции, иначе кэш, если доходность за период формирования <= 0 (Choi 2014, DAILY баров)
Итог: Отменено
MddRankedMonthlyMomentumSpotTop5
Сводка по итогам
Стратегия тестировала ротацию Binance Spot только с длинными позициями: выбирала активы с наименьшей просадкой из ликвидной вселенной на каждый момент времени и переводила активы в денежные средства при неположительной доходности за период формирования. Метрики доходности не получены из-за тайм-аута проверки на слое 3. После пяти итераций запуск оставили на этапе проверки; до следующих этапов конвейера он не дошёл.
Гипотеза
verification_loop: sandbox_timeout: Проверка не пройдена (слой 3 — бэктест в песочнице): дымовой тест превысил лимит времени 300 с на окне примерно в 20000 баров (2400 дней с BTCUSDT.BINANCE_SPOT-1-DAY-LAST-EXTERNAL). Почти всегда это означает, что вычисления на каждом баре растут вместе с историей — например, полный просмотр ряда funding или вспомогательного ряда либо пересоздание списка и вызов min()/sorted() внутри calculate_signal()/on_bar() на каждом баре. Заранее вычислите отсортированные массивы временных меток ONCE в __init__ и используйте bisect либо кэшируйте значения по временной метке, чтобы стоимость обработки бара была O(log n), а не O(n).
Реализация
Моментум по Choi (2014) MDD на Binance Spot, дневные бары. На первом дневном баре каждого календарного месяца пул из 20 спотовых пар USDT фильтруется с учётом состава на эту дату: активу нужны как минимум 60 баров и место в топ-20 по долларовому объёму за 30 дней. Оставшиеся активы ранжируются по максимальной просадке за 30 дней, по возрастанию. 5 активов с наименьшим значением удерживаются с весом 19% капитала каждый (только длинные позиции, 1x); актив с доходностью за 30 дней <= 0 заменяется кэшем. rank_by='return' — заранее зарегистрированный парный тест на опровержение: ранжирование по накопленной доходности за 30 дней по убыванию при тех же вселенной, фильтре выхода в кэш, весах и расписании.
Результаты верификации
sandbox_timeout: Проверка не пройдена (слой 3 — бэктест в песочнице): дымовой тест превысил лимит времени 300 с на окне примерно в 20000 баров (2400 дней с BTCUSDT.BINANCE_SPOT-1-DAY-LAST-EXTERNAL). Почти всегда это означает, что вычисления на каждом баре растут вместе с историей — например, полный просмотр ряда funding или вспомогательного ряда либо пересоздание списка и вызов min()/sorted() внутри calculate_signal()/on_bar() на каждом баре. Заранее вычислите отсортированные массивы временных меток ONCE в __init__ и используйте bisect либо кэшируйте значения по временной метке, чтобы стоимость обработки бара была O(log n), а не O(n).
Добавьте параметр rank_by со значением {'mdd','return'}. При значении 'return' сортируйте по -ret вместо (mdd, -ret) в _rank(), чтобы сравнение выполнялось по тому же пути кода.
Гипотеза заранее регистрирует прямое сравнение с портфелем, сформированным тем же способом, но ранжированным по накопленной доходности за 30 дней; это тест на опровержение. Параметром можно выбрать только вариант B (require_positive_return=false). Портфель для сравнения по доходности нельзя выбрать параметром.
При желании требуйте, чтобы день месяца бара был 1 или чтобы это был первый обработанный бар нового месяца, прежде чем проводить первую ребалансировку.
Первая ребалансировка срабатывает на первом баре, когда любой актив набирает 60 баров (min_history_bars). Это может произойти в середине месяца, а не на первом баре месяца. Затем соблюдается график первого числа месяца. Такое происходит один раз за бэктест или прогрев и не влияет на результат.
Допустимо без изменений. Если важно покрыть более ранний период, добавьте явную проверку актуальности (последняя загруженная ts == ts бара), а инструменты с более поздним листингом перенесите на более медленный или несинхронизированный механизм обработки.
Гипотеза исключает активы с устаревшими или отсутствующими барами. Код проверяет только количество баров в истории. На практике барьер синхронизации базового шаблона для одного таймфрейма приостанавливает основной сигнал, пока у каждого инструмента не появится бар с текущей временной меткой. Поэтому нельзя ранжировать актив по устаревшим ценам. Обратная сторона: весь портфель ждёт самый поздно добавленный актив (2020 окно ковида показывает доходность 0.0%) и пропускает любую дату, на которую у одного инструмента отсутствует бар.
Анализ
(1) Повторите запуск за весь доступный период по 2026-09. Отчёт заканчивается на 2024-06-17, хотя для всех 20 инструментов есть дневные бары по 2026-09-26. Проверьте конечную дату бэктеста и бюджет баров; возможно, ограничение задано в тестовой среде, и оператору нужно его снять. (2) Добавьте параметр rank_by со значением {mdd, return}. При значении 'return' ранжируйте по убыванию доходности за 30 дней, оставив вселенную, условие перехода в денежные средства, веса и расписание без изменений. Покажите оба запуска; гипотеза подтверждается, только если коэффициент Шарпа MDD выше коэффициента Шарпа версии с ранжированием по доходности за тот же период. Другую логику не меняйте. Ожидается, что эффективный интервал вырастет с 3.7 до примерно 6 лет, а доля прибыли от 2021 уменьшится. Если коэффициент Шарпа MDD за полный период будет ниже примерно 0.5 или уступит парной версии, ожидайте отказа от гипотезы (premise_falsified). Подробности: workspace/discussions/1a5cf146-86a2-4fe3-b974-c3647e0fe164/iteration_1_feedback.md
Сводка по итогам
Ограничьте вычисления на каждом баре и ранжируйте активы раз в месяц, только при ребалансировке.
Стратегию оставили после сбоя проверки: время бэктеста в песочнице истекло. В записанном диагнозе указаны чрезмерные вычисления на каждом баре, растущие вместе с историей; до следующих этапов дело не дошло.
Стратегия пыталась ранжировать вселенную Binance Spot USDT топ--20 на каждый момент времени по наименьшей максимальной просадке за последние 30 дней, держать пять лучших активов только в длинных позициях и переводить выбранные активы в денежные средства, если доходность за период формирования была неположительной.
Метрики бэктеста или оптимизации отсутствуют, поскольку проверка не завершилась. После пяти итераций бэктест в песочнице на слое 3 превысил лимит в 300 секунд примерно на 20,000 барах.
Анализ
Максимальная просадка, восстановление и импульс
Обзор бэктеста
- Шарп
- 0,90
- Общая доходность
- 296,20%
- Максимальная просадка
- 36,10%
- Всего сделок
- 105
- Доля прибыльных
- 45,7%
- Профит-фактор
- 2,26
Stratmill — это инструмент для исследований и бумажной торговли, а не финансовая консультация или брокер. Результаты бэктестов и бумажной торговли являются гипотетическими. Торговля сопряжена с риском убытков.