Блог им. quantAIengineer

Учет комиссий, проскальзывания и риск-менеджмента
Отбор торговых сессий по критериям волатильности (импульсы ≥5% за 10 минут)
Дискретное пространство действий: LONG, SHORT, CLOSE, HOLD
Reward shaping для контроля поведения
Полные логи бэктеста и визуализации
Публикация сигналов в реальном времени (Telegram)
Доходность: +144.23%
Sharpe: 1.85, Sortino: 2.05
Прибыльных дней: 78.57%
Сделок: 112 (~2 в день), включая SL/TP
Среднесуточная доходность: +1.61%
Точность сигналов: LONG — 69.9%, SHORT — 68.4%




Dueling Double DQN (D3QN)
Prioritized Experience Replay (PER)
Подбор гиперпараметров с Optuna
Состояние включает рыночные данные, позицию, контекст и историю действий
Обычные RL-модели обучаются на непрерывных рыночных данных, где шум подавляет сигнал.
В проекте используется отбор только высокосигнальных сессий:
Триггер: движение цены ≥5% за 10 минут
Контраст: 90 минут спокойного рынка до импульса
Сессия: 150 минут (90 мин контекста + 60 мин торговли)
Формат: матрица 150×7 (OHLC, VWAP, объём, сделки)
📊 Разбиение:
Train [2020-01-14 — 2024-08-31): 24 104 сессии
Validation ([2024-09-01 — 2024-12-01): 1 377 сессии
Test [2024-12-01 — 2025-03-01): 3 400 сессий
Backtest [2025-03-01 — 2025-06-01): 3 186 сессий
Агент учится только на рыночных импульсах, а не на шуме.
Примеры данных для всех четырех подвыборок: Train, Validation, Test, Backtest:



Агент работает в режиме реального времени: каждую минуту сканирует рынок Binance Futures, формирует прогноз (LONG/SHORT) и публикует сигнал в Telegram с последующей верификацией.

⚠️ Важное примечание: агент работает в экспериментальном режиме. Все решения, принимаемые пользователями на основе информации из канала, осуществляются под их личную ответственность.
Проект является исследовательским и предоставляется бесплатно исключительно в образовательных целях.
💬 Если вам интересны детали архитектуры и примеры работы — приглашаю изучить полную статью на Хабре.
Код, датасеты и онлайн-работа агента доступны для всех: вы можете изучать реализацию, запускать проект на своём компьютере, воспроизводить эксперименты и совершенствовать собственные стратегии.
Этот проект задуман как полноценная исследовательская лаборатория, цель которой — вдохновить вас на более глубокое изучение обучения с подкреплением в алгоритмической торговле.
Если в этой фразе последние три слова заменить на точку, будет гораздо честнее.
Synthetic,
Я сторонник аргументированной дискуссии и всегда рад объективному мнению со стороны — это ценно для развития проекта. Но ваш аргумент про «точку» скорее свидетельствует о компетенциях в области пунктуации и правописания, нежели в алгоритмической торговле с применением искусственного интеллекта.
В любом случае благодарю за комментарий. Надеюсь, что подобные исследовательские проекты будут служить противовесом невежеству и поверхностным репликам.
Again!,
Спасибо за интерес!
Архитектура, код и датасеты доступны в открытом доступе — каждый может воспроизвести эксперименты и поработать с гиперпараметрами.
Для тех, кто хочет погрузиться глубже, ссылка на статью на Хабре приведена в посте: там подробно описаны все детали.
>> цель которой — вдохновить вас на более глубокое изучение обучения с подкреплением в алгоритмической торговле
А в отношении себя какая цель проекта? Не всё делается ради денег, понятно, обычно любая цель она как правило с тебя начинается. Можно хотеть вдохновить людей но для чего, почему?
Replikant_mih,
Личная цель — сократить разрыв между розничными и институциональными участниками через открытую и воспроизводимую RL-платформу. Публикую код, данные и метрики, чтобы любой мог проверить и развивать решения.
Проект исследовательский, не коммерциализируется и не является торговой рекомендацией.
Просто трейдер,
Спасибо за отзыв. Публикация свежая, но разработку проекта веду около года.
Проект исследовательский, некоммерческий. Если будут конкретные технические вопросы — с радостью отвечу.
Редкий случай, когда пайплан описан корректно и исчерпывающе. И сам подход тоже грамотный, а не как обычно «я засунул гигабайт ohlc в нейронку и получил оверфит». Спасибо за труд!
Можно пару вопросов?
1) В чем разница между периодами test и backtest?
2) Насколько вижу, модель сошлась в основном к стратегиям «лонг в продолжение импульса» / «лонг падающего ножа». Шортов меньше в % соотношении? А отдельно рассмотреть их результат не пробовали? А разделить вышеуказанные 2 страты и рассмотреть их по отдельности? Вдруг все тащщит 1 лучшая страта, а остальные висят мертвым грузом / наоборот тормозят.
Eth_algotrader,
Спасибо за вопросы.
Test vs Backtest
Тестовый набор (3 400 сессий) использовался строго для финальной проверки после обучения/валидации, без оптимизаций.
Бэктест (3 186 сессий) — это отдельный период, максимально приближённый к реальной торговле: с комиссиями, проскальзыванием, логированием сделок и риск-менеджментом. То есть test — чистая оценка обобщающей способности, а backtest — имитация реальной эксплуатации.
Распределение стратегий
Да, модель чаще открывает лонги, что логично для крипторынка с ярко выраженным ап-трендом. В бэктесте:
лонги — ~93 сделки, точность ~70%;
шорты —-19 сделок, точность ~68%.
Обе стороны в плюсе, хотя вклад лонгов выше. Разделение сценариев (импульсный вход vs «падающий нож») уже видно на визуализациях в статье: часть сессий тянет именно continuation-логика, часть — отскоки. Более детальный анализ стратегий — следующий шаг, но уже сейчас видно, что прибыль не сводится к одной «лучшей» схеме.
Тут очень важно еще их средние сделки сравнивать. Из-за разницы средних результативность лонгов может быть далеко не на 2% выше.
Eth_algotrader,
Понял, спасибо, надеюсь ЧС это крайняя мера, стараюсь верить в людей :). Я здесь именно за содержательной дискуссией, поэтому нормальная критика и вопросы только приветствуются. Остальное — действительно проще фильтровать.
У вас ошибка в коде в environment.
1)pnl_change -= exec_price * volume * self.transaction_fee
2)self.balance += pnl_change #->обнуляем balance
3)elif action == 3 and self.position != 0:
volume = self.balance / self.entry_price #->он всегда ноль!
Итого, после любой покупки баланс навсегда становится = 0, reward-ы не поступают.
Sowelo,
Итог заранее: вы не правы. Баланс нигде не обнуляется.
1. Про self.balance += pnl_change
Это прибавление дельты, а не присваивание. На входе в позицию pnl_change = -fee, баланс становится balance = balance — fee. Ноль тут взять неоткуда.
2. Про “объём всегда ноль”
В коде при закрытии используется:
volume = self.balance / self.entry_price
После входа баланс положительный (чуть меньше из-за комиссии).
Значит, volume > 0.
Заявление “всегда ноль” — ошибка чтения.
3. Про “реворды не поступают”
Награда считается так:
reward = (pnl_change / initial_balance) — inaction_penalty
pnl_change появляется при списании комиссии и при закрытии позиции (прибыль/убыток минус комиссия). Следовательно, реворды не нулевые по определению.
Мини-калькуляция (чтобы закрыть вопрос окончательно)
initial_balance = 10_000, fee = 0.04%.
Вход LONG по 10:
volume_open = 10_000 / 10 = 1_000
fee_open = 10 * 1_000 * 0.0004 = 4
balance = 10_000 — 4 = 9_996 (не ноль!)
Закрытие по 11:
volume_close = balance / entry_price = 9_996 / 10 = 999.6
trade_pnl = (11 — 10) * 999.6 = 999.6
fee_close = 11 * 999.6 * 0.0004 ≈ 4.39824
pnl_change ≈ 999.6 — 4.39824 = 995.20176
balance_new ≈ 9_996 + 995.20176 = 10_991.20176
reward ≈ 995.20176 / 10_000 ≈ 0.0995 (точно не 0)
Вывод: в указанных строках нет описанной вами ошибки. Баланс не обнуляется, объём при закрытии не равен нулю, реворды есть. Ваше замечание — результат неправильной интерпретации кода.