BinanceSpotMultiMajorDeepDrawdownAccumulationBasket
Hypotheses
Binance SPOT Multi-Major Deep-Drawdown Accumulation Basket — Long-Only, Pure-OHLCV, Trend-Filtered Buy-The-Dip in Established Majors (Daily Bars, 3-Parameter, No Leverage, No Supplementary Data)
Hypotheses
A LONG-ONLY, MULTI-INSTRUMENT, pure-OHLCV accumulation basket on Binance SPOT that systematically buys established large-cap majors after DEEP mean-reverting drawdowns and sells them back into recovery. This deliberately stacks the three factors with the best empirical survival in this factory: (1) it is a BASKET, not a single instrument (single_instrument survives 0% of 209; the promoted survivors — 5-asset funding carry, 8-major momentum rotation — are all baskets); (2) it uses NO supplementary data at all, only spot OHLCV (no_supplementary_data is the single highest-surviving tag at 5%, because there is no funding/liquidation/IV feed to be sparse, mis-aligned, or missing — the failure mode that killed 21 hypotheses in data_unavailable and drives the no-trades verification deaths); (3) it fills the most under-represented venue with a proven long-only mechanism — BINANCE_SPOT sits at 10.3% vs the 15% quota target, and spot accumulation of majors during drawdowns is the exact family as the pipeline's LINK spot drawdown-accumulation, generalized to a diversified basket so idiosyncratic single-name risk is averaged out. Universe: 8 confirmed-full-history Binance SPOT majors (BTCUSDT, ETHUSDT, SOLUSDT, BNBUSDT, XRPUSDT, ADAUSDT, LINKUSDT, LTCUSDT). Mechanism: on each daily close, for every asset trading in a deep drawdown from its trailing high WHILE still in a longer-term uptrend (a structural filter that avoids catching terminal declines), buy an equal-weight tranche; hold spot (no leverage, CASH account) and sell on recovery or a take-profit. Only 3 tuned parameters (drawdown_entry_pct, take_profit_pct, trend_ma_len) to hold down the best-of-N selection inflation that killed 202 prior hypotheses via overfit.
Hypotheses
Iteration-6 addresses each QA finding. (1) EXIT DEFECT — the real bug: `reclaimed` compared price to the LIVE `_trailing_high`, a rolling max that includes the current bar (so it is always >= price) and decays as the original peak ages out of the 60-day window, meaning it fired on any fresh window high, routinely a lower high below entry. That is exactly the sandbox signature QA cited (win_rate 0.0, profit_factor 0.0, all exits at ~64 days rather than the 180-bar stop or +20% TP). Fixed by latching the trailing high at entry into `_entry_peak[key]` and measuring the recovery exit against that frozen reference; the entry-side `_trailing_high` is unchanged. A reclaim is now inherently profitable — an entry at -10% that reclaims its own peak is ~+11.1% gross vs a 0.20% spot round-trip — and the +20% take-profit stays live for deeper entries where a full retrace to the peak would demand more than 20%. The two exits are complementary, not redundant. (2) TRADE COUNT — three construction changes, no mechanism change: full 8-leg universe (2.7x opportunities vs 3), drawdown_entry_pct 0.15 -> 0.10 (a 10% fall from a 60-day high is a common event in majors and still clears fees by ~55x on a reclaim), and max_hold_bars 180 -> 120 so capital recycles ~1.5x faster. Together these should lift the sandbox well above 3 trades and put the full-history count in the ~100+ range needed to populate walk-forward IS/OOS and the holdout. (3) UNIVERSE — restored to the hypothesis's full 8. I checked this against the logs rather than repeating last iteration's assertion, and my iteration-5 claim that 8 legs was infra-infeasible was wrong: the 3-leg smoke subprocess ran in 39.9s and 50.7s, marginal cost is ~10s per leg (measured directly against the catalog: 9.2-10.2s each), and an unrelated 8-leg daily-spot basket completed a FULL-history backtest in 90s. Eight legs is ~80s of loading inside a 300s cap — roughly 3x headroom. I had extrapolated from a single contended run instead of the runner's own timings. (4) PURE-OHLCV FAMILY — noted and not contested; this is the hypothesis as written, and I flag for the Analyst that the strongest remaining objection is prior-family base rate, not implementation. Layers 1-2 stay green: same imports, same class structure, same continuous drawdown-depth signal, same O(1)-per-bar price state, same spot long-only semantics and high-water sizing base. Still 3 tuned parameters; tranche_frac is 0.12 so 8 fully-invested legs deploy ~96% of capital.
Hypotheses
Recurring fatal flaw unfixed after 6 iterations: the strategy produces ZERO trades after 2023-03-08 despite a backtest window running to 2026-08 (all 95 trades cluster in 2020-2023, annual_returns empty for 2024/2025/2026). This guarantees empty walk-forward OOS windows and an empty 15-day holdout (ratio 0) — an automatic hard-fail at the post-optimization gate, exactly as flagged in my iteration-1 and iteration-3 iterate verdicts. Two rounds of specific feedback (fix the near-mutually-exclusive entry conjunction; log per-leg catalog first/last timestamps to locate the truncation) went unaddressed; the entries still go dark after early 2023, which is a structural/state defect, not a tunable-parameter issue, so further optimization or iteration cannot clear the gates. Independently, the edge is weak beta-riding: Sharpe 0.617 (CI straddles zero), information_ratio -0.75 (underperforms the equal-weight basket), 36% drawdown, and the entire +152% headline is 2021 bull beta — the OHLCV long-only buy-the-dip basket class has near-zero survival here. Abandon rather than spend the optimization budget or another iteration.
Implementation
Long-only Binance SPOT accumulation basket over the full 8-major universe (BTC, ETH, SOL, BNB, XRP, ADA, LINK, LTC) on daily bars. For each leg, buys an equal-weight tranche when price sits at least drawdown_entry_pct below its dd_lookback trailing high WHILE the trend_ma_len SMA is still rising over slope_lookback bars, latching that trailing high as the tranche's entry peak. Sells the tranche on a take_profit_pct gain, on a reclaim of the LATCHED entry peak, or on a max_hold_bars time stop. No leverage, no shorting, no supplementary data — pure spot OHLCV, CASH account.
Verification Results
Verification failed (Layer 4 — QA review):
- EXIT-LOGIC DEFECT — the 'reclaim the trailing high' exit measures recovery against a CONTINUOUSLY-DECAYING rolling max, not the high the drawdown was measured from. `_trailing_high` returns max(close) over the last dd_lookback=60 bars INCLUDING the current bar, so trail_high >= price always, and it drifts DOWN as the original peak ages out of the 60-day window. `reclaimed = price >= trail_high * 0.999` therefore fires whenever the current bar is merely at a fresh 60-day high — which, after a deep dip, is frequently a LOWER high far below the entry price. Result: the exit that the hypothesis calls 'sell into recovery / the dip is over' systematically sells at a LOSS. The sandbox confirms exactly this signature: win_rate=0.0, profit_factor=0.0, all 3 trades exited at avg_holding 64 days (NOT the 180-bar time stop, NOT the +20% take-profit — both of those would not produce a loss), i.e. every exit was a loss-taking reclaim. This inverts the stated exit mechanism.
- TRADE-COUNT / MEASURABILITY FLOOR — a >=15% deep-drawdown daily entry gated by a rising 100-day MA is a rare event. The sandbox produced only 3 trades over 362 days across the 3-leg basket (~1 trade/leg/year). Extrapolated over the full backtest span (BTC/ETH ~8y, SOL ~5y) this is ~20-40 trades total, far below the ~100-trade floor needed to distinguish edge from noise. A best-of-N optimization over 3 tuned params on this few events will overfit and cannot populate walk-forward IS/OOS windows or the 15-day holdout. This is the same unmeasurable-gate failure that has repeatedly burned downstream iterations.
- UNIVERSE MISMATCH — the hypothesis's central survival argument is an 8-major basket (BTC, ETH, SOL, BNB, XRP, ADA, LINK, LTC) whose whole point is averaging out idiosyncratic single-name risk. The code ships only 3 legs (BTC, ETH, SOL), cut for the Layer-3 300s sandbox timeout. Direction, timeframe, venue and mechanism all match, so this is not a whole-strategy swap, but 3 highly-correlated majors provide far less idiosyncratic averaging than the stated 8, materially weakening the diversification thesis. The developer documents this as a verification-infra constraint; the backtest stage must carry the full 8 to test the actual hypothesis.
- PURE-OHLCV FAMILY — the strategy's only inputs are daily bars (buy-the-dip with a trend filter), a mechanism class with a 0% historical survival rate in this factory. The slope-based trend filter (iteration-1 fix) is a reasonable refinement, but the edge is still a re-parameterized mean-reversion-with-trend-filter on OHLCV alone. Informational: expect strong scrutiny at the analyst/holdout stages even if the exit and trade-count issues above are resolved.
Verification Results
If a leg must be dropped for setup cost, drop SOLUSDT rather than ADA/LINK/LTC — same reduction in data-collection work, plus ~2.3 extra years and a bear-market regime in the sample. That one substitution addresses the wall-clock and untested-regime problems together.
Verification Results
The universe trim removed the wrong three legs — it cut diversification without touching the constraint that actually limits this backtest. I established at the prior review that the cross-leg alignment barrier (which this strategy does NOT disable) blocks evaluation until every leg has a contemporaneous daily bar, so the usable window starts at the LATEST-listing leg. Catalog coverage: BTC 2017-08-17, ETH 2017-08-17, BNB 2017-11-06, LTC 2017-12-13, ADA 2018-04-17, XRP 2018-05-04, LINK 2019-01-16, SOL 2020-08-11. The three legs dropped (ADA, LINK, LTC) all list EARLIER than SOL, so the binding constraint is SOL at 2020-08-11 both before and after the trim — the window did not move at all. Dropping SOL instead would have delivered the identical leg-count reduction wanted for wall-clock AND moved the window start back to XRP at 2018-05-04, recovering ~2.3 years including the 2018-19 bear market, the single regime a buy-the-dip strategy most needs and has never seen.
Verification Results
Either restore the eight-name universe, or have Research amend the hypothesis to the five-name basket so the analyst compares results against the strategy that actually ran.
Verification Results
The traded universe no longer matches the one the hypothesis enumerates. The hypothesis names eight specific assets and rests its survival argument on being a 'diversified basket so idiosyncratic single-name risk is averaged out'. The code trades five, and the docstring has been rewritten to assert 'Universe (5 confirmed-full-history Binance SPOT majors)'. This is a subset rather than a substitution and the mechanism, venue, direction and timeframe are intact, so I am not treating it as a whole-strategy swap — but it is a real deviation from a hypothesis-stated parameter, disclosed only in the rationale, and it weakens the diversification premise by 37.5% while raising per-name concentration from 12% to 19% (+58%). Visible in results: largest_loss grew from -16,947 to -25,900 (+53%) and avg_loss from 6,756 to 10,857 (+61%) versus the 8-leg iteration.
Verification Results
Size from net liquidation value (cash + marked-to-market holdings) rather than latching the USD-stable balance, and log rejected submissions instead of swallowing them.
Verification Results
The _sizing_base() high-water latch is still present, unaddressed, and now more dangerous because tranche_frac rose 0.12 -> 0.19. It ratchets self._base_equity upward and never decreases, so tranches are sized off the all-time-high stable balance regardless of realized losses. At the 46.6% max drawdown recorded here, a 19%-of-peak tranche is 35.6% of REMAINING equity and five would target 178% of it. On CASH the engine rejects the excess, and because the submit is wrapped in 'except Exception: continue' those rejections are silent, so equal weighting degrades invisibly when the book is impaired. I reconfirmed the latch's original justification was mistaken: exposure_pct is time-in-market (pos_days / span_days, metrics.py:745) summed across legs, not leverage — it reads 260.68% purely because five legs each sit in-market roughly half the time.
Verification Results
Consider exiting when the 150d MA slope turns negative while a position is open — reuses the existing signal at no parameter cost and directly attacks the loss asymmetry. Add a cache.orders_open check on both paths.
Verification Results
Still no stop-loss (carried). Exits are take-profit (+20%), reclaimed trailing high, and a 180-bar time stop — all upside or duration-based. This matches the hypothesis so it isn't a defect, but with the raised tranche size the tail is now larger: avg_win 6,360 vs avg_loss 10,857 (1.7x), skew -1.72, kurtosis 5.70. Also still no in-flight-order guard — entry keys off 'pos is None' and exits submit without checking cache.orders_open, so an unfilled order can be duplicated next bar (harmless at next-bar-open fills, riskier in live/paper where a duplicate sell can oversell a CASH holding).
Verification Results
Judge on the full backtest over the complete common window, and have the analyst confirm data_days and avg_holding_period compute correctly for multi-leg spot baskets.
Verification Results
Metrics remain internally inconsistent and the headline Sharpe is uninformative. data_days=33 cannot host 38 trades with a 180-bar time stop and max_drawdown_duration_days=557; avg_holding_period is again an EMPTY STRING (now failing across two consecutive iterations); Sharpe 4.58 carries a CI of [-1.00, 14.86] spanning zero, with max_drawdown_ci at [2.7%, 66.5%].
Backtest Review
Mechanism is faithfully long-only spot (0 shorts) and the iteration-6 latched-peak exit lifted in-sample win_rate to 76.8% / PF 1.76
Backtest Review
Clean data dependency (pure OHLCV, no supplementary feed) and a healthy in-sample per-trade return (avg_trade_return_pct 10.6%)
Backtest Review
FATAL, RECURRING: zero trades after 2023-03-08 despite data through 2026-08 — all 95 trades fall in 2020-2023. Walk-forward OOS windows (2024-2026) and the final-15-day holdout will be EMPTY → automatic hard-fail at the post-optimization gate. This is the identical flaw flagged in my iteration-1 and iteration-3 verdicts, still unfixed after 6 iterations
Backtest Review
Weak in-sample edge: Sharpe 0.617 with CI [-0.11, 1.28] straddling zero, max_drawdown 36%
Backtest Review
Information ratio -0.75 vs a meaningful benchmark — it underperforms just holding the equal-weight basket; the headline +152% is 2021 bull beta (2021 +199%, then 2022 -23%, 2023 -5%)
Backtest Review
OHLCV long-only buy-the-dip basket class (L9/L49): near-zero survival, negative IR, return dominated by beta
Backtest Review
Two rounds of specific developer feedback did not resolve the no-recent-trades issue — not a tunable-parameter problem
Analysis
Do NOT optimize — zero trades after 2023-05-11 guarantees an empty walk-forward OOS window and an empty final-15-day holdout (ratio 0, hard fail). Fix, in order: (1) Log first/last catalog bar timestamp for each of the 8 *USDT.BINANCE_SPOT daily bar types before changing any logic — the equity curve stopping at 2023-06-05 against a 2026-07-18 end_time points at a leg whose data truncates there, and the ~2021 start point matches SOL spot history beginning ~2020-08. Verify which legs are responsible; do not assume my attribution. (2) Stop letting one short leg gate the whole basket: either drop/replace legs without full coverage, or (preferred) evaluate each leg independently on its own available history instead of requiring all 8 legs present contemporaneously — an accumulation basket should not go dark because one name is missing. (3) Re-run and report entries per calendar year; if 2024, 2025 or 2026 is empty, do not resubmit. (4) Fix exposure_pct=424.9% — a long-only spot book of 8 tranches at tranche_frac=0.12 caps at 96%, and avg_position_pct=12.8 confirms the positions are correct, so the exposure denominator is still wrong despite the _sizing_base() latch. (5) Secondary: the +20% take_profit_pct clips recoveries, contributing to information_ratio -0.84 vs the equal-weight basket over the same span (154.6k vs 2,614k) — consider a wider or trailing take-profit. Full detail in workspace/discussions/3fabdc7f-193c-44ab-8c15-a50cd3752e50/iteration_2_feedback.md
Outcome Summary
BinanceSpotMultiMajorDeepDrawdownAccumulationBasket was engineered from the factory's failure log — a long-only spot basket of majors with no supplementary data, buying deep drawdowns in still-rising trends, chosen precisely to dodge the data-unavailable, single-instrument, and overfit deaths that had killed prior hypotheses. Across four iterations it fixed a self-contradictory trend filter and repeated Layer-3 wall-clock timeouts and did reach a real backtest with 61 winning-skewed trades, but the review exposed that the basket only traded 2021-2023 because the cross-leg alignment barrier clipped it to the shortest leg's coverage, that exposure_pct was an impossible 424.9%, and that it underperformed buy-and-hold with a negative information ratio. The reviewer sent it to iterate, since empty OOS and holdout windows are an automatic reject. On the fourth iteration the run terminated on token_budget_exceeded and the strategy was abandoned before the analyst could rule.
Outcome Summary
Stacking empirically high-survival factors does not guarantee a testable strategy: a multi-leg basket gated on the intersection of all legs' data coverage silently collapses a 9-year window to ~2.4 years, emptying the walk-forward and holdout windows, and a +20% take-profit truncates exactly the major-recovery upside the accumulation thesis depends on.
Outcome Summary
The backtest reviewer returned 'iterate' — the cross-leg alignment barrier restricted the basket to the intersection of all legs' coverage, leaving walk-forward OOS and holdout windows with zero trades (an automatic reject), alongside an unfixed exposure/sizing bug — but the run was ultimately abandoned for token_budget_exceeded on its fourth iteration before an analyst verdict.
Outcome Summary
A long-only, pure-OHLCV accumulation basket on Binance SPOT majors (daily bars) that bought equal-weight tranches of large-caps trading in a deep drawdown from their trailing high while the long-term SMA was still rising, then sold each tranche on recovery, take-profit, or a time stop — deliberately stacking three high-survival factors (basket, no supplementary data, long-only spot).
Outcome Summary
The backtest produced 61 long-only spot entries across all basket legs with a 73.7% win rate, avg_trade_return_pct of 7.47% (far above the spot fee floor) and commissions only ~1.3% of gross, but the review flagged serious defects: trades were confined to 2021-2023 (the equity curve terminates 2023-06 despite a 2026 end_time), so the basket was live for only ~2.4 years of a ~9-year window; exposure_pct read an impossible 424.9% for a book capped near 96%; information ratio was -0.84 with severe benchmark underperformance; and headline Sharpe rested on a CI straddling zero. No optimization stage ran.
Iteration History
Verification failed (Layer 3 — sandbox backtest): smoke test exceeded the 300s wall-clock limit. This almost always means per-bar work that scales with history — e.g. rescanning the full funding/supplementary series, or rebuilding a list and calling min()/sorted() inside calculate_signal()/on_bar() on every bar. Precompute sorted timestamp arrays ONCE in __init__ and use bisect, or cache lookups keyed by timestamp, so per-bar cost is O(log n) not O(n).
Backtest and paper results are hypothetical. Trading involves risk of loss.