Probability of Backtest Overfitting: обыграл ли ваш поиск подбрасывание монеты?
Статья из серии "Бэктесты без иллюзий".
📄 Эта статья выросла в исследовательскую работу. Каждое число ниже получено одним детерминированным скриптом, который строит контролируемую истину — поиски с нулевым edge, поиски с заложенным edge и реальную сетку параметров moving average на случайном блуждании, — а затем прогоняет через нее Combinatorially Symmetric Cross-Validation (CSCV), чтобы оценить по ней Probability of Backtest Overfitting, напрямую измеряя, насколько хорошо обобщается сама процедура отбора. Читайте статью онлайн (интерактивная версия + PDF) на pbo-search.marketmaker.cc, код и данные — на github.com/suenot/pbo-search.
Deflated Sharpe Ratio судил вашего победителя: с учетом того, что вы перебрали N конфигураций, превосходит ли этот Sharpe то, что покупает удача? Эта статья судит кое-что другое — сам акт отбора. Вы прогнали сетку, оставили лучшую ячейку и пошли дальше. Но был ли сам отбор заслуживающим доверия? Если бы вы пересобрали все разбиение in-sample/out-of-sample другим способом, вышла бы наверх та же конфигурация — или вы просто короновали самую везучую из сотни монет?
Probability of Backtest Overfitting (PBO), введенная Bailey, Borwein, López de Prado и Zhu (2017), отвечает ровно на этот вопрос — и делает это числом, которое большинство читает неправильно с первого взгляда. Вот самое важное предложение всей статьи, прочтите его дважды:
Ноль PBO равен 0.5, а не 1. Поиск без out-of-sample мастерства получает PBO ≈ 0.5. Половина — это не "наполовину оверфит", половина — это полный оверфит, подбрасывание монеты. Вам нужен PBO около нуля.
Это ловит всех. Нас учат читать вероятности против нуля как "ничего", и для оверфита интуиция подсказывает, что "невиновное" прочтение — это 0. Это не так. PBO — это вероятность того, что конфигурация, выбранная вами как лучшая in sample, оказывается в нижней половине поля out of sample. Если ваш поиск на самом деле не выучил ничего, что обобщается, in-sample победитель out of sample с равной вероятностью может оказаться где угодно в рейтинге — так что примерно в половине случаев он попадает в нижнюю половину. PBO ≈ 0.5 означает, что ваша процедура отбора — подбрасывание монеты. PBO ≈ 0 означает, что in-sample победитель надежно остается победителем out of sample — отбору можно доверять. Все, что дальше, построено так, чтобы сделать этот единственный калибровочный факт конкретным, на данных, где мы знаем истину.
| Режим (200 конфигураций, T = 1000, S = 16) | Что это | In-sample Sharpe победителя | Out-of-sample Sharpe | PBO | Вердикт |
|---|---|---|---|---|---|
| Поле с нулевым edge (200 iid шумовых стратегий) | чистая удача, edge нигде нет | 1.98 | 0.06 | 0.476 | оверфит — подбрасывание монеты |
| Заложенный edge (20 конфигураций несут годовой Sharpe 2.38) | настоящее, устойчивое мастерство | 3.73 | 2.34 | 0.001 | заслуживает доверия |
| Сетка MA-crossover на чистом случайном блуждании (170 конфигураций) | соблазнительный мираж | 0.97 | 0.04 | 0.463 | оверфит — подбрасывание монеты |
Sharpe ratio аннуализированы ×√252. Все три строки усредняют Sharpe отобранной стратегии по 60 Monte-Carlo матрицам — яблоки к яблокам, так что оверфитная сетка оценивается тем же способом, что и нуль и заложенный edge. На этой усредненной основе отобранный in-sample Sharpe сетки (0.97) на самом деле ниже, чем раздутые 1.98 у нуля, ее out-of-sample Sharpe — слегка положительные 0.04, а ее PBO (0.463) лежит чуть ниже ½ — статистически неотличимо от нуля. Драматичные числа с одной матрицы (лучший в сетке in-sample Sharpe 2.33, схлопывающийся до медианного out-of-sample −0.22, PBO 0.573) относятся к одному представительному random-walk seed и приводятся, четко помеченные, в Акте 4. Каждое число прослеживается до файла с результатами.
Три режима, один урок. Поиск без edge сидит точно на линии подбрасывания монеты 0.5 независимо от того, iid ли шум (PBO 0.476) или он наряжен в настоящую сетку moving average (PBO 0.463) — эти два статистически неотличимы, и оба уличают. Настоящий edge роняет PBO до 0.001. Усредненный по матрицам отобранный победитель сетки ничем не примечателен — in-sample Sharpe 0.97, ниже раздутых 1.98 у нуля, — и это само по себе честный диагноз: поиск без edge читается как нуль. Драма живет в хвосте. На одной представительной random-walk матрице (Акт 4) лучшая ячейка сетки показывает in-sample Sharpe 2.33 — по сути равный out-of-sample 2.34 у заложенного edge, ничья, — и тем не менее out of sample она попадает в нижнюю половину примерно так же часто, как в верхнюю. Этот разрыв между шикарным бэктестом и бесполезным отбором невидим в собственном Sharpe победителя и виден только тогда, когда вы оцениваете саму процедуру. Именно это делает PBO.
Акт 1 — Процедура под судом: что на самом деле делает CSCV

DSR — параметрический: он моделирует распределение максимального Sharpe при нулевой гипотезе и дефлирует значимость победителя аналитически. CSCV — непараметрический ответ на ту же проблему selection bias: вместо моделирования максимума он ресемплирует train/test разбиение всеми возможными способами и эмпирически смотрит, продолжает ли in-sample победитель побеждать. Никаких предположений о распределении, никакого подсчета "эффективных испытаний". Просто: обобщается ли выбор?
Начнем с сырого материала. Вы прогнали бэктест N = 200 конфигураций класса стратегий по T = 1000 синхронным наблюдениям. Уложите ряд доходностей каждой конфигурации в столбец — и получите T × N матрицу результатов M: 1,000 строк времени, 200 столбцов стратегий. Это единственный вход, который нужен CSCV.
Теперь сама конструкция, в четыре шага:
- Разбейте время на
S = 16непересекающихся блоков равной длины (T/Sстрок в каждом). Блоки сохраняют локальную временную структуру — решение, которое имеет значение в тот момент, когда у доходностей есть память. - Переберите все способы использовать половину блоков для тренировки, а половину — для теста. При
S = 16это всеC(16, 8) = 12,870способов выбрать 8 из 16 блоков в тренировочный набор; остальные 8 идут в тестовый. Отсюда и берется "комбинаторно симметричный": у каждого разбиения есть зеркало (поменять местами train и test), так что схема использует ваши данные симметрично, а не дает вам один привилегированный срез прошлое→будущее, как единичный walk-forward. - На каждом разбиении ранжируйте все 200 конфигураций по in-sample Sharpe и выберите победителя
n*. Затем найдите, на каком месте эта же конфигурацияn*стоит out of sample, на отложенных 8 блоках. - Зафиксируйте относительный out-of-sample ранг победителя и переведите его в логит. PBO — это доля из 12,870 разбиений, где этот логит ≤ 0.
Перебор пишется совсем коротко:
from itertools import combinations
combos = list(combinations(range(S), S // 2)) # C(16, 8) = 12,870 splits
Для каждого разбиения пусть — out-of-sample ранг in-sample победителя среди конфигураций (ранг 1 = худший, = лучший). Нормализуем его до относительного ранга , возьмем его логит и проинтегрируем по разбиениям:
Логит — просто удобная линейка. означает, что победитель попал в верхнюю половину out of sample (относительный ранг выше ½) — согласованность in-sample/out-of-sample, хорошо. означает, что он оказался на уровне медианы out of sample или ниже — in-sample выбор не обобщился на этом разбиении. PBO — это доля разбиений, на которых in-sample победитель не смог обыграть медиану out of sample. Все определяет матрица целиком: при заданных M и S PBO детерминирован — никакого seed для ресемплинга, все 12,870 разбиений перечисляются исчерпывающе.
В коде, когда у вас уже есть in-sample и out-of-sample Sharpe каждой конфигурации на каждом разбиении (матрицы R_tr и R_te, каждая 12,870 × 200), сердце оценщика умещается в шесть строк:
n_star = R_tr.argmax(axis=1) # in-sample winner, per split
oos_sh = R_te[rows, n_star] # that winner's OWN out-of-sample Sharpe
rank = (R_te <= oos_sh[:, None]).sum(axis=1) # its OOS rank among N configs, 1..N
omega = np.clip(rank / (N + 1.0), 1e-6, 1 - 1e-6) # relative OOS rank in (0,1)
lambdas = np.log(omega / (1.0 - omega)) # logit
pbo = float(np.mean(lambdas <= 0.0)) # fraction of splits with lambda <= 0
Обратите внимание, чего здесь нет: никакого p-value, никакого порога на Sharpe победителя, никакой модели нулевого распределения. PBO никогда не спрашивает, хорош ли победитель. Он спрашивает, является ли выбор in-sample лучшего решением, которое переживает столкновение с отложенными данными. Это свойство вашего поиска, а не вашей стратегии — именно поэтому он ловит то, что собственная статистика победителя поймать не может.
Акт 2 — Калибровка — это все доказательство: ноль равен 0.5

Диагностика, которую нельзя откалибровать, — это слух. Поэтому прежде чем доверять PBO на чем-то реальном, зафиксируем две опорные точки на данных, где ответ известен: поле, где edge нет нигде, и поле с настоящим edge. Если PBO не окажется около 0.5 на первом и около 0 на втором, он бесполезен.
Опорная точка нуля. Построим M из 200 столбцов независимого нормального шума с нулевым сносом и нулевым edge — истинный Sharpe ровно 0 у каждой конфигурации — и прогоним CSCV. Усредним по 60 таким матрицам. Отобранная (лучшая in-sample) стратегия показывает средний in-sample годовой Sharpe 1.98. Это не маленькое число; это то же раздутие отбором, которое измеряла статья про DSR, — лучший из 200 шумовых столбцов выглядит как стратегия, под которую можно привлечь финансирование. Out of sample тот же победитель выдает годовой Sharpe 0.06. Он отдал обратно практически все. И вердикт по процедуре:
Вот оно, измеренное подбрасывание монеты. По 12,870 разбиениям in-sample победитель с равной вероятностью оказывается ниже out-of-sample медианы, что и выше нее, — 0.476, чуть меньше ½, неотличимо от 0.5 с учетом Monte-Carlo разброса. Сопутствующая диагностика согласна: вероятность того, что out-of-sample Sharpe отобранной стратегии отрицателен, равна 0.475 — выберите in-sample лучшего из чистого шума, и он теряет деньги out of sample примерно в половине случаев. В отборе нет мастерства, потому что искать нечего, и PBO сообщает ровно это: 0.5 — это линия оверфита, и чистый шум сидит ровно на ней.
Почему 0.5, а не 1? Потому что при истинном нуле все 200 столбцов взаимозаменяемы — статистически неразличимые выборки из одного и того же шумового процесса. In-sample победитель особенный только in sample; out of sample это просто еще один столбец, с равной вероятностью оказывающийся на любом месте. Так что его относительный out-of-sample ранг равномерен на , логит симметричен вокруг 0, и доля с сходится к ½. PBO, равный 1, был бы хуже подбрасывания монеты — это означало бы, что in-sample успех надежно предсказывает out-of-sample провал, а для этого нужен активный механизм анти-персистентности, а не просто отсутствие edge (подробнее об этом — в заметках честности).
Опорная точка edge. Теперь построим поле, где 20 из 200 конфигураций несут реальный, заложенный edge — Sharpe на одно наблюдение 0.15, что при аннуализации дает 2.38 (вывод: ), — а остальные 180 остаются шумом. Прогоним тот же самый CSCV. Картина переворачивается полностью:
| In-sample Sharpe (год.) | Out-of-sample Sharpe (год.) | PBO | P(убыток OOS) | |
|---|---|---|---|---|
| Нуль (edge = 0) | 1.98 | 0.06 | 0.476 | 0.475 |
| Заложенный edge (Sharpe 2.38) | 3.73 | 2.34 | 0.001 | 0.0006 |
Победитель с заложенным edge показывает in-sample годовой Sharpe 3.73 — раздутый отбором, как всегда, — но на этот раз он сохраняет out-of-sample 2.34, и PBO схлопывается до 0.001. По всем 12,870 разбиениям in-sample победитель практически никогда не попадает в нижнюю половину out of sample. Вероятность out-of-sample убытка падает до 0.0006. Вот как выглядит заслуживающая доверия процедура отбора: как бы вы ни резали train против test, побеждает один и тот же тип конфигурации, потому что там есть реальный, устойчивый эффект, за который поиск может зацепиться. Две опорные точки — 0.476 на шуме, 0.001 на настоящем edge — и есть калибровка. PBO работает.
Акт 3 — Непрерывный термометр, а не тест да/нет

Две опорные точки доказывают, что PBO умеет отличать шум от edge. Но более глубокое свойство в том, что делает он это плавно. Проведите заложенный edge от нуля до сильного, и PBO не перескакивает резко с 0.5 на 0 — он съезжает вниз по монотонному склону, а out-of-sample Sharpe отобранной стратегии поднимается ему навстречу, шаг за шагом:
| Заложенный истинный Sharpe (годовой) | PBO | OOS Sharpe отобранной стратегии (год.) |
|---|---|---|
| 0.00 | 0.52 | −0.05 |
| 0.48 | 0.44 | 0.19 |
| 0.95 | 0.21 | 0.81 |
| 1.59 | 0.03 | 1.65 |
| 2.38 | 0.001 | 2.48 |
| 3.17 | 0.00 | 3.29 |
Читайте два столбца данных вместе. При нулевом истинном edge PBO равен 0.52, а отобранная стратегия зарабатывает −0.05 out of sample — снова подбрасывание монеты, и победитель, теряющий деньги. Добавьте намек на edge (годовой 0.48) — PBO опускается до 0.44. К годовому истинному Sharpe 0.95 — по-настоящему скромному, правдоподобному edge — PBO уже 0.21, а out-of-sample Sharpe вырос до 0.81. При 1.59 — 0.03; при 2.38 — 0.001; при 3.17 — фактически 0.00, а отобранная стратегия несет 3.29 out of sample. PBO монотонно падает по мере роста реального edge, а out-of-sample результативность победителя растет в такт — это один и тот же факт, увиденный с двух сторон.
Именно это свойство делает PBO применимым на практике: это непрерывный термометр оверфита, а не бинарная сигнализация. PBO 0.21 говорит не просто "не оверфит" — он говорит, что у вашего отбора есть частичное out-of-sample мастерство: in-sample победитель обыгрывает out-of-sample медиану в 79% случаев, но edge достаточно тонок, чтобы пятая часть разбиений все же его хоронила. Вы можете наблюдать, как это число движется, пока усиливаете сигнал, сужаете вселенную или обрезаете сетку, и понимать, какое направление честное. Собственное практическое правило статьи — отвергать, когда PBO превышает 0.05, — естественным образом вытекает из этого склона: ниже годового Sharpe ~1.5 поиск еще не прошел планку; выше ~1.6 — прошел. Но сам склон информативнее любого единственного порога, потому что он говорит не просто оверфит ли вы, а насколько близко к подбрасыванию монеты вы находитесь.
Акт 4 — Реалистичная ловушка: красивый бэктест, сертифицированный как бесполезный

Нуль на iid-шуме честен, но его легко отмахнуть — "мои стратегии не случайные нормальные столбцы". Так что вот ловушка в той форме, в которую практики на самом деле попадают. Возьмем moving-average crossover, самое протестированное правило в мире: идти в лонг, когда быстрая MA пересекает медленную снизу вверх, иначе — вне рынка. Построим сетку — 10 быстрых длин 17 медленных длин, оставляя валидные пары fast-below-slow, всего K = 170 конфигураций. Теперь прогоним эту сетку на ряде с доказуемо нулевым edge: чистом случайном блуждании. Там нечего искать. Crossover не может предсказать случайное блуждание. Мы знаем, что ответ — "стратегии нет".
Сетка этого не знает. Она вручает вам победителя, и этот победитель соблазнителен:
| Диагностика (одна представительная random-walk матрица, seed 3000, K = 170, S = 16) | Значение |
|---|---|
| Лучший in-sample Sharpe (годовой) | 2.33 |
| PBO | 0.573 |
| Медианный out-of-sample Sharpe (годовой) | −0.22 |
| Вероятность out-of-sample убытка | 0.63 |
| Наклон деградации out-of-sample относительно in-sample | −0.92 |
| Медианный логит | −0.25 |
Это одна матрица с фиксированным seed. Усредненные по 60 независимым random-walk матрицам, те же диагностики дают PBO 0.463 ± 0.223, отобранный in-sample Sharpe 0.97, затухающий до 0.04, и P(убыток OOS) 0.47 — статистически неотличимо от нуля. 0.573 у seed 3000 — одна выборка с верхней стороны от полосы нуля ~0.5, шум сэмплирования вокруг значения подбрасывания монеты, вполне в пределах разброса ±0.223 между матрицами, — и картина идентична в любом случае.
In-sample годовой Sharpe 2.33 на moving-average crossover — это тот тип результата, который оказывается в питч-деке. Он практически равен out-of-sample Sharpe нашего по-настоящему заложенного edge из Акта 2 (2.34 — ничья). Если бы вы остановились на бэктесте, вы бы его профинансировали. CSCV отказывает. Здесь PBO — подбрасывание монеты: 0.463 в среднем по 60 матрицам, 0.573 на этой конкретной — оба говорят, что у поиска нет out-of-sample мастерства. Не переоценивайте 0.573: он лежит на 0.073 выше ½, это шум сэмплирования вокруг нуля 0.5 и вполне в пределах полосы ±0.223 между матрицами; PBO, по-настоящему превышающий 0.5 — где in-sample успех активно предсказывал бы out-of-sample провал, — требует структуры анти-персистентности или торговых издержек, которых это случайное блуждание не содержит (см. заметки честности). На этой матрице медианный логит −0.25 ставит медианного in-sample победителя на относительный out-of-sample ранг около 0.44 (вывод: ) — примерно 75-й из 170 (вывод: ), чуть ниже середины поля, которое он должен был возглавлять. Медианный out-of-sample Sharpe этого победителя равен −0.22 — отрицательный, — и он несет out-of-sample убыток в 63% случаев. Sharpe бэктеста 2.33, чье out-of-sample ожидание — убыток: вот определение миража.
Наклон деградации −0.92 — второй нож. Регрессируем out-of-sample Sharpe отобранного победителя на каждом разбиении на его in-sample Sharpe; наклон круто отрицателен — чем лучше конфигурация выглядит in sample, тем хуже она работает out of sample. Это отпечаток оверфита на ряде с памятью: crossover цепляется за преходящие паттерны в тренировочных блоках, которые, будучи артефактами случайного блуждания, разворачиваются out of sample. Одна тонкость, которую стоит проговорить, чтобы не переоценить наклон: отрицательный наклон сам по себе не приговор. Даже режим с настоящим edge из Акта 2 имеет отрицательный наклон деградации (−0.52) — регрессия к среднему всегда немного тянет отобранный максимум вниз out of sample. Что отличает мираж от настоящего edge — не то, что наклон отрицателен, а где оказывается победитель: настоящий edge остается около верха (PBO 0.001), немного отдавая назад; мираж сидит на линии подбрасывания монеты (PBO 0.463 в среднем, 0.573 на этом seed), и его победитель не более вероятно окажется выше out-of-sample медианы, чем ниже. Читайте наклон, чтобы понять, насколько сильна усадка; читайте PBO, чтобы понять, обобщается ли она все еще. Мираж проваливается по обоим пунктам.
Вот почему PBO заслуживает места рядом с сырым бэктестом. In-sample Sharpe 2.33 — не ложь: стратегия действительно заработала его, in sample, на этом случайном блуждании. Это отбор, наряженный в знакомое правило на реалистично выглядящей сетке, и сколько ни всматривайся в кривую капитала, этого не увидишь. Раскрывает это только оценка процедуры.
Акт 5 — PBO и DSR: два честных вопроса, одно плато

PBO и Deflated Sharpe Ratio — две половины одной и той же проверки на честность, и они не дублируют друг друга — они допрашивают разные объекты:
| Deflated Sharpe Ratio (DSR) | Probability of Backtest Overfitting (PBO) | |
|---|---|---|
| Объект под судом | победитель | процедура отбора |
| Вопрос | превосходит ли этот Sharpe то, что покупает удача, по N испытаниям? | обобщается ли выбор in-sample лучшего out of sample? |
| Метод | параметрический — дефлирует порог значимости | непараметрический — ресемплирует все C(S, S/2) train/test разбиений |
| Значение при нуле | DSR ≈ 0.5 (победитель лишь совпадает с потолком шума) | PBO ≈ 0.5 (победитель — подбрасывание монеты out of sample) |
| Нужно | DSR около 1 | PBO около 0 |
| Нужен счет испытаний N? | да — и коррелированные сетки делают N неоднозначным | нет — ресемплирование разбиений обрабатывает зависимость естественно |
Они даже могут расходиться, и расхождение диагностично. DSR можно обмануть коррелированной сеткой в сторону передефляции (ловушка, которой целиком посвящен финальный акт статьи про DSR — 640 коррелированных ячеек это не 640 независимых испытаний, и скармливание сырого счета раздувает потолок шума). PBO никогда не считает испытания; он ресемплирует фактическую матрицу доходностей, так что корреляция сетки уже встроена в разбиения бесплатно. И наоборот, PBO говорит вам, что процедура обобщается, но не говорит, проходит ли победитель порог доходности — у поиска может быть низкий PBO и при этом отобрано что-то, чей out-of-sample Sharpe, надежно превышающий медиану поля, слишком мал, чтобы торговать. DSR оценивает цену победителя; PBO оценивает цену процедуры. Запускайте оба.

Под всем этим лежит геометрическая интуиция, и это самое полезное, что стоит унести с собой. Настоящий edge — это плато; оверфит — это шип. Когда вашей сеткой управляет реальный эффект, хорошие конфигурации кучкуются — fast=3/slow=55 работает, и его соседи тоже, потому что все они сэмплируют один и тот же лежащий в основе сигнал. Это плато устойчиво к ресемплированию: на каких бы 8 из 16 блоков вы ни тренировались, in-sample победитель берется из той же широкой области, и эта область остается наверху out of sample. Многие разбиения согласны → низкий PBO. Когда вашей сеткой управляет оверфит, "победитель" — одинокий шип: одна ячейка, которой случилось подойти под шум тренировочных блоков, окруженная посредственными соседями. Этот шип хрупок: другое train/test разбиение коронует другой одинокий шип, и ни один из них не доживает до тестового набора. Разбиения расходятся → PBO ≈ 0.5. Это тот же урок, к которому наше исследование plateau-analysis приходит со стороны карты параметров; PBO по сути — это различие плато-против-шипа, измеренное сразу по каждому симметричному ресемплированию ваших данных.
Это также объясняет, почему CSCV превосходит стандартный для практиков walk-forward split. Walk-forward дает вам один срез прошлое→будущее и один вердикт; CSCV дает 12,870 симметричных срезов и спрашивает, переживает ли победитель все из них. Шип может пережить один произвольный срез по удаче; 12,870 он пережить не может. (Combinatorial Purged Cross-Validation, CPCV, Лопеса де Прадо расширяет ровно эту идею purging'ом и embargo, чтобы убить утечку меток, от которой простое ресемплирование может страдать при сериальной зависимости — естественная следующая ступень, как только ваши метки начинают перекрываться.) То же структурное предостережение проходит через всю серию: метрика, которую вы оптимизируете, тайно выбирает вашу стратегию (дизайн objective-function), утечка в один бар фабрикует Sharpe 15 из шума (look-ahead bias), поиск с multiple testing фабрикует Sharpe 1.63 из шума (DSR) — а здесь ресемплированная процедура отбора фабрикует бесполезного победителя, которого может разоблачить только PBO.
Заметки честности
Четыре оговорки, сказанные прямо, потому что контролируемое исследование заслуживает своих выводов, только называя свои границы.
- Процессы, порождающие данные, синтетические — намеренно. iid нормальный шум для нуля, поле с заложенным Sharpe для развертки edge и сетка moving average на чистом случайном блуждании для ловушки. Ни одно из них не претендует на рыночный реализм; каждое выбрано ради контролируемой истины. Доказать, что PBO читается как 0.5 на "нет мастерства" и 0 на "настоящее мастерство", можно только генерируя данные, где мы знаем, что есть что. Реальные доходности имеют толстые хвосты, автокоррелированы и нестационарны; результат здесь — откалиброванная диагностика, а не стратегия.
- Ноль PBO равен 0.5, и это особенность, а не странность. Проговаривайте это каждый раз, когда сообщаете PBO, потому что иначе половина читателей воспримет 0.5 как "наполовину безопасно". Поиск без out-of-sample мастерства сидит на 0.5; настоящий edge толкает его к 0. У PBO ≈ 0.5 нет "невиновного" прочтения — это вердикт "полный оверфит".
- PBO > 0.5 — это "извращенная" область, которую мы не форсируем. PBO систематически выше 0.5 означает, что in-sample успех активно предсказывает out-of-sample провал — худшие по IS конфигурации становятся лучшими по OOS. Для этого нужна структура анти-персистентности или торговых издержек, а не просто отсутствие edge. Наши оверфитные поиски сидят на ≈ 0.5 (0.476 для iid шума; 0.463 в среднем для сетки MA; 0.573 на одном seed с верхней стороны, в пределах полосы Monte-Carlo ±0.14–0.22 по 60 матрицам), что уже означает "нет out-of-sample мастерства". Мы не фабрикуем извращенную область; мы лишь показываем, что оверфит приводит вас на линию подбрасывания монеты, а этого достаточно, чтобы уличить.
- PBO детерминирован при заданной матрице; случайна только сама матрица. При фиксированных
MиS = 16всеC(16, 8) = 12,870разбиений перечисляются исчерпывающе — никакого bootstrap seed и никакой дисперсии сэмплирования в самом PBO нет. Разброс, который мы приводим (±0.137 на нуле, ±0.223 на сетке MA), — это дисперсия между 60 Monte-Carlo матрицами, а не внутри оценщика. Sharpe с каждой стороны оценивается примерно по 500 наблюдениям — 496 после усечения блоков CSCV, посколькуT = 1000, разделенные на 16 равных блоков, оставляют 992 пригодных строки, разбитых на две половины по 496; поскольку Sharpe инвариантен к порядку, порядок строк внутри train или test набора не важен (он был бы важен для path-dependent метрик вроде отношения доходность/просадка).
Выводы
- PBO оценивает процедуру отбора, а не победителя — и ее ноль равен 0.5. Это вероятность того, что конфигурация, выбранная вами как лучшая in sample, окажется в нижней половине out of sample. PBO ≈ 0.5 — подбрасывание монеты (полный оверфит); PBO ≈ 0 — заслуживающий доверия отбор. Вам нужно, чтобы он был около нуля, и это нужно проговаривать вслух, потому что для неопытного глаза 0.5 читается как "безопасно", а означает ровно обратное.
- Калибровка доказывает, что это работает. На 200 iid стратегиях с нулевым edge лучший in-sample годовой Sharpe 1.98 схлопывается до 0.06 out of sample, а PBO = 0.476 — шум сидит на линии подбрасывания монеты, теряя деньги out of sample в 47.5% случаев. Заложите настоящий edge (годовой Sharpe 2.38), и in-sample 3.73 сохраняется до out-of-sample 2.34, пока PBO падает до 0.001. Две опорные точки, одна откалиброванная диагностика.
- PBO — непрерывный термометр. Проведите заложенный edge, и PBO падает монотонно — 0.52 → 0.44 → 0.21 → 0.03 → 0.001 → 0.00 при годовых истинных Sharpe 0.00 / 0.48 / 0.95 / 1.59 / 2.38 / 3.17 — а out-of-sample Sharpe отобранной стратегии растет в такт (от −0.05 до 3.29). Он измеряет, насколько близко к подбрасыванию монеты вы находитесь, а не просто да/нет.
- Реалистичная ловушка — вот в чем весь смысл. Сетка moving average на 170 конфигураций на чистом случайном блуждании усредняет отобранный in-sample Sharpe всего в 0.97, затухающий до 0.04, при PBO 0.463 — статистически неотличимо от нуля, поиск без edge читается как нуль. На одной представительной матрице мираж особенно нагляден: лучший in-sample Sharpe 2.33 (число для питч-дека), медианный out-of-sample Sharpe −0.22, 63% шанс out-of-sample убытка, PBO 0.573 и крутой наклон деградации −0.92. Красивый бэктест с отрицательным out-of-sample ожиданием, невидимый ни для одной статистики, напечатанной рядом с победителем, и видимый только тогда, когда вы оцениваете процедуру.
- Сочетайте PBO с Deflated Sharpe Ratio. DSR оценивает цену победителя (превосходит ли этот Sharpe удачу с учетом N испытаний?); PBO оценивает цену процедуры (обобщается ли отбор?). DSR нужен счет испытаний, и его можно обмануть коррелированными сетками; PBO ресемплирует матрицу и никогда не считает испытания. Настоящий edge — это широкое плато, с которым согласны многие разбиения (низкий PBO); одинокий in-sample шип — это оверфит (разбиения расходятся, PBO ≈ 0.5). Запускайте оба и читайте плато.
Победитель поиска виновен, пока не доказано обратное — и PBO допрашивает сам поиск, а не алиби, которое он вам вручает. Он игнорирует, насколько хорошо победитель выглядит in sample, и спрашивает только, было ли его избрание решением, которое переживает 12,870 разных пересечений. Когда не переживает — когда ваш роскошный Sharpe 2.33 оказывается попадающим в нижнюю половину out of sample едва ли не так же часто, как в верхнюю, — вы не нашли стратегию. Вы нашли самую везучую монету, и PBO — это число, которое ловит ее на подбрасывании.
Полный эксперимент — стенд калибровки на нуле, развертка термометра по заложенному edge, ловушка сетки на случайном блуждании и каждое число в этой статье, регенерируемое одним детерминированным скриптом, — в статье-компаньоне на pbo-search.marketmaker.cc, код и данные — на github.com/suenot/pbo-search.
Авторы
Инженер торговых систем
Разработка торговых ботов с 2017 года: межбиржевой арбитраж (подключал до 30 бирж), парный арбитраж на коинтеграции между спотом и фьючерсами, скальпинг, фронтраннинг, торговля по новостям, сентиментный анализ, трендовые алгоритмы, а также алгоритмы управления и балансировки портфелей. Делает выставление ордеров до 1 мс, warehouse для big data, бэктестинг-движки, AI-агентов и интерфейсы для ботов (в т.ч. open-source profitmaker.cc). Стек: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, архитектура.