1 листопада 2026 · дослідження

Як прогріти бектест, не зараховуючи lookback до результату?

Як прогріти бектест, не зараховуючи lookback до результату?

20-денний Donchian у специфікації виглядає нешкідливо. Агент пише 20-баровий rolling max, бектест стартує з рядка 1 parquet-файлу, і перші 2 тижні «20-денний максимум» — це просто running max із тих барів, які вже є. На 4-й день це 4-денний максимум. Стратегія, яку ви думали, що тестуєте, — не та, що дала першу дюжину філів.

У мене є ноутбук на денних барах ETHUSDT, де Sharpe на повній вибірці — 1.4. Відріжте перші 20 сесій — і він падає до 0.6. Залиште ці 20 і викиньте решту 1-го року — і він друкує 3.1. Ніхто не злив завтра. Стратегія користувалася минулим, просто його було замало, а звіт сприйняв ці напівсформовані угоди як доказ.

1.4Sharpe на повній вибірці, включно з незавершеним вікном
0.6той самий код після 20 завершених сесій
3.1Sharpe, якщо залишити лише угоди прогріву

Дозволити вікну торгувати, поки воно ще наповнюється

Звична катастрофа — це min_periods=1. Pandas порахує rolling mean навіть на 1 барі, якщо дозволити. Агенти роблять так постійно, бо NaN на верху фрейму здається багом, а заповнити його — і unit-тест зеленіє.

20-денний realized-vol таргет із 2 спостереженнями дохідності — це вибух сайзу. Дисперсія 2 чисел — це підкидання монети: ви її інвертуєте, і перша позиція в кілька разів більша за задуманий ризик. z-score проти майже нульового стандартного відхилення робить той самий трюк зі знаком: стратегія ніби має бритвений вхід, який більше ніколи не з'являється, щойно вікно стає чесним.

Пробої гірші, бо виглядають як справжнє правило. 20-баровий канал на барі 6 — це 6-баровий канал. Ви отримуєте кластер угод просто на старті, часто в тихому відрізку, який би не спрацював на готовому індикаторі. Тихі ринки трохи дрейфують. Тісний канал стріляє. Крива капіталу отримує фору, яку жоден пізніший рік не повторює.

Zero-fill і forward-fill вигадують іншу брехню. RSI на 0 читається як перепроданість. Відсутній ATR, рівний 0, роздуває розмір юніта, і бектест сумлінно купує склад. Я краще хай NaN убиває ордер, ніж 0 його вигадує.

Я досі ловию себе на тому, що малюю з рядка 0, бо порожній місяць ліворуч на чарті виглядає незавершеним. Порожній місяць — це чесна частина.

Обрізати криву капіталу, залишити позицію

Ця помилка виживає на код-рев'ю. Ви коректно рахуєте 20-денні фічі, відкидаєте перші 20 рядків із намальованої кривої й публікуєте з 21 січня. Позицію 21 січня відкрито 14 січня. High-water трейлінг-стопу, лічильник піраміди, кеш після тих прогрівів — усе це зайшло в «чисту» вибірку.

Катастрофа — паперова стратегія, яку неможливо стартувати в дату з матеріалу. Рестарт із флету на заявлену дату старту — і ордери першого тижня не збігаються. Іноді бектест уже в угоді, в яку паперовій системі немає підстав входити. Іноді паперова система входить, бо її lookback холодний, а бектест сидить осторонь, бо його прихований місяць уже взяв пробій. Дві стартові книги, одна опублікована дата старту.

Walk-forward фолди роблять це тихо. У кожного тестового вікна є lookback-хвіст, який ви не малюєте. Не симулювати цей хвіст — і перші тестові угоди знову з незавершеного вікна. Симулювати його й звітувати лише тестові дні — і позиція тестового дня залежить від філів, яких ви не показуєте. Другий варіант може бути легітимним дослідницьким вибором. Називати перший ранок фолду холодним стартом, коли трейлінг-стоп уже живий із хвоста, — ось як 2 дослідники отримують 2 Sharpe з однієї конфігурації.

Якщо рестарт із флету на опубліковану дату старту змінює P&L, прогрів уже в трек-рекорді. Lookback-дані можуть бути присутні. Lookback-угод бути не може.

Прогрівати в календарних днях, коли фіча — не день

«Дайте йому 30 днів» залишає фічу недовизначеною. 30 календарних днів на 5-хвилинному Donchian — це тисячі барів понад 20-періодний lookback. 30 днів на денній фічі, якій потрібно 20 сесій, — або жирно, або тонко, залежно від вихідних і дірок.

z-score ставки фінансування на одному з наших perp-майданчиків отримав 30-денний прогрів, бо в специфікації було 30 періодів, а хтось переклав періоди в календар. Funding там друкується кожні 8 годин. 30 днів — це близько 90 сетлментів. 30 періодів — це 10 днів. Зайві 2 місяці прогріву випадково захопили тиждень депегу. Якщо їх відкинути, живе вікно виглядало спокійнішим за реальну історію стратегії. Люди звинувачували чутливість до дати старту. Прогрів з'їв режим.

А крипто проти акцій змінює значення того самого числа, ніхто навіть параметр не редагує. 20 «днів» ETH включають суботи. 20 сесій акцій — це майже календарний місяць. Скопіюйте 20-денний lookback зі стокового ноутбука на годинні perpetual-свічки — і отримаєте 20-годинний канал із 20-денною назвою. Перший валідний бар тоді або через 20 годин, або через 20 днів, якщо якась пізніша функція ресемплює, і я бачив обидва варіанти в одному агентському diff.

Зафіксувати перший торговий timestamp

Прогрів — це вимога до даних, а не бонусна вибірка. Кожна фіча називає кількість завершених спостережень, яких їй потрібно, у тих одиницях, у яких її рахують. Перший торговий timestamp — це перший бар, де все це істинне і з флет-рахунку було б дозволено надіслати ордер.

ФічаЩо зазвичай каже специфікаціяЩо насправді має існуватиТиха підміна
20-денний Donchian20 денних максимумів20 завершених сесійRunning max з min_periods=1
30-денна realized vol30-денне вікно30 close-to-close дохідностей2-денна дисперсія, інвертована в сайз
20-принтний funding z-score20 днів20 сетлментів funding20 календарних днів (~90 принтів), або 20 барів неправильного таймфрейму
14-періодний RSI на 5m14 періодів14 закритих 5-хвилинних барів14 днів, або 14 барів із forward-filled пропусками

P&L до цього timestamp не потрапляє в трек-рекорд. Стан до цього timestamp усе ще може потребувати симуляції, тож трейлінг-стоп або кулдаун реальні, коли годинник б'є перший торговий бар, але ці філи не йдуть у Sharpe, кількість угод чи математику місткості. Далі запустіть неприємну перевірку: рестарт із флету на цей timestamp, lookback доступний лише як дані. Якщо ордери змінюються, ви відвантажували приховані угоди.

Паперова торгівля стартує за тим самим контрактом. Так само кожне тестове вікно walk-forward. Якщо чарт виглядає так, ніби бракує місяця, хай бракує.

бектестингінжиніринг данихwalk-forwardAI-агентипаперова торгівля
ПоділитисяXLinkedInFacebookRedditHacker NewsWhatsAppTelegramEmail
← Усі статті