Arbitrage trading bots: cross-exchange, triangular and the hidden costs
The pitch is irresistible: the same asset trades at two prices, so you buy the cheap one and sell the dear one at the same moment and pocket the difference — a "risk-free" spread. That idea is real, but the easy version of it has been hunted to near-extinction by professional firms. This guide explains how arbitrage bots actually work, the four main types, the triangular math, and the hidden costs that quietly turn a clean-looking spread into a loss.
The core idea — one asset, two prices
Arbitrage exploits a simple inefficiency: the same thing is priced differently in two places. If Bitcoin is bid at one price on exchange A and offered cheaper on exchange B, you buy on B and sell on A at the same instant, and the gap is yours. Because the two legs are meant to happen together, the textbook describes the profit as locked in and the position as market-neutral — you don't care whether Bitcoin goes up or down, only that the gap closes.
That's the theory, and it's worth understanding cleanly before we tear it apart. In a frictionless world with instant, free transfers and zero execution risk, arbitrage really would be free money, and markets would have no price gaps at all. The reason gaps exist is precisely that the world has friction — and the moment you account for that friction honestly, "risk-free" stops being an accurate word.
The four main types of arbitrage
Bots chase the same inefficiency in different shapes. The four you'll meet most often:
Cross-exchange arbitrage is the classic: a price gap for the same pair between exchange A and exchange B. You hold inventory on both venues, buy on the cheaper one and sell on the dearer one. Conceptually the simplest, operationally the hardest, because you must already have capital sitting on both sides — moving coins across in the moment is far too slow.
Triangular arbitrage stays on a single exchange and exploits a loop of three pairs whose cross-rates don't quite line up. A typical loop is BTC → ETH → USDT → BTC: convert Bitcoin into Ether, Ether into Tether, and Tether back into Bitcoin. If the rates around the loop multiply to more than one after fees, you end with more BTC than you started with. No cross-venue transfers means no withdrawal delay — its bottleneck is pure speed.
Funding-rate (cash-and-carry) arbitrage harvests the gap between the spot price and a perpetual futures price. When the perpetual trades at a premium and pays a positive funding rate, you can hold the spot asset and short the perpetual against it: the position is roughly price-neutral and you collect funding payments. It's slower-moving and less of a sprint, but it ties up capital and carries its own basis and liquidation risks.
Statistical arbitrage is a brief mention here because it's a different animal: rather than the same asset in two places, it trades two correlated assets and bets that an unusually wide spread between them will revert to its historical mean (classic pairs trading). It's a probabilistic edge, not a locked-in one, and deserves its own treatment elsewhere.
| Arbitrage type | Where the edge is | Main risk |
|---|---|---|
| Cross-exchange | Same pair priced differently on two venues | Transfer delay & pre-funding both sides |
| Triangular | Three-pair loop on one exchange mis-prices | Speed — gap closes in milliseconds |
| Funding-rate (carry) | Spot vs perpetual premium & funding | Basis swing & liquidation on the short |
| Statistical (pairs) | Mean-reversion of correlated assets | Correlation breaks — spread keeps widening |
Why the easy arbitrage is gone
Two decades ago a patient human could spot a price gap and trade it by hand. Today you are racing pros. High-frequency trading firms run co-located servers next to the exchange matching engine, ingest data in microseconds, and fire orders before a retail bot has even finished parsing the previous tick. When a gap appears, dozens of machines see it at once and the fastest one takes it — everyone else gets a worse fill or nothing. The obvious, large, persistent spreads that beginners imagine simply don't survive in liquid markets; they're closed almost the instant they appear.
This doesn't mean retail arbitrage is impossible, but it does mean the realistic niches are narrow: thinner pairs and smaller exchanges the big firms ignore, single-venue triangular loops where you remove the transfer problem, or slower funding-rate carry where the edge is a recurring payment rather than a microsecond sprint. Going in clear-eyed about who you're competing with is the difference between a hobby that loses slowly and one that loses fast.
The triangular math
Triangular arbitrage is the one type where the maths is easy to write down. Take three pairs that form a loop and multiply the exchange rate you'd actually receive at each step. If the product of those three rates is greater than 1, the loop is profitable before costs; once you subtract the fee on each of the three trades, it has to stay above 1 to be worth doing.
Start with 1 BTC. Convert to ETH, ETH to USDT, USDT back to BTC. Multiply the three rates. If
r1 × r2 × r3 > 1after deducting three lots of fees, you finish with more BTC than you began with. If it's below 1, the loop quietly costs you money.
The trap is that a raw product like 1.004 looks like a clean 0.4% — but three trades at a 0.1% fee each strip roughly 0.3% straight off the top, and slippage takes more. A loop has to clear that whole stack of costs and beat every other bot to the fill before it's real profit. For more on how fees compound across legs, see crypto trading bot fees explained.
A Python loop check
Here's the skeleton of a triangular-loop checker. It takes the three rates around the loop and the per-trade fee, computes the after-fee product, and tells you whether the loop is worth firing.
python · triangular.pydef loop_profit(r1, r2, r3, fee=0.001):
# r1,r2,r3 = rate received at each leg, e.g. BTC->ETH->USDT->BTC
keep = (1 - fee) ** 3 # 3 trades, fee on each
product = r1 * r2 * r3 * keep
return product # >1 means more BTC than you started with
def check(r1, r2, r3, fee=0.001, min_edge=0.0015):
p = loop_profit(r1, r2, r3, fee)
edge = p - 1 # net fractional gain after fees
if edge > min_edge: # buffer for slippage + missed fills
print(f'FIRE — net edge {edge:.4%}')
else:
print(f'SKIP — only {edge:.4%}, not worth the risk')
check(18.9, 3120, 1/58900) # plug in live order-book rates
Note the min_edge buffer. A loop that's only barely above 1 after fees is a trap: by the time your second and third orders land, the price has moved and your true edge is gone. Real arbitrage bots demand a margin comfortably above breakeven precisely because the spread you measure is never quite the spread you get.
The hidden costs that eat the spread
This is where most arbitrage dreams die. The spread on screen is gross; what you keep is net, and the gap between them is brutal:
Fees on both legs. Arbitrage is at minimum two trades, often three. Every one pays a taker fee. A spread that looks like 0.3% can be entirely consumed by two or three rounds of fees before you've earned a cent.
Transfer time and withdrawal fees. For cross-exchange arbitrage you cannot move coins between venues instantly — an on-chain transfer can take minutes and costs a network fee, and the price gap is long gone by the time it confirms. That's why cross-exchange bots must pre-fund both sides and rebalance later, which leads to the next cost.
Capital tied up on every venue. To trade instantly you need inventory sitting on both exchanges at all times. That's capital exposed to exchange risk, doing nothing until an opportunity appears, and split so thin across venues that each trade is small.
Slippage. Order books are thin at the best price. Size up and you walk the book, getting a worse average price than the quote you based your decision on — and arbitrage margins are too small to absorb much of that.
Execution risk. The single biggest one. Arbitrage assumes both legs fill together. If one leg fills and the other doesn't — the price moved, the order was rejected, the venue lagged — you are no longer market-neutral. You're now holding a directional position you never wanted, and you have to unwind it at whatever the market gives you.
The clean two-legged trade only exists on paper. In reality one leg can fill while the other fails, leaving you directional and exposed. Treat every arbitrage position as if a leg might miss — size it so a half-filled trade can't hurt you, and have an unwind plan before you fire. Pair this with proper risk management.
Latency is the deciding factor
Once you've accepted that the spread is thin and the costs are real, what's left to compete on is speed. An arbitrage opportunity exists only until someone takes it, and because every bot is watching the same prices, the fastest order to the matching engine wins the fill. Everyone slower gets a worse price or nothing. That's why serious arbitrage operations obsess over latency — faster market data, leaner decision code, orders placed in microseconds, sometimes physical co-location next to the exchange. Cross-exchange arbitrage in liquid markets is largely a professional game for exactly this reason, and even single-venue triangular loops live or die on how quickly your bot can recognise the loop and fire all three legs. If you want to build the engineering around this, start with how to build a trading bot and size every position with the calculator.
Frequently asked questions
Is arbitrage trading actually risk-free?
No. In theory you buy and sell the same asset simultaneously for a locked-in spread, but in practice fees on both legs, transfer delays, slippage, and the chance that only one leg fills all introduce real risk. "Risk-free" is a marketing word, not a description of live trading.
Can a retail trader still profit from crypto arbitrage?
The easy cross-exchange gaps are closed in milliseconds by professional firms with co-located servers, so racing them on raw price differences is usually a losing game. Smaller, faster niches like triangular loops on a single venue or funding-rate carry are more realistic for retail, but margins are thin and execution speed decides who profits.
What is triangular arbitrage?
It's a loop of three pairs on one exchange — for example BTC → ETH → USDT → BTC. You multiply the three exchange rates around the loop; if the product is greater than one after fees, you finish with more of the starting asset than you began with. Because there are no cross-venue transfers, its only real bottleneck is speed.
Why is latency so important for arbitrage bots?
An arbitrage opportunity exists only until someone else takes it. Because many bots watch the same prices, the fastest order to the matching engine wins and the rest get worse fills or no fill. Lower latency — faster data, faster decisions, faster orders — is often the line between a profitable arbitrage bot and one that always arrives late.