Skip to content

View translation

BtcCmInverseHourlyRangingRegimeReversionLS

Hypotheses

BTC COIN-M Ranging-Regime Reversion, Long-Short (BTCUSD_PERP.BINANCE_CM, 1H Bars — Fade 2-Sigma Stretches From a 48h Anchor ONLY When the Market Is Directionless; Exit on Reversion to the Mean; Pure OHLCV, Trend Gate Stands Aside, ~2-Parameter)

Hypotheses

A LONG-SHORT, single-instrument MEAN-REVERSION strategy on the BTC-margined COIN-M inverse perpetual (BTCUSD_PERP.BINANCE_CM, ~0.06% RT taker → 0.10% fee floor). It fills three under-represented buckets at once — BINANCE_CM venue (3.5% vs 5% target), long-short direction (13.1% vs push target), and it uses a mechanism DELIBERATELY DISTINCT from the recent COIN-M failures (the ETHUSD_PERP vol-regime switch was DIRECTIONAL trend-by-vol-bucket with an inverted sign; SolCoinM was a breakout-trap fade; my prior CM idea was session carry-over). This is not a momentum/trend clone (L38), not a portfolio-construction basket (L48), not a non-price-feed gate (L46), not an options structure (engine graveyard), and not a dated-quarterly/liquidation edge (L47 data_unavailable). It is pure OHLCV — the tag family with the best survival rate (no_supplementary_data 3%). Core idea: over the majority of hours crypto is NOT trending, and within those directionless windows sharp intrabar stretches away from a short rolling anchor over-shoot and snap back. We measure the price's z-score vs its 48-hour rolling mean, and we ONLY fade the stretch when a price-derived directionality measure (efficiency ratio) says the market is ranging — standing completely aside when it is trending, which is the classic failure mode of naive reversion. Correct-signed: fade extremes only in chop, never in a trend.

Hypotheses

Iteration 3 fixes the two mechanical causes of the -100% equity curve without touching the z-score, the ER gate, the entry polarity or the inverse-contract sizing (all of which passed Layers 1-3). (1) Inverted payoff: iteration 2's FIXED 2% bracket legs are the wrong units for a sigma-scaled signal. The ER gate deliberately selects quiet windows, where the true profit target -- the distance back to the 48h anchor, (|z|-exit_z) x sigma -- is well inside 2%, so winners were closed early by the signal exit for a fraction of a percent while the 2% stop was only ever reached by a vol expansion that paid it in full (iteration 1: avg_win $438 vs avg_loss $914 at a 63% hit rate). Both legs are now denominated in sigma: TP sits at the reversion target (the same target as the signal exit, but reached INTRA-BAR), stop at TP/rr_target, giving a structural 1.5:1 reward:risk, and any entry whose reversion target cannot clear min_edge_frac (round-trip fees + slack) is skipped. (2) Path-blind sizing: on BINANCE_CM all PnL/commission settles in BTC while get_account_equity() reads the untouched USD-stable balance, so it returns a constant 100k and every entry was sized off full starting capital -- a losing tail then digs a LINEAR hole to exactly -100% instead of decaying. The strategy now harvests realized PnL from closed positions (coin PnL converted to USD at the current price, harvested once per trade on the position->flat transition, never per bar) and sizes off equity + realized, floored at 15% of the start; the correction is applied only when the instrument is inverse so nothing changes elsewhere. Per-trade risk (1.0%) and the gross cap (30%) are also cut so a drawdown shrinks the next bet. Leverage stays 1.0.

Hypotheses

negative_expectancy: negative-expectancy mean-reversion on a decisive 1059-trade / 6.9-year sample — the account liquidated (total_return -100%, PF 0.82, avg_trade_return_pct -0.174% i.e. BELOW ZERO and far under the ~0.10% COIN-M round-trip, expectancy -$49.79/trade, Sharpe -0.86). The core premise is falsified, not mis-tuned: performance is WORST in the calm/ranging tercile (Sharpe -1.84, -100% return) — the exact chop the ER gate selects for — so the ER<=er_max regime filter fails to isolate profitable reversion windows. There is no positive gross edge for the fee advantage to rescue, so optimizing entry_z/er_max cannot invert a wrong-signed regime response. This is iteration 3 of the same mechanism reaching the same wipeout. Not worth 2 hours of optimization.

Implementation

Long-short mean reversion on the BTC-margined COIN-M inverse perpetual (BTCUSD_PERP.BINANCE_CM, 1h bars). Each bar it computes the close's z-score against a 48-hour rolling mean/stdev and Kaufman's efficiency ratio over the same window. It fades 2-sigma stretches (SHORT above the anchor, LONG below) ONLY while the efficiency ratio says the market is directionless (ER <= er_max), standing aside entirely in trends. Exits are a venue-managed OUO bracket whose legs are SIGMA-SCALED per entry -- take-profit placed exactly at the reversion target ((|z|-exit_z) x sigma) and stop at take-profit/1.5, so every trade carries a 1.5:1 reward:risk -- backed by a signal exit on reversion to the anchor and a 48-bar hold cap. Sizing risks 1% of PATH-AWARE equity against the actual bracket stop, capped at 30% gross notional, floored to whole $100 inverse contracts.

Verification Results

Confirm what get_account_equity() returns on a BINANCE_CM (inverse, BTC-margined) account in the backtest engine. If it already reflects realized BTC PnL, remove the _realized_usd correction to avoid double-counting; if it truly is constant, the current harvest is correct.

Verification Results

_path_equity() adds harvested realized PnL to get_account_equity() ONLY for inverse instruments, on the assumption that get_account_equity() returns a constant USD-stable balance that never tracks the BTC-settled PnL path. If the BINANCE_CM account equity in the engine actually reflects the BTC balance change (i.e. already tracks the path), this double-counts losses and shrinks position size faster than intended. The effect is conservative (smaller bets after drawdown), not catastrophic, so it does not block — but the assumption that get_account_equity() is a frozen 100k should be verified against the engine's inverse-account accounting.

Verification Results

Verify the base template honors an overridden min_bars_required(); if it uses a different hook name, align to it.

Verification Results

min_bars_required(self) shadows the base framework method (static-analysis base_shadow warning). If the base template relies on its own warm-up gating and does not dispatch to this override, the intended 48+5 bar warmup may not be enforced by the framework. Synthetic + sandbox both ran and warmed up correctly, so this is informational only.

Verification Results

Sandbox is net negative (total_return -12.5%, Sharpe -0.36, PF 0.96, avg_trade_return_pct -0.025% i.e. below the ~0.10% CM round-trip cost) over 564 trades. Notably the regime attribution shows the WORST performance in the calm tercile (return -11.87%, Sharpe -0.66) — the exact ranging condition the ER gate is designed to select for — which is the opposite of what the hypothesis predicts (reversion should work best in chop). This is a direct test of the core premise and it comes out backwards on this unoptimized draw. The mechanism (thin per-trade reversion edge that must clear inverse-contract fees) may not carry after costs. Worth the analyst checking whether the ER<=er_max gate actually isolates profitable reversion windows before spending optimization budget; entry_z/er_max tuning may not invert a wrong-signed regime response.

Backtest Review

Reliable, decisive sample: 1059 trades over 6.9 years of 1H BTC COIN-M data, metrics_reliable=true.

Backtest Review

Mechanism is correctly signed (fades stretches, stands aside in trends) and cleanly implemented; sizing/inverse-contract handling is sound.

Backtest Review

Negative expectancy on a decisive sample: profit_factor 0.82, avg_trade_return_pct -0.174% (BELOW ZERO, not merely below the ~0.10% COIN-M fee floor), expectancy -$49.79/trade, Sharpe -0.86 with CI [-1.80, 0.09].

Backtest Review

The account LIQUIDATED (total_return -100%, liquidation 2024-05-21) — this is the 3rd iteration of the same mechanism and it wipes out again.

Backtest Review

Core premise falsified: the WORST regime tercile is calm/ranging (return -100%, Sharpe -1.84) — the exact chop condition the ER gate is built to select for. Reversion is supposed to work best here and comes out backwards.

Backtest Review

Adverse win/loss structure (41% win rate) and the ER<=er_max gate does NOT isolate profitable reversion windows — QA's edge concern is confirmed on full history.

Analysis

Backtest gate: - metrics unreliable: Incoherent: Sharpe 0.12 disagrees in sign with total_return -100.00% — the Sharpe is computed from the mtm_equity_curve series while the return comes from the equity curve. Judge on the equity curve.

Iteration History

Verification failed (Layer 4 — QA review) [class=no_edge]: - NET LOSER with the inverted reward/risk the hypothesis claimed the ER gate would prevent. profit_factor 0.815 (<1), total_return -22.36%, avg_trade_return_pct -0.167% (negative), expectancy -$62.6, Sharpe -0.416, alpha -0.066, over 316 well-measured trades. Textbook reversion trap: win_rate 0.630 but avg_loss $914 is more than double avg_win $438 — the failed-reversion tail plus the 4% stop and fees overwhelm the many small wins. The efficiency-ratio gate did NOT fix the inverted-payoff failure mode. Same death as the ETH-CM Bollinger reversion sibling (PF 0.96), worse here (PF 0.815, negative avg_trade). No parameter change rescues a book whose average loss is 2x its average win with a negative per-trade return. - Mean-reversion-fade is a repeatedly-dead family for this inverted reward/risk profile; the ER filter was the differentiator and did not deliver. The structural asymmetry (small target to the anchor vs a wide failed-reversion loss) is intrinsic, not fixable by entry_z/er_max.

Iteration History

Verification failed (Layer 4 — QA review) [class=no_edge]: - Faithful iter-2 implementation is net negative with no edge: total_return −25.8%, Sharpe −0.264 (CI [−1.37, 0.83]), PF 0.903 (<1), avg_trade_return_pct −0.078% (negative, below the CM fee floor), expectancy −$38.84/trade over 423 trades. The intra-bar bracket fix QA requested was applied correctly and worked mechanically (PF 0.815→0.903, tail normalized) but converted a bigger loser into a smaller loser, not an edge — exactly as the developer's ETH-CM precedent predicted. - Payoff still inverted despite the symmetric 2%/2% bracket: win_rate 0.593 but avg_win $608 < avg_loss $983. Winners are capped small by the reversion-to-anchor exit (|z|≤0.25, inside the 2% TP) while losers run to the full 2% stop, so a >50% hit rate still loses. long_win 0.586 / short_win 0.600 are both >0.5 — not a polarity bug, the reversions happen; the geometry just doesn't clear costs.
Strategy report

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