Что это значит

Look-ahead bias — когда стратегия в момент времени T использует информацию, которая в реальности появится только в T+1 или позже. На бэктесте это выглядит как магия: точные входы, минимальные просадки. На реальных данных стратегия мгновенно теряет 80–100% доходности.

Самая обидная категория ошибок — потому что в коде она часто незаметна: одна неправильная индексация, и весь бэктест становится фантазией.

Откуда просачивается

1. Сдвиг индексов в коде. Сигнал считается по close[i], но исполняется по open[i] вместо open[i+1]. Стратегия эффективно «знает» закрытие до того, как оно произошло.

2. Использование revised data. Макроэкономические показатели (ВВП, инфляция) публикуются с лагом и потом ревизируются. Если в бэктесте используется текущая (ревизованная) версия, стратегия знает то, что в реальном времени не знала бы.

3. Survivorship-bias через текущий индекс. Тестирование «топ-50 по капитализации сегодня» использует знание о том, кто выжил. Реальная стратегия 10 лет назад тестировала бы топ-50 тех времён.

4. Нормализация на полной серии. Если вы делаете z-score (x - mean) / std по всему ряду — для каждого момента стратегия использует среднее и std, посчитанные по будущим данным.

5. ML-модели обучены на данных, частично пересекающихся с тестом. Особенно опасно при кросс-валидации временных рядов «как обычные данные».

Как обнаружить

  • Сравните результаты при сдвиге исполнения на 1 бар. Если стратегия теряет 50%+ доходности — у вас явный look-ahead.
  • Проверьте «нереалистичные» метрики. Sharpe > 5, drawdown < 5%, winrate > 80% на тысячах сделок — это почти всегда либо подгонка, либо look-ahead.
  • Проиграйте в режиме streaming. Перезапустите бэктест бар-за-баром, передавая в стратегию только данные до текущей точки. Если результаты разошлись с обычным бэктестом — есть утечка.
  • Code review. Все индексные операции по времени — кандидаты на ошибку. Особенно df.shift(-1) и df['col'].rolling().apply().

Что важно знать

Даже опытные разработчики допускают look-ahead-ошибки. Это не вопрос аккуратности — это структурная проблема, которую нужно решать архитектурно: фреймворк бэктеста должен передавать в стратегию данные строго до текущей точки, а не весь DataFrame.

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

Связанные понятия

Look-ahead bias — главный враг честного бэктеста. Walk-forward частично защищает, но не гарантирует.