BtcLiquiditySweepContinuationTickDriven
Hypotheses
BTC Liquidity-Sweep Continuation, Long-Short (Single-Instrument BTCUSDT.BINANCE Perp, TRADE-TICK Driven — Detect a Large Aggressive Volume BURST That Sweeps Resting Liquidity, Trade WITH the Sweep for Short-Term Continuation, Fee-Aware Large-Event-Only, Tight Stop / Time Stop, 3-Parameter)
Hypotheses
A LONG-SHORT, single-instrument, EVENT-DRIVEN microstructure strategy on BTCUSDT.BINANCE USD-M perpetual that trades discrete LIQUIDITY-SWEEP events from the trade tape (trade_ticks) — structurally distinct from the two continuous-imbalance microstructure probes already pending (BtcOrderFlowImbalanceContinuation reads a rolling CVD imbalance over minutes; EthOrderBookDepthImbalance reads resting depth skew). This reads a DISCRETE EVENT: a sudden large burst of one-sided aggressive volume that sweeps through resting liquidity in seconds — the footprint of an urgent/informed participant or a stop-run cascade. The evidence forcing microstructure: every bar-based directional edge on majors is now proven noise at the fee boundary (dual-TF confluence family ALL abandoned Sharpe 0.3-0.45/PF~1.19; trend baskets Sharpe ~0.3), fades/reversions are refuted (cross-sectional reversal −48%, VWAP/wick/weekend dead), and cross-sectional momentum — the one real edge — is exhausted and execution-cursed. Bars destroy the sweep signal by aggregation. The mechanism trades WITH the sweep (continuation), not against it (avoiding the dead fade family): when a large aggressive-SELL burst sweeps bids, near-term price tends to CONTINUE lower (the level was defended and is now gone, and cascades/stop-runs extend); mirror for aggressive-buy sweeps. The single decisive design choice is FEE-AWARENESS via EVENT SELECTIVITY: only sweeps whose burst volume exceeds a HIGH multiple of normal (rare, large events) trade — these are the ones that historically precede a continuation exceeding the ~0.10% round-trip cost — so the strategy trades infrequently on big moves rather than scalping (the classic microstructure fee-death). Event-driven design also keeps parameters minimal (3), directly attacking the overfit that is the #1 killer. Fills the under-represented SHORT horizon (9.0% vs 10%) and long_short direction (13.5%). Single instrument, single venue (no cross-venue infra trap). BTC has the deepest, cleanest tick tape on Binance with multi-year history → measurable event count. Adds to over-represented BINANCE — accepted; tick-tape depth is the reason and this is an exploratory probe of the encouraged large-order/liquidity-sweep niche.
Hypotheses
Root-caused the Layer-3 zero trades, and it is not a threshold problem: on_trade_tick was never invoked, so no threshold could have fired. Catalog audit of the sandbox window (last ~28 days, 2026-08-08..2026-09-05): trade_tick/BTCUSDT.BINANCE holds 4 files ALL dated 2026-05-06 (~1 day, ~120 days before the window); quote_tick/BTCUSDT.BINANCE holds 2 records (12 KB); the only *USDT.BINANCE or *USD.HYPERLIQUID perp with ANY Aug/Sep-2026 tick file is PONSUSD.HYPERLIQUID with 10 seconds of prints; the deepest tape in the catalog (SOLUSDT.BINANCE, 8.5M prints) ends 2026-07-17; and there is no BINANCE:BTCUSDT:aggTrades cache, with ticks not collected on demand for backtests (runner.py only queries catalog.trade_ticks for the window). _volume_sum therefore stayed 0, _intensity() returned 0.0 every evaluation, and should_enter correctly returned None 40,574 times — the designed 'no tape -> no trades' contract, which the module docstring commits to rather than substituting a bar-derived wick/volume proxy (a different edge). Two honest changes rather than an identical resubmit, neither a proxy: (1) a real latent defect fixed — SIGNAL_VALID_SECONDS was a flat 60 s while the decision bar is 60 s, so a sweep latched early in a bar was already ~60 s old at that bar's close and was dropped by the '>' expiry test; only sweeps in a bar's final seconds could ever be traded. The validity horizon is now max(60 s, 2 x observed bar interval), measured from consecutive bar timestamps, which strictly raises the event-to-trade conversion rate on any window that has ticks. (2) a one-shot 'NO TRADE TAPE' warning once NO_TAPE_WARN_BARS bars have passed with zero ticks, set off the hot path (in _roll_bucket) so per-tick cost is unchanged and the iteration-3 timeout fix stays intact. Config now explicitly sets subscribe_trade_ticks true. Everything Layers 1-2 passed remains untouched: imports, bucketed tape accounting, one-sidedness gate, polarity (trades WITH the sweep), fee-aware bracket, timestamp-anchored time stop, sizing.
Hypotheses
verification_loop: Verification failed (Layer 3 — sandbox backtest): No trades produced
Bar type used: BTCUSDT.BINANCE-1-MINUTE-LAST-EXTERNAL, Bars processed: 40270
Diagnostics: should_enter() returned a side 0 times over 40266 evaluated bars -> your ENTRY CONDITION never triggered. Loosen the entry logic / thresholds.
Ensure your strategy produces trades with the given data and parameters.
Implementation
Long-short, event-driven microstructure strategy on BTCUSDT.BINANCE USD-M perp. From the trade tape it maintains, in ~1-second buckets, the taker volume printed in the last burst_window_seconds and its signed (buy-minus-sell) imbalance. A LIQUIDITY SWEEP is a burst whose volume exceeds burst_volume_mult times an EWMA baseline of normal per-window volume AND is at least 80% one-sided. The most extreme sweep since the previous bar is latched and traded WITH its direction (aggressive selling sweeps bids -> SHORT; aggressive buying -> LONG) at the next 1-minute bar boundary while still fresh. Exits are a 0.25% profit target (~2.5x the 0.10% round trip), a tight 0.15% stop (0.6x target, ~1.67:1 reward:risk) and a 30-minute time stop anchored to bar timestamps. Per-tick work is pure arithmetic; all evaluation happens at most once per bucket. With no trade tape it deliberately trades nothing — there is no OHLCV sweep proxy.
Verification Results
Verification failed (Layer 3 — sandbox backtest): No trades produced
Bar type used: BTCUSDT.BINANCE-1-MINUTE-LAST-EXTERNAL, Bars processed: 40270
Diagnostics: should_enter() returned a side 0 times over 40266 evaluated bars -> your ENTRY CONDITION never triggered. Loosen the entry logic / thresholds.
Ensure your strategy produces trades with the given data and parameters.
Iteration History
Verification failed (Layer 4 — QA review):
- DATA STARVATION — the strategy's required primitive (trade_tick) is absent, so it cannot be validated. The developer re-verified coverage immediately before submitting: BTCUSDT.BINANCE trade_tick is still ONE DAY (2026-05-06, 4 files), upstream agg_trades still 29 days, and on_demand.py ensures bars only so the tape will not self-heal. The hypothesis's premise ('deepest, cleanest tick tape with multi-year history') is false on this catalog. The sandbox confirms it: 29 trades ALL from the single 2026-05-06 day, with degenerate one-day artifacts (PF 0.08, Sharpe -1.04, skew -17.0, kurtosis 303, PSR 0.003), not an edge. No code change resolves this; it requires a Data Engineer aggTrades->trade_tick backfill — the SAME task that blocks the sibling order-flow hypothesis.
- The code is CORRECT and faithfully implements a genuinely DISTINCT mechanism (discrete sweep event, not the sibling's rolling CVD). on_trade_tick maintains a 10s burst window with running sums; intensity = volume_sum/baseline signed by net direction; a sweep latches when |intensity| >= burst_volume_mult (8x) AND one-sidedness >= 0.80 (correctly rejecting high-volume two-way churn). The latch is well-justified (a 10s burst ages out before a 1-min bar closes; expires after 60s, consumed on use). The baseline is an EWMA from bar volume (scale reference only; edge still tape-derived, so no tape -> no events). Continuation polarity correct (net aggressive selling -> SHORT, net buying -> LONG; WITH the sweep). Fee-aware exits (0.25% target, tight 0.6x stop ~1.67:1, 30-min bar-ts time stop), subscribe_trade_ticks=true correctly matches on_trade_tick, fixed-fraction sizing with min-notional, NO OHLCV proxy. NO code defect.
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).
Iteration History
Verification failed (Layer 3 — sandbox backtest): No trades produced
Bar type used: BTCUSDT.BINANCE-1-MINUTE-LAST-EXTERNAL, Bars processed: 40578
Diagnostics: should_enter() returned a side 0 times over 40574 evaluated bars -> your ENTRY CONDITION never triggered. Loosen the entry logic / thresholds.
Ensure your strategy produces trades with the given data and parameters.
Iteration History
Verification failed (Layer 1.5 — hypothesis/config consistency) [class=hypothesis_mismatch]:
- config.instrument_id is SOLUSDT.BINANCE but the hypothesis declares BTCUSDT.BINANCE — a different asset. Implement the hypothesis as written (or the Research Lead must revise it).
Backtest and paper results are hypothetical. Trading involves risk of loss.