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

Стратегии

ETH OKX vn.py AtrRsiStrategy — перенос исходных настроек без изменений

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

EthOkxFrozenAtrRsiStrategy

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

EthOkxFrozenAtrRsiStrategy выполнила перенос стратегии ATR/RSI из vn.py с фиксированными исходными настройками и размером позиции относительно капитала. Проверочная симуляция за пять дней показала -0.139% на сделку по 38 закрытым позициям и коэффициент прибыли 0.626. После трёх итераций QA всё ещё выявлял несоответствие источнику при исполнении входов и трейлинг-стопа, поэтому работу прекратили до полного бэктестинга или оптимизации.

Гипотеза

Точный перенос сигналов и ордеров AtrRsiStrategy автора 用Python的交易员, лицензия MIT. Источник: https://github.com/vnpy/vnpy_ctastrategy/blob/6ef76981624bf55b2ea978f8587f74d633aafc72/vnpy_ctastrategy/strategies/atr_rsi_strategy.py. Сохрани atr_length=22, atr_ma_length=10, rsi_length=5, rsi_entry=16, trailing_percent=0.8 и fixed_size=1. Используй бессрочный контракт ETHUSDT.OKX и завершённые бары 1-MINUTE, соответствующие генератору баров по умолчанию в источнике, который агрегирует тики в минутные бары. Не выполняй……Показать большеСвернуть

Точный перенос сигналов и ордеров AtrRsiStrategy автора 用Python的交易员, лицензия MIT. Источник: https://github.com/vnpy/vnpy_ctastrategy/blob/6ef76981624bf55b2ea978f8587f74d633aafc72/vnpy_ctastrategy/strategies/atr_rsi_strategy.py. Сохрани atr_length=22, atr_ma_length=10, rsi_length=5, rsi_entry=16, trailing_percent=0.8 и fixed_size=1. Используй бессрочный контракт ETHUSDT.OKX и завершённые бары 1-MINUTE, соответствующие генератору баров по умолчанию в источнике, который агрегирует тики в минутные бары. Не выполняй агрегацию старшего таймфрейма, не добавляй фильтры и не подбирай параметры. Явно разрешённая адаптация размера позиции для платформы: fixed_size=1 задаёт одну аллокацию относительно капитала; при входе её размер равен 10% текущего капитала в номинальном выражении и округляется вниз до точности количества инструмента. Удерживай это количество до выхода; не наращивай позицию. Кредитное плечо в конфигурации=1.0. Начальный капитал — $100,000. Инициализация источника запрашивает исторические бары за десять дней; поддерживай скользящий буфер, эквивалентный ArrayManager на 100 баров, и не торгуй, пока он не инициализирован. Журналирование и обратные вызовы событий не генерируют сигналы; обратные вызовы ордеров и стоп-ордеров в остальном ничего не делают.

В заявке заданы исполняемые правила входа и выхода. Требование пользователя точно воспроизвести стратегию важнее, чем изобретение другого механизма для выполнения квот разнообразия. OKX недопредставлен: 2.3% при целевом значении 5%; кроме того, стратегия допускает оба направления, тогда как портфель 82.6% ориентирован только на длинные позиции. Концентрация корпуса отсутствует, поэтому новизну на уровне инструментов установить нельзя. ETH делает буквальное смещение ордера на пять ценовых единиц более соразмерным, чем для дешёвого альткоина. Здесь проверяется импульс на расширении волатильности, а не несработавшая стратегия возврата к среднему Connors-BTC RSI. Экономическая состоятельность не подтверждена; исходным параметрам следует дать возможность не сработать без последующей подгонки.

verification_loop: проверка не пройдена (уровень 4 — обзор QA) [класс=hypothesis_mismatch]: - [edge_concern] Пятидневный пробный тест показал -0.139% на сделку по 38 закрытым позициям, при этом PF 0.626. При оценке на полной истории следует изучить оборот и отдачу прибыли из-за трейлинг-стопа; сами по себе эти результаты не являются основанием для отклонения стратегии. - [критично] Резервный сценарий при пересечении стопа не сохраняет исходное исполнение. _submit_exit() немедленно вызывает close_position(); у OKX……Показать большеСвернуть

verification_loop: проверка не пройдена (уровень 4 — обзор QA) [класс=hypothesis_mismatch]: - [edge_concern] Пятидневный пробный тест показал -0.139% на сделку по 38 закрытым позициям, при этом PF 0.626. При оценке на полной истории следует изучить оборот и отдачу прибыли из-за трейлинг-стопа; сами по себе эти результаты не являются основанием для отклонения стратегии. - [критично] Резервный сценарий при пересечении стопа не сохраняет исходное исполнение. _submit_exit() немедленно вызывает close_position(); у OKX задана нулевая задержка, поэтому Nautilus исполняет ордер по текущему рынку на закрытии бара принятия решения, а не на открытии следующего бара. Кроме того, vn.py проверяет обновлённый стоп на диапазоне следующего бара: гэп обратно выше стопа для длинной позиции может оставить его несработавшим. Безусловный рыночный выход меняет и время, и условия срабатывания. Источник: https://raw.githubusercontent.com/vnpy/vnpy_ctastrategy/6ef76981624bf55b2ea978f8587f74d633aafc72/vnpy_ctastrategy/backtesting.py (строка 163) — исправление: Реализовать отложенные стопы по образцу исходной системы, проверяемые по последующим рыночным данным, с сохранением условного срабатывания и исполнения по цене гэпа. При необходимости добавить в движок хук исполнения; не заменять стоп немедленным закрытием по рынку. Проверить обычное пересечение, гэп через стоп и гэп в сторону от стопа для обоих направлений. - [критично] Лимитные ордера BUY по цене закрытия+$5 и SELL по цене закрытия-$5 становятся исполнимыми по рынку при отправке в книгу Nautilus с текущей ценой закрытия. При post_only=False и нулевой задержке OKX они могут исполниться на сигнальном баре. Исходный бэктестер сопоставляет существующие ордера до вызова on_bar, поэтому новые лимитные ордера впервые могут исполниться на следующем баре, при этом ограничение по цене сохраняется. Это меняет входы, обработку гэпов и последующее состояние трейлинг-стопа. Источник: https://raw.githubusercontent.com/vnpy/vnpy_ctastrategy/6ef76981624bf55b2ea978f8587f74d633aafc72/vnpy_ctastrategy/backtesting.py (строка 144) — исправление: Обеспечить активацию на следующем баре с исходной лимитной ценой и объёмом, рассчитанным для входа. Убедиться, что вход не исполняется на сигнальном баре и что гэп на следующем баре за пределы лимита препятствует исполнению на открытии, если диапазон следующего бара не достигает лимитной цены.

Реализация

Зафиксированный перевод AtrRsiStrategy из vn.py на бары ETHUSDT.OKX длительностью 1 минут. Когда ATR(22) выше среднего за 10 баров и RSI(5) выше 66 (или ниже 34), стратегия входит в позицию лимитным ордером по цене закрытия +/- $5 (или по зеркальному значению для коротких позиций). Выход осуществляется только через трейлинг-стоп 0.8%, который обновляется каждый бар. Номинальный объём каждой позиции составляет 10% собственного капитала.

Итерация 3 исправляет критический дефект QA. Площадка отклоняет повторно выставленный трейлинг-стоп, который уже пересёк цену закрытия бара (reject_stop_orders=True), из-за чего у позиции не было выхода. Теперь, если уровень стопа уже пересечён (stop >= close для длинной позиции, stop <= close для короткой), стратегия закрывает позицию рыночным ордером только для сокращения на следующем баре. Это соответствует vn.py, где такой стоп срабатывает на следующем баре примерно по цене открытия. В остальных случаях обновлённый STOP_MARKET остаётся на площадке отложенным, как и прежде. В качестве дополнительной защиты on_order_rejected закрывает позицию, если отклонён любой STOP_MARKET. Логика входа, индикаторы, размер позиции и все зафиксированные параметры не изменились. QA также обратил внимание на крайний случай: бары по 1 минут, ордера тейкера на входе и выходе и до 0.8%, отдаваемых в каждой сделке. Это свойство исходных настроек, которые, согласно гипотезе, должны иметь возможность не пройти проверку без спасательной настройки. Настройка параметров не проводилась.

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

Проверка не пройдена (уровень 4 — обзор QA) [класс=hypothesis_mismatch]: - [edge_concern] Пятидневный пробный тест показал -0.139% на сделку по 38 закрытым позициям, при этом PF 0.626. При оценке на полной истории следует изучить оборот и отдачу прибыли из-за трейлинг-стопа; сами по себе эти результаты не являются основанием для отклонения стратегии. - [критично] Резервный сценарий при пересечении стопа не сохраняет исходное исполнение. _submit_exit() немедленно вызывает close_position(); у OKX задана нулевая……Показать большеСвернуть

Проверка не пройдена (уровень 4 — обзор QA) [класс=hypothesis_mismatch]: - [edge_concern] Пятидневный пробный тест показал -0.139% на сделку по 38 закрытым позициям, при этом PF 0.626. При оценке на полной истории следует изучить оборот и отдачу прибыли из-за трейлинг-стопа; сами по себе эти результаты не являются основанием для отклонения стратегии. - [критично] Резервный сценарий при пересечении стопа не сохраняет исходное исполнение. _submit_exit() немедленно вызывает close_position(); у OKX задана нулевая задержка, поэтому Nautilus исполняет ордер по текущему рынку на закрытии бара принятия решения, а не на открытии следующего бара. Кроме того, vn.py проверяет обновлённый стоп на диапазоне следующего бара: гэп обратно выше стопа для длинной позиции может оставить его несработавшим. Безусловный рыночный выход меняет и время, и условия срабатывания. Источник: https://raw.githubusercontent.com/vnpy/vnpy_ctastrategy/6ef76981624bf55b2ea978f8587f74d633aafc72/vnpy_ctastrategy/backtesting.py (строка 163) — исправление: Реализовать отложенные стопы по образцу исходной системы, проверяемые по последующим рыночным данным, с сохранением условного срабатывания и исполнения по цене гэпа. При необходимости добавить в движок хук исполнения; не заменять стоп немедленным закрытием по рынку. Проверить обычное пересечение, гэп через стоп и гэп в сторону от стопа для обоих направлений. - [критично] Лимитные ордера BUY по цене закрытия+$5 и SELL по цене закрытия-$5 становятся исполнимыми по рынку при отправке в книгу Nautilus с текущей ценой закрытия. При post_only=False и нулевой задержке OKX они могут исполниться на сигнальном баре. Исходный бэктестер сопоставляет существующие ордера до вызова on_bar, поэтому новые лимитные ордера впервые могут исполниться на следующем баре, при этом ограничение по цене сохраняется. Это меняет входы, обработку гэпов и последующее состояние трейлинг-стопа. Источник: https://raw.githubusercontent.com/vnpy/vnpy_ctastrategy/6ef76981624bf55b2ea978f8587f74d633aafc72/vnpy_ctastrategy/backtesting.py (строка 144) — исправление: Обеспечить активацию на следующем баре с исходной лимитной ценой и объёмом, рассчитанным для входа. Убедиться, что вход не исполняется на сигнальном баре и что гэп на следующем баре за пределы лимита препятствует исполнению на открытии, если диапазон следующего бара не достигает лимитной цены.

Реализуй отложенные стопы по логике источника, проверяя их по последующим рыночным данным и сохраняя условное срабатывание и исполнение по цене с учётом гэпа. При необходимости добавь хук исполнения движка; не заменяй стоп немедленным рыночным закрытием. Проверь обычное пересечение, гэп через стоп и гэп в сторону от стопа для обоих направлений.

Запасной выход при пересечении стопа не сохраняет исполнение исходной стратегии. _submit_exit() немедленно вызывает close_position(); у OKX настроенная задержка равна нулю, поэтому Nautilus исполняет ордер по текущему рынку на закрытии бара принятия решения, а не на открытии следующего бара. Кроме того, vn.py проверяет обновлённый стоп по диапазону следующего бара: гэп выше стопа для длинной позиции может оставить его неактивированным. Безусловный рыночный выход меняет и время, и условия срабатывания. Источник: https://raw.githubusercontent.com/vnpy/vnpy_ctastrategy/6ef76981624bf55b2ea978f8587f74d633aafc72/vnpy_ctastrategy/backtesting.py

Активируй на следующем баре исходную лимитную цену и размер позиции, рассчитанный при входе. Проверь, что вход не исполняется на сигнальном баре и что гэп на следующем баре за пределы лимита не приводит к исполнению на открытии, если последующий диапазон не достигает лимита.

Лимитные ордера BUY по цене закрытия+$5 и SELL по цене закрытия-$5 становятся исполнимыми по рынку при отправке в книгу Nautilus с текущей ценой закрытия. При post_only=False и нулевой задержке OKX они могут исполниться на сигнальном баре. Исходный бэктестер сопоставляет существующие ордера до вызова on_bar, поэтому новые лимитные ордера впервые могут исполниться на следующем баре, при этом ограничение по цене сохраняется. Это меняет входы, обработку гэпов и последующее состояние трейлинг-стопа. Источник: https://raw.githubusercontent.com/vnpy/vnpy_ctastrategy/6ef76981624bf55b2ea978f8587f74d633aafc72/vnpy_ctastrategy/backtesting.py

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

Проверка не пройдена (уровень 1.5 — согласованность гипотезы и конфигурации) [класс=hypothesis_mismatch]: - optimization_plan фиксирует плечо на уровне 1.0

Проверка не пройдена (уровень 4 — проверка QA) [класс=code_defect]: - [edge_concern] Песочница: 38 сделок за 5 дней, avg_trade_return_pct -0.139%, PF 0.63, комиссии составили 43% от валового результата. И вход (лимитный ордер на закрытии±$5, поэтому он пересекает цену и исполняется как ордер тейкера), и выход (стоп-маркет) оплачиваются по ставкам тейкера — около 0.10% за сделку туда и обратно. Каждая сделка может отдать до 0.8% через трейлинг-стоп, а сигнал 1-минутного RSI(5)>66 должен покрывать эти издержки……Показать большеСвернуть

Проверка не пройдена (уровень 4 — проверка QA) [класс=code_defect]: - [edge_concern] Песочница: 38 сделок за 5 дней, avg_trade_return_pct -0.139%, PF 0.63, комиссии составили 43% от валового результата. И вход (лимитный ордер на закрытии±$5, поэтому он пересекает цену и исполняется как ордер тейкера), и выход (стоп-маркет) оплачиваются по ставкам тейкера — около 0.10% за сделку туда и обратно. Каждая сделка может отдать до 0.8% через трейлинг-стоп, а сигнал 1-минутного RSI(5)>66 должен покрывать эти издержки примерно 7 раз в день. За историю длиной около 2,444 дней ожидаются тысячи сделок. После исправления стопа сначала проверь валовую доходность на сделку относительно порога 0.15%. При таком числе сделок значение PF около 1 указывало бы на ошибочное измерение, а не на параметр для настройки. - [критично] Трейлинг-стоп повторно выставляется на каждом баре как отдельный STOP_MARKET на уровне intra_trade_high*(1-0.8%) для длинных позиций (или intra_trade_low*(1+0.8%) для коротких). Этот уровень учитывает максимум (или минимум) текущего бара. Если бар закрывается более чем на 0.8% ниже своего максимума, новый стоп для длинной позиции уже находится на рынке в момент выставления. На площадке бэктеста OKX по умолчанию включён параметр NautilusTrader reject_stop_orders=True; в engine.pyx функция _process_stop_market_order отмечает сработавший стоп как REJECTED, но не исполняет его. should_exit() всегда возвращает False, поэтому в этом баре у позиции нет выхода. На следующих барах уровень стопа может только повышаться для длинных позиций или понижаться для коротких, поэтому он остаётся на рынке и продолжает отклоняться, пока цена не вернётся выше него. Убыток по позиции может расти без ограничения. В vn.py тот же стоп срабатывает на следующем баре и исполняется примерно по цене открытия. Таким образом, единственный выход гипотезы — трейлинг-стоп 0.8% — реализован ненадёжно. Это затрагивает именно выбранный стратегией режим высокой волатильности ATR>ATR_MA, включая сигнальный бар с длинной тенью, если он становится первым баром срабатывания стопа. В песочнице за 5 дней такого случая не было (максимальный убыток — -0.96% от номинала), но за примерно 2,444 дней на 1-минутных барах ETH он возникнет. (строка 186) — исправление: перед вызовом _submit_stop_market проверь, пересечён ли уровень стопа. Для длинной позиции проверь stop >= current_close; для короткой — stop <= current_close. Если условие выполнено, вызови self._submit_exit(position) (рыночное закрытие только для сокращения позиции), как при срабатывании стопа в vn.py на следующем баре. Иначе выставь отложенный стоп, как сейчас. В качестве дополнительной защиты также отслеживай отклонённые стоп-ордера, например в on_order_rejected, и закрывай позицию. - [предупреждение] entry_price_offset — фиксированная величина $5. Это около 0.13-0.33% от цены ETH за всю историю, поэтому лимитный ордер на вход всегда пересекает цену и исполняется как ордер тейкера на следующем баре. Это соответствует источнику и не является дефектом. Учти, что vn.py исполняет ордер по меньшему из лимитной цены и цены открытия следующего бара; Nautilus ведёт себя аналогично. (строка 133) — исправление: изменения не требуются; замечание зафиксировано для аналитика.

Перед вызовом _submit_stop_market проверь, пересечён ли уровень стопа. Для длинной позиции проверь stop >= current_close; для короткой — stop <= current_close. Если условие выполнено, вызови self._submit_exit(position) (рыночное закрытие только для сокращения позиции), как при срабатывании стопа в vn.py на следующем баре. Иначе выставь отложенный стоп, как сейчас. В качестве дополнительной защиты также отслеживай отклонённые стоп-ордера, например в on_order_rejected, и закрывай позицию.

Трейлинг-стоп повторно выставляется на каждом баре как отдельный STOP_MARKET на уровне intra_trade_high*(1-0.8%) для длинных позиций (или intra_trade_low*(1+0.8%) для коротких). Этот уровень учитывает максимум текущего бара (или минимум). Если бар закрывается ниже собственного максимума более чем на 0.8%, новый стоп для длинной позиции уже находится в рынке в момент его выставления. Тестовая площадка OKX выполняет бэктест с параметром NautilusTrader reject_stop_orders=True по умолчанию; в engine.pyx, в……Показать большеСвернуть

Трейлинг-стоп повторно выставляется на каждом баре как отдельный STOP_MARKET на уровне intra_trade_high*(1-0.8%) для длинных позиций (или intra_trade_low*(1+0.8%) для коротких). Этот уровень учитывает максимум текущего бара (или минимум). Если бар закрывается ниже собственного максимума более чем на 0.8%, новый стоп для длинной позиции уже находится в рынке в момент его выставления. Тестовая площадка OKX выполняет бэктест с параметром NautilusTrader reject_stop_orders=True по умолчанию; в engine.pyx, в _process_stop_market_order, сработавший стоп REJECTED, а не исполняется. should_exit() всегда возвращает False, поэтому в этот бар у позиции нет выхода. На последующих барах уровень стопа может только повышаться (для длинных позиций) или понижаться (для коротких), поэтому он остаётся в рынке и продолжает отклоняться, пока цена не восстановится выше него. Убыток по позиции может расти без ограничений. В vn.py тот же стоп срабатывает на следующем баре и исполняется примерно по цене открытия. Таким образом, единственный выход, предусмотренный гипотезой, — трейлинг-стоп 0.8% — реализован ненадёжно. Это затрагивает именно волатильный режим ATR>ATR_MA, который выбирает стратегия, в том числе случай, когда бар сигнала с длинной тенью становится первым баром срабатывания стопа. В 5-дневном тесте это случайно не произошло (максимальный убыток составил -0.96% от номинала), но за ~2,444 дней торговли на барах длительностью 1 минут по ETH это произойдёт.

Изменения не требуются; замечание зафиксировано для аналитика.

entry_price_offset — фиксированная величина $5. Это около 0.13-0.33% от цены ETH за всю историю, поэтому лимитный ордер на вход всегда пересекает спред и исполняется как тейкер на следующем баре. Это соответствует исходной системе и не является дефектом. Следует учесть, что vn.py исполняет ордер по min(лимитная цена, цена открытия следующего бара), и Nautilus ведёт себя аналогично.

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

Точный перенос должен сохранять возможность выставления ордера на следующем баре, условное срабатывание стопа и исполнение с учётом гэпов, а также расчёты индикаторов.

После трёх итераций уровень 4 QA отклонил перевод из-за несоответствия гипотезе: рыночные выходы при пересечении стопа изменили время и условия срабатывания исходной системы, а исполнимые по рынку лимитные ордера на вход могли исполниться на сигнальном баре. Убытки в пробном тесте указывали на риск для преимущества стратегии, но сами по себе не являлись основанием для отклонения.

Перенеси стратегию ATR/RSI из vn.py с исходными настройками на бессрочные минутные бары ETHUSDT.OKX, сохранив сигналы и ордера, а размер позиции при входе установи на уровне 10% капитала с плечом 1.0.

Пятидневный проверочный смоук-тест зафиксировал -0.139% на сделку на 38 закрытых позициях при факторе прибыли 0.626. До полного тестирования на исторических данных, оптимизации, оценки аналитика и проверки рисков дело не дошло.

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

verification_loop: проверка не пройдена (уровень 4 — проверка QA) [класс=hypothesis_mismatch]: - [edge_concern] Проверочная симуляция за пять дней показала -0.139% на сделку по 38 закрытым позициям, с PF 0.626. При оценке на полной истории следует проверить частоту торговли и отдачу прибыли через трейлинг-стоп; эти результаты сами по себе не блокируют стратегию. - [критично] Запасной выход при пересечении стопа не сохраняет исполнение исходной стратегии. _submit_exit() немедленно вызывает close_position(); у OKX……Показать большеСвернуть

verification_loop: проверка не пройдена (уровень 4 — проверка QA) [класс=hypothesis_mismatch]: - [edge_concern] Проверочная симуляция за пять дней показала -0.139% на сделку по 38 закрытым позициям, с PF 0.626. При оценке на полной истории следует проверить частоту торговли и отдачу прибыли через трейлинг-стоп; эти результаты сами по себе не блокируют стратегию. - [критично] Запасной выход при пересечении стопа не сохраняет исполнение исходной стратегии. _submit_exit() немедленно вызывает close_position(); у OKX настроенная задержка равна нулю, поэтому Nautilus исполняет ордер по текущему рынку на закрытии бара принятия решения, а не на открытии следующего бара. Кроме того, vn.py проверяет обновлённый стоп по диапазону следующего бара: гэп выше стопа для длинной позиции может оставить его неактивированным. Безусловный рыночный выход меняет и время, и условия срабатывания. Источник: https://raw.githubusercontent.com/vnpy/vnpy_ctastrategy/6ef76981624bf55b2ea978f8587f74d633aafc72/vnpy_ctastrategy/backtesting.py (строка 163) — исправление: реализуй отложенные стопы по логике источника, проверяя их по последующим рыночным данным и сохраняя условное срабатывание и исполнение по цене с учётом гэпа. При необходимости добавь хук исполнения движка; не заменяй стоп немедленным рыночным закрытием. Проверь обычное пересечение, гэп через стоп и гэп в сторону от стопа для обоих направлений. - [критично] BUY устанавливает лимит на закрытии+$5, а SELL — на закрытии-$5; при выставлении в книгу Nautilus по цене текущего закрытия они становятся рыночными. При post_only=False и нулевой задержке OKX они могут исполниться на сигнальном баре. Исходный тестировщик сначала сопоставляет существующие ордера и только затем вызывает on_bar, поэтому новые лимитные ордера становятся доступными для исполнения лишь на следующем баре, а ограничение по цене сохраняется. Это меняет входы, обработку гэпов и дальнейшее состояние трейлинг-стопа. Источник: https://raw.githubusercontent.com/vnpy/vnpy_ctastrategy/6ef76981624bf55b2ea978f8587f74d633aafc72/vnpy_ctastrategy/backtesting.py (строка 144) — исправление: активируй на следующем баре исходную лимитную цену и размер позиции, рассчитанный при входе. Проверь, что вход не исполняется на сигнальном баре и что гэп на следующем баре за пределы лимита не приводит к исполнению на открытии, если последующий диапазон не достигает лимита.

Анализ

AtrRsiStrategy

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