Рынки предсказаний кажутся самой простой в мире задачей для бэктеста. Цена находится в диапазоне [0, 1]. Выплата — доллар или ничего. Никакого плеча, фондирования, базиса и странностей бессрочных свопов в 00:00 UTC. У нас уже был бэктестер, который учитывал комиссии, фондирование и импакт для криптовалютных бессрочных контрактов. План был за 2 дня адаптировать его, а затем приступить к генерации стратегий.
На это ушло 8 дней. Вот журнал событий, примерно в хронологическом порядке, включая день, когда кривая капитала выглядела невероятно — и действительно была такой.
День 1: адаптер, который должен был быть элементарным
Изначальное соответствие было взаимно однозначным и выглядело аккуратно. Рынок — это инструмент. Цена YES — это цена. Покупка YES — лонг, покупка NO — шорт. Расчёт — принудительное закрытие по 1.00 или 0.00. Загружаем почасовой ряд цен в тот же цикл событий — готово.
Такое соответствие продержалось около 90 минут после знакомства с реальными данными. Первым развалился ряд доходности. Весь наш риск-модуль — определение размера позиции, таргетирование волатильности, расчёт Sharpe — предполагал логарифмическую доходность инструмента, который продолжает существовать. У рынка, цена которого падает с 0.04 до 0.00, логарифмическая доходность не определена, а полная потеря — определена. И рынок по 0.04 за 3 дня до расчёта — принципиально иной объект, чем рынок по 0.04 за 4 минуты до него, хотя в обоих рядах стоит 0.04.
В итоге мы перепараметризовали весь ряд, используя время до расчёта вместо календарного времени, и стали считать PnL конечным результатом, а не переоценкой позиции. Это было правильное решение, но оно сделало недействительным весь код отчётности, который зависел от него.
День 2: формула комиссии и есть стратегия
На Kalshi торговая комиссия — это не скидка в базисных пунктах. Она квадратично зависит от цены: примерно 0.07 × contracts × P × (1−P), с округлением вверх до цента на уровне ордера. Получается, что комиссия максимальна именно там, где рынок с шансами 50/50 наиболее интересен, и почти ничего не стоит на краях диапазона.
| Цена | Комиссия за контракт | Необходимое преимущество (пункты вероятности) | Комиссия в % от ставки |
|---|---|---|---|
| 5¢ | 0.33¢ | 0.33 | 6.7% |
| 10¢ | 0.63¢ | 0.63 | 6.3% |
| 25¢ | 1.31¢ | 1.31 | 5.3% |
| 50¢ | 1.75¢ | 1.75 | 3.5% |
| 75¢ | 1.31¢ | 1.31 | 1.8% |
| 90¢ | 0.63¢ | 0.63 | 0.7% |
| 95¢ | 0.33¢ | 0.33 | 0.35% |
Смотрите на третий столбец: чтобы выйти в ноль, покупая по 50¢ и удерживая позицию до расчёта, ваша оценка вероятности должна превосходить рыночную на 1.75 пункта. Не на 1.75% относительно рынка, а в абсолютном выражении. Если закрыть позицию до расчёта, а не держать её до конца, комиссию придётся заплатить дважды, плюс спред.
В CLOB Polymarket исторически действовала совершенно иная структура комиссий: сама сделка обходилась почти бесплатно, поэтому все издержки приходились на спред и глубину. Одна и та же логика стратегии поэтому имеет совершенно разную экономику на разных площадках, а любое сравнение площадок с единой моделью комиссии — выдумка. Теперь мы задаём отдельную функцию комиссии для каждой площадки, а не одно числовое значение.
Если вы прочитаете в отчёте о бэктесте рынка предсказаний только одну строку, пусть это будет комиссия в пунктах вероятности. Стратегия с заявленным преимуществом в прогнозе на 1.2 пункта для рынков по 50¢ на Kalshi убыточна ещё до учёта любых других издержек. Это должно быть видно на первой странице, а не требовать от читателя самостоятельных расчётов.
День 3: стакан ступенчатый и короткий
Наша модель импакта представляла собой корневую функцию, откалиброванную по стаканам бессрочных контрактов BTC. Здесь она не подходит. При шаге цены 1¢ и инструменте стоимостью $1 во всём стакане всего 99 возможных ценовых уровней. В рынке со средней ликвидностью на верхнем уровне могут стоять пару сотен контрактов, а дальше — разрыв.
Вот снимок рынка экономических данных, который мы отслеживали, сторона YES, примерно за 30 часов до расчёта:
| Уровень | Объём (контракты) | Накопленная стоимость покупки |
|---|---|---|
| 42¢ | 310 | 310 @ средняя цена 42.0¢ |
| 43¢ | 85 | 395 @ средняя цена 42.2¢ |
| 45¢ | 140 | 535 @ средняя цена 42.9¢ |
| 49¢ | 600 | 1,135 @ средняя цена 46.1¢ |
Ордер на 1,000 контрактов — риск в 500 долларов, погрешность округления для криптовалютного рынка — поднимает эффективную цену на 4 цента. Это больше чем вдвое превышает комиссию. Здесь не подобрать плавную функцию: нужно проходить стакан уровень за уровнем, иначе вы просто придумываете цифры. Мы удалили корневую модель для этого класса активов и написали буквальный обход стакана. Он работает медленнее, зато правильно.
В какой-то момент я поймал себя на раздражении: эти рынки «слишком малы, чтобы иметь значение». Они малы, потому что цена здесь относится к одному конкретному вопросу из реального мира с установленным сроком, а в среду есть лишь ограниченное число людей, готовых высказаться о первичных заявках на пособие по безработице в США. Размер рынка и есть сам рынок. Жаловаться на него — всё равно что сетовать на то, что за покерным столом всего 9 мест.
День 4: день, когда кривая капитала была прекрасна
Sharpe 4.1 на 1,400 рынках. Гладкая кривая. У любого исследователя тут должно было бы сжаться нутро; у меня так и случилось, но лишь спустя примерно 40 минут после того, как я уже сделал скриншот.
Ошибка оказалась в ресэмплере. Для рынков с низкой ликвидностью история цен приходит с нерегулярными временными метками, поэтому мы привели её к равномерной почасовой сетке. Последняя точка любого архивного ряда — цена расчёта: 1.00 или 0.00. При переиндексации мы заполняли пропуски ближайшим соседом без ограничения направления, поэтому для любого рынка, где последняя сделка прошла за несколько часов до расчёта, цена расчёта распространялась назад через весь этот промежуток. Модель видела сегодняшний строке ответ, который станет известен только завтра, именно на тех низколиквидных рынках, где можно было нарастить позицию, не упираясь в ограничения глубины.
Заполнение по ближайшему соседу подходит для непрерывно торгуемого инструмента. Но если последнее наблюдение — это истинный результат, такой подход превращается в машину подглядывания в будущее. Теперь мы проверяем, что заполнение всегда идёт только вперёд, а строка расчёта помечается и исключается из вычисления признаков. Эта проверка занимает 9 строк и стала самой ценной частью кода, написанной нами за всю неделю.
Дни 5–6: 1,412 рынков, примерно 180 ставок
Размер выборки на рынках предсказаний — ловушка с приветливым лицом. Вы дожидаетесь расчёта по 1,412 рынкам, думаете, что у вас есть 1,412 наблюдений, и соответственно вычисляете t-статистику. Но 14 матчей NFL в одно воскресенье зависят от одной и той же погоды, публикации отчётов о травмах и общего потока ставок. 51 рынок по выборам на уровне штатов зависит от одного национального сдвига. «Случится ли X до 31 марта» и «случится ли X до 30 июня» — это одна и та же ставка с разными сроками, и результаты по ним станут известны одновременно.
Мы сгруппировали рынки по источнику базового события и дате расчёта и получили примерно 180 эффективных независимых наблюдений. Этого недостаточно, чтобы при тех размерах эффекта, которые мы изучали, отличить настоящее преимущество от шума. И никакой бутстрэппинг отдельных рынков не исправит ситуацию: бутстрэппинг должен выбирать кластеры, а не строки. Если ошибиться, значимость незаметно завышается в 2 или 3 раза.
День 7: расчёт тоже подчиняется распределению вероятностей
Вот что мы совсем не учли и обнаружили на собственном опыте:
- Досрочный расчёт. Рынок со сроком «до 31 декабря» может разрешиться уже 4 августа, когда событие действительно произойдёт. Капитал вернётся раньше, а срок удержания позиции никогда не был таким, каким его подразвало название контракта.
- Споры. На рынках, где исход определяет оракул, есть период для оспаривания. Позиция может зависнуть на несколько дней после события, а в небольшом числе случаев результат меняется на противоположный по сравнению с тем, что казалось очевидным.
- Аннулирование. Если исходные данные неоднозначны, рынок отменяют, а всем возвращают деньги. В нашей выборке таких рынков меньше 1%, но они концентрируются именно вокруг неоднозначных вопросов, в которых модель находит неверную цену.
- Заморозка капитала. Преимущество в 3 пункта, полученное за 90 дней, и преимущество в 3 пункта за 6 часов — несопоставимы. Бэктестер, который сообщает только суммарное преимущество без знаменателя, учитывающего время использования капитала, всегда будет отдавать предпочтение медленному варианту.
Мы добавили в симулятор издержки за время удержания позиции и случайный сдвиг даты расчёта. Ни то, ни другое не описано точно. Но оба фактора лучше неявного предположения, что расчёт наверняка произойдёт ровно в указанную дату.
День 8: что мы бы пропустили и с чего начали бы
- Сразу откажитесь от всей инфраструктуры, основанной на доходности. Не адаптируйте модуль управления риском с таргетированием волатильности к инструменту с конечной выплатой. Напишите модуль определения размера ставки, оперирующий вероятностью и суммой. Мы потратили 2 дня, пытаясь подогнать старый модуль.
- Сначала создайте функцию расчёта комиссии, а потом стратегию. Для каждой площадки, на которой планируете торговать, постройте кривую безубыточного преимущества и повесьте её над столом. Так отсекается примерно половина идей ещё до того, как они потребуют запуска бэктеста.
- С первого дня проходите стакан по уровням. Любая параметрическая модель импакта, перенесённая с непрерывного рынка, ошибётся так, что результат будет в вашу пользу.
- Сначала объединяйте в кластеры, потом считайте. Определите ключ кластеризации для эффективного размера выборки одновременно с выбором вселенной рынков, а не после того, как получите Sharpe, который вас устраивает.
- Проверяйте направление заполнения пропусков. По одной проверке на каждое объединение рядов. Если ряд заканчивается истинным результатом, считайте заполнение назад ошибкой по умолчанию, а не тем, что вы заметите при ревью.
Эти 8 дней того стоили, главным образом потому, что рынки предсказаний убирают неоднозначность, из-за которой так легко обмануться при бэктесте криптовалютных рынков. Тут нечего списать на ставку фондирования и не о чем спорить в части правил расчёта mark price. Есть только вопрос, срок и ответ. Если здесь бэктест ошибается, можно точно указать, в чём именно.
← Все статьи

