The canonical discovery-loop control flow: vectorbt sweeps, autoinv confirms, López de Prado gates
The question
What's the canonical architecture for a systematic-strategy discovery loop — candidate generation → walk-forward validation → deflated-Sharpe/PBO gating → paper-deploy — that vectorbt (vectorized sweep) and the autoinv event engine (high-fidelity confirm) implement together? Context: Phase 2 of RDCO's automated-investing pipeline is parked pending founder go; this brief gives Phase 2 a control-flow spec to build against, with honest statistical reporting (no inflated Sharpe on tiny trade counts) as a non-negotiable.
What we already know (from the vault)
- The discovery-loop spine is already drawn in [[2026-05-29-strategy-pipeline-architecture-v0]]: eight modules left-to-right (data → backtest engine → strategy interface → discovery/search → validation gate → sizing → execution → monitoring), with the load-bearing decision "buy the vectorized core (vectorbt), build the RDCO discipline shell." The sweep runs vectorbt over
family × symbol/universe × horizon × param-gridon the TRAIN/VALIDATION partition only, auto-incrementing a cumulative trial counter N; the validation gate is three GATES-not-reports (economic prior → DSR → PBO-via-CSCV) plus dual buy-and-hold benchmarks, then exactly one sealed-holdout touch. - [[2026-06-01-cpcv-deflated-sharpe-autoinv-validation]] supplies the formulas and the honest scope ruling: the current
autoinv/validation.pywraps sklearnTimeSeriesSplit(single walk-forward path) + a bias-audit checklist and has NO CPCV / purge / embargo / DSR / PBO yet — these are the Phase-2 build. It gives the CPCV path math (φ[N,k]=(k/N)·C(N,k); N=6,k=2 → 15 splits / 5 paths), the DSR and MinTRL formulas, and the decisive caveat that DSR is defined over T = return observations, NOT round-trip trades. - [[2026-06-01-ensemble-admission-correlation-threshold]] settles where ensembles slot in: only AFTER each constituent independently passes economic-prior + DSR + PBO + dual-BH and earns one clean holdout touch. Ensembling is a post-validation variance reducer (a three-part gate: independent-validation-first → shared-feature veto → OOS correlation/effective-bet floor), never a rescue path for gate-failed cells.
- [[investing-backtest-thesis]] (v2 harness) is the source of the honest-stats rule the gate inherits: trade-count-aware Sharpe precision (<10 trades → no decimals AND no DSR claim; 10-50 → 1 decimal; 50+ → 2 decimals), mandatory leave-one-out by stress episode, bootstrap CIs, and dual buy-and-hold benchmarks. The autoinv repo ([[01-projects/automated-investing/index]]) is Phase-1 only today: event-driven spine + a fail-closed no-lookahead
guard.py+ shadoworacle.py; Phase 2 (discovery, gate, vectorbt sweep) is a separate founder go.
What the web says
- The two-stage vectorized→event-driven split RDCO chose is the canonical practitioner pattern, not an RDCO invention. Hasan Javed's 2026 backtesting-library survey states it plainly: "Vectorized for research. Event-driven for anything that will ever touch real money. If your vectorized result looks too good, it is." Vectorization is "a filtering stage, not a validation stage" (hasanjaved.me, Best Python Backtesting Libraries 2026).
- The named failure mode is exactly the vectorbt→autoinv handoff's reason to exist: "you will discover 'alpha' that does not survive event-driven re-execution with realistic fills. Always port your best ideas to an event-driven framework before touching capital." Vectorized engines abstract fills as instantaneous, slippage as a fixed percentage, and gloss order-of-events ambiguities; event-driven matches live behavior tick-by-tick (hasanjaved.me).
- vectorbt's own positioning is built for the discovery stage: "test tens of thousands of strategy variants," "1,000,000 backtest simulations in 20 seconds," Numba/Rust-accelerated array ops over the full price series, with native walk-forward optimization and a modular data→indicators→signals→allocations→portfolio decomposition (vectorbt GitHub; PyQuant News).
- The gating stack is the López de Prado canon. Combinatorial Purged Cross-Validation (CPCV): partition the series into N sequential groups, choose k as test → C(N,k) splits; "φ[N,k]=(k/N)C(N,k)" backtest paths (N=6,k=2 → 15 splits / 5 paths). Purging: "Any training observations whose label horizon overlaps with the test period are excluded." Embargo: a small-percentage buffer of post-test observations is dropped. CPCV's product is a distribution of OOS paths, not a single estimate, which "reduces the dependence on any single market regime" (Wikipedia, Purged cross-validation).
- Deflated Sharpe Ratio (Bailey & López de Prado 2014) corrects the observed Sharpe for selection bias under multiple testing AND non-normal returns — it "helps separate legitimate empirical findings from statistical flukes" (SSRN 2460551). The companion gate is PBO (probability the in-sample winner falls below median OOS). Controlled-environment studies find CPCV "demonstrates marked superiority in mitigating overfitting risks… lower Probability of Backtest Overfitting (PBO) and superior Deflated Sharpe Ratio (DSR)" vs walk-forward/k-fold, because the single-path methods can't furnish the OOS distribution the metrics need (ScienceDirect, backtest overfitting comparison).
Convergences and contradictions
- Convergence (web + vault, tight): the canonical loop is unambiguous and RDCO's v0 already implements it — vectorized sweep for cheap candidate generation, event-driven re-execution with realistic fills for high-fidelity confirmation, López de Prado's DSR + PBO + CPCV as the anti-overfit gate, and exactly one sealed-holdout touch per survivor. The vault even named the precise web warning ("alpha that doesn't survive event-driven re-execution") as the reason for the two-engine split.
- Contradiction the canon flags that v0 must respect: the literature prescribes CPCV (a distribution of OOS paths) as the proper basis for DSR/PBO, but v0's DISCOVERY stage as currently specced uses a single walk-forward path through vectorbt's WFA and a cumulative trial-counter N for the DSR deflation. Counted-N under-deflates because dense grid cells are correlated (v0's own red-team flagged this; the canon's "effective N, not literal N" is the same point). The honest fix is to source V[SR_n] and effective-N from CPCV path Sharpes at the confirm stage, not from grid-cell count at the sweep stage.
- The scope contradiction that disqualifies the whole stack on part of the book: DSR/PBO/CPCV are defined over T = return observations and need many near-independent blocks. RDCO's capital-cycle book has ~5-6 trades in ~40 years — CPCV can't form non-degenerate C(N,k) paths there, and DSR over a handful of trade-returns is dominated by skew/kurtosis estimation noise. Both vault and canon agree: route the gate at large-sample liquid surfaces; keep rare-state cyclicals on the v2 leave-one-out harness, never on DSR.
Synthesis for RDCO
The canonical loop, as a Phase-2 control-flow spec. Five stages, each with an explicit gate that a candidate must clear before consuming the next (more expensive) resource. (1) CANDIDATE GENERATION — vectorbt owns it. The discovery swarm sweeps param_space() × point-in-time universe × horizon on the TRAIN/VALIDATION partition only (holdout import-walled out), bounded by a pre-registered trial budget (e.g. ≤2000 cells/run) so N is known a priori, auto-incrementing the cumulative trial counter. Gate here = GATE 0, economic prior: a candidate with an empty economic_prior is hard-rejected at registration, and prior_strength scales the DSR bar it must later clear (a story-less candidate gets a harsher discount, never a free pass). This is the cheapest cull and it stops a pure pattern-miner from ever reaching the exhaustible holdout. vectorbt's job ends at producing a ranked table of {strategy, symbol, horizon, params, in-sample Sharpe, trial_id} — ranked by economic-gated candidacy, never by raw Sharpe.
(2) WALK-FORWARD VALIDATION and (3) DSR/PBO GATING — autoinv (the event engine) owns both. This is the high-fidelity confirm stage and the reason the two engines exist separately: vectorbt's instantaneous-fill, fixed-slippage abstraction generates false positives by construction, so every surviving candidate is re-executed event-driven with the real cost model (maker-limit fills, slippage bps, after-tax/wash-sale-aware net returns) and the fail-closed no-lookahead guard. Inside autoinv: anchored walk-forward (cycle-aligned windows for slow strategies, calendar-stepped for fast), leave-one-out by stress episode, bootstrap CIs, a deliberate future-leak mutation test that MUST change the result. Then the multiple-testing gates: GATE 1, Deflated Sharpe (DSR<0.5 = noise REJECT, DSR>1.0 = real-skill confidence; report raw SR and DSR side by side) and GATE 2, PBO via CSCV/CPCV (high PBO = the search process itself overfits → reject the whole family, not just the cell). The honest correction the canon demands: estimate effective-N and V[SR_n] from CPCV path Sharpes (N=6,k=2 → 5 paths is the canonical default; confirm each group still holds enough bars after purge+embargo), not from correlated grid-cell count. A candidate must clear GATE 0+1+2 AND beat BOTH mandatory buy-and-hold benchmarks before it earns the next stage.
(4) SEALED HOLDOUT — the single arbiter. A HoldoutManager with import-level read access is the only module that can touch the holdout segment; the discovery path receives a feed handle that physically excludes holdout dates and a test asserts it RAISES on any holdout read. A survivor is run on holdout EXACTLY ONCE; a second peek burns that segment (logged, retired). DSR/PBO are necessary-not-sufficient pre-screens — the sealed holdout is the real verdict. The pre-registered go/no-go bar (set BEFORE looking at OOS) is the three-bar wet rehearsal: null-test passes (structure vs iid) → calibration holds OOS within CI → risk-adjusted improvement after cost AND after tax beats both benchmarks across ≥2 leave-one-out episodes. (5) PAPER-DEPLOY GATING. Only a triple-gate + holdout-clearing survivor reaches sizing (vol-target spine → earn-your-Kelly, fixed-fractional 1% until OOS-calibrated edge graduates it to quarter-half Kelly → heat/correlation caps) and execution (Alpaca paper, fractional DAY LIMIT only, never OPG/market-on-open per [[feedback_alpaca_paper_opg_unreliable]]). Live capital is a separate founder-gated DECISION — canonical APPROVE or explicit "deploy" verb, structural agreement is not enough ([[feedback_paper_trade_deploy_authorization]]).
The statistical guardrails, made mechanical. Min trade count: <10 trades → no decimals on Sharpe and NO DSR claim at all; 10-50 → DSR only alongside its MinTRL and a wide bootstrap CI; 50+ → DSR as a hard gate. Below ~30 independent observations the skew/kurtosis feeding the deflation term are too noisy and the deflation is theater. Wire the MinTRL guard as a refusal, not a report line: validation.py returns "insufficient track record — report distribution instead" when available T < MinTRL(observed SR, skew, kurt, benchmark, confidence). Deflation thresholds: DSR<0.5 reject / >1.0 confidence. The mandatory new report section vs today's harness is the multiple-testing ledger (cumulative N, DSR, PBO, trial-Sharpe distribution). And the cultural guardrail the build pre-registers: MOST candidates should FAIL — a pipeline that "discovers" many winners is suspect, and a clean negative (nothing beats buy-and-hold-with-kill-switch after cost+tax) is a SUCCESS of the discipline. The capital-cycle book is explicitly carved OUT of this entire stack: it stays on the v2 leave-one-out-by-episode harness with integer-precision Sharpe, because DSR/CPCV on 5 trades is exactly the false rigor the harness forbids.
Open follow-ups
- Pre-register the effective-N estimator (changes every DSR the pipeline ever reports). Does GATE-1's N come from the cumulative trial counter, the CPCV path count, or a correlation-adjusted effective-N? The canon says CPCV paths; v0's sweep currently counts grid cells. Resolve before coding.
- Confirm N=6, k=2 against each swarm surface's train/validation span — verify each of the N groups still holds enough bars after purge + embargo, per universe, or pick a different (N,k).
- Decide whether the autoinv confirm stage runs CPCV in addition to anchored walk-forward, or instead of it — v0 wants both (walk-forward for the time-ordered view, CPCV for the distribution feeding DSR/PBO); confirm the build carries two CV regimes rather than one.
- Pin the holdout-refresh policy — touch-once-then-retire makes the holdout a depleting resource; is a periodic roll-forward reseal the sanctioned replenishment, or a different policy?
- Read the AFML primary (de Prado ch. 7 + ch. 12) and SSRN 2460551 to verify the embargo-fraction default and the exact CSCV partition count behind the "lower PBO / higher DSR" claim (cited from secondary sources here, not deep-read).
Related
- [[2026-05-29-strategy-pipeline-architecture-v0]] — the eight-module pipeline spine and three-GATE validation design this brief turns into a control-flow spec
- [[2026-06-01-cpcv-deflated-sharpe-autoinv-validation]] — CPCV path math, DSR/MinTRL formulas, the "T = return observations not trades" caveat, and the current-autoinv gap analysis
- [[2026-06-01-ensemble-admission-correlation-threshold]] — where ensembles slot in (post-validation only) and the three-part admission gate
- [[investing-backtest-thesis]] — the v2 walk-forward / leave-one-out / honest-stats harness the gate inherits and the capital-cycle book stays on
- [[01-projects/automated-investing/index]] — the RayDataCo/automated-investing repo pointer; Phase-1 (event-driven spine + no-lookahead guard) built, Phase-2 a separate founder go
Sources
Vault:
~/rdco-vault/01-projects/investing/2026-05-29-strategy-pipeline-architecture-v0.md— pipeline spine, vectorbt-buy/discipline-build decision, three-GATE design, sealed-holdout discipline, phased build plan (Phase 2 = the gate)~/rdco-vault/06-reference/research/2026-06-01-cpcv-deflated-sharpe-autoinv-validation.md— CPCV/DSR/MinTRL formulas, φ[N,k] path math, current autoinv/validation.py gap, capital-cycle carve-out~/rdco-vault/06-reference/research/2026-06-01-ensemble-admission-correlation-threshold.md— ensemble admission gate (independent-validation-first → shared-feature veto → OOS correlation/effective-bet floor)~/rdco-vault/01-projects/investing/plugin/skills/backtest-thesis/skill.md— v2 honest-stats harness (trade-count-aware precision, leave-one-out, bootstrap CIs, dual benchmarks)~/rdco-vault/01-projects/automated-investing/index.md— repo pointer; Phase-1 spine + no-lookahead guard built, Phase-2+ deferred
Web:
- Best Python Backtesting Libraries 2026 (Hasan Javed) — https://hasanjaved.me/blog/best-python-backtesting-libraries-2026/ (vectorized-for-research / event-driven-before-capital; "alpha that doesn't survive event-driven re-execution")
- vectorbt — https://github.com/polakowo/vectorbt and https://www.pyquantnews.com/the-pyquant-newsletter/1000000-backtest-simulations-20-seconds-vectorbt (vectorized sweep scale; native walk-forward optimization)
- Purged cross-validation (CPCV / purging / embargo) — https://en.wikipedia.org/wiki/Purged_cross-validation (φ[N,k]=(k/N)·C(N,k); N=6,k=2 → 15 splits / 5 paths; distribution-of-paths)
- The Deflated Sharpe Ratio (Bailey & López de Prado 2014) — https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2460551 (selection-bias + non-normality correction)
- Backtest overfitting comparison (synthetic controlled environment) — https://www.sciencedirect.com/science/article/abs/pii/S0950705124011110 (CPCV → lower PBO / higher DSR vs walk-forward/k-fold)