MaticFourHourVolumeConfirmedBreakoutLong
Hypotheses
MATIC Four-Hour Volume Breakout Long-Only (BINANCE USD-M Futures, 4H, OHLCV-Only)
Hypotheses
Long-only MATIC 4-hour strategy on BINANCE USD-M futures. Direct analog of the landed BTC/ETH/SOL/BNB/AVAX/DOGE/XRP FourHourVolumeBreakoutLong family — applied to MATIC. Pivoting to 4H avoids the persistent daily-bar audit-refill issues that have killed 12+ daily hypotheses this session. Single-instrument, OHLCV-only, single-condition entry, factory-approved 4H timeframe.
Hypotheses
Iteration 4 addresses ONLY the reported Layer-3 failure (300s smoke-test wall-clock timeout). Layers 1 and 2 already passed, so imports, class structure, signal semantics, entry/exit conditions, sizing, and leverage wiring are unchanged. The timeout came from per-bar data marshalling: the previous revision rebuilt four numpy arrays every bar via list comprehensions over Bar objects (`np.array([b.close.as_double() for b in recent])` x4), costing ~200 Cython attribute calls plus four numpy allocations per bar. Although the window was already bounded, numpy's fixed allocation overhead dominates at ~52 elements. The fix: an `_ingest()` method extracts each bar's OHLCV floats exactly once on arrival (idempotent via `bar.ts_init`, so Layer-2's proxy re-entry cannot double-append) into four aligned Python float lists, trimmed together as one unit to preserve index alignment. All rolling statistics now use builtin `sum`/`min`/`max` over small slices — strictly cheaper than numpy at this window size and O(window), not O(history). numpy was dropped for `math.isfinite`, which is a permitted stdlib import and keeps Layer 1 green. Every threshold remains parameterised, `calculate_signal` still returns a continuous breakout-distance proxy every bar (never gated to a constant), `should_enter` thresholds the `_armed` flag, and `position_size()` still reads `self.config.leverage` so the 2.0x setting is genuinely consumed (0.60 x 2.0 = 1.2x equity notional). The 20-bar breakout with a 6% stop and 18% target targets per-trade moves far above the ~0.10% round-trip taker cost.
Hypotheses
Long-only breakout on a structurally declining asset — loses money in every year of its existence, and no parameter can fix the premise. total_return -33.21%, sharpe_ratio -3.1496, sortino -5.697, profit_factor 0.742, omega_ratio 0.553, expectancy -$370.65 across 90 trades, max_drawdown 44.83% (CI to 66.20%), probabilistic_sharpe 0.0885, with annual_returns negative in all three years (2024 -0.19%, 2025 -17.45%, 2026 -19.11%) and rolling Sharpe negative continuously from 2025-07-18 to the end of the run. The decisive tell is in the strategy's own docstring: the developer shortened the regime filter from ~200 bars to 50 because 'a 200-day SMA regime filter would block essentially every long and produce zero trades.' That zero-trade output WAS the correct answer — it is the filter reporting that POL has no sustained bull regime in this window — and weakening it until trades appear fits the parameter to a desired trade count rather than to the asset. It also breaks the 'direct analog of the landed family' premise the hypothesis rests on. Not 'iterate': the code is correct and faithfully implements the mechanism (90 long / 0 short, 90/90 orders submitted, zero drops), so there is no bug to fix; restoring the proper 200-bar regime filter would simply return zero trades, which is the same verdict by another route. Not 'optimize': a 225-trial sweep over a long-only breakout cannot manufacture an uptrend in the underlying, and the run only spans 2024-09-13 onward (~1.8 years, data_days 75) because MATICUSDT was delisted, so a 3-window walk-forward would fit noise on a fraction of the history the siblings were validated over. Costs compound the problem: total_impact_usd $23,079 is roughly DOUBLE total_commission $11,088 on turnover 745 in a thin alt, and avg_position_pct 140.99% exceeds the stated 1.2x design because notional is sized off shrinking equity, so effective leverage rises as the strategy loses. Note that information_ratio +0.4322 must NOT be read as an edge — alpha is -0.1189, and the positive IR only reflects losing more slowly than POL's own buy-and-hold. FAILURE PATTERN: porting the promoted 4H Volume-Confirmed Breakout family (BTC/ETH/SOL/BNB/AVAX/DOGE/XRP) to MATIC/POL does NOT inherit promotability. The siblings' edge is inherited from assets that trend UP over the test window; POL has declined persistently since the rename, so the long-only expression is net-negative before any tuning. Two generalizable rules: (1) when a regime filter blocks every entry, that is a VERDICT about the instrument, not a parameter to relax — a strategy that must disable its own trend gate to trade is telling you the trend is absent; (2) before porting a long-biased mechanism to a new asset, check that the asset's price trend over the available history is non-negative — the same lesson the BCH drawdown-accumulation abandon already recorded.
Implementation
Long-only 4H volume-confirmed Donchian breakout on POLUSDT (the currently-listed successor to the delisted MATICUSDT) on Binance USD-M futures at 2x leverage. Enters long when the 4H close breaks above the prior 20-bar high, volume exceeds 1.2x its 20-bar average, and price is above a 50-bar SMA (bull regime). Exits on a 10-bar Donchian-low break, a 6% stop, an 18% take-profit, or a 30-bar time stop. Pure OHLCV, single instrument, no supplementary data.
Verification Results
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 Review
The code is competently written and faithfully implements the volume-confirmed Donchian breakout family: 90 long / 0 short (correct for a long-only hypothesis), entry_diag shows 90 signaled -> 90 submitted with zero drops. No mechanism mismatch, no coding bug.
Backtest Review
The developer correctly detected that MATICUSDT was delisted (~2024-09) and re-pointed to the successor POLUSDT contract rather than failing on data_unavailable. That diagnosis was right.
Backtest Review
Trade count (90) would be an adequate sample if the sign of the result were favorable.
Backtest Review
THE STRATEGY LOSES MONEY IN EVERY YEAR OF ITS LIFE. annual_returns: 2024 -0.19%, 2025 -17.45%, 2026 -19.11%. total_return -33.21%, sharpe_ratio -3.1496, sortino -5.697, profit_factor 0.742, omega_ratio 0.553, expectancy -$370.65/trade. probabilistic_sharpe 0.0885. Rolling Sharpe turns negative on 2025-07-18 and never recovers across the following twelve months.
Backtest Review
THE REGIME FILTER WAS DISABLED BECAUSE IT WORKED. The docstring states a 200-bar SMA regime filter 'would block essentially every long and produce zero trades', so regime_bars was cut to 50. That zero-trade output was the correct answer, not an obstacle: it means POL has no sustained bull regime in this window. Shortening the filter until trades appear fits the parameter to a desired trade count, and it is a deviation from the proven sibling template that invalidates the 'direct analog' premise.
Backtest Review
LONG-ONLY BREAKOUT ON A STRUCTURALLY DECLINING ASSET. This is the known BCH drawdown-accumulation failure pattern. The BTC/ETH/SOL/BNB/AVAX/DOGE/XRP siblings inherit their edge from assets that trend up over the test window; POL does not. No parameter inside a long-only breakout can manufacture an uptrend, so there is nothing for optimization to tune toward.
Backtest Review
SIZING EXCEEDS SPEC AND COMPOUNDS THE LOSS: avg_position_pct is 140.99% against a stated design of position_pct 0.60 x leverage 2.0 = 1.2x. Notional is computed from shrinking equity, so effective leverage rises as the strategy bleeds. Combined with max_drawdown 44.83% (CI up to 66.20%) and annualized_volatility 61.77%, this is 1.4x leverage into a falling asset.
Backtest Review
COSTS ARE SEVERE: total_impact_usd $23,079 is roughly DOUBLE total_commission $11,088, on turnover 745 in a thin alt. commission_pct_of_gross 11.54%. Even a real edge would struggle to clear this.
Backtest Review
HISTORY IS TOO SHORT REGARDLESS: the POLUSDT contract only begins 2024-09-13 (data_days 75, 3,901 4H bars, ~1.8 years). The landed siblings were validated over ~6 years. A 3-window walk-forward here would fit noise.
Backtest Review
information_ratio is +0.4322 only because the strategy lost LESS than holding POL outright; alpha is -0.1189. Underperforming cash while outperforming a falling asset is not an edge.
Outcome Summary
The developer got the hard part right: MATICUSDT was delisted around 2024-09 after the rename to POL, and rather than failing on data_unavailable the strategy correctly re-pointed to the successor POLUSDT contract. The code then faithfully implemented the breakout family — 90 long / 0 short, every signal filled — but POL has declined persistently since the rename, so the long-only expression was net-negative in all three years, and the docstring recorded the moment the premise broke: the trend gate was weakened until trades appeared. Costs compounded it (total_impact_usd $23,079, roughly double the $11,088 in commissions, on turnover 745 in a thin alt) and avg_position_pct reached 140.99% against a 1.2x design, because notional was sized off shrinking equity so effective leverage rose as the strategy bled. The reviewer declined both iterate (no bug — restoring the proper filter just returns zero trades, the same verdict by another route) and optimize (a sweep cannot create an uptrend, and ~1.8 years of history would only fit noise), and flagged the positive information_ratio of +0.4322 as an artifact of losing more slowly than POL itself, not an edge — alpha is -0.1189.
Outcome Summary
When a regime filter blocks every entry, that is a verdict about the instrument, not a parameter to relax — and a long-biased mechanism only inherits its siblings' promotability if the new asset's trend over the available history is non-negative.
Outcome Summary
The backtest-review gate abandoned it before optimization ran: the decisive tell was in the strategy's own docstring, where the developer cut the regime filter from ~200 bars to 50 because a 200-bar SMA 'would block essentially every long and produce zero trades' — a long-only breakout on a structurally declining asset, where no parameter can manufacture an uptrend.
Outcome Summary
Port the promoted 4H Volume-Confirmed Breakout Long family (BTC/ETH/SOL/BNB/AVAX/DOGE/XRP) to MATIC — trading the successor POLUSDT.BINANCE USD-M contract on 4-hour bars, entering long on a volume-confirmed Donchian breakout above a 50-bar SMA regime filter, exiting on channel break, take-profit, stop-loss, or a max-hold time stop.
Outcome Summary
Across 90 long trades (90 signaled, 90 submitted, zero drops) it returned -33.21% total with Sharpe -3.1496, Sortino -5.697, profit_factor 0.742, omega_ratio 0.553 and expectancy -$370.65 per trade, against a 44.83% max drawdown (CI to 66.20%). It lost money in every year of its life — 2024 -0.19%, 2025 -17.45%, 2026 -19.11% — with rolling Sharpe turning negative on 2025-07-18 and never recovering.
Iteration History
Verification failed (Layer 3 — sandbox backtest): No trades produced
Bar type used: POLUSDT.BINANCE-4-HOUR-LAST-EXTERNAL, Bars processed: 3903
Diagnostics: should_enter() returned a side 0 times over 0 evaluated bars -> your ENTRY CONDITION never triggered. Loosen the entry logic / thresholds.
Ensure your strategy produces trades with the given data and parameters.
Backtest and paper results are hypothetical. Trading involves risk of loss.