Ночь, когда мой бэктест мне солгал

Однажды ночью бэктест сообщил мне, что я превратил скромный стартовый баланс в 2 792 триллиона вон — больше, чем годовой объём производства большинства экономик планеты. Я смотрел на это. На несколько минут какая-то тихая, жадная часть меня отправилась искать причины, по которым это могло бы быть правдой.

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

Число, которое должно было меня напугать

Я запускал перебор параметров — тысячи конфигураций, каждая из которых проигрывалась на исторических данных и ранжировалась по итоговому результату. Большинство возвращалось заурядными. Одна вернулась безумной.

Безумный-в-твою-пользу — это самый опасный результат, который система способна выдать, потому что он приходит с лицом успеха. Убыточный прогон заставляет тебя отлаживать. Прогон, который «работает», заставляет тебя праздновать. Внимание распределяется асимметрично, и направлено оно ровно в неправильную сторону: мы допрашиваем результаты, которые нам не нравятся, и пропускаем те, что любим. Я едва не пропустил этот.

Инстинкт, которому мне пришлось научиться — трудным путём, — обратный. Чем более впечатляющ результат, тем вернее, что что-то сломано. Рынки не вручают новичку-разработчику ВВП небольшой страны. Если твоя симуляция утверждает, что вручают, значит, симуляция лжёт, и твоя единственная задача — выяснить, как именно.

Ошибка первая: ставить весь счёт, каждый раз

Первый изъян был в позиционном сайзинге. Каждая сделка по размеру составляла практически весь счёт, и прибыль реинвестировалась напрямую в следующую ставку. В тот момент, когда ты так делаешь, ты перестаёшь моделировать торговлю и начинаешь моделировать геометрическую прогрессию. Достаточно длинная череда даже едва-едва благоприятных исходов — или чистого шума, который случайно достаточно часто ложится в нужную сторону, — не растёт, а детонирует. Математика убегает от реальности и больше не оглядывается.

Вот что соблазнительно в полностью реинвестирующем бэктесте: ему не нужна хорошая стратегия, чтобы выдать великолепное число. Ему нужно лишь достаточно сделок и симулятор, достаточно щедрый, чтобы позволить ставке продолжать кататься. Реинвестирование превращает слабый, ничего не значащий статистический перекос в экспоненциальную кривую, а экспоненциальная кривая на тысячах сделок выдаёт число, которое выглядит как судьба и не значит ничего. Астрономический баланс не был свидетельством преимущества. Он был свидетельством экспозиции на весь счёт, применённой к случайности.

Ошибка вторая: симулятор, который не мог умереть

Второй изъян был хуже, потому что он был философским. У моего бэктестера не было поглощающего барьера — точки, в которой счёт был бы попросту мёртв. Так что когда полоса плохих сделок просаживала баланс на 99,99%, симуляция не останавливалась. Она оставляла труп на столе и позволяла ему продолжать торговать. И с этого почти нулевого баланса удачная серия «воскрешала» счёт и вытаскивала его обратно на нелепую высоту.

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

Оптимизатор охотился за моим слепым пятном

Вот часть, которую мне дольше всего было понять: перебор параметров не наткнулся на эту абсурдную конфигурацию случайно. Он отправился её искать.

Перебор по тысячам конфигураций — не нейтральный наблюдатель. Это противник, оптимизирующий ту метрику, которую ты ему вручаешь. Если твоя метрика — «итоговый баланс», а у твоего симулятора есть слабое место — точка, где нереалистичным вещам тихо позволено происходить, — перебор найдёт это слабое место и навалится на него всем своим весом. Он вознаграждает не лучшую стратегию. Он вознаграждает конфигурацию, которая наиболее эффективно эксплуатирует разрыв между твоей симуляцией и реальностью.

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

Признак

Сложи эти ошибки вместе — и получишь машину, производящую чудеса. Она может пережить что угодно, поэтому переживает всё; она ставит всё, поэтому, когда переживает, переживает колоссально; а перебор тихо настраивает её делать и то и другое как можно сильнее. На выходе — не результативность стратегии. На выходе — форма самого бага, нарисованная очень крупными числами.

Вот почему «сначала выживание» — не лозунг. Бэктест, который не может разориться, при достаточном числе конфигураций для перебора всегда в конце концов выдаст одну, которая выглядит как гениальность, — не потому, что эта конфигурация хороша, а потому, что перебор терпеливо разрабатывает слепое пятно твоего симулятора. Впечатляющее число — это симптом. Отсутствующее банкротство — это болезнь.

Скучное исправление

Починка была невзрачной. Размеры позиций стали небольшой фиксированной долей счёта вместо целого, так что выигрыш не мог раскатиться в бессмыслицу, а проигрыш не мог быть «всё или ничего». Симулятор получил настоящее условие разорения: упади ниже минимального выживающего баланса — и прогон окончен, помечен как мёртвый, точка. И он получил минимальный размер ордера, так что сделки, слишком маленькие, чтобы существовать на реальном рынке, не могли тихо держать умирающий счёт на аппарате жизнеобеспечения.

Ни одна из этих идей не остроумна. В них нет ни озарения, ни преимущества. Это симуляция, наконец согласившаяся подчиниться ограничениям, которые реальность никогда не ослабляет, — издержкам, которые тебя не прощают, ликвидности, которая не бесконечна, и нулю, с которого не возвращаются. Бо́льшая часть работы по созданию честного бэктеста — именно в этом: не сделать его умнее, а отказать ему в праве жульничать. Первейшая обязанность честного бэктеста — не показать тебе прибыль. Она в том, чтобы быть способным показать тебе разорение.

Почему я перестал доверять хорошим новостям

Вот неудобная часть. Баг был простым. Трудным было то, что я едва не отказался смотреть — потому что число было в мою пользу, и я хотел, чтобы оно было правдой. Результат, который тебе противоречит, подвергается допросу. Результат, который тебе льстит, принимается на веру.

Эта асимметрия — место, где живёт большая часть самообмана в этой работе. Дело не в том, что люди не могут найти свои баги; дело в том, что они перестают искать в тот момент, когда баг начинает им платить. Рынок в конце концов выставит полный счёт за каждое удобное допущение, которое ты так и не проверил, — но бэктест с радостью позволит тебе держаться за это допущение месяцами, потому что он, по самой своей конструкции, единственное место, где ошибаться бесплатно.

Что это на самом деле изменило

Так что дисциплина, которую я вынес из фальшивого триллиона вон, почти не имеет отношения к позиционному сайзингу. Она изменила порядок моего доверия. Хорошо выглядящий результат теперь виновен, пока не доказана его невиновность: прежде чем спросить «как ему это удалось?», я спрашиваю «что здесь сломано?» — и я пытаюсь, намеренно, сломать его сам, прежде чем такой шанс получит рынок. Результаты, которые переживают это враждебное обращение, — единственные, которым я позволяю себе верить, и их куда меньше, чем мне хотелось бы.

Бэктестер, который не может потерять всё, не оптимистичен. Он лжёт. И самая опасная ложь, которую он может сказать, — та, которую ты и так уже надеялся услышать.

— Никаких сигналов, никакой доходности, не является инвестиционной рекомендацией.