Methodology Re-Audit · sub5_pump SHORT

3 независимых аудитора + clean re-research 6/12/24 мес · MOO→11:00 · gap≥10% × px<$5 · May 04 2026

📁 research_results/methodology_audit_may04/ 🌳 worktree bridge-cse_01HZ4s7DG9AQb25K9QD9TAvj 📅 OOS window: 2025-11-01..2026-04-30 📊 N(OOS)=220 trades / 90 trade-days / 112 tickers

🎯 Главный вывод: verdict «DEAD» получен по неправильным причинам, но направление верное

Все три аудитора независимо сошлись: frozen reference Sh=5.0 / PF=2.17 никогда не существовал в данных, а используемая methodology не способна отличить мёртвую стратегию от живой. OOS verdict «DEAD» оказался правильным «случайно» — через комбинацию трёх независимых ошибок:

P0 · STATS

Permutation test = шум-генератор

Outcome-shuffle сохраняет total mean → тестирует кластеризацию, НЕ «mean>0». Power 4-8% даже при истинном Sh=5-8. Все 5 стратегий получают p∈[0.69, 1.00].

P0 · DATA

Split-adj mismatch в train

prev_close (split-adj) ÷ pm_close (raw) → BULZ fake gap=875%, ITUB/GGB 25-40%. 3 тикера = 28.7% train signal. На OOS не задевает (0/340).

P0 · REPRO

Sh=5.0 нигде не воспроизводится

Лучший 12-мес. window: Sh_daily=2.86 raw / 0.07 при 50bps. Calendar-2023: PF=1.08 (не 2.17). Frozen ref был overfit или с другими фильтрами.

Verdicts от 3 аудиторов

⚠️ A · STATISTICS — REVISE
OOS MDE Sh @ α=0.05, power=0.80~4.2
Perm-test power @ true Sh=5.04%
Perm-test power @ true Sh=8.08%
Phase 1 perm_p диапазон[0.69, 1.00]
Bonferroni α (15 hyps)0.0033
🔀 B · PIPELINE — MIXED
Look-ahead checkPASS
Survivorship checkPASS
Leveraged ETF filterFAIL
Split-adj contamination (train)28.7%
Split-adj contamination (OOS)0/340
❌ C · REPRODUCIBILITY — FAILS
Frozen ref Sh5.00
Best replay Sh (12-mo, raw)2.86
Best replay Sh (12-mo, 50bps)0.07
Calendar-2023 PF1.08 (не 2.17)
Reproduction gap vs frozen94%

Regime-shift evidence (Auditor C)

Sharpe daily по годам (raw, без slippage)

Mean PnL %/trade по годам

Что говорят данные

Все P0 находки (8 шт)

A · Статистика (3× P0/P1)

P0
Permutation test проверяет clustering, НЕ mean>0
Outcome-shuffle сохраняет total sum PnL → mean дневного ряда инвариантен под перестановкой. Тест ловит только дневную кластеризацию.
Empirical Monte-Carlo: при истинном daily Sh = 0.5/1/2/3/5/8 power = 16/16/12/8/4/8%.
В реальных результатах: organic_pump_short Sh=+1.59 → p=1.00, smoke Sh=+2.17 → p=0.93.
✅ FIX: заменить на sign-flip / stationary block bootstrap (block=5-10 days) на дневном ряду PnL.
P0
90-day OOS не различает DEAD от healthy
SE(Sh) ≈ 1.67 на 90 trade-days → MDE ≈ 4.2 при α=0.05, power=0.80. Frozen 5.0 еле выше MDE; observed 0.51 имеет CI включающий и 0, и 5.
✅ FIX: расширить OOS до ≥250 дней ИЛИ ввести verdict tier INSUFFICIENT_DATA когда CI Sh пересекает 0 и frozen×ratio.
P1
Multiple-testing correction отсутствует (Phase 2)
15 гипотез без Bonferroni/BH. На практике moot (0/8 даже uncorrected p≤0.05), но methodology unsound.
✅ FIX: BH-FDR control в Phase 2 _triage. Reporting q-values рядом с p-values.

B · Data Pipeline (2× P0)

P0
Split/ADR-adjustment mismatch
prev_close из split-adjusted daily_4yr_ohlcv делится в raw unadjusted pm_close из PM cache.
phase0/03_merge_pm_caches.py:73-76
BULZ 2022-10-31: prev_close=$2.84 (adj) vs pm_close=$27.71 (raw) → fake gap=875%
ITUB persistent 35-40% fake gaps (2021-04-01..05)
GGB persistent 25-30% fake gaps
Train contamination: 351/1225 = 28.7% сигнала. После очистки train Sh: -1.19 → +0.57.
OOS: 0/340 затронуты → DEAD verdict устоял.
✅ FIX: либо raw close из daily API (match raw PM cache), либо split-adjust pm_close через polygon/datum splits feed. Hard-filter reverse-split / ADR ratio events. Sanity bound |gap|<200%.
P0
Leveraged ETF leak
BULZ (3x FANG ETN) проникает 86 раз в train sub5_pump candidates. ADV-2M filter не имеет asset-type exclusion.
✅ FIX: explicit ETF-type exclusion list в data_loaders.load_train_oos_features (TQQQ, SQQQ, SOXL, BULZ, BERZ, NAIL, ...).

C · Reproducibility (3× P0)

P0
Sh=5.0 daily ≠ replay 2.86 raw / 0.07 @50bps
Frozen ref overstated в 2-70× в зависимости от slippage. Никогда не наблюдался в raw replay 5y.
✅ FIX: retract Sh=5 из strategy_moo1100_asym_FINAL.md; replace с «best 12-month historical Sh_daily ~2.8 raw / ~0.1 @50bps; majority of years flat-to-negative».
P0
Per-trade vs daily Sharpe label confusion
May02 phase1 verdict.json field sharpe — per-trade annualized, сравнивается с frozen «daily Sh». Здесь численно совпадают (~1 trade/day), но это совпадение, не равенство.
✅ FIX: явно компъютить daily Sharpe через groupby('date').sum() → mean/std × √252. Унифицировать label во всех verdict.json и frozen refs.
P0
PF=2.17 в 2023 pre-period не воспроизводится
Calendar-2023 replay: PF=1.08 N=267, Sh_daily=0.43. Frozen claim PF=2.17 либо использовал (a) другой prev_close range / pm_dvol gate, (b) hand-picked subset overfit, (c) дополнительные regime/SPY/earnings overlays.
✅ FIX: пересчитать с явной фиксацией всех overlays и публиковать confidence interval для PF.

Что прошло (PASS)

✅ Look-ahead discipline

prev_close через shift(1), adv_20d через rolling.shift(1), pm_close это pre-09:30 aggregate. Дисциплина выдержана.

✅ Survivorship

36,254 unique tickers в daily_ohlcv, 13,843 delisted in-sample. Quarterly snapshots в universe_history/ point-in-time. Delisted carried в alive quarters.

✅ Sharpe-scale fix v2

v2 _block_v2 reports daily_sharpe и per_trade_sharpe раздельно, verdict gate uses daily vs daily. Apples-to-apples восстановлено (но perm-test всё равно слаб).

Что делать дальше

🔥 Немедленно

  1. Retract Sh=5.0 / PF=2.17 из strategy_moo1100_asym_FINAL.md. Заменить на «best 12-mo: Sh~2.8 raw / 0.07 @50bps».
  2. Заменить permutation test: outcome-shuffle → sign-flip / block-bootstrap на дневном PnL.
  3. Добавить INSUFFICIENT_DATA verdict tier когда CI Sh пересекает 0 и frozen×ratio.
  4. Filter leveraged ETFs (BULZ/SOXL/TQQQ/...) в data_loaders.
  5. Fix split-adj mismatch: либо raw close, либо split-adjust pm_close.

🔧 В течение недели

  1. BH-FDR correction в Phase 2 hypothesis triage.
  2. Embed slippage в core stats (не только ex-post stress).
  3. Halt-bar handling для sub-$5 имён (n_bars filter).
  4. Унифицировать daily-Sharpe label во всех verdict.json и frozen refs.
  5. Расширить OOS до ≥250 trade-days (1y) перед следующим audit.
  6. Re-run полного аудита на cleaned data — проверить, не сдвинется ли verdict для остальных 4 стратегий.

🔬 Re-research под исправленной методикой · 6 / 12 / 24 мес

Чистый replay с lev-ETF blocklist (140 тикеров, 35,141 строк дропнут), |gap|>200% filter, halt n_bars<60 filter, sign-flip perm test на дневном PnL, block-bootstrap CI95 (block=5d). Окна заканчиваются 2026-04-30.

Окно N trades N days N tickers Sh raw Sh @50bps PF WR % perm p CI95 raw Verdict
6 мес
2025-10-31 → 2026-04-24
218 91 111 +0.33 −3.83 1.05 13.8 0.832 [−4.70, +3.10] DEAD
12 мес
2025-05-01 → 2026-04-24
406 179 169 −0.85 −5.28 0.89 11.8 0.474 [−4.17, +1.58] DEAD
24 мес
2024-05-02 → 2026-04-24
627 307 208 −0.55 −4.70 0.92 12.9 0.536 [−2.67, +1.15] DEAD

Cumulative PnL · 24 мес окно

Raw equity curve трендит вниз (-42% за 2 года), при 50bps slippage обвал до -355%. Виден локальный bounce ноябрь 2025 (best month) — но он не перевешивает 2024-09 / 2025-06 wipe-outs.

Best / worst месяц

Best month (все окна)2025-11 · Sh +7.79 (N=21)
Worst month 6мес2026-03 · Sh −7.61 (N=66)
Worst month 12мес2025-06 · Sh −33.94 (all SL)
Worst month 24мес2024-09 · Sh −45.37 (N=7)

Top contributors 24мес

+ CAN (N=9, +31%) · CGC (N=8, +16%) · MIST (N=2, +14%) · ORBS (N=3, +13%) · BYND (N=5, +11%)
− TMDE (N=11, −11%) · CRWG (N=9, −9%) · FFAI (N=9, −9%) · BITF (N=8, −8%) · OPEN (N=8, −8%)

📌 Что это закрывает

Итоговая позиция

Verdict «DEAD» — оставляем, но переформулируем причину:

💡 Что значит для трейдинга: sub5_pump SHORT не «сломалась» — она была переоценена с самого начала. Не ждём возврата регима 2023. Ищем новые edges под текущий рынок, а старые pre-2024 strategy specs пересматриваем с учётом 50bps slippage и daily-Sh metric (а не per-trade × √252).