VIZANIXРазработка торгового ПО
Исследование и проверкаResearch9 мин чтения

Заглядывание в будущее: как автоматический аудит нашёл три настоящие утечки в нашей модели

Любая просочившаяся крупица будущего делает бэктест красивее. Именно поэтому утечки так трудно заметить — свидетельством бага оказывается результат, которого вы и ждали.

Инженеры Vizanix · об авторе

МАТЕРИАЛ
9 минвремя чтения
РАЗДЕЛ
Исследование и проверка
ОПУБЛИКОВАНО
2026-08-28
ГЛАВ
6
ЧИТАТЬ ДАЛЬШЕ
3
ЯЗЫК
написано на русском
Инженерный разбор, а не пересказ документации.
LOOK-AHEADLEAK AUDITPURGEEMBARGOOOS

Утечка в будущее — это любой путь, по которому информация с момента t+1 попадает в решение, принимаемое в момент t. В бэктесте она невидима и приятна: метрики улучшаются, кривая эквити сглаживается, и все ваши стимулы направлены прочь от того, чтобы это проверить.

Откуда утечки берутся на самом деле

Не из экзотики. Источники повторяются и они прозаичны:

  • Сдвиг на единицу при выравнивании. Открытый интерес, фандинг или ряд старшего таймфрейма приклеиваются к вашим барам, и берётся индекс -1 — то есть текущее, ещё не завершённое значение. Это самая частая причина.
  • Использование той свечи, на которой вы торгуете. Если сигнал использует закрытие бара t, войти на открытии бара t нельзя.
  • Нормализация по всему набору данных. Среднее, стандартное отклонение или скейлер считаются на всех данных, а потом делаются train и test. Статистики тестовой выборки теперь внутри обучающих признаков.
  • Метки, которые подглядывают. Целевая переменная «максимальный ход за следующий час» нормальна; признак, посчитанный по тому же окну, — нет.
  • Выживаемость в универсуме. Отобрать сегодняшние ликвидные монеты и тестировать их по истории — это ставка на знание того, кто выживет.
  • Ресемплинг с протяжкой через границу. Переиндексация медленного ряда на быстрый с forward-fill, который начинается раньше, чем значение существовало.

Аудит, который действительно работает

Читать код в поисках утечек не масштабируется и не находит ошибок выравнивания. Работает механический метод: пересчитать каждый признак на баре t на ряде, обрезанном по t, где будущего физически нет, и сравнить со значением, которое выдал обычный конвейер.

Любое расхождение — это утечка по определению. Здесь нет шага интерпретации и нет места для оценочного суждения.

python
def audit(df, feature_fn, sample_points, tol=1e-9):
    """Пересчитываем каждый признак на обрезанном ряде. Любое расхождение — утечка."""
    full = feature_fn(df)
    leaks = []
    for t in sample_points:
        truncated = df.iloc[: t + 1]          # будущего здесь не существует
        partial = feature_fn(truncated)
        for col in full.columns:
            a, b = full[col].iloc[t], partial[col].iloc[-1]
            if not close_enough(a, b, tol):
                leaks.append((col, t, a, b))
    return leaks

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

Что нашёл наш

Мы построили такой аудит для сигнальной модели разворота пампа — 59 признаков по структуре эпизода, старшему таймфрейму, фону BTC и ликвидности. Он нашёл три настоящие утечки, и все три оказались ошибками выравнивания, а не концептуальными.

Схема каждый раз была одинаковой: при выравнивании открытого интереса, фандинга и фона BTC по времени к ряду баров индекс -1 указывал на значение, которое станет известно только после точки принятия решения. Каждая из них делала модель красивее. Ни одну не нашли бы чтением кода, потому что код выглядел правильно — соединение было написано так, как такие соединения обычно и пишут.

Purge и embargo

Кросс-валидация, придуманная для независимых строк, неверна для временных рядов. Если ваша метка смотрит на час вперёд, то обучающий образец непосредственно перед валидационным делит с ним этот час — разбиение течёт через собственную границу.

Лечится зазором размером с горизонт метки: выбросить обучающие образцы, чьи окна меток перекрываются с валидационной выборкой, и добавить embargo после неё с учётом автокорреляции. Это не факультативное уточнение: случайное разбиение на упорядоченных во времени данных обыграет честное всегда, и разница целиком вымышленная.

В TideGBM purging и embargo встроены как поведение по умолчанию, а не как опция, вместе со строгим режимом, отказывающимся обучаться на признаках, не прошедших линт заглядывания. Сделать честный путь путём по умолчанию — единственная версия этой идеи, которая переживает дедлайн.

И опубликуйте честную цифру

После закрытия трёх утечек одиночный AUC вне выборки у трёх наших геометрических формул составляет примерно 0,50–0,52. Это едва лучше подбрасывания монеты, и мы так и пишем на странице кейса.

Предсказательная сила этой модели приходит из другого места: структура эпизода, сколько ног движение уже прошло, как долго оно идёт, какой была самая глубокая просадка, ликвидность инструмента и волатильность BTC. Формулы оправдывают своё место как независимая перекрёстная проверка и как объяснение для оператора. Выдавать их за источник прибыли было бы неправдой.

Короткий протокол

  1. Пишите аудит до модели. Это сотня строк, и она меняет то, что вы построите.
  2. Сэмплируйте тысячи баров из разных режимов, а не десяток.
  3. Purge и embargo по умолчанию в каждом разбиении.
  4. Держите аудит в CI. Утечки возвращаются со следующим рефакторингом.
  5. Публикуйте честную цифру вне выборки, в том числе когда она невпечатляющая.

Последнее — самое трудное и самое полезное. Модель, чьи слабости задокументированы, можно улучшать. Модель с прекрасным бэктестом по причинам, которых никто не проверял, — это обязательство в красивой обёртке.

Статья описывает инженерную практику. Это не инвестиционная рекомендация. Vizanix разрабатывает программное обеспечение и не обещает торговую доходность.

Блог

Читать дальше

Открытый код · 8 мин

TideGBM: градиентный бустинг, уважающий стрелу времени

Обычный градиентный бустинг считает строки взаимозаменяемыми. Рыночные данные такими не являются. Мы написали библиотеку, где purged-валидация по умолчанию, а заглядывание в будущее — ошибка линтера.

Проверка · 8 мин

Бэктест и paper trading доказывают разные вещи

Бэктест проверяет гипотезу о рынке. Paper trading проверяет вашу программу против реальности. Пропустить любой из них — значит выйти в бой на непроверенном допущении.

Хотите такое у себя?

Мы пишем о том, что строим. Если нужно построить — напишите, разбор бесплатный.

Бриф

Получить оценку проекта

Четыре вопроса и контакт. Предоплата для разговора не нужна — если задача не наша, скажем сразу.

01Что вам нужно
02Биржа
03Рынок
04Стратегия
05Контакты

Проще написать напрямую? Telegram @vx_ceo

Обсудить систему