Почему бэктестинг криптовалютных стратегий врёт на истории
Ровная кривая доходности на графике и убыток в первые же дни живой торговли — самая частая история, с которой приходят к нам заказчики. Дело обычно не в самой стратегии, а в том, как построена проверка стратегии на исторических данных: тест измеряет не то, что будет происходить с деньгами.
Чаще всего в расчёте есть подглядывание в будущее. Сигнал считается по цене закрытия свечи, и сделка исполняется по этой же цене, хотя в реальности заявка уходит уже после закрытия. Если индикаторы пересчитываются по всей истории сразу, то в каждой точке времени неявно используется ещё не наступившая информация — и доходность получается завышенной.
Дальше — смещение выжившего: список монет берётся на сегодня, поэтому обнулившиеся и делистингованные пары в тест не попадают. Плюс качество данных: дыры в свечах, разные часовые пояса бирж, разный способ сведения периодов при склейке дают сигналы там, где сделки физически не было.
Издержки в тесте обычно занижены или отсутствуют: комиссии, спред, проскальзывание, ставка финансирования по бессрочным контрактам и глубина стакана на редких парах. В реальности именно они съедают прибыль на частых сделках.
Наконец, переобучение: если перебрать тысячи наборов параметров на одной и той же истории, лучший результат почти наверняка подогнан под шум. Отсюда и расхождение теста и реальной торговли, которое не лечится подкруткой порогов. Разбираем, как это закрывается на уровне самой платформы.
Что даёт честная проверка стратегии на исторических данных
Скорость прогона стратегии определяет, сколько гипотез вы успеете проверить до смены рыночного режима. Векторное ядро на VectorBT считает всю матрицу параметров по истории свечей параллельно: перебор, который в событийном цикле занимал часы, укладывается в минуты, и сетка перестаёт быть узким местом.
Воспроизводимость результатов тестирования держится на трёх фиксациях: снапшот рыночных данных с контрольной суммой, версия кода стратегии и зафиксированное зерно генератора. Любой прогон из журнала поднимается заново и даёт ту же кривую доходности — расхождение в доли процента уже сигнал о неявном источнике случайности, который надо убрать до вывода стратегии в работу.
Устойчивость стратегии к переобучению проверяем схемой скользящего окна: параметры подбираются на одном отрезке, проверяются на следующем, которого расчёт не видел. Если оптимум выглядит одинокой вершиной, а не плато, стратегия держится на шуме и развалится на живых данных. Дополнительно прогоняем набор через тренд, боковик и участки резких просадок отдельно.
Журнал прогонов хранит по каждому запуску датасет с его версией, полный набор параметров, учтённые комиссии и проскальзывание, кривую сделок и метрики риска. По нему видно, какая проверка отсеяла гипотезу и на каком шаге — так закрываются целые классы ошибок: подглядывание вперёд, тестирование только на уцелевших инструментах, недооценка издержек.
Режимы прогона: векторный, событийный и потоковый
Три режима отличаются не форматом итогового отчёта, а тем, что именно они моделируют. Векторный прогон считает сделки по массивам исторических свечей и работает быстрее всех — он нужен, чтобы отсортировать тысячи комбинаций параметров и отбросить заведомо слабые гипотезы. Событийный прогон по стакану воспроизводит поток заявок с учётом глубины, частичных исполнений и времени отклика, а потоковый расчёт в реальном времени идёт на живых данных и проверяет, что модель совпадает с фактическим исполнением.
Выбирать один режим бессмысленно: сравнение режимов тестирования строится как пирамида — от быстрой отбраковки к точной проверке.
| Режим | Когда подходит | Ограничения |
|---|---|---|
| Векторный прогон | Первичный отбор гипотез, перебор большого числа наборов параметров | Не видит движение цены внутри свечи, очередь заявок и проскальзывание — результат оптимистичнее реального |
| Событийный прогон по стакану | Проверка исполнения: проскальзывание, частичные заявки, поведение на редких инструментах | Нужен архив глубины рынка, расчёт идёт заметно дольше, объём данных растёт быстро |
| Потоковый расчёт в реальном времени | Финальная проверка перед выводом стратегии на реальные объёмы | Историю не переиграть, окно наблюдения ограничено, требуется устойчивость к разрывам связи |
Чтобы результаты были сопоставимы, все три режима прогоняем на одном наборе данных, с одними правилами расчёта комиссий и одинаковой логикой управления позицией. Расхождение между векторным и событийным прогоном — это и есть измеримая оценка того, насколько модель исполнения отличается от рынка; если разрыв велик, стратегия уходит на доработку до вывода на живой контур.
Этапы разработки платформы: от аудита данных до передачи
Прежде чем писать код, разбираем, откуда берутся данные и как именно считается результат сделки. Платформа ломается не на математике, а на расхождениях: разные таймзоны бирж, пропущенные свечи, делистинг пар, неучтённая ставка финансирования. Поэтому первые этапы — аудит исторических данных и согласованная схема расчётов: без них любая цифра доходности на графике ничего не значит. Ниже — последовательность, по которой мы ведём проект.
- Аудит исторических данных. Сверяем ряды с независимым источником, ищем пропуски, дубли, разрывы на листингах и делистингах, приводим метки времени к одному поясу. Фиксируем, какие пары и периоды покрыты, а где проверять стратегию нельзя.
- Схема расчётов. Договариваемся о модели исполнения: комиссии, спред, проскальзывание, ставка финансирования, момент срабатывания заявки внутри свечи. Схема становится эталоном, по которому потом сверяется каждая цифра.
- Реализация ядра расчёта. Прогон по событиям с детерминированным результатом: один и тот же набор данных и параметры дают один и тот же отчёт, который можно воспроизвести.
- Проверка корректности расчётов. Эталонные сценарии — стратегия без сделок, покупка и удержание, заранее посчитанный вручную случай. Плюс сверка с независимой реализацией и регрессионные тесты на каждом изменении.
- Прогон на отложенном периоде. Делим историю на обучающую и контрольную части, проверяем устойчивость результата к задержке исполнения и к проскальзыванию.
- Передача. Документация, схема расчётов, тестовый стенд, развёртывание на вашей инфраструктуре и обучение команды работе с платформой.
Состав поставки: схемы данных, журналы прогонов, регламенты
Комплект поставки собираем так, чтобы платформу можно было вести и развивать без нас. Каждый артефакт закрывает свой вопрос: откуда берутся данные, как повторить конкретный прогон, по какому регламенту его запускать и что проверять после правок в стратегии.
- Схема данных — сущности и связи: инструменты, исторические котировки, сигналы, сделки, метрики, правила нормализации и хранения. По ней новый источник подключается без вмешательства в расчётное ядро.
- Регламент прогона — параметры запуска, окно истории, обработка пропусков и выбросов, порядок фиксации версии стратегии. Прогон воспроизводится по тому же входу и спустя месяцы.
- Журналы прогонов — по каждому: версия стратегии, срез данных, метрики риска и доходности, полный лог сделок. Сравнение вариантов идёт по сохранённым результатам, без повторного пересчёта.
- Документация платформы — описание модулей, интерфейс расчётного ядра, порядок добавления индикаторов и новых стратегий.
- Инструкция по развёртыванию — поднять стенд с нуля, настроить резервное копирование и восстановление после сбоя.
- Приёмочные проверки — набор тестов на корректность расчёта метрик, который вы запускаете сами после каждой правки.
- Матрица доступа — роли и права: кто меняет стратегии, кто запускает прогоны, кто выгружает результаты.
Передаём комплект с приёмкой на ваших данных: вы прогоняете свои стратегии и сверяете метрики с ожидаемыми до закрытия работ.
Кейс: как убрали расхождение между тестом и реальной торговлей
Где терялась точность
Заказчик — управляющий алгоритмической стратегией на споте и фьючерсах Binance. Прогон на истории давал плавную кривую, а фактическая торговля приносила другой результат: расхождение по итогу дня доходило до 15-20%. Искали причину не в логике стратегии, а в движке исполнения — и нашли три.
Первая: решение принималось по цене закрытия бара, хотя в реальности ордер уходит внутри бара. Вторая: проскальзывание, комиссии и ликвидность стакана в модели не учитывались вообще. Третья: тиковые ряды приходили с разными часовыми поясами и пропусками, а хранилище на ClickHouse не проверяло их непрерывность.
Что изменили
Переписали движок событий: бар разбирается по шагам, сигнал считается только на данных, доступных на этот момент. Добавили модель проскальзывания и комиссий по фактическим условиям исполнения, снапшоты стакана — чтобы объём сделки не двигал цену в тесте сильнее, чем в жизни. Собрали модуль сверки сделок: сигнал, отправленный ордер и факт исполнения связываются по идентификатору, расхождение подсвечивается автоматически.
Стало: расхождение теста и реальной торговли уложилось в 1-2% по итогу дня, ручная сверка сделок сократилась с двух дней до 15 минут на отчёт. Стратегии, которые на старом движке выглядели прибыльными за счёт ошибок исполнения, теперь отсеиваются до запуска — этот класс «красивых» отказов ушёл.
Чем отличается бэктестинг от форвард-теста на демо-счёте?
Бэктестинг прогоняет стратегию по историческим данным: сделки считаются на уже известных ценах, поэтому результат получается за минуты, а не за недели. Форвард-тест работает по тому же коду, но на живом потоке котировок — заявки проходят реальные проверки, а исполнение зависит от текущей ликвидности. Это и есть отличие форвард-теста: он проверяет не логику сигнала, а её стык с рынком.
Тестирование на демо-счёте уязвимо к подгонке: если перебирать параметры по одному и тому же отрезку истории, находится набор, который идеально работал в прошлом и ломается на новых данных. Форвард так подогнать нельзя — будущие котировки неизвестны. Но у него своя цена: чтобы набрать значимое число сделок, нужны недели, а на медленных стратегиях — месяцы.
Поэтому вопрос «бэктестинг или форвард-тест» обычно не ставится как выбор одного. Мы строим оба режима на общем ядре исполнения — та же логика заявок, тот же расчёт комиссий, проскальзывания и ставок финансирования. Иначе сам переход из истории в живой поток меняет результат, и сравнивать прогоны бессмысленно. Выбор способа проверки зависит от частоты стратегии: для внутридневных сначала длинная история, затем короткий форвард; для позиционных — наоборот.
Практический критерий готовности — расхождение метрик. Если доходность и просадка в форварде держатся в пределах того, что показывает бэктест с учётом издержек, стратегию можно выпускать в торговлю. Систематическое отклонение — сигнал, что в истории чего-то не хватало: неполных данных, отсутствия проскальзывания или режима рынка, который больше не повторяется.
Частые сомнения: данные, задержки, ликвидность, переобучение
Сомнения инженеров сводятся к одному: воспроизведётся ли результат теста на реальном счёте. Разбираем четыре темы, которые всплывают до старта работ.
Откуда берутся исторические данные и как проверяется их качество?
Сводим сделки и свечи по нужным парам и биржам, помечаем пропуски, дубликаты и аномальные всплески. Отдельно убираем ошибку выжившего: пары, ушедшие с биржи, остаются в выборке — иначе тест завышает доходность.
Стратегия не переобучится под историю?
Обучаем на одном отрезке времени, проверяем на следующем, который модель не видела. Ограничиваем число параметров и прогоняем на разных режимах рынка — тренд, боковик, резкий провал. Результат, который держится на одном наборе настроек, — это переобучение, и мы скажем о нём до запуска.
Учитываются ли ликвидность и задержка исполнения?
В тест закладываем спред, комиссии, проскальзывание и задержку между сигналом и исполнением, объём заявки сверяем с доступной ликвидностью. Стратегия, прибыльная только при мгновенном входе по цене закрытия, отсеивается здесь.
Как понять, что тест совпадает с реальным исполнением?
Сверяем расчётные сделки с фактическими по времени, цене, объёму и комиссии. Расхождение разбираем до причины: данные, модель исполнения или логика стратегии. Журнал сверки остаётся у заказчика.
Обсудим задачу и вернёмся с оценкой и планом работ
Чтобы разговор про оценку проекта платформы был предметным, пришлите описание задачи в свободной форме: рынки и инструменты, частота сигналов, горизонт удержания позиции, нужные режимы проверки. Этого хватает, чтобы понять класс нагрузки и контур решения.
Минимальный набор для старта:
- Формулировки двух-трёх стратегий — правилами входа и выхода: по какой величине считается сигнал, где ставится стоп, как распределяется размер позиции.
- Источники исторических котировок: биржевые выгрузки, свои архивы или агрегаторы, глубина истории и частота свечей.
- Требования к реализму расчёта: комиссии, проскальзывание, ограничения ликвидности, задержка исполнения.
- Метрики решения: доходность с поправкой на риск, просадка, доля прибыльных сделок, поведение на отложенном отрезке.
- Сценарии проверки: прогон по отложенному периоду, стресс на волатильных участках, сравнение с пассивной тактикой.
- Роли и доступы: кто запускает прогоны, кто видит результаты, нужна ли изоляция команд между собой.
- Ограничения по инфраструктуре и срокам: где размещаем, какие объёмы данных держим, к какой дате нужен рабочий контур.
После обсуждения задачи возвращаемся с планом работ: состав модулей загрузки данных, движка прогонов и отчётности, очерёдность, точки сдачи и оценка диапазоном. Чем раньше придут материалы, тем меньше уточнений на старте — обычно хватает одного созвона и списка выше, чтобы зафиксировать этапы и подготовиться к запуску.







