Strategies
DOGE Intraday VWAP-Reversion, Long-Short (Single-Instrument BINANCE Perp, 15m Bars, Fade Moderate Z-Score Deviations from Rolling VWAP Back to Fair Value — Applied to the Highest-Amplitude Liquid Perp for Maximum Fee Headroom, Trend-Regime Gated, Favorable-RR Geometry, Pure OHLCV, 3-Parameter)
Outcome: Abandoned
DogeVwapReversionLS15m
Single-name, single-mechanism, 3 parameters — no cross-sectional best-of-N surface to overfit
Hypothesis
Implementation
Long-short, single-instrument intraday VWAP z-score mean-reversion on DOGEUSDT.BINANCE USD-M perpetual, 15m bars, pure OHLCV. Each bar computes a 1-day rolling VWAP anchor and a z-score of the close's deviation from it (normalized by recent deviation dispersion), and a Kaufman efficiency-ratio regime gate. It SHORTS when z ≥ entry_z and LONGS when z ≤ -entry_z, only in a non-trending regime (ER ≤ trend_er_max). Iteration 3 fixes the inverted-RR geometry defect: both exits are now expressed in the SAME z/sd units — the TARGET is reversion to the anchor (|z| ≤ exit_z) and the STOP is further divergence (|z| ≥ stop_z) — so reward (entry_z−exit_z) exceeds risk (stop_z−entry_z) by construction and the two exits no longer live in incompatible units. The z-space hard stop also bounds each loss in sd units, and entries are more selective (higher entry_z, tighter regime gate, a 2h post-exit cooldown, quarter-equity sizing) to cut the commission churn that dominated the prior run. Three tunable knobs: entry_z, stop_z, trend_er_max.
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.
In optimization, treat entry_z and the cooldown as primary turnover levers and verify that thinning trades actually lifts avg_trade_return_pct above the ~0.15% futures floor rather than just shrinking a negative-expectancy sample.
Despite the anti-churn changes, the sandbox still shows commission at 25.47% of gross over 312 trades (turnover 272x) — fee drag remains the dominant loss driver, the exact failure mode the iteration targeted. The churn controls are implemented correctly but appear insufficient to reach fee viability.
Backtest Review
- Sharpe
- -1.07
- Total return
- -100.00%
- Max drawdown
- 100.00%
- Trades
- 3425
- Win rate
- 47.9%
- Profit factor
- 0.54
Single-name, single-mechanism, 3 parameters — no cross-sectional best-of-N surface to overfit
Large trade count (3,425) makes the negative result statistically decisive rather than noise
Account LIQUIDATED 2021-12-04: total_return -100%, max_drawdown 100%, CAGR -100% — the iter-3 z-space stop bounds single losses but does not fix negative expectancy (daily return -579.6% on the blowup day)
Negative per-trade edge: avg_trade_return_pct -0.101% (below the 0.15% fee floor, L22), profit_factor 0.54, expectancy -$45.52/trade, Sharpe -1.07 (CI [-2.75, -0.66] fully below zero), PSR 0.0
Inverted realized RR persists despite the geometry fix: avg_win $111.7 < avg_loss $189.8, largest_loss -$7,724, skew -30.9, kurtosis 1,277 — winners capped, losers run
Loses across all three vol regimes (calm/normal/stressed Sharpe -8.3/-6.3/-3.0) and nearly every month of the traded window
L55/L7 zero-survivor single-name intraday VWAP/price-reversion fade — the fade thesis has the wrong sign on DOGE 15m; the high-amplitude 'fee headroom' choice amplified adverse excursions into a liquidation
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.