Skip to content

View original

BtcFlowLeadsEthLeadLagLS

Hypotheses

BTC-Flow-Leads-ETH Cross-Instrument Lead-Lag, Long-Short (Trade ETHUSDT.BINANCE on a Strong BTCUSDT DEEP-aggTrades Taker-Flow Impulse That ETH Has NOT Yet Followed — BTC Order Flow Leads Alt Price by Minutes — a CROSS-INSTRUMENT Signal, Not the Single-Name Order-Flow That Fee-Died, Fast Catch-Up Hold, 3-Parameter)

Hypotheses

A LONG-SHORT, CROSS-INSTRUMENT strategy: the traded instrument is ETHUSDT.BINANCE (USD-M perp) but the SIGNAL comes from BTCUSDT's DEEP aggTrades taker flow — a genuinely different family from every single-name idea this session, all of which are now confirmed dead (single-name OHLCV, funding, and my own single-name aggTrades order-flow probes — absorption, large-print sweep, all fee-died decisively; the maker-execution reversion also just collided/died). The mechanism is documented cross-asset LEAD-LAG: BTC is the market's beta driver and its aggressive order flow (a burst of net taker buying/selling on the deepest tape) propagates to alts with a short lag; when BTC prints a strong flow impulse AND moves, but ETH has NOT yet caught up (its price still near pre-impulse level), ETH tends to follow within minutes. Enter ETH in the direction of the BTC flow impulse, capturing the catch-up; exit once ETH has converged to the implied move or the lag window closes. This is NOT single-name order flow (the signal instrument ≠ the traded instrument), NOT reversion/momentum on ETH's own price, NOT funding/carry/options. It uses the deepest, cleanest flow tape (BTC's) to trade the less-efficient follower (ETH), and the catch-up move (~0.2–0.5%) clears the ~0.10% USD-M round trip. Cross-instrument (2 instruments), LONG-SHORT (fills the 85%-long imbalance), fast intraday hold. 3 core parameters (BTC flow-impulse threshold, ETH lag-gap threshold, catch-up hold window).

Hypotheses

Iteration fix, one root cause: the previous version produced ZERO trades because its BTC flow series was empty - `metrics` is injected for the PRIMARY symbol only (ETH), and the (correct) symbol guard dropped every ETH row rather than substitute ETH's own tape, so the entry gate could never arm. The engine already wires the exact feed this mechanism needs: supplementary_data['taker_flow_by_instrument'] is attached for EVERY leg (primary + extras) when the strategy source quotes that key (subprocess_entry._add_per_leg_taker_flow -> supp_collector.load_taker_flow_series), so the BTC leg's real taker buy/sell ratio is now read directly while ETH stays the traded primary. The symbol-guarded metrics parse is kept only as a fallback, and the real-flow guard is unchanged (no BTC flow -> stand flat, never an OHLCV volume proxy). Only other change: position/hold bookkeeping moved above the flow early-returns so the hold-window exit keeps counting on bars without a fresh flow point, and flow_thresh raised 0.015 -> 0.05 so the flow confirmation is actually binding (measured |flow deviation| median is ~0.19). Checked against the real catalog+metrics data over the sandbox window: BTC taker flow covers it (metrics/BTCUSDT all.parquet through 2026-07-31 plus daily.parquet through 2026-09-02) and the full compound entry gate fires ~165 times over 34 days of 1-minute bars, so Layer 3 will produce trades. One honest caveat for the Analyst, per scope rules: on that same 34-day sample the post-entry 15-bar ETH return in the impulse direction is negative (about -0.08%), i.e. the lag closed by BTC reverting rather than ETH catching up - the reverse (fade) sign carried the edge; I implemented the hypothesis as specified.

Hypotheses

Negative expectancy to the point of account liquidation on a decisive 12,517-trade / 6.7-year sample: total_return -100% (liquidated 2020-11-26), profit_factor 0.057, Sharpe -2.02 (CI fully negative), avg_trade_return_pct -0.0055% (below ZERO, not just below the 0.15% USD-M fee floor). The directional premise is INVERTED — QA's measurement and the full backtest agree that BTC flow does not lead ETH catch-up; the lag closes by BTC reverting toward ETH, so the follow-direction entry is wrong-signed (avg_loss ~9x avg_win, win rate 0.334 both sides). The 3 optimizable parameters (impulse/gap thresholds, hold window) cannot flip the entry sign, so no parameterization repairs a wrong-signed premise, and commission_pct_of_gross 538% / turnover 587 on 1-minute bars means it also churns heavily against fees. Not worth 2 hours of optimization. The FADE (reverse-sign) variant would be a new hypothesis for the Research Lead, not a tuning of this one.

Implementation

Long-short ETHUSDT.BINANCE perp on 1-minute bars, driven by BTCUSDT's REAL taker order flow (per-leg taker buy/sell volume ratio, aggTrades-derived, 5-min native spacing) plus BTC's 5-bar price impulse. When BTC prints a >=0.25% 5-minute move confirmed by a same-signed taker-flow deviation from its 60-bar baseline, and ETH has NOT yet followed (aligned BTC-minus-ETH return gap >= 0.15%), enter ETH in the impulse direction to capture the catch-up. Exit on gap convergence (35% of entry gap), 15-bar hold window, 0.5% take-profit or 0.5% stop-loss. No leverage; 50% of equity notional per trade.

Verification Results

Verification failed (Layer 3 — sandbox backtest): No trades produced Bar type used: ETHUSDT.BINANCE-1-MINUTE-LAST-EXTERNAL, Bars processed: 40708 Diagnostics: should_enter() returned a side 0 times over 40679 evaluated bars -> your ENTRY CONDITION never triggered. Loosen the entry logic / thresholds. Ensure your strategy produces trades with the given data and parameters.

Verification Results

Analyst: at backtest-review, test the reverse (fade) entry sign; if the follow sign is confirmed net-negative over full history, abandon this variant rather than optimize thresholds.

Verification Results

The entry enters ETH in the BTC-impulse direction (follow / catch-up), exactly as the hypothesis specifies, but the developer's pre-registered honest caveat and the sandbox both show the impulse-direction ETH move is negative — the profitable sign is the fade. This is a directional-premise failure of the hypothesis, not a code bug; flagged as advisory context, not a blocker.

Verification Results

Optionally round to the instrument's size precision (4) for ETHUSDT.

Verification Results

position_size rounds ETH size to 3 decimals (round(size, 3)) while ETHUSDT size precision is 4. Not a defect (3dp is within precision 4 and notional is far above min), but slightly coarser than the venue allows.

Verification Results

The developer's own measurement (restated in the config rationale) and the sandbox both indicate the hypothesis's directional premise is INVERTED: over the 34-day sample the post-entry 15-bar ETH return in the BTC-impulse direction is ~-0.08% — the lag closed by BTC reverting toward ETH rather than ETH catching up to BTC, so the FADE sign carried the edge. Sandbox confirms: total_return -8.13%, Sharpe -9.27, profit_factor 0.12, win_rate 0.22, avg_trade_return_pct ~0.003% (both long 0.286 and short 0.121 win-rates weak). The 3 optimizable parameters (impulse/gap thresholds, hold window) cannot flip the entry sign, so no parameterization repairs an inverted directional premise. Commission_pct_of_gross 366% and turnover 1088 on 1-minute bars mean the follow-the-flow signal is also churning heavily against fees. Recommend the analyst either abandon the follow-direction variant or test the reverse (fade) sign explicitly — the mechanism's lead-lag inference appears to point the wrong way for a follower trade. This is advisory and does not block; the code is a faithful implementation of the hypothesis as written.

Backtest Review

Genuinely cross-instrument design (BTC flow signal, ETH traded) with a real per-leg taker-flow feed wired in — not the single-name order-flow family that fee-died

Backtest Review

Large, reliable sample (12,517 trades over 6.7 years), so the result is decisive rather than noisy

Backtest Review

Account LIQUIDATED 2020-11-26 (total_return -100%, CAGR -100%, max_drawdown 100%) — the strategy blew up in its first months and never traded again

Backtest Review

Profit factor 0.057, Sharpe -2.02 (CI [-5.50, -1.71], fully negative), Sortino -1.78, avg_trade_return_pct -0.0055% (BELOW ZERO, not merely below the 0.15% USD-M fee floor)

Backtest Review

avg_loss 36.8 vs avg_win 4.15 (~9x adverse asymmetry), win_rate 0.334 both long and short — the follow-the-flow entry is wrong-signed

Backtest Review

commission_pct_of_gross 538% and turnover 587 on 1-minute bars — the signal churns violently against fees even before the directional problem

Backtest Review

QA's edge concern is borne out: the lead-lag points the wrong way for a follower trade (BTC reverts toward ETH rather than ETH catching up); the 3 optimizable params (impulse/gap thresholds, hold window) cannot flip the entry SIGN

Iteration History

Verification failed (Layer 2 — synthetic scenarios): Parameters used: ['stop_loss', 'flow_thresh', 'hold_window', 'take_profit', 'min_notional', 'exit_gap_frac', 'position_frac', 'eth_gap_thresh', 'impulse_window', 'btc_impulse_thresh'] Check that __init__ sets all attributes from self.parameters.get(). - steady_uptrend: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735689600000) - steady_downtrend: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735689600000) - flat_ranging: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735689600000) - volatility_spike: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735689600000) - zero_volume: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735689600000) - price_gap: TypeError: FactoryStrategy._bar_ts() takes 1 positional argument but 2 were given (bar timestamp: 1735689600000)

Iteration History

Verification failed (Layer 4 — QA review): - The strategy LIQUIDATED the account. Sandbox: total_return -100.0%, max_drawdown 100.0%, liquidated=true on 2025-11-18, Sharpe -2.40 (CI [-9.58, -2.17], entirely negative), profit_factor 0.14, return_skew -16.5, kurtosis 280, largest_loss -$6,469. Risk controls do NOT contain losses: avg_loss $282 is 3.6x avg_win $78 despite a nominal 0.4% stop, and avg_position_pct is 217% vs the intended 180% (position_frac 0.60 x leverage 3.0). The 0.4% stop is checked only on the NEXT ETH bar via should_exit, so on 1-minute bars with 1.8x+ leverage adverse moves blow through it before the exit evaluates; combined with leverage 3.0 this produces the liquidation. Hard risk failure (L15). - Fee/impact death at extreme turnover. 1522 trades over 300 days, ~2-minute average hold, turnover 2032, total_impact_usd $152,618 on a ~$100k account. avg_trade_return_pct is 0.0157% — an order of magnitude below the ~0.10% round trip and the 0.15% futures floor — so even before the liquidation the gross catch-up edge (claimed ~0.2-0.5%) does not survive costs. The hypothesis's own fee arithmetic is falsified. - The hypothesis's core signal is BTC's DEEP aggTrades TAKER FLOW. The code does NOT use taker flow — it derives 'flow' from BTC OHLCV BARS: direction = sign(close - open) per bar times bar volume, normalized by total volume. That is an OHLCV-derived up/down-volume proxy, not order flow. So the traded edge is effectively CROSS-INSTRUMENT OHLCV MOMENTUM, not the order-flow family the rationale asserts. The stated non-price dependency (aggTrades taker flow) is absent; the only inputs are BTC and ETH OHLCV, placing this in the pure-OHLCV-derivative class (L7: 0 survivors), NOT a genuinely different family.

Iteration History

Verification failed (Layer 1.5 — hypothesis/config consistency) [class=hypothesis_mismatch]: - config.instrument_id is BTCUSDT.BINANCE but the hypothesis declares ETHUSDT.BINANCE — a different asset. Implement the hypothesis as written (or the Research Lead must revise it).
Strategy report

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