SolTakerFlowMomentumLS
Hypotheses
SOL Perp Aggressor-Flow Momentum — Long-Short, Single-Instrument: Ride Sustained One-Sided Taker Pressure, Exit on Flow Exhaustion (BINANCE SOLUSDT USD-M, 1H Bars, Taker Buy/Sell Volume Delta, 3-Parameter)
Hypotheses
A LONG-SHORT, SINGLE-INSTRUMENT directional strategy on SOLUSDT.BINANCE USD-M perpetual whose signal is NOT price-derived at all — it is the exchange's TAKER BUY/SELL VOLUME split (aggressor flow), a crypto-native microstructure series that is collected as supplementary data (taker_ratio) with multi-year Binance history and is injectable into the Layer-3 sandbox. On each 1H bar we compute a cumulative taker-delta = (taker_buy_vol - taker_sell_vol)/total_vol, standardize it as a rolling z-score over a lookback window, and take a position in the DIRECTION of dominant aggressor flow only when that z-score is extreme AND still building. This is order-flow MOMENTUM (persistence of who is hitting the book), deliberately distinct from the dead classes flagged by the meta-learner: it is NOT OI-gated (L71), NOT funding-gated (L70), NOT a cross-venue carry two-leg (L69), NOT a cross-sectional rotation basket (L68), NOT a pure-OHLCV trend/momentum-confluence clone (L9/L41/L62 — the price series is only used for the exit stop, never the entry), and NOT an options/COIN-M structure (L64/L65). Fills three under-represented portfolio buckets at once: long_short (14.2% vs ≤55%), a fresh microstructure mechanism absent from the 0.7%-survival book, and mid/short horizon. Deliberately only 3 fitted parameters (z-lookback, entry_z, ATR-stop multiple) to resist the 338x overfit graveyard.
Hypotheses
Iteration 3 addresses each QA finding with the minimum change, leaving the (already-passing) flow construction, z-score math, imports and structure untouched. (1) Inverted payoff / 1-bar holds: the exhaustion exit fired at z < entry_z*0.30 = +0.39, which noisy 6h-mean flow crosses the very next bar, cutting winners while losers ran to the stop. It now fires only when flow FLIPS to the opposite side (z < -entry_z*0.25 for longs) and only after min_hold_bars=6, and a chandelier trail (armed after 1.5 ATR of open gain, exits on 2.0 ATR giveback) caps retracement instead of an immediate z-decay exit — so winners are allowed to run and giveback is bounded, reversing the avg_win 96 / avg_loss 159 asymmetry. (2) 424x turnover / fee drag: entry_z raised 1.3 -> 1.8, a 6-bar re-entry cooldown was added, and the per-trade risk budget cut (risk_pct 0.01 -> 0.005, notional cap 0.60 -> 0.30) — together these should cut trade count several-fold and turnover by roughly an order of magnitude, which is what the -59.8% fee-driven return needs. (3) 'Still building' tested on a noisy raw flow tick: replaced with the z-score slope over build_bars=3 bars (same units as the extremity test), so entries confirm a durable build instead of re-firing around a flow peak. Honest caveat: the previous run showed a genuinely negative gross-of-turnover edge, so if the flow-momentum persistence is real it must show up as longer, larger winners here — if this iteration still returns a negative avg_trade_return_pct, the mechanism itself is refuted rather than mis-parameterized.
Hypotheses
aggressor_flow_momentum_negative_expectancy: SOL taker-flow momentum is a net loser over a well-measured 898-trade sample — total_return -14.34%, profit_factor 0.90 (<1.0), expectancy -$15.87/trade, Sharpe -0.295 (CI [-0.967, 0.343]), avg_trade_return_pct 0.0549% (below the 0.15% futures fee floor), information_ratio -0.88. The strategy is negative in every full year (2022 -8.1%, 2023 -0.86%, 2024 -4.66%, 2025 -0.31%, 2026 -2.87%), so the order-flow-persistence premise does not survive net of costs in any regime. Per L8/L9 negative total return with PF<1.0 is disqualifying, and this is already iteration 3 with the same negative-expectancy core; the 3 fitted params cannot turn negative expectancy positive, so a ~225-trial optimization would only curve-fit noise. The microstructure mechanism is novel and cleanly built, but a demonstrated negative edge is a premise refutation, not a tuning gap.
Implementation
Long/short SOLUSDT USD-M perpetual on 1H bars driven purely by exchange taker buy/sell aggressor flow (supplementary taker_ratio + metrics taker_long_short_vol_ratio, merged into one hourly delta series keyed on the hour END to avoid look-ahead). The signal is the z-score of the 6h rolling aggressor delta versus its own trailing z_lookback distribution, returned continuously every bar. Entries take the side of the dominant flow when |z| >= entry_z AND the z-score has been rising/falling over the last build_bars bars (a multi-bar build, not a 1-bar tick). Exits: fixed 2.5-ATR stop from entry, a chandelier trail armed after 1.5 ATR of open gain, a 72-bar time stop, and a flow-exhaustion exit that requires the aggressor flow to actually FLIP against the position (z past -0.25*entry_z) and only after a 6-bar minimum hold. Sizing is ATR-risk-based at 0.5% of equity per stop-out, capped at 30% of equity notional; a 6-bar cooldown blocks immediate re-entry into the same flow spike.
Verification Results
Verification failed (Layer 4 — QA review):
- Fee-nonviable / negative post-fee edge. The Layer-3 sandbox over a well-populated sample (930 trades, 363 days) is decisively negative: total_return -59.8%, profit_factor 0.357 (<1.0), avg_trade_return_pct -0.0404% (NEGATIVE, and below the 0.15% futures viability floor even in magnitude), Sharpe -0.28 (CI [-2.09, 1.27] straddling zero), information_ratio -0.52, max_drawdown 60.6%. Per QA checklist item 7 — a negative avg_trade_return_pct with PF<1.0 is a hard fee-viability failure and must be blocked rather than advanced to the 2-hour optimization run.
- Excessive turnover with an inverted payoff contradicts the hypothesis's 'ride SUSTAINED one-sided pressure' thesis. turnover is 424x and avg_holding_period is ~1h 2m (≈1 bar) despite max_hold_bars=72. Root cause: the flow-exhaustion exit fires at exit_level = entry_z*exit_z_frac = 1.3*0.30 = 0.39, so a long entered at z>=1.3 exits as soon as the noisy 6h-mean z decays below 0.39 (often the next bar), while losers run to the 2.5-ATR stop. Result avg_win 96 vs avg_loss 159 — winners cut fast, losers run: the opposite of letting trends run. It is scalping single-bar z-spikes and paying 424x equity in fees to do it.
- 'Still building' is tested on the raw flow change (flow - prev_flow > 0) while extremity is tested on the z-score. Near a flow peak, flow_delta flips sign bar-to-bar, so entries cluster/re-fire around noisy peaks rather than confirming a durable build — inflating turnover.
Verification Results
Route to the analyst at BACKTEST_REVIEW for a full multi-year backtest; if the per-trade edge stays below 0.15% net of futures fees on full history, abandon as weak/fee-nonviable rather than iterating parameters.
Verification Results
Marginal fee viability. The Layer-3 sandbox (206 trades / 363 days, a clean and adequately-sized sample) reports avg_trade_return_pct = 0.146%, just BELOW the 0.15% futures per-trade floor, with profit_factor 0.969 (<1.0), negative total_return, and Sharpe -0.40 (CI [-2.06, 1.21] straddling zero). The order-flow momentum edge, as parameterized, does not clearly clear the ~0.10% round-trip futures cost. This is not a code defect — the mechanism, entries, exits, and sizing all execute correctly — but the realized per-trade edge is at/below the viability boundary. Same signature the developer flagged in the config rationale.
Verification Results
Analyst should weight total_return / profit_factor / USD expectancy over avg_trade_return_pct when deciding optimize/iterate/abandon.
Verification Results
Metrics ambiguity (not a strategy bug): report shows avg_trade_return_pct = +0.146% alongside avg_trade_pnl_usd = -4.98 and profit_factor < 1.0. avg_trade_return_pct disagrees in sign with USD expectancy here; net-of-fee economics are negative.
Backtest Review
Genuinely novel microstructure mechanism (taker aggressor flow, not price-derived entry) — fills an under-represented bucket
Backtest Review
Well-measured 898-trade sample and clean, non-clone implementation (no OHLCV/OI/funding/cross-venue crutch)
Backtest Review
Turnover already reduced across 3 iterations; benchmark_correlation ~0 (market-neutral in exposure terms)
Backtest Review
Net loser: total_return -14.34%, PF 0.90 (<1.0), expectancy -$15.87/trade — disqualifying per L8/L9
Backtest Review
Sharpe -0.295 with CI [-0.967, 0.343]; Sortino -0.24; omega 0.89 — no risk-adjusted edge
Backtest Review
avg_trade_return_pct 0.0549% — well below the 0.15% futures fee floor (L22)
Backtest Review
Negative in every full year (2022 -8.1%, 2024 -4.66%, 2026 -2.87%) — premise refuted across all regimes
Backtest Review
information_ratio -0.88; already iteration 3 with the same negative-expectancy core
Outcome Summary
SolTakerFlowMomentumLS pursued a genuinely fresh idea: trade SOL perps on the direction of sustained taker aggressor flow rather than price, deliberately avoiding all the dead single-instrument classes flagged by the meta-learner and filling under-represented portfolio buckets. Three iterations progressively refined the mechanism — flip-based exhaustion exits, a chandelier trail, a slope-based 'still building' test, higher entry threshold and cooldowns to cut turnover — but the core signal never earned money. Across a well-measured 898-trade sample it lost 14.34% with a profit factor of 0.90, negative Sharpe, and per-trade returns far below the fee floor, and it was negative in every full year from 2022 to 2026. The analyst abandoned it at the backtest-review gate, concluding the order-flow-persistence premise was refuted net of costs and that three parameters could not convert a demonstrated negative expectancy into an edge.
Outcome Summary
A genuinely novel, cleanly-built microstructure signal is worthless if it has negative expectancy — order-flow persistence (taker aggressor delta) did not survive net of costs in any regime, and once a well-measured sample shows PF below 1.0, more iterations and parameters cannot rescue it.
Outcome Summary
The analyst issued an 'abandon' verdict at the pre-optimization backtest-review gate: a demonstrated negative edge (negative total return with PF below 1.0 is disqualifying per the factory's rules) across a large sample and every market regime is a premise refutation, not a tuning gap, so three parameters could not turn negative expectancy positive and optimization would only curve-fit noise. This was already the third iteration with the same negative-expectancy core; it never reached optimization, post-opt analyst review, or risk review.
Outcome Summary
A long-short, single-instrument order-flow momentum strategy on SOLUSDT Binance USD-M perp (1h bars) whose entry signal was not price-derived but the exchange's taker buy/sell volume delta (aggressor flow), z-scored over a lookback and traded in the direction of extreme, still-building one-sided pressure, exiting on flow flip, chandelier trail, ATR stop, or time stop, with only 3 fitted parameters.
Outcome Summary
Over a well-measured 898-trade sample (459 long / 439 short, 46.9% win rate) it was a net loser: total return -14.34%, profit factor 0.90, expectancy -$15.87/trade, Sharpe -0.295 (95% CI [-0.967, 0.343]), Sortino -0.24, information ratio -0.88, and avg_trade_return_pct of 0.0549% — well below the 0.15% futures fee floor — and it was negative in every full year from 2022 through 2026.
Iteration History
Verification failed (Layer 2 — synthetic scenarios):
Parameters used: ['entry_z', 'risk_pct', 'atr_period', 'z_lookback', 'exit_z_frac', 'min_notional', '_param_bounds', 'atr_stop_mult', 'max_hold_bars', 'min_stop_frac', 'min_z_samples', 'flow_window_hours', 'max_notional_frac']
Check that __init__ sets all attributes from self.parameters.get().
- steady_uptrend: TypeError: SolTakerFlowMomentumLS._to_ns() takes 1 positional argument but 2 were given (bar timestamp: 1735690740000)
- steady_downtrend: TypeError: SolTakerFlowMomentumLS._to_ns() takes 1 positional argument but 2 were given (bar timestamp: 1735690740000)
- flat_ranging: TypeError: SolTakerFlowMomentumLS._to_ns() takes 1 positional argument but 2 were given (bar timestamp: 1735690740000)
- volatility_spike: TypeError: SolTakerFlowMomentumLS._to_ns() takes 1 positional argument but 2 were given (bar timestamp: 1735690740000)
- zero_volume: TypeError: SolTakerFlowMomentumLS._to_ns() takes 1 positional argument but 2 were given (bar timestamp: 1735690740000)
- price_gap: TypeError: SolTakerFlowMomentumLS._to_ns() takes 1 positional argument but 2 were given (bar timestamp: 1735690740000)
Backtest and paper results are hypothetical. Trading involves risk of loss.