Bitcoin latency arbitrage: when the edge is the structure, not the prediction

After my research certified that price action on 5-minute BTC has no tradable edge, the right question wasn't "what better signal can I find?", but: "is there an edge that doesn't require predicting price at all?".

The answer was in the structure of my setup: I could see two prices for the same asset. The reference exchange feed (Binance futures, via websocket) and my CFD broker's quote on the same underlying. The broker's price follows the exchange's — it must, by construction — but with variable delay and noise. When the fast feed moves sharply, for a fraction of time the slow price is "wrong": not a prediction — a fact, with an expiry.

This is latency arbitrage in its retail form: buy/sell the slow price in the direction the fast one has already gone, and exit at convergence. The edge source is structural: it's paid by the friction of the broker's quoting mechanism.

The symmetric warning, upfront: brokers know this edge very well, terms of service often restrict it, and it can evaporate with a feed update on their side. ToS and prop-rule compliance checking is part of the project, not a detail. A structural edge is not an eternal edge: it's an edge for as long as the structure lasts.

v4, v5: chronicle of an instructive failure

v4 worked "by log feel": it fired on divergences, closed on time. v5 added ambitious take profits (0.55–0.85%) with a 600-second max horizon. Result: 50 live trades, market −$8.54, commissions −$118.48, net −$127.02. 93% of the loss was costs. The autopsy goes further, and every detail is a general lesson:

Three different bugs with the same root: components written before precisely understanding the phenomenon. v6 was born by inverting the order: first the physics of the phenomenon, then the code.

v6: the cost-gated architecture

  1. Cost-gate: enter only if the measured divergence exceeds 2× the total live-estimated cost (commissions + current spread + EWMA slippage). It's the filter that sends the system silent for hours, and that's correct: here, selectivity is the strategy.
  2. Exit at convergence, not at a target: gap closed, trade closed. Max holding time 120 seconds — beyond that, the hypothesis that justified the trade has expired, and a position whose hypothesis has expired must be closed regardless of its P&L.
  3. Explicit prop baseline, hard-coded as a contractual constant; anti-martingale sizing anchored to the remaining margin above the floor.
  4. EV kill-switch: the system keeps books on its own realized expectancy over a rolling window; if measured EV turns negative net of costs, it shuts itself down. The question "is it broken or is it variance?" answered with a written threshold instead of anxiety.
  5. Shadow mode: the system does everything — detects, decides, sizes, records — except sending orders. It produces the dataset of virtual trades with timestamps and estimated costs, at zero risk.

The promotion criterion from shadow mode to real money is written in the code, not in my mood: at least 30 shadow trades with positive average EV. The system stays there until the criterion is met. If it never is, v6 will die without having lost a euro — the second-best possible outcome for a system, and infinitely better than the third.

The portable lessons (even if you never do HFT)

The Binance feed and data pipeline behind this project: Quant research with Python and the Binance API. The AI development method that wrote v6: here, with the prompts.