Стратегии
vn.py DualThrustStrategy от 用Python的交易员: точный перенос AVAX на бессрочный контракт
Итог: Отменено
AvaxVnpyDualThrust
Сводка по итогам
AvaxVnpyDualThrust воспроизвела правила исходной стратегии: пробой диапазона предыдущего календарного дня и разворот на AVAX бессрочных контрактах, с размером позиции относительно капитала и выходом по таймеру через UTC. После двух итераций бэктест за всю историю дал 1,388 закрытых сделок, доходность -47.33% и коэффициент Шарпа -3.044; каждый календарный год был убыточным. Обзор бэктеста привёл к отказу от замороженного воспроизведения из-за отрицательного математического ожидания. Выявленных дефектов или разрешённых путей настройки, которые оправдывали бы оптимизацию, не обнаружено; до последующих этапов дело не дошло.
Гипотеза
Перенесите предоставленную DualThrustStrategy, распространяемую по лицензии MIT, в FactoryStrategy, сохранив торговые ветви и значения по умолчанию: k1=0.4, k2=0.6, fixed_size=1, exit_time=14:55 и load_bar(10). Торгуйте инструментом AVAXUSDT.BINANCE, используя бары 1-MINUTE, неттинговый счет MARGIN и кредитное плечо=1.0. Исходные инструмент, часовой пояс и множитель контракта не указаны; в этом эксперименте явно выбираются AVAX и UTC. Источник: [DualThrustStrategy для vn.py от трейдера, использующего Python](https://github.com/vnpy/vnpy_ctastrategy/blob/6ef76981624bf55b2ea978f8587f74d633aafc72/vnpy_ctastrategy/strategies/dual_thrust_strategy.py). В этой реализации используется разница между максимумом и минимумом предыдущего накопленного календарного дня, а не классическая формула диапазона Dual Thrust за несколько дней. Сохраните правила сигналов и ордеров; единственная адаптация размера позиции — сопоставление одной единицы размера из исходника с количеством на платформе, пропорциональным капиталу. Показатели эффективности не проверены.
Пользователь просит точное воспроизведение, поэтому не следует добавлять индикаторы, фильтры рыночного режима, цели прибыли или оптимизированные пороги. Для длинных и коротких позиций нужны фьючерсы. Binance представлена в данных избыточно, но её многолетняя поминутная история подходит для этих точных внутридневных часов; поминутная история Hyperliquid — нет. AVAX позволяет избежать ещё одного эксперимента с BTC, хотя предоставленный пустой corpus_concentration не подтверждает её историческую долю. Объём в один инструмент сохраняется, поскольку добавление хеджирующих позиций изменило бы запрошенный механизм.
negative_expectancy: это замороженное воспроизведение стратегии AVAX на бессрочных контрактах Binance с таймфреймом 1 UTC приносит убыток по 1,388 закрытым сделкам. Средняя чистая доходность сделки составляет -0.612% при минимальном пороге обзора фьючерсных стратегий +0.15%; значение PF — 0.573, а общая доходность — -47.331%. Каждый календарный год убыточен. Опасения QA подтверждены данными за всю историю. Выявленных дефектов или разрешённых путей настройки, которые оправдывали бы оптимизацию, нет. Это отвергает только заданное воспроизведение, а не стратегию автора исходного кода на его неуказанных оригинальных рынке и торговой сессии. Сбои данных или учёта не утверждаются.
Реализация
Точный перенос DualThrust из vn.py на AVAXUSDT.BINANCE с барами по 1 мин.: дневной диапазон по максимуму и минимуму предыдущего UTC дня; стоп-заявки на покупку по open+k1*range и на продажу по open-k2*range, разворот по противоположной границе (один раз в день для каждой стороны) и рыночный лимитный выход в 14:55 UTC.
Исправление по результатам итерации: исходный код отменяет и заново выставляет все стоп-заявки на каждом баре; на барах по 1 минут это означало около 1440 циклов отмены и выставления в день. Теперь стратегия сохраняет активные стоп-заявки, пока желаемый набор стопов (сторона, объём, триггер, reduce-only) не меняется, и отменяет и выставляет их заново только при изменении набора (новый день, изменение позиции, смена стороны относительно открытия дня или исполнение заявки). Экономический результат совпадает с отменой и выставлением на каждом баре, поскольку триггеры и объёмы в течение дня не меняются. Лимитная заявка выхода по времени по-прежнему выставляется заново на каждом баре по последней цене закрытия, как и в исходном коде. Сигнал, размер позиции, параметры и бар по 1 минут не изменены.
Результаты верификации
При желании замените пару одной стоп-заявкой без reduce-only объёмом position_qty + size — это напрямую соответствует неттингу. Это необязательно.
Разворот выполняется стоп-заявкой только на закрытие позиции и отдельной стоп-заявкой на вход, обе по одному триггеру. На счёте NETTING итог соответствует исходному действию «продать fixed_size, затем открыть короткую позицию fixed_size» только в том случае, если первым исполнится заявка на закрытие позиции. Код отправляет её первой, поэтому это условие должно выполняться. Если первой обработают стоп-заявку на вход, она закроет позицию, стоп-заявка только на закрытие будет отклонена, и в итоге позиция будет нулевой, а не короткой.
Не требуется.
Когда цена закрытия уже пересекла триггер, _source_stop отправляет рыночную заявку по цене закрытия бара. В бэктестинге vn.py локальный стоп, который уже пересечён, исполняется на открытии следующего бара; поэтому на площадке типа 24/7 эти два варианта экономически эквивалентны (execution_capabilities указывает next_bar_open_fill как use_equivalent). Этот рыночный путь обходит проверки прогрева и заморозки начальных данных внутри _submit_stop_market. Это безопасно, поскольку базовый класс вызывает _process_primary только вне прогрева и заморозки, а seen_bars также ограничивает торговлю.
Согласовать сведения об источнике с цитатой в гипотезе.
Сведения об источнике URL указывают на коммит 5da04d9, а гипотеза ссылается на 6ef7698. Предполагается, что файл DualThrust идентичен в обоих коммитах, поэтому это лишь расхождение метаданных.
В симуляции было 3 закрытых сделок за 5 дней, все убыточные (среднее -0.75% от номинала, около -$74 за сделку при номинале около $10 тыс., -0.22% капитала). Этой выборки слишком мало для выводов. Это пробой и разворот по диапазону одного дня на 1-минутных барах AVAX с принудительным закрытием в 14:55 UTC. Исходный код создан для биржевой сессии, а гипотеза привязывает дневные часы к произвольному времени UTC на рынке, работающем 24/7. Аналитику следует проверить, превышает ли движение цены в сделке (несколько процентов дневного диапазона) затраты около 0.10% за круговую сделку с учётом воздействия на цену. В симуляции воздействие на цену ($144) было примерно равно 5x комиссии ($30). Также следует проверить, как часто за день срабатывают обе границы: в таких случаях резкие колебания приводят к убыткам на обоих этапах.
Обзор бэктеста
- Шарп
- -3,04
- Общая доходность
- -47,33%
- Максимальная просадка
- 48,46%
- Всего сделок
- 1388
- Доля прибыльных
- 36,9%
- Профит-фактор
- 0,57
Надёжное измерение за всю историю: 1,388 закрытых сделок за 2,200 дней, корректный учёт и отсутствие открытых позиций на конец периода.
Записи сделок соответствуют разворотам при пробое, размеру позиции относительно капитала и выходу по таймеру через UTC.
Опасения QA относительно экономической целесообразности подтвердились: средняя чистая доходность сделки — -0.612%, PF 0.573, коэффициент Шарпа — -3.044, общая доходность — -47.331%. Каждый календарный год убыточен.
Оба направления торговли встречаются в 100 из 1,288 дней входа; на эти дни приходится около -$35,058 отражённого в отчёте результата по сделкам.
Расчётное влияние проскальзывания составляет $21,029 при комиссиях $7,775; даже полное устранение влияния проскальзывания оставило бы значительные убытки.
Доходность стратегии «купи и держи» на выбранном участке составляет +163.01% при просадке около 94.99%, тогда как просадка стратегии — 48.46%.
Все параметры контракта заморожены; выявленного дефекта реализации, который оправдывал бы ещё одну итерацию, нет.
Анализ
Сохранять активные стопы, а не отменять и выставлять заново на каждом баре, либо использовать более крупный интервал бара
История итераций
Проверка не пройдена (уровень 1.5 — согласованность гипотезы и конфигурации) [класс=hypothesis_mismatch]: - optimization_plan фиксирует плечо на уровне 1.0
Закрывать полную позицию position.quantity стоп-заявкой разворота reduce-only, как фактически делает vn.py при fixed_size == pos.
Объём закрытия при развороте равен min(size, position.quantity), где size — пересчитываемое ежедневно значение unit_quantity. Если позиция сохраняется до нового UTC дня (например, лимитная заявка выхода по времени в 14:55 каким-то образом не исполнилась до полуночи), значение unit_quantity нового дня может быть меньше удерживаемого объёма. Тогда стоп-заявка reduce-only закроет лишь часть позиции, оставив остаток, к которому добавится следующая входная позиция. При обычной работе рыночная лимитная заявка 0.99/1.01 исполняется на следующем баре, поэтому такой сценарий редок.
Для этой площадки изменений не требуется; оставьте переопределение задокументированным.
_process_primary и min_bars_required переопределяют базовые методы фреймворка (это отметил статический анализ). Я сверил это с base_template: прогрев, заморозка воспроизведения и проверки устаревших баров выполняются в _maybe_process_primary до вызова _process_primary, поэтому они по-прежнему действуют. Немедленный путь рыночной заявки в _source_stop обходит проверку нехватки средств в _submit_stop_market, но BINANCE — площадка типа MARGIN, поэтому здесь это безвредно.
Ничего. Особенность точно воспроизведена, а прогрев нейтрализует её.
Эта особенность исходного кода намеренно воспроизведена. В первый обрабатываемый день day_low начинается со значения 0, а min(0, low) оставляет его на 0, поэтому первый диапазон равен day_high. Этот некорректный диапазон влияет только на первый день, который попадает в период прогрева: 10 дней (14400 баров). Поэтому в сделках он не используется.
Сводка по итогам
Даже точный перенос исходного кода требует экономической проверки с учётом особенностей конкретного рынка; эти результаты отвергают заданное воспроизведение AVAX/UTC, а не исходную стратегию на неуказанных оригинальных рынке и торговой сессии.
Обзор бэктеста вынес вердикт об отказе из-за отрицательного математического ожидания и невыполнения порога +0.15% средней доходности сделки. Поскольку параметры заморожены и дефект реализации не выявлен, до оптимизации и последующих этапов обзора дело не дошло.
Точно перенесите правила vn.py для пробоя дневного диапазона и разворота на AVAX бессрочных контрактах Binance с минутными барами, используя замороженные значения по умолчанию, размер позиции относительно капитала и выход по таймеру через 14:55 UTC.
За 2,200 дней бэктест по 1,388 закрытым сделкам показал доходность -47.33%, коэффициент Шарпа -3.044 и максимальную просадку 48.46%. Средняя чистая доходность сделки составила -0.612%, коэффициент прибыльности — 0.573; каждый календарный год завершился убытком.
Анализ
DualThrustStrategy
Stratmill — это инструмент для исследований и бумажной торговли, а не финансовая консультация или брокер. Результаты бэктестов и бумажной торговли являются гипотетическими. Торговля сопряжена с риском убытков.