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

Стратегии

Предоставление ликвидности пробными заявками для покупки по выгодной цене после шоков вынужденных продаж: ступенчатые заявки мейкера ниже цены закрытия часа снижения с высоким объёмом, падение за который составляет не менее 3 сигма, выход через 12 ч (OKX USDT бессрочных контрактов ADA/DOGE/AVAX/DOT, 1H, только длинные позиции)

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

OkxForcedSellingSteppedMakerBids

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

Стратегия выставляла ступенчатые лимитные заявки маркет-мейкера после необычно сильных падений с высоким объёмом. В ходе теста в среде закрылось 294 позиций со средней доходностью -0.378% на позицию. QA выявил два несоответствия, связанных со стопом, поэтому проверка не пройдена, а запуск остановлен до полного бэктеста и оптимизации.

Гипотеза

Классификация: (a), но лишь отчасти. Публикация Zero FMZ (2015) описывает, как EXECUTE покупку, но не WHEN покупать. Вместо покупки по цене аск ты выставляешь заявку на покупку глубоко внутри спреда и постепенно повышаешь её ($1.05 -> $1.06 -> ... -> цена аск), пока нетерпеливый контрагент не исполнит её. Само по себе это не даёт преимущества: экономится часть спреда и разница комиссий мейкера и тейкера — около 0.03-0.05% на исполнение бессрочного фьючерса OKX. Этого слишком мало, чтобы обосновать стратегию, а……Показать большеСвернуть

Классификация: (a), но лишь отчасти. Публикация Zero FMZ (2015) описывает, как EXECUTE покупку, но не WHEN покупать. Вместо покупки по цене аск ты выставляешь заявку на покупку глубоко внутри спреда и постепенно повышаешь её ($1.05 -> $1.06 -> ... -> цена аск), пока нетерпеливый контрагент не исполнит её. Само по себе это не даёт преимущества: экономится часть спреда и разница комиссий мейкера и тейкера — около 0.03-0.05% на исполнение бессрочного фьючерса OKX. Этого слишком мало, чтобы обосновать стратегию, а урок L167 исключает перенос тикового цикла короче секунды в его нынешнем виде. Поэтому мы сохраняем механизм и формулируем его на уровне баров, связывая с моментом, когда предпосылка публикации наиболее убедительна: нетерпеливые продавцы платят за немедленное исполнение. Для свопов OKX USDT сигналом служит бар 1-HOUR, логарифмическая доходность которого ниже -k x почасовая сигма за предыдущие 30 дней, а объём не меньше 3x от медианного почасового объёма за предыдущие 7 дней. Это час принудительных или нетерпеливых продаж (срабатывание стопов, ликвидации). После сигнала мы действуем как охотник за выгодной ценой. В течение следующих 3 баров выставляем лимитную заявку мейкера на покупку LIMIT, начиная далеко от рынка и постепенно приближая её к нему: заявка на покупку бара 1 = цена закрытия x exp(-1.0 x сигма x depth_scale), бара 2 = цена закрытия x exp(-0.5 x сигма x depth_scale), бара 3 = цена закрытия сигнального бара. Каждая неисполненная заявка отменяется при закрытии бара и заменяется следующей, более высокой (цикл отмены и повышения из публикации). Если к бару 3 ничего не исполнено, мы пропускаем событие и не догоняем рынок рыночной заявкой: исполнение происходит только тогда, когда продавцы снижаются до нашей цены. Выход по рынку через hold_bars (12ч) или раньше при стопе, эквивалентном 3 сигма. Инструменты: ADAUSDT.OKX (основной), DOGEUSDT.OKX, AVAXUSDT.OKX, DOTUSDT.OKX. Сигнал срабатывает независимо для каждого инструмента; не более одной позиции на инструмент, период охлаждения 24ч для каждого инструмента и одинаковый риск на событие. Вселенная ограничена 4 инструментами (урок L173). Источник: Zero, «Высокочастотная торговая стратегия: поиск выгодной цены», https://www.fmz.com/bbs-topic/41. source_ref: абзац, начинающийся описанием ступенчатых заявок на покупку $1.05 -> $1.06 -> $1.07.

verification_loop: проверка не пройдена (слой 4 — проверка QA) [класс=hypothesis_mismatch]: - [edge_concern] В среде было зарегистрировано 294 закрытых позиций со средней доходностью -0.378% на позицию. Полный бэктест должен оценить, покрывают ли отскоки торговые издержки; этот результат не определяет вердикт о корректности. - [критично] В гипотезе задан стоп на уровне 3 сигм, но в фиксированной конфигурации используется 4.0. Это меняет и порог выхода, и размер позиции, рассчитанный исходя из риска. (строка 123) — исправление: задать фиксированный параметр stop_sigma равным 3.0 и последовательно использовать его при расчёте размера позиции и выходах. - [критично] Код проверяет, пробил ли часовой минимум уровень стопа, только после закрытия бара, а затем отправляет рыночную заявку на выход. Следовательно, заявленный стоп не срабатывает на уровне пробоя. (строка 124) — исправление: при исполнении заявки на покупку выставлять стоп-рыночный ордер только на сокращение позиции и отменять его перед выходом по времени.

Реализация

Длинные позиции с предоставлением ликвидности по OKX USDT бессрочным контрактам (ADA — основной, DOGE/AVAX/DOT — дополнительные инструменты, 1H). По каждому инструменту сигнал срабатывает отдельно, когда часовая логарифмическая доходность <= -shock_k, умноженного на сигму за последние 720 часов, а объём >= 3x, умноженного на медиану объёма за последние 168 часов. Затем в течение 3 баров выставляется ступенчатая лестница лимитных заявок маркет-мейкера post-only: цена закрытия триггерного бара x exp(-1.0*сигма*depth_scale), затем x exp(-0.5*сигма*depth_scale), затем цена закрытия триггерного бара. Каждая неисполненная заявка отменяется и повышается; после шага 3 событие пропускается, за ценой не гонятся. Выход — рыночной заявкой через hold_bars часов или по стопу в 4 сигм. Риск — 1% на событие, лимит номинала — 25% на инструмент и 60% суммарно; период ожидания — 24ч на инструмент.

Исправление в итерации 2 для sandbox_timeout. Логика сигнала, входа, выхода и размера позиции не изменилась. (1) Медиана объёма за 168 баров вычислялась через statistics.median(), которая заново сортировала окно на каждом баре. Теперь используется инкрементально обновляемое отсортированное окно (bisect insort/remove), поэтому затраты на бар составляют O(log w) и не зависят от продолжительности бэктеста. (2) Для поиска идентификаторов инструментов в _gross_notional теперь используется кэшированный словарь……Показать большеСвернуть

Исправление в итерации 2 для sandbox_timeout. Логика сигнала, входа, выхода и размера позиции не изменилась. (1) Медиана объёма за 168 баров вычислялась через statistics.median(), которая заново сортировала окно на каждом баре. Теперь используется инкрементально обновляемое отсортированное окно (bisect insort/remove), поэтому затраты на бар составляют O(log w) и не зависят от продолжительности бэктеста. (2) Для поиска идентификаторов инструментов в _gross_notional теперь используется кэшированный словарь key->InstrumentId вместо перебора генератора. Локальный замер: BacktestRunner на ADA+DOGE/AVAX/DOT OKX 1H занял 228с по настенным часам на интервале 2024-05..2026-08. cProfile на более коротком интервале показывает, что собственный код стратегии занял около 1.5с суммарно из 281с. Примерно 260с приходится на поиск файлов ParquetDataCatalog по шаблону (spec.glob/find, около 2.4M вызовов stat в parquet.py get_file_list_from_data_cls, 216с — на два запроса bars()). Это накладные расходы, зависящие от размера каталога, а не работа стратегии на каждом баре. Согласно уроку L155(c), если среда снова прервёт выполнение по тайм-ауту, причина будет в стоимости запросов к каталогу, а не в этом коде; нужно исправить инфраструктуру (поиск по шаблону в каталоге или предварительно отфильтрованный список файлов), а не делать ещё одну итерацию кода. Примечание: некоторые лимитные заявки post-only на шаге -3 у цены закрытия триггерного бара отклоняются, поскольку пересекли бы спред. Это соответствует гипотезе: не гнаться за ценой, а пропустить событие.

Результаты верификации

Проверка не пройдена (слой 4 — проверка QA) [класс=hypothesis_mismatch]: - [edge_concern] В среде было зарегистрировано 294 закрытых позиций со средней доходностью -0.378% на позицию. Полный бэктест должен оценить, покрывают ли отскоки торговые издержки; этот результат не определяет вердикт о корректности. - [критично] В гипотезе задан стоп на уровне 3 сигм, но в фиксированной конфигурации используется 4.0. Это меняет и порог выхода, и размер позиции, рассчитанный исходя из риска. (строка 123) — исправление: задать фиксированный параметр stop_sigma равным 3.0 и последовательно использовать его при расчёте размера позиции и выходах. - [критично] Код проверяет, пробил ли часовой минимум уровень стопа, только после закрытия бара, а затем отправляет рыночную заявку на выход. Следовательно, заявленный стоп не срабатывает на уровне пробоя. (строка 124) — исправление: при исполнении заявки на покупку выставлять стоп-рыночный ордер только на сокращение позиции и отменять его перед выходом по времени.

История итераций

sandbox_timeout: проверка не пройдена (слой 3 — бэктест в среде): проверка работоспособности превысила лимит в 300с по настенным часам на окне примерно в 20000 баров (833 дней по ADAUSDT.OKX-1-HOUR-LAST-EXTERNAL). Обычно это означает, что работа на каждом баре растёт вместе с длиной истории: например, полный повторный просмотр ряда ставок финансирования/дополнительных данных или создание списка и вызов min()/sorted() внутри calculate_signal()/on_bar() на каждом баре. Предварительно вычислите отсортированные массивы временных меток ONCE в __init__ и используйте bisect либо кэшируйте поисковые результаты по временной метке, чтобы затраты на бар составляли O(log n), а не O(n).

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

Привести стоп в соответствие с гипотезой и выставлять ордер при исполнении заявки на покупку.

После двух итераций проверка слоя 4 QA провалена: настроенный стоп составлял 4 сигмы вместо предложенных 3 сигм, а код отправлял рыночную заявку на выход только после того, как бар пересекал стоп. До следующих этапов дело не дошло.

Стратегия пыталась покупать на шоках принудительных продаж по четырём бессрочным контрактам OKX USDT, используя ступенчатые лимитные заявки маркет-мейкера.

В среде было зарегистрировано 294 закрытых позиций со средней доходностью -0.378% на позицию. Полного бэктеста или отчёта об оптимизации нет.

Причина отказа

verification_loop: проверка не пройдена (слой 4 — проверка QA) [класс=hypothesis_mismatch]: - [edge_concern] В среде было зарегистрировано 294 закрытых позиций со средней доходностью -0.378% на позицию. Полный бэктест должен оценить, покрывают ли отскоки торговые издержки; этот результат не определяет вердикт о корректности. - [критично] В гипотезе задан стоп на уровне 3 сигм, но в фиксированной конфигурации используется 4.0. Это меняет и порог выхода, и размер позиции, рассчитанный исходя из риска. (строка 123) — исправление: задать фиксированный параметр stop_sigma равным 3.0 и последовательно использовать его при расчёте размера позиции и выходах. - [критично] Код проверяет, пробил ли часовой минимум уровень стопа, только после закрытия бара, а затем отправляет рыночную заявку на выход. Следовательно, заявленный стоп не срабатывает на уровне пробоя. (строка 124) — исправление: при исполнении заявки на покупку выставлять стоп-рыночный ордер только на сокращение позиции и отменять его перед выходом по времени.

Анализ

Высокочастотная торговая стратегия: охота за выгодной ценой

Stratmill — это инструмент для исследований и бумажной торговли, а не финансовая консультация или брокер. Результаты бэктестов и бумажной торговли являются гипотетическими. Торговля сопряжена с риском убытков.