What does a forex arbitrage algo system actually need to work?
4 parts
speed is the whole edge
DetectA real-time feed + mispricing detector
DecideA risk gate that sizes and vetoes
ExecuteA broker API that fills in one loop
SurviveCosts modeled before you go live
An arbitrage system is four moving parts. This guide builds each one — and shows why the loop that joins them is the real strategy.
You already understand the idea: the same currency, priced two different ways at the same instant, is free money if you can buy the cheap side and sell the rich side before the gap closes. Every explainer stops there. Almost none of them tell you the part that actually decides whether you make money — how to build the system that catches and fills that gap faster than everyone else chasing it.
That is the gap this guide fills. You are not here to learn what arbitrage is; you are here to learn how to turn it into a running algo system. So we treat it as an engineering problem: which arbitrage type is realistic to code, the architecture that catches a mispricing, the latency budget that keeps the edge, real detection code you can adapt, and — before any of that — the cost math that tells you whether the trade was ever profitable in the first place.
One honest framing up front, because it saves you months: in modern forex, the arbitrage opportunity is not secret and it is not yours by default. The price discrepancy is visible to every participant with a fast feed. Whoever detects and executes fastest keeps it; everyone else fills into a gap that has already closed. That single fact drives every design decision below.
Key Takeaways
Forex arbitrage is an execution problem, not an idea problem — the mispricing is public; whoever detects and fills it fastest keeps the edge.
Pick the arbitrage type your infrastructure can actually service: triangular and statistical are realistic to code retail-side; pure latency arbitrage demands co-located, institutional-grade speed.
Your whole edge is the detection-to-fill loop: a price feed, a mispricing detector, a risk gate, and a broker order call — every millisecond of that loop is either kept profit or lost profit.
Model the trade after spread, commission, and slippage before you write a line of production code — a gross edge that disappears once costs and partial fills hit is the default outcome, not the exception.
Table of Contents (23 min read)Contents
Why Arbitrage Is an Execution Problem, Not an Idea
Here is the trap almost every new arbitrage coder falls into. You backtest on historical tick data, you see hundreds of moments where broker A quoted a price broker B hadn't caught up to yet, you multiply the average gap by the number of occurrences, and you get a P&L curve that looks like a staircase to the moon. Then you go live and lose money.
The backtest lied because it assumed something the live market never gives you: that you could have filled at the price you saw. By the time your order reaches the broker, the mispricing you detected is often already gone — closed by someone with a faster loop than yours, or simply arbitraged away by the broker's own liquidity provider. What you actually get is a fill at the new, corrected price, plus the spread, plus a commission, plus whatever slippage the market handed you in the milliseconds it took your order to travel.
That is why arbitrage belongs to the discipline of algorithmic trading rather than to strategy design. The "strategy" — buy low here, sell high there — is trivial and completely public. The engineering — feed latency, detection speed, order-routing time, fill quality — is where the whole edge lives, and it is the only part a competitor can't copy off your chart.
The uncomfortable truth
Your edge decays in milliseconds
A mispricing is a candle burning at both ends. The moment it appears, every fast participant is racing to close it — including the broker's own liquidity provider. Your detection-to-fill loop is not a formality that happens after the real work; it is the real work. A system that detects perfectly and fills 200 milliseconds late is a system that donates spread to the market.
Detecting the gap is easy. Getting paid for it is the entire problem.
So before we pick a strategy, internalize the design goal: minimize the time between "a mispricing exists" and "my order is resting at the broker." Everything in the architecture section exists to shrink that number.
Choose the Arbitrage Type Your Infrastructure Can Service
There is no single "forex arbitrage." There are several, and they differ enormously in how much speed and infrastructure they demand. Choosing the wrong one for your setup is the most expensive mistake you can make, because you'll build a system that is structurally incapable of winning. Match the type to what you can realistically run.
The four you'll actually consider:
Triangular arbitrage — exploit an inconsistency between three related pairs (e.g. EUR/USD, GBP/USD, and EUR/GBP) whose implied cross-rate drifts out of line with the quoted cross-rate. It's self-contained on one venue, so it's the most realistic type to code retail-side.
Two-broker (latency) arbitrage — one broker's feed lags another's; you trade the slow broker using the fast broker as your "true price." Conceptually simple, but it is a pure speed race and many brokers explicitly forbid it.
Statistical arbitrage — trade the mean-reversion of a historically correlated pair or basket (a form of mean reversion). It's slower and probabilistic rather than risk-free, which paradoxically makes it more survivable for a retail system because it doesn't demand sub-millisecond fills.
Covered-interest / carry arbitrage — exploit the relationship between spot, forward, and interest-rate differentials. Institutional in practice; listed for completeness, not as a retail build target.
Match the type to your infrastructure
Arbitrage type
What it exploits
Speed demand
Realistic to build retail?
Triangular
Cross-rate vs implied cross-rate
High
Yes — best first build
Two-broker / latency
One feed lagging another
Extreme
Rarely — speed race, often banned
Statistical
Mean-reversion of correlated pairs
Moderate
Yes — most forgiving of latency
Covered interest
Spot / forward / rate spread
Low
No — institutional plumbing
Pick by the speed you can actually deliver, not by the theoretical profit. Triangular is the standard first build; statistical survives real latency best.
For the rest of this guide, triangular arbitrage is our worked example — it's the canonical first system because it lives on a single venue (no cross-broker sync headaches), the detection math is clean, and it exposes every architectural problem the harder types share. Everything you build for it transfers.
The Architecture of an Arbitrage System
Strip away the strategy and every arbitrage system is the same four-stage pipeline. Your job as the builder is to make each stage fast and each hand-off between stages nearly instantaneous. The execution speed of the whole chain is what you're optimizing — a fast detector feeding a slow order call is a slow system.
The pipeline
The four stages of an arbitrage algo
1
Ingest the price feed
Stream live quotes for every leg over a persistent WebSocket or broker push feed, never REST polling. Stale prices only find stale gaps.
2
Detect the mispricing
On every tick, recompute the implied cross-rate and compare it to the quoted one. If the gap clears your cost threshold, you have a candidate.
3
Gate on risk
Size the position, check exposure and open-trade limits, and veto anything the account can't safely carry. Runs in microseconds or the edge is gone.
4
Fire the orders
Send all legs as close to simultaneously as the broker allows, then confirm every fill. A partial fill on one leg is now an open, un-hedged position.
Ingest, detect, gate, execute. Each stage must hand off in microseconds — the slowest link sets your true speed.
Two architectural decisions dominate everything else:
Use streaming, not polling. If you're pulling quotes over a REST endpoint on a timer, you have already lost — you're detecting mispricings from prices that are hundreds of milliseconds old. You want a persistent WebSocket streaming connection (or the broker's native push feed) so a new quote reaches your detector the instant it prints. The difference between push and pull here is the difference between a working system and a museum piece.
Keep detection and execution in one process, close to the broker. Every network hop is latency you can't get back. Serious arbitrage runs on a VPS or server geographically near the broker's matching engine, with the detector and the order-sender in the same process so there's no internal queue between "found it" and "fired it." You are engineering out every avoidable millisecond because, as the tension section warned, the edge decays in exactly those milliseconds.
The execution flow, message by message
It helps to see the actual sequence of messages, because the latency budget lives in the round-trips. Here is one triangular opportunity from tick to fill.
sequenceDiagram
autonumber
participant Feed as Price Feed
participant Bot as Arb Engine
participant Broker as Broker API
Feed->>Bot: New quotes (3 legs)
Note over Bot: Recompute implied cross-rate
Bot->>Bot: Gap clears cost threshold?
alt Edge survives costs
Bot->>Broker: Send all 3 legs
Broker-->>Bot: Fills (or partial)
Note over Bot: Confirm every leg is hedged
else Edge too thin
Bot->>Bot: Skip, keep listening
end
The whole race is steps 1 to 5. Any delay between the quote arriving and the order landing is edge you hand to a faster participant.
Notice what the diagram makes obvious: the cost check happens before the order fires, not after. A system that fires first and checks profitability later is a system that accumulates losing trades at machine speed. The gate is not optional overhead — it's the thing standing between you and automated capital destruction.
Code the Detection Loop
The heart of the system is small. Below is the core of a triangular detector: on each fresh set of quotes it computes the implied cross-rate from two legs, compares it to the third quoted leg, and flags an opportunity only when the gap survives an estimated cost buffer. This is deliberately framework-agnostic — the same logic drops into a Python service against a broker API, an MQL5 Expert Advisor, or a connector that pipes signals into MetaTrader.
The detector
pythontriangular_detector.py
# Legs: EUR/USD, GBP/USD, EUR/GBP
# Implied EUR/GBP = (EUR/USD) / (GBP/USD)
# We buy at the ask, sell at the bid, so use the
# worst side of every quote -- never the mid price.
COST_BUFFER = 0.0002 # spread + commission + slippage cushion
def check_triangle(eurusd, gbpusd, eurgbp):
# eurusd = (bid, ask), etc.
implied_ask = eurusd[1] / gbpusd[0] # cost to synthesize EUR/GBP
implied_bid = eurusd[0] / gbpusd[1] # value if we unwind it
# Path A: quoted EUR/GBP is cheap vs the synthetic route
edge_a = implied_bid - eurgbp[1] # buy quoted, sell synthetic
# Path B: quoted EUR/GBP is rich vs the synthetic route
edge_b = eurgbp[0] - implied_ask # sell quoted, buy synthetic
best = max(edge_a, edge_b)
if best > COST_BUFFER:
return ('A' if edge_a > edge_b else 'B', best)
return None # no edge after costs -- do nothing
The whole strategy is a few lines. Note it always uses the worst side of each quote and only fires when the edge clears a real cost buffer.
Three things in that snippet are non-negotiable, and they're exactly what the shallow explainers skip:
Always price against the side you'd actually trade. You buy at the ask and sell at the bid. Computing an edge off the mid price manufactures profit that doesn't exist — it's the single most common reason a backtested arbitrage system evaporates live.
The cost buffer is the gate.COST_BUFFER is where you subtract the spread you'll cross, the commission per leg, and a realistic slippage allowance. If the gap doesn't clear it, there was never a trade.
Doing nothing is the correct default. A good arbitrage engine sits idle almost all the time. Most ticks produce no edge. A system that trades constantly isn't finding arbitrage — it's finding noise and paying costs to trade it.
For a serious build you'd wrap this in the streaming feed, the risk gate, and an order-sender that fires all legs together and reconciles fills — but the profit logic itself is this compact. The infrastructure around it, not the math inside it, is what you'll spend your time on.
Cost-Test the Trade Before You Trust It
Here is the calculation that should come before you write production code, not after you've lost money. An arbitrage trade has a gross edge (the raw price gap) and a stack of costs that eat it: the spread you cross on each leg, the commission per leg, and slippage on the fill. On a triangular trade you pay these on multiple legs, so the cost stack is larger than beginners expect.
Model your own numbers. Plug in a realistic gap and the per-leg costs your broker actually charges, and watch how quickly a "free" edge turns negative.
Try the numbers
Net arbitrage edge after costs
Enter the raw gap you detect and your real per-leg trading costs. A triangular trade pays costs on 3 legs — see how much of the gross edge actually survives.
Gross gap detected (pips)
Avg spread crossed per leg (pips)
Commission per leg (pips equiv.)
Slippage allowance per leg (pips)
Legs in the trade
Total cost stack
—
Net edge after costs
—
Slide the costs up and the net edge collapses fast — this is why a gap that looks huge on paper is usually already gone once real fills hit.
Play with it and you'll feel the core truth of retail arbitrage: the gross gap is almost never the story — the cost stack is. A six-pip gap looks enormous until you subtract spread, commission, and slippage across three legs, at which point it's often negative. This is the illustrative, honest version of what "broker fees erode thin margins" actually means when you're the one paying them.
What Makes a Retail Arbitrage System Actually Survive
Put the pieces together and a pattern emerges about which retail arbitrage systems last. It's not the ones chasing the fastest, thinnest opportunities against institutions — that's a race you can't win. It's the ones that pick a type forgiving enough to fill reliably, gate ruthlessly on cost, and treat execution quality as the whole game.
Concretely, if you're building your first system:
Start with triangular on one venue. No cross-broker synchronization, clean math, and it teaches you every architectural problem the harder types share.
Or go statistical for survivability. If you can't guarantee low latency, a mean-reversion "stat-arb" approach tolerates slower fills because the edge plays out over minutes, not milliseconds — you're trading a probabilistic relationship, not racing a clock.
Instrument everything. Log detection time, order round-trip time, and realized-vs-expected fill on every trade. Your latency numbers are your strategy; if you're not measuring them, you're flying blind.
Run near the broker. Co-locate on a VPS close to the matching engine and keep the loop in one process. Every hop you remove is edge you keep.
And know when not to build it. If your realistic access is a standard retail feed with retail latency, pure latency arbitrage will lose to faster players every time — and if you simply want disciplined, low-latency entries without engineering an execution stack yourself, a purpose-built delivery layer that already solves the speed problem is the pragmatic route. That's exactly the gap our own sub-10ms signal latency is built to close, whether you take entries as live forex signals or wire execution straight into MetaTrader through our MT4/MT5 connectors.
FAQ
Is forex arbitrage actually profitable for a retail trader?
It can be, but rarely in the "free money" form the marketing implies. The gross price gaps are real, but they're small, short-lived, and shrink dramatically once you subtract spread, commission, and slippage across every leg. Profitability is almost entirely a function of your execution speed and cost structure — not of finding the opportunity, which is public. Statistical arbitrage tends to be more survivable retail-side than pure latency arbitrage, because it doesn't require you to win a millisecond race against institutions.
What programming language should I build an arbitrage bot in?
Use whatever gets you closest to the broker with the least latency in the hot path. Python is excellent for prototyping the detection logic and is fine in production when paired with a fast streaming client, because the bottleneck is network round-trip, not language speed. If you're trading inside MetaTrader, an MQL5 Expert Advisor keeps the loop native to the platform. The language matters far less than eliminating network hops and using a streaming feed instead of REST polling.
Why did my backtested arbitrage strategy fail live?
Almost always because the backtest assumed you filled at the price you detected. Live, the mispricing is frequently gone by the time your order arrives, so you fill at the corrected price plus costs. If your backtest priced edges off the mid price instead of the ask/bid you'd actually trade, it manufactured profit that never existed. Rebuild it to use the worst side of every quote and subtract a realistic cost buffer, and the staircase-to-the-moon curve usually flattens.
Do brokers allow arbitrage trading?
Many explicitly restrict latency or two-broker arbitrage in their terms, because it exploits their own pricing lag and their liquidity provider ultimately eats the cost. Triangular arbitrage on a single venue and statistical arbitrage are generally treated as ordinary automated strategies rather than abuse, but you must read your broker's terms on automation and arbitrage before you deploy. Don't build a system whose entire premise your broker's terms forbid.
Is triangular or statistical arbitrage better for a first build?
Triangular is the better learning build: it's self-contained on one venue, the math is clean, and it forces you to solve the real problems (streaming feeds, simultaneous multi-leg fills, cost gating). Statistical is the better survivability build if you can't guarantee low latency, because its edge plays out over minutes rather than milliseconds. A common path is to code triangular first to learn the architecture, then move to statistical if your infrastructure can't win the speed race.
Sources & Further Reading
Want to go deeper? These independent, authoritative sources shaped this guide — each one is worth reading in full:
The Forex Desk is the SignalBots editorial team responsible for our currency-market coverage. We research and write the guides, explainers and reference articles on how the majors, minors and crosses actually trade — sessions, spreads, swaps and the macro releases that move price.
Discussions 0
Leave a comment