Блог им. empenoso
В этой статье расскажу о том, как воспроизвел и протестировал торговую систему для фьючерсов Московской биржи, основанную на идеях Александра Резвякова. Недавно, просматривая раздел алготрейдинга на Смартлабе, я наткнулся на видео с его выступления на конференции 2024 года под названием "5-6 идей для построения прибыльной торговой системы на фьючерсах". Меня привлекла четкость и понятность предложенных им правил торговли.
Поскольку я активно занимаюсь автоматизацией процессов и стремлюсь глубже изучить возможности Python библиотеки backtesting.py, мне показалось это хорошей идеей для практического применения.
Хотя я лично не знаком с Александром, полагаю, что публичное представление идеи предполагает возможность её независимого анализа и тестирования сообществом трейдеров и программистов.
Основная идея — открывать сделки в строго определенное время и использовать структуру рынка последних дней для принятия решений.
Дополнительно предлагалось увеличивать объем позиции при успешных сделках.
Для лонга
Подготовка среды для тестированияДля реализации и тестирования стратегии Александра Резвякова я выбрал Python и библиотеку backtesting.py. Этот выбор обусловлен несколькими факторами: Python предоставляет гибкие возможности для работы с данными, а backtesting.py позволяет эффективно моделировать торговые стратегии.
В своем проекте применил модульный подход, разделив функциональность на несколько основных компонентов:
Хотя в оригинальном видео Александр Резвяков рекомендовал работать на 5-минутном таймфрейме, я принял решение использовать 1-минутные свечи. Это позволяет более детально анализировать движение цены и точнее отслеживать срабатывание трейлинг-стопов. Благодаря более гранулярным данным, становится проще визуализировать и понять всю логику выхода из позиции, особенно в критических моментах, когда цена колеблется вблизи уровня стопа.
Полный исходный код всех модулей доступен в моем репозитории на GitHub для тех, кто захочет воспроизвести эксперимент или улучшить предложенную реализацию.
Реализация стратегии на Python с использованием backtesting.pyВот подробное описание каждого шага с точки зрения программирования:
Первым шагом является загрузка и предобработка исторических данных о фьючерсах. Модуль resample_data_1min.py отвечает за получение минутных данных с использованием API брокера (в данном случае, T-Invest API) и выборку необходимых временных интервалов. Он загружает данные из CSV-файлов, содержащих котировки, и фильтрует их по заданному диапазону дат. Ключевым моментом является функция filter_by_date, которая обеспечивает выборку данных за определенный период.
save_filtered_data сохраняет обработанные данные в отдельные файлы для каждого тикера, готовые к дальнейшему использованию.
Модуль data_loader.py отвечает за загрузку исторических данных из CSV-файлов и преобразование их в формат, пригодный для использования с библиотекой backtesting.py. Функция load_data_for_ticker считывает данные для указанного тикера, выполняет парсинг дат и устанавливает столбец timestamp в качестве индекса. Это позволяет backtesting.py правильно интерпретировать временные ряды.
В модуле strategy_Random_1min.py реализована основная логика торговой стратегии. Класс RandomEntryStrategy наследуется от класса Strategy из библиотеки backtesting.py. В методе init происходит инициализация необходимых параметров и индикаторов.
Метод resample_to_daily пересчитывает минутные данные в дневные бары, необходимые для принятия решений о входе в позицию.
В методе next реализуются правила входа и выхода из позиции, описанные Александром Резвяковым. Время входа строго фиксировано (10:00), а решение о входе в лонг или шорт принимается на основе анализа предыдущих двух дневных баров. Вероятность входа в сделку устанавливается как 50%. Время выхода установлено на 20:40.
Интерактивный HTML
Для реализации трейлинг-стопов в strategy_Random_1min.py используются методы update_long_position и update_short_position. В этих методах вычисляется уровень трейлинг-стопа на основе текущей цены и заданного процента (2%).
Трейлинг-стоп автоматически подтягивается вверх для длинных позиций и вниз для коротких, обеспечивая фиксацию прибыли и ограничение убытков. При достижении ценой уровня трейлинг-стопа позиция автоматически закрывается.
Тестирование стратегииБиблиотека backtesting.py позволяет не только моделировать сделки, но и визуализировать их в интерактивных HTML-отчетах. Это помогает детально анализировать точки входа и выхода, проверять корректность реализации логики и выявлять возможные ошибки в коде.
Чтобы избежать нагромождения данных в интерактивных HTML-отчетах решил загружать данные по неделям.
Кроме того, я задал комиссию в размере 0,2%, поскольку комиссии оказывают заметное влияние на итоговую доходность:
<code>
bt = Backtest(
df,
DynamicStrategyClass,
cash=1_000_000,
commission=0.002,
margin=0.1, # Требование к первоначальной марже 10%
trade_on_close=True,
hedging=False,
)
</code>
Так как стратегия использует случайный вход в сделки (вероятность 50% на покупку или продажу), результаты тестирования также носят случайный характер. Однако, уже на первых тестах удалось увидеть интересные закономерности.
Вот пример удачного теста на фьючерсе NGH5:
<code>
==================================================
🚀 Запуск бэктеста для NGH5
==================================================
📋 Технические данные (для справки):
Колонки в данных: ['ticker', 'Open', 'High', 'Low', 'Close', 'Volume']
Первые 5 строк данных:
ticker Open High Low Close Volume
timestamp
2025-03-10 05:59:00 NGH5 4.610 4.610 4.610 4.576 8743
2025-03-10 06:00:00 NGH5 4.610 4.605 4.629 4.605 10655
2025-03-10 06:01:00 NGH5 4.605 4.592 4.607 4.592 8855
2025-03-10 06:02:00 NGH5 4.592 4.597 4.598 4.592 5293
2025-03-10 06:03:00 NGH5 4.597 4.602 4.605 4.597 3682
Типы данных:
ticker object
Open float64
High float64
Low float64
Close float64
Volume int64
dtype: object
⏳ Запуск бэктеста...
ПРОДАЖА на 2025-03-12: Цена: 4.33, Стоп: 4.33
ВЫКУП (трейлинг-стоп) на 2025-03-12: Цена: 4.31, Стоп: 4.31, Вход: 4.33, Мин.закр.: 4.30, P/L: 0.44%
ПРОДАЖА на 2025-03-14: Цена: 4.08, Стоп: 4.09
ВЫКУП (трейлинг-стоп) на 2025-03-14: Цена: 4.02, Стоп: 4.02, Вход: 4.08, Мин.закр.: 4.01, P/L: 1.40%
📊 Результаты бэктеста:
⚙️ Стратегия: NGH5_RandomEntryStrategy
📅 Период тестирования: с 2025-03-10 05:59:00 по 2025-03-14 20:49:00
💰 Начальный капитал: 100,000 руб.
💵 Конечный капитал: 1104162.00 руб.
📈 Общая доходность: 10.42%
📊 Годовая доходность: 14652.07%
📈 Коэффициент Шарпа: 1.11
📉 Максимальная просадка: -6.51%
🔄 Количество сделок: 2
✅ Процент выигрышных сделок: 100.00%
💪 Лучшая сделка: +1.40%
🙁 Худшая сделка: 0.44%
⏱️ Средняя продолжительность сделки: 0 days 00:40:00
📊 Построение графика результатов...
✅ График успешно построен!
==================================================
🏁 Бэктест для NGH5 завершен
==================================================
</code>
При этом были и серии неудачных сделок, где убытки накапливались из-за резких движений против позиции.
Хотя идея случайных входов была заложена в стратегии изначально, анализ показал, что в некоторых тестах убытки накапливались быстрее, чем прибыльные сделки перекрывали потери. В будущем стоит рассмотреть добавление дополнительных фильтров для входа.
Рекомендации по улучшению стратегииАвтор рекомендует увеличивать объем позиции в прибыльных сделках. Однако в текущей реализации теста этот момент не был учтен. Основная сложность в том, как правильно идентифицировать момент для добавления к позиции и реализовать это в backtesting.py.
Если у кого-то из читателей есть идеи или готовые решения, буду рад обсудить их.
В текущей версии трейлинг-стоп фиксирован на уровне 2%, однако более гибкий подход, основанный на волатильности актива, может улучшить результаты. Например, можно использовать ATR (Average True Range) для динамического определения уровня стопа.
Вход в 10:00 производится без дополнительных условий, что делает стратегию чувствительной к случайным колебаниям рынка. Можно добавить индикаторы тренда (например, SMA, VWAP) или фильтры объема, чтобы подтверждать сигналы на вход.
Вместо фиксированного размера позиции можно вводить динамическое управление рисками на основе максимальной просадки (drawdown) или волатильности актива.
Все эти идеи требуют детального тестирования, но их внедрение может значительно повысить эффективность стратегии.
ЗаключениеВ рамках этой статьи я воспроизвел и протестировал торговую систему Александра Резвякова на фьючерсах Московской биржи, используя Python и библиотеку backtesting.py.
Несмотря на кажущуюся простоту (случайные входы в 10:00 с вероятностью 50%), стратегия показала интересные результаты благодаря четким правилам выхода из позиций: трейлинг-стопы и закрытие по времени в 20:40.
Данный опыт может быть особенно полезен начинающим алгоритмическим трейдерам.
Что касается перспектив развития, система обладает значительным потенциалом для улучшения. Добавление динамических трейлинг-стопов на основе ATR, интеграция дополнительных фильтров для входа и реализация механизма наращивания позиций в прибыльных сделках могут существенно повысить эффективность стратегии. Python и backtesting.py предоставляют все необходимые инструменты для таких экспериментов, открывая широкие возможности для дальнейших исследований и оптимизации.
Автор: Михаил Шардин
🔗 Моя онлайн-визитка
📢 Telegram «Умный Дом Инвестора»
19 марта 2025 г.
С комиссиями, с склейкой
А где получше, там изменено время входа и выхода и стоп в 2%
Причем в условиях не написано растущие свечи или падающие, и не понятно зачем 3 свечи, если смотрится максм и минимум последних 2-х
Алекс Ч., я переделал, но раз вход случайный, то и результаты когда как получаются.
К тому же мне кажется её зря прямо на годах тестируют. Мне кажется это для только здесь и сейчас.
правда есть желание поменять условия входа и попробовать сделать трендовуху. попробовать отыграть будущее укрепление рубля на фьючах руб-юань
2.Вчера зеленая — сегодня лонг.
3.Наклоны индикаторов и лонг сегодня.
4.Цена открытия > цены закрытия, и лонг.
5.Утреняя сессия растет — лонгуем основную.
6. итд....
Это всё одно и то же, системой и не пахнет. Беда в том что слишком всё логично и пусто. Т.е. каждый кто имеет хоть 5 грамм мозга додумается до такого. Я просто уверен все новички пробуют это в начале пути. Но это не система, внутри нет системы, это ковыряние на результат. В чем идея то? Её нет! Или всем пофик?
Подобные «ТС» должны пролетать мимо и без тестирования. Не стоит тратить внимание и время на подобное. Ценность нулевая.
Если говорить про инвестиции, та же условная идея «не класть все яйца в одну корзину» на длительном временном интервале даёт хорошие результаты.
Но если мы говорим про трейдинг из него гораздо легче вылететь если делаешь что-то не так
Сразу вижу, вход/выход по времени, т.е. без стопа по деньгам, кочергааа… Это значит нужно прикручивать риск и снова крутить настройку. Крутим настройку — портим винрейт… итд.
Ну и всегда перед тем как пустить в бой ТС, спрашиваю себя, почему рынок не сможет поиметь меня? Будет сложнее меня поиметь?)) Это просто статистика или что-то еще. Спокойнее когда кажется что есть что-то еще кроме сухой статистики.
Допускаю что это все такой же уровень абстракции, следующий уровень абстракции, и такой же бред!)))
George Martin, вы имеете ввиду что вас важно не просто, чтобы стратегия показывала прибыль в долгосрочном тесте, а чтобы она имела высокий винрейт в моменте?
Какие модели ML позволяют эффективно подстраиваться под рыночные изменения и избегать устаревания стратегии?
покупка в 10:00, уже подразумевает что система сломается, вход ведь по маркету?
во вторых какая то ошибка в цифрах,
100к -> 1.1 млн
и третье, самое важное, в системе отсутствует логическая составляющая, если лои за прошлые дни все выше и выше это не дает никакой альфы к будущему, ну и плюс резвякова слушать, он на конференции предлагал открывать одновременно две сделки, одну в лонг другую в шорт, а то и вообще случайные входы, если за много лет трейдинга он пришел к этому то это даже не смешно, это печально
Но обычно вместе с критикой ждёшь и каких-то предложений
При простом «подкидывании монетки» вы получите тоже винрейт 50%, но соотношение лосс: профит = не лучше 1:1 — это вам не удастся изменить в свою пользу (если попытаетесь улучшить ratio лосс: профит, то винрейт сразу упадет ниже 50%).
В этом отличие Системы от «подбрасывания монетки».
Правда, доходность такой системы получается не оч.большая — всего 20-30% годовых…
У западных трейдеров встречал этот термин (young momentum).
в NGработать не будет...
т.к этот актив торгуется не в россии и российская сессия торгов и время входя-выхода не имеет никакого отношения к реальному движению NG...
более того NG это не акция а комод… т.е тренда в нем нет..
надо торговать российский актив типа сбера или газпрома... или индекс ртс
вообще резвяков говорит правильные вещи… у мя даже бот есть похожий...
который ловит в тренде локальные падения
питон не обязателен… для таких примитивных тестов за глаза хватит QLUA с визуализацией входов-выходов прямо на графиках QUIK
стратегия "вход по тренду — выход по стоп-тейку с закрытием открытой сделки вечером" способна генерировать небольшой профит в тестах на исторических данных
однако, на незнакомых данных такая стратегия генерирует переменный результат... проверял лично… не однократно… на разных инструментах
если кому-то нужно объяснить, что такое переменный результат, обращайтесь… лишаю иллюзий бесплатно и быстро))
автору совет:
протестируйте стратегию рандомным WFT с несколькими итерациями — и после этого запилите пост про инфоцыгана Резвякова с его стратегиями для верующих))
Изменил на Гитхабе — в коде была проблема с часовыми поясами. Данные из API брокера приходят в одном часовом поясе: UTC, а биржа работает в другом часовом поясе (UTC+3).