Skip to content
All strategies

Strategies

COIN-M ETH Inverse-Perp Regime-Gated Bollinger Mean Reversion, Long-Short (Single-Instrument BINANCE_CM, 1H, Fade Band Extremes ONLY in Ranging/Low-ADX Regime, Mid-Band Take-Profit, Failed-Reversion Stop, Pure OHLCV, Low-Parameter, Cheapest-Fee Venue)

Outcome: Abandoned

EthCoinMRangingBollingerReversionLS

Well-measured (781 trades over 5.8 years); clean 4-parameter pure-OHLCV construction with an ADX regime gate and correct inverse-contract sizing

Hypothesis

A LONG-SHORT, SINGLE-INSTRUMENT, pure-OHLCV counter-trend MEAN-REVERSION strategy on ETHUSD_PERP.BINANCE_CM (Binance COIN-M inverse perpetual, ETH-margined, 1-HOUR bars). It deliberately fills the two most under-target buckets at once: BINANCE_CM venue (only 1.7% of the portfolio vs the >=5% quota — the single most starved venue, and barely explored) and long_short direction (14.5%). COIN-M also carries the cheapest round-trip taker fee in the entire venue set (~0.06% RT), which widens the post-fee edge headroom……Show moreShow less

A LONG-SHORT, SINGLE-INSTRUMENT, pure-OHLCV counter-trend MEAN-REVERSION strategy on ETHUSD_PERP.BINANCE_CM (Binance COIN-M inverse perpetual, ETH-margined, 1-HOUR bars). It deliberately fills the two most under-target buckets at once: BINANCE_CM venue (only 1.7% of the portfolio vs the >=5% quota — the single most starved venue, and barely explored) and long_short direction (14.5%). COIN-M also carries the cheapest round-trip taker fee in the entire venue set (~0.06% RT), which widens the post-fee edge headroom for a reversion strategy whose per-trade targets are modest. Critically, this is a MECHANISM the factory has not validated — it is NOT momentum/breakout/continuation (the squeeze-breakout, opening-range-breakout, impulse-bar-continuation, Donchian, and time-series-momentum families already in the book) but its orthogonal counterpart: fading short-term overextension back to the mean. The well-known failure mode of classic Bollinger/RSI mean reversion in crypto (trends run over the fade and stop you out) is addressed structurally with an ADX ranging-regime GATE: the strategy only fades band extremes when ADX(14) confirms a low-trend / range-bound regime, and stands aside entirely when ADX shows a strong trend. Pure OHLCV means zero supplementary-data dependency (sidestepping the funding/option-settlement data failures that abandoned the recent families). Kept intentionally low-parameter (4 core params) to resist the overfitting that has been the recurring abandonment cause.

This is the smallest change that addresses the specific defect QA identified, and it is a structural fix rather than a parameter tweak. QA accepted that the reversion effect is real (win_rate 0.717, positive gross per trade) and located the expectancy leak precisely: the failed-reversion stop was evaluated on the bar CLOSE, so fast adverse moves blew through it, leaving largest_loss -$5,289 against avg_loss $762 - a ~7x tail. The arithmetic makes the fix worth attempting: expectancy is 0.717*$289 -……Show moreShow less

This is the smallest change that addresses the specific defect QA identified, and it is a structural fix rather than a parameter tweak. QA accepted that the reversion effect is real (win_rate 0.717, positive gross per trade) and located the expectancy leak precisely: the failed-reversion stop was evaluated on the bar CLOSE, so fast adverse moves blew through it, leaving largest_loss -$5,289 against avg_loss $762 - a ~7x tail. The arithmetic makes the fix worth attempting: expectancy is 0.717*$289 - 0.283*avg_loss, which is -$8.2 at avg_loss $762 and turns POSITIVE once the average loss drops below ~$732, i.e. a ~4% reduction. Capping a 7x tail intra-bar should exceed that comfortably, so unlike a threshold sweep this has a mechanical reason to change the result rather than reshuffle noise. Implementation: use_bracket_orders is enabled with stop_loss_pct=2.0%, and the z-based stop is REMOVED from should_exit so the position cannot be double-exited (the base template cancels the resting legs when the mid-band signal exit fires). I picked 2.0% by measuring the OLD dynamic stop distance, sigma*(stop_z-|z|)/price, on this instrument's real 1h history at entry-zone z values: median 2.12%, p25 1.27%, p75 3.54%. So the stop sits essentially where it always sat - only WHEN it fires changed - which is what keeps this a fix to the tail rather than a re-tuning of the edge. Sizing now measures risk against that same bracket distance, keeping _risk_pct semantically true. Everything else is untouched: imports, the ADX state machine, the arm/re-entry logic, the continuous z-score signal and the inverse-contract sizing are as they were through Layers 1-3. I want to be straight about the residual risk: QA measured the gross per-trade edge at roughly 0.11% against a ~0.10% COIN-M round trip, so even with the tail capped the margin is thin and the take-profit side is unchanged - if this run still shows profit_factor near 1.0 with a normalised loss distribution, the honest conclusion is that the mechanism has no room on this venue and it should be abandoned rather than tuned further.

Negative-expectancy single-name mean-reversion — no edge to optimize. Over 781 measured trades: profit_factor 0.907 (<1), avg_trade_return_pct -0.059% (negative), expectancy -$14.74/trade, total_return -19.6% over 5.8 years, Sharpe -0.019 with bootstrap CI [-0.85, 0.76] straddling zero (PSR 0.48). The iteration-2 intra-bar bracket stop worked as designed (win_rate rose to 64.3%) but the reward:risk stays inverted (avg_win $224 < avg_loss $444, ~0.5), so at that win rate expectancy is still ~-$17/trade — the……Show moreShow less

Negative-expectancy single-name mean-reversion — no edge to optimize. Over 781 measured trades: profit_factor 0.907 (<1), avg_trade_return_pct -0.059% (negative), expectancy -$14.74/trade, total_return -19.6% over 5.8 years, Sharpe -0.019 with bootstrap CI [-0.85, 0.76] straddling zero (PSR 0.48). The iteration-2 intra-bar bracket stop worked as designed (win_rate rose to 64.3%) but the reward:risk stays inverted (avg_win $224 < avg_loss $444, ~0.5), so at that win rate expectancy is still ~-$17/trade — the classic small-wins/large-losses mean-reversion signature the fix could not flip. It is fee-fragile (commission 17.34% of gross at the 1H cadence), loses in most years (2022 -8.3%, 2024 -3.0%, 2026 -2.6%) with almost all stress windows negative (china-ban -3.3, FTX -2.7, SVB -5.2) and max_drawdown 35% (CI to 76.5%). This is the L55 single-name fade/reversion family (0/174 survivors), where re-tuning entry/exit thresholds has never lifted the class over costs. No parameter change flips a sub-1-PF, negative-per-trade, RR-inverted reversion. Failure pattern: no_edge/fee_edge single-name mean-reversion, RR-inverted (L55).

Implementation

Long-short ADX-gated Bollinger band fade on the ETH COIN-M inverse perpetual (ETHUSD_PERP.BINANCE_CM, 1-hour bars, pure OHLCV). It computes the close's Bollinger z-score over 20 bars, arms a fade when z reaches a band extreme (+/-2.0), and enters only once price starts reverting back inside the band while Wilder ADX(14) confirms a ranging regime below 20. The mid-band (z crossing the SMA) is the take-profit and a 48-bar time stop bounds the hold. Iteration 2 moves the failed-reversion stop from a bar-close z check to a VENUE-MANAGED bracket leg at 2.0% that triggers intra-bar, so a fast adverse move is cut at the level instead of at the next close. Sizing risks 0.5% of equity over that bracket stop distance, capped at 0.75x equity of gross notional, floored to WHOLE $10-face inverse contracts.

Verification Results

CLEAN RESTART 2026-09-04 — this run's verdict history and learning records were removed and it was restarted from verification. Its previous abandonment came from the pipeline, not from the market: the Layer-2 harness mis-bound @staticmethod helpers (fixed), QA issued terminal performance verdicts on an unoptimized smoke test (removed — QA now judges correctness only), and sandbox timeouts came from backtest-slot starvation (fixed). The hypothesis and the strategy code are unchanged. Verify the code on its merits; performance is decided later by the full backtest and the optimizer.

Analyst to decide abandon vs optimize on full history; if PF stays ~1.0 after walk-forward, abandon per the developer's stated condition rather than burning a 3-phase optimization.

Fee-viability is marginal by the developer's own measurement (gross per-trade edge ~0.11% vs ~0.10% CM round trip), realized as breakeven-to-negative (PF 1.0001, avg_trade_return_pct ~0). Classic mean-reversion fee-graveyard tension: the mid-band TP caps wins small while the 2% bracket stop makes losses ~2x larger, so almost no post-fee headroom. Not a code defect — the mechanism, gate, and exits are correctly implemented.

Backtest Review

Sharpe
-0.02
Total return
-19.62%
Max drawdown
35.12%
Trades
781
Win rate
64.3%
Profit factor
0.91

Well-measured (781 trades over 5.8 years); clean 4-parameter pure-OHLCV construction with an ADX regime gate and correct inverse-contract sizing

Iteration-2 intra-bar bracket stop worked mechanically (win_rate up to 64%); no blow-up, contained per-trade risk

Negative expectancy: PF 0.907, avg_trade_return_pct -0.059%, expectancy -$14.74/trade, total_return -19.6%, Sharpe -0.019 (CI [-0.85, 0.76])

RR still inverted (avg_win $224 < avg_loss $444, ~0.5) — the high win rate does not overcome the loss asymmetry; the stop fix lifted win-rate but not expectancy

Fee-fragile: commission 17.34% of gross at the 1H reversion cadence

L55 single-name fade/reversion family (0/174 survivors); loses in most years; stress windows almost all negative; max_drawdown 35% (CI to 76.5%)

Iteration History

Verification failed (Layer 4 — QA review) [class=no_edge]: - FEE-NONVIABLE / NEGATIVE EXPECTANCY. The mean-reversion effect is real (win_rate 0.717, positive gross per-trade edge) but too small to survive fees plus fat-tailed failed-reversion losses. Sandbox: profit_factor 0.962 (<1), avg_trade_pnl -$8.21 (negative expectancy), total_return -11.9%, alpha -0.0338 over 750 days / 265 trades. Classic asymmetric reversion trap: small mid-band take-profits (avg_win $289) outweighed by large failed-reversion stops……Show moreShow less

Verification failed (Layer 4 — QA review) [class=no_edge]: - FEE-NONVIABLE / NEGATIVE EXPECTANCY. The mean-reversion effect is real (win_rate 0.717, positive gross per-trade edge) but too small to survive fees plus fat-tailed failed-reversion losses. Sandbox: profit_factor 0.962 (<1), avg_trade_pnl -$8.21 (negative expectancy), total_return -11.9%, alpha -0.0338 over 750 days / 265 trades. Classic asymmetric reversion trap: small mid-band take-profits (avg_win $289) outweighed by large failed-reversion stops (avg_loss $762, largest_loss -$5,289) when a trend runs through the fade despite the ADX gate. The developer's honest measurement matches: gross per-trade edge ~0.11% ~= one round-trip of COIN-M fees, and the ADX gate is already at its best setting (ungated -0.12%/trade, adx_max=25 -0.03%, adx_max=20 +0.013% gross) yet still can't clear the 0.10% floor. No parameter change rescues an edge that structurally equals its trading cost. - The failed-reversion stop is checked on z at bar CLOSE (stop_z=3.5), so a fast adverse move blows past it before the check fires — largest_loss -$5,289 vs avg_loss $762 (~7x tail). Design behavior, not a bug, but it's why the high win rate doesn't yield positive expectancy.

Verification failed (Layer 4 — QA review) [class=no_edge]: - The iteration-2 fix is correct and worked mechanically, but it revealed the mechanism is fee-nonviable with no room to recover. The intra-bar bracket stop capped the tail exactly as intended (largest_loss -$5,289 -> -$525, avg_loss $762 -> $414, max_drawdown 31% -> 6.78%, kurtosis normalized to 3.4) and lifted expectancy from -$9 to -$0.40 — but the result is now break-even/slightly negative: profit_factor 0.997, expectancy -$0.40, avg_trade_return_pct……Show moreShow less

Verification failed (Layer 4 — QA review) [class=no_edge]: - The iteration-2 fix is correct and worked mechanically, but it revealed the mechanism is fee-nonviable with no room to recover. The intra-bar bracket stop capped the tail exactly as intended (largest_loss -$5,289 -> -$525, avg_loss $762 -> $414, max_drawdown 31% -> 6.78%, kurtosis normalized to 3.4) and lifted expectancy from -$9 to -$0.40 — but the result is now break-even/slightly negative: profit_factor 0.997, expectancy -$0.40, avg_trade_return_pct -0.0016% (below the 0.10% CM floor), total_return -4.04%, Sharpe 0.072 (CI [-1.14, 1.18] straddling zero), over 271 trades. The tail cap also cut win_rate (0.717 -> 0.672) and avg_win ($289 -> $202) because the 2% intra-bar stop closes trades that dipped then recovered, so the ~0.11% gross edge nets to zero against the ~0.10% round-trip cost. The developer stated the criterion up front: 'if this run still shows profit_factor near 1.0 with a normalised loss distribution, it should be abandoned rather than tuned further' — that condition is exactly met (PF 0.997, normalized losses). No parameter change closes a gap this structural. - Credit where due (not a defect): the bracket conversion is implemented correctly per check 16 — use_bracket_orders with both stop_loss_pct and take_profit_pct > 0, the z-stop removed from should_exit so there is no double-exit, only signal-based exits (mid-band TP, time stop) remain, and sizing measures risk against the actual bracket stop distance. Exactly the fix QA asked for; it exposed the absence of edge rather than creating one.

Backtest and paper results are hypothetical. Trading involves risk of loss.