contents
How I competed with co-located institutional traders

Crypto Arbitrage Trader

multi-exchange trader · live demo · paper only

What
A multi-market (BTC, ETH, etc) arbitrage trader running across multiple exchanges (Coinbase, Kraken, etc). It treats every tradeable pair on every connected exchange as a single graph and searched that graph for profitable three-way cycles — BTC→ETH→USDT→BTC.
Why it was hard
Arbitrage is the most heavily watched trade in markets. Institutional agents with colocated hardware and near-zero taker fees take those spreads in milliseconds. The edge is to look where they aren't. By looking at multi-leg cycles, small discrepencies can accumulate to break the profit threshold.
What I decided
Model the market as a directed graph — nodes are (asset, venue), edges are tradeable conversions weighted by the negative log of the rate net of that venue's fee. A profitable cycle is then a negative-weight cycle, which is a solved problem rather than a novel one. Capital sits pre-positioned on every venue so all legs of a cycle fire simultaneously against inventory already there; moving coin between exchanges is a separate, asynchronous rebalancing concern that never enters the hot path.
What happened
The cycle search found edge on combinations that a pairwise detector, watching the same feeds at the same instant, scored as flat. The demo below shows why that mattered — across a real 16-minute window, 99% of moments look profitable at zero fees — and by 3 bps, an order of magnitude below any real retail taker fee, not one survives.

The trade everyone looks for — the same coin cheaper here than there — is the one trade you cannot win. It is watched by agents sitting in the same data centres as the exchanges, paying fees you cannot get, acting in microseconds. By the time a retail system has parsed the quote, the spread is gone.

So this trader looked somewhere else: at cycles.

(There’s a live two-venue monitor further down that lets you take the institutional side of this apart by hand — skip to it if you’d rather start there.)

Why three-way cycles

A pairwise detector asks one question, many times: is BTC cheaper on A than on B? That question has a small answer space, and every well-capitalised participant is asking it continuously.

A cycle detector asks a different question: is there any sequence of trades that returns more of an asset than it started with? Concretely —

   USD ──buy BTC──▶ BTC ──sell for ETH──▶ ETH ──sell for USD──▶ USD
        Kraken            KuCoin                Coinbase
                                                    │
                          more USD than you started with?

The dislocation that makes that cycle profitable can be distributed across three legs, none of which looks wrong on its own. BTC/USD is fine. ETH/BTC is fine. ETH/USD is fine. Compose them and the round trip pays. A detector comparing single pairs scores every leg as flat and reports nothing — which is exactly why the opportunity is still there to take.

That is the whole edge: not being faster than the institutions, but asking a question they were not bothering to ask on the venues I could reach.

The formulation

The search is a solved problem once you frame it correctly. Build a directed graph:

  • Nodes are (asset, venue) — BTC@Kraken is a different node from BTC@KuCoin.
  • Edges are tradeable conversions, weighted −log(rate × (1 − fee)).

Multiplying rates around a cycle becomes adding logs, so a cycle that multiplies to more than 1 sums to less than 0. A profitable cycle is a negative-weight cycle, and finding those is textbook Bellman-Ford.

Two details matter more than the algorithm:

The fee belongs in the edge weight, not in a filter afterwards. Score cycles gross and nearly all of them evaporate when you subtract three legs of taker fee. Bake (1 − fee) into the weight and the search only ever returns cycles that are already net-profitable.

Cross-exchange edges are not free. An edge from BTC@Kraken to BTC@KuCoin is a transfer, and transfers take confirmations — which is the subject of the next section, and the thing that dictates the whole architecture.

Market Arbitrage

Arbitrage is buying low with a guaranteed buyer to ensure a profit. Since there is no risk, the spread can confidently be tiny.

Market Arbitrage is doing the same thing, but using open market buyers and sellers. Open markets are real time, so there is no longer a time-agnostic guarantee to the trade.

An example would be a broker in New York calling their partner in Toronto and orchestrating a buy and sell opportunity for 50 shares. “I have a seller for $10/share and you have a buyer for $11/share.” Each agent starts with 100 stocks and $1,000 every day so they can each pay out the buyer and seller simultaneously, then at the end of every day, they each send a runner to equalize their accounts. At the end of day 1, the New York agent has $500 and 150 stocks (100 + 50), then the Toronto agent would have $1,550 and 50 stocks. Let’s assume they pay their runner $10. They profit $40.

That story contains the entire architecture. Neither broker waits for the runner. They can only trade simultaneously because each already holds stock and cash before the call comes; the runner settles up afterwards, on a schedule nobody is watching the clock on. Replace broker with exchange account, and runner with blockchain transfer, and that is the trader:

Get this backwards — detect the spread, buy on one venue, transfer, sell on the other — and it fails on arithmetic rather than execution. A transfer needs confirmations measured in tens of minutes; the dislocation lives for seconds. By the time the coin lands you are long an asset you did not want at a price you did not choose. Transfers have to leave the hot path entirely, which is what pre-positioned inventory buys you, and it is why the cross-exchange edges in the graph are rebalancing decisions rather than trades.

The three-way cycle is this same structure with one more leg — BTC → ETH, ETH → USDT, USDT → BTC — and, as above, the legs can sit on different exchanges.

The live demo

Everything above is the trader. What follows is a two-venue monitor built to make the hard part of that problem tangible: it walks real level-2 order books from Kraken and Coinbase and lets you apply fees and size by hand, so you can watch apparent opportunity turn into loss.

It is a demonstration of market mechanics, not the trader itself — one pair, two venues, no cycles, no execution. Paper only.

SIMULATED · PAPER ONLY reads public order books with no keys · places no orders, ever
data source
RECORDED SAMPLE · loading committed dataset · contacting live venues
  • ○Krakenconnectingfirst request pending
  • ○Coinbaseconnectingfirst request pending
Kraken mid Coinbase mid net-positive, fully fillable edge visible, book can’t fill it no edge
Loading the recorded window… — if this text persists, the committed dataset failed to load and the banner above says why.

hover or tap the chart for any single moment

0.5 bps

per leg, charged on both legs · 0–120 bps on a log-ish scale, so the 0–2 bps collapse stays draggable. Marks are approximate entry-tier taker rates, checked 13 Aug 2026: — verified, spot Tier 1 on kraken.com’s published schedule (0.40/0.80%, restructured 9 Jul 2026); — an estimate, not a verified figure: Coinbase’s fee pages refuse automated requests and trackers disagree between 60 and 120 bps, so drag past the mark to see the higher reading. Volume tiers, maker rebates and promotions all move these; treat them as the right order of magnitude, not a quote.

top of book

leftmost = whatever the top rung offers · then 0.001–2 BTC, log scale. Above zero the size is filled by walking the book: rungs are consumed in order until the size is filled or the recorded depth runs out.

the same window as numbers

Drag the fee slider from zero to a real taker rate and watch the green drain out of the window. Then push size up and watch the fill fall short of what you asked for — the spread is still on the screen, but the book underneath it isn’t. Those are the two forces that close the simple trade, and the reason the trader had to go looking for cycles instead.

What the window shows

The chart is a real 16-minute capture — 13 Aug 2026, 17:04:55–17:20:54 UTC, 293 snapshots at 3-second intervals from Kraken and Coinbase, both quoting BTC/USD, twenty rungs a side rather than a single top quote — or, when your browser can reach both venues, the same page driven live. Kraken’s mid moved $121.80 (0.19%) across the window; no fetch failed. The shipped file drops only the rungs deeper than 2.5 BTC of cumulative resting size — the size control tops out at 2 BTC, so every walk this page can perform is identical to one over the full capture, at 327 KB instead of 507 KB. Every figure below is scoped to that window; this page keeps no longer history, deliberately (more on that at the end).

Taker fee (per leg)Moments with positive net edge (top of book)
0 bps290 / 293 (99%)
0.5 bps203 (69%)
1 bps108 (37%)
2 bps12 (4%)
3 bps0
10 bps0
80 bps0

At zero fees, virtually every moment looks like free money — the two venues sat a median of $9.31 apart at the best cross, about 1.5 bps. By 3 bps — an order of magnitude below any real retail taker fee — every single one is gone. The sliders above recompute this table from the raw rungs; nothing is pre-baked.

Depth kills what fees miss, and level-2 shows exactly how. The median quantity resting at the touch is 0.122 BTC on Kraken’s bid, 0.900 on its ask, 0.133 on Coinbase’s bid and 0.154 on its ask — the thinnest of those is under $8,000 of notional. Behind the touch it does not deepen quickly: across the recorded rungs the median Coinbase book holds 2.26 BTC of bids and 1.93 BTC of asks. So:

  • Ask for 1 BTC and 12 of the 293 moments cannot fill it at all; the median fill costs you 1.68 bps worse than the top quote.
  • Ask for 2 BTC and 170 of 293 moments cannot fill it — the median moment fills 1.87 BTC and pays 2.10 bps of walk. The worst moment in the window (17:06:07) fills 0.572 BTC of the 2 you asked for — 29%.
  • At zero fees, net-positive moments fall from 290 at top of book to 246 at 0.25 BTC, 186 at 0.5 BTC, 72 at 1 BTC, and 13 at 2 BTC.

The thinnest quote in the window is a Coinbase top-of-book of 0.000018 BTC at 17:06:33 — about $1.13 of bitcoin. The monitor treats near-zero depth as what it is: nothing worth trading against, not an infinite opportunity. (Zero-size rungs get the same treatment — the walk passes over them and never divides by them — though this particular window happens to contain none.)

The best moment, walked

The single best moment of the window is 17:08:22 UTC: Coinbase’s ask sat $18.25 below Kraken’s bid, an apparent 2.90 bps edge. Watch what depth does to it as you ask for more:

You askBook fillsEffective VWAP (buy → sell)Walk costGross edge
top of book0.4072 BTC63,013.95 → 63,032.20—2.90 bps ($7.43)
1 BTC1.0000 BTC63,016.32 → 63,032.200.38 bps2.52 bps ($15.88)
2 BTC1.9029 BTC63,018.21 → 63,030.560.94 bps1.96 bps ($23.51)

The dollar figure rises with size while the edge decays — which is exactly why a gross-dollar headline is the wrong number to watch. And fees settle it regardless: that same best moment, at top of book, nets +$2.30 at 1 bps, −$2.83 at 2 bps, and −$43.90 at a 10 bps taker fee — $7.43 of gross against $51.33 of fees. At Kraken’s published entry tier of 80 bps it nets −$403.19. From 3 bps upward, not one moment in the entire window is net-positive; the least-bad is a fraction of a cent on a dust-sized fill.

About this demo

Live data comes from your browser calling the venues’ public endpoints directly — no server, no keys, nothing written at runtime. Those endpoints are sometimes geo-blocked, so a recorded window ships with the page as a backup and the banner always tells you which one you are looking at.

The demo showcases how difficult market arbitrage actually is to compete in against colocated hardware running discounted taker fees. That difficulty is the premise of the trader above: when the simple trade is closed, the remaining edge is in the combinations nobody else is enumerating.

And the door is not shut permanently. During market turbulence and heavy volume, spreads become too large for established arbitrage agents to fully absorb, and opportunity opens up for retail players — which is precisely when a cycle search across four exchanges earns its keep.