Перейти к содержимому
Все стратегии

Стратегии

Моментум по месячному рангу максимальной просадки на Binance Spot: держать 5 активов с наименьшим значением-30-дневного-MDD из актуального на дату отбора топ--20 по ликвидности; только длинные позиции, иначе кэш, если доходность за период формирования <= 0 (Choi 2014, DAILY баров)

Итог: Отменено

MddRankedMonthlyMomentumSpotTop5

Сводка по итогам

Стратегия тестировала ротацию Binance Spot только с длинными позициями: выбирала активы с наименьшей просадкой из ликвидной вселенной на каждый момент времени и переводила активы в денежные средства при неположительной доходности за период формирования. Метрики доходности не получены из-за тайм-аута проверки на слое 3. После пяти итераций запуск оставили на этапе проверки; до следующих этапов конвейера он не дошёл.

Гипотеза

Классификация: (a) конкретное проверяемое правило. В аннотации заявлены две гипотезы: (1) на горизонте MONTHLY ранжирование активов по максимальной просадке (MDD) за период формирования и покупка активов с наименьшим значением MDD превосходят классический моментум по накопленной доходности; (2) на горизонте WEEKLY ранжирование по восстановлению выявляет возврат к среднему. Мы проверяем гипотезу ONLY (1). Гипотеза 2 — недельный контрарный портфель с поперечным ранжированием; недельный разворот на крипторынке……Показать большеСвернуть

Классификация: (a) конкретное проверяемое правило. В аннотации заявлены две гипотезы: (1) на горизонте MONTHLY ранжирование активов по максимальной просадке (MDD) за период формирования и покупка активов с наименьшим значением MDD превосходят классический моментум по накопленной доходности; (2) на горизонте WEEKLY ранжирование по восстановлению выявляет возврат к среднему. Мы проверяем гипотезу ONLY (1). Гипотеза 2 — недельный контрарный портфель с поперечным ранжированием; недельный разворот на крипторынке относится к неудачной семье стратегий mean_reversion / с нейтральными несколькими позициями (L113, L137), поэтому мы его не предлагаем. Гипотеза 1 переформулирована для длинных позиций на BINANCE_SPOT — подходящей площадке для ротации длинных позиций без плеча (спот составляет 10.9% корпуса при целевом значении >=15%). Короткая позиция в активе с высокой MDD не рассматривается, поскольку у нейтральных портфелей с несколькими позициями 0 выживших стратегий (L137). Вселенная (состав на каждую дату, по L151): разработчик загружает пул-кандидат из спотовых пар Binance USDT как extra_instruments. При каждой ежемесячной ребалансировке актив допускается в выборку ELIGIBLE, только если к этой дате у него есть >= 60 дневных баров истории и он входит в топ-20 по долларовому объёму за предыдущие -30 дней (цена закрытия*объём) на эту дату. Ещё не торгующиеся активы и активы с устаревшими или отсутствующими барами автоматически исключаются. Сам пул — это выбор, сделанный в 2026, и мы указываем его явно: это 20 крупнейших спотовых пар USDT, а фильтр на каждую дату определяет состав. Формирование: для каждого подходящего актива рассчитать MDD по ценам закрытия за последние 30 дней: MDD = максимум по t от (1 - close_t / running_max_close_up_to_t). Сортировать по MDD по возрастанию (наименьшая просадка = сильнейший актив). Удержание: 5 активов с наименьшим значением MDD, с равными весами по 19% капитала каждый (95% брутто, 1x, денежный счёт). Предусмотрено ONE абсолютное условие, задающее заявленное состояние вне рынка: если доходность выбранного актива за 30 дней <= 0, он заменяется кэшем, а не следующим активом в рейтинге. Актив с почти нулевым значением MDD может иметь слегка отрицательную доходность при затяжном снижении, поэтому это условие переводит портфель в кэш в медвежьи месяцы. Ожидаемая доля времени вне рынка — около 25-35% календарного времени, преимущественно в 2022 и похожих режимах. Согласно L130, отметим: это условие входит в заранее зарегистрированное основное правило, поскольку корзина альтернативных активов для длинных позиций без такого фильтра имела бы просадку около 70% в 2022, а такую гипотезу нельзя реализовать на практике. Вариант B (без фильтра, чистое ранжирование по MDD) заранее зарегистрирован как отдельное сравнение. Проверяемое утверждение — собственное прямое сравнение в статье: портфель с рангом по MDD должен превзойти портфель, построенный так же и ранжированный по накопленной доходности за 30 дней, по коэффициенту Шарпа на OOS. Этот портфель с ранжированием по доходности по сути представляет собой существующую спотовую ротацию, коэффициент Шарпа которой в статье равен -2.14. Если ранжирование по MDD не превзойдёт его, вывод статьи не применим к крипторынку. Примечание по реализации (7 недавних сбоев sandbox_timeout): хранить фиксированный кольцевой буфер из 60 ячеек с ценами закрытия и объёмами для каждого инструмента в on_bar/on_extra_bar, рассчитывая MDD и долларовый объём ONLY на баре ребалансировки (O(20*30) раз в месяц). Не пересчитывать всю историю на каждом баре.

Оба замечания проверили непосредственно на платформе. (1) Окно, заканчивающееся на 2024-06-17, ограничено NOT бюджетом баров, и исправить это в коде стратегии нельзя. По всем 20 инструментам в каталоге есть дневные бары вплоть до 2026-09-28 (проверено в data/catalog). Агент бэктестинга передаёт end=final_exam_boundary (backtest_agent.py:341, pipeline_processor._final_exam_boundary_iso -> src/optimization/vault). Зафиксированное хранилище финальной проверки гипотезы начинается примерно с 2024-06-17. По замыслу……Показать большеСвернуть

Оба замечания проверили непосредственно на платформе. (1) Окно, заканчивающееся на 2024-06-17, ограничено NOT бюджетом баров, и исправить это в коде стратегии нельзя. По всем 20 инструментам в каталоге есть дневные бары вплоть до 2026-09-28 (проверено в data/catalog). Агент бэктестинга передаёт end=final_exam_boundary (backtest_agent.py:341, pipeline_processor._final_exam_boundary_iso -> src/optimization/vault). Зафиксированное хранилище финальной проверки гипотезы начинается примерно с 2024-06-17. По замыслу отрезок [boundary, catalog end) считывается ровно один раз при утверждении (_take_final_exam) с оптимизированными параметрами. Расширение исследовательского окна израсходовало бы отложенную выборку. Если аналитик хочет включить 2024-H2..2026 в исследовательскую выборку, оператору нужно переместить или разблокировать хранилище. (2) rank_by по {mdd, return} уже реализован (см. _rank). Запустите парный вариант с той же конфигурацией и параметрами.rank_by='return'. В этой итерации изменился только код без изменения поведения: _rank обращается напрямую к кольцевому буферу вместо копирования всей очереди, что сокращает затраты на ребалансировку после последнего повтора из-за ограничения времени выполнения в песочнице. Конфигурация, набор инструментов, параметры и торговая логика побайтно совпадают с предыдущим запуском, поэтому результаты можно напрямую сравнивать.

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 — это инструмент для исследований и бумажной торговли, а не финансовая консультация или брокер. Результаты бэктестов и бумажной торговли являются гипотетическими. Торговля сопряжена с риском убытков.