Arbitrage
This EA implements a triangular arbitrage strategy across EURUSD, GBPUSD, and EURGBP currency pairs. It monitors the price difference between the synthetic EURGBP rate (derived from EURUSD/GBPUSD) and the actual EURGBP market rate, entering a three-legged arbitrage position when the spread exceeds commission costs. Trades are opened simultaneously in all three pairs to capture the pricing inefficiency.
Open the interactive view (equity curve, symbol switch)Key facts
Backtest results (H1, about 1 year)
| Symbol | P&L | Annual | Max DD | Trades | Win rate | Sharpe | Recovery | Losing streak | Per trade | Status |
|---|---|---|---|---|---|---|---|---|---|---|
| EURUSD | 0.00% | 0.00% | 0.00% | 0 | — | — | — | — | — | Not convertible yet |
| GBPUSD | 0.00% | 0.00% | 0.00% | 0 | — | — | — | — | — | Not convertible yet |
| USDJPY | 0.00% | 0.00% | 0.00% | 0 | — | — | — | — | — | Not convertible yet |
| XAUUSD | 0.00% | 0.00% | 0.00% | 0 | — | — | — | — | — | Not convertible yet |
Why this EA never traded: no entry rule survived the conversion.
Converted from MQL5 to Python and run with the same rules for every EA. Positions use MT5 lot sizes (100,000 units per FX lot, 100 oz per gold lot) with 1:100 leverage, one order at a time, and a stop-out below 10% of the starting balance. Sharpe is computed from the equity curve. Results marked as unreliable are shown for completeness only.
Blow-up risk: No blow-up pattern found
- Has no stop loss or trailing stop
On its own this is not a typical blow-up pattern, and the account was not stopped out in our backtests. That is not a guarantee: any EA can lose money.
High: stopped out in our backtest, or martingale/grid sizing without a stop loss. Elevated: martingale or grid sizing with a stop loss, or several positions at once without a stop loss. What the label means and what we found →
Strategy analysis
This strategy employs triangular arbitrage by comparing the synthetic EURGBP rate (EURUSD ask / GBPUSD bid) against the actual EURGBP market rate to detect pricing inefficiencies. Entry conditions: when the difference between the synthetic rate and the actual EURGBP ask exceeds the spread plus triple commission costs, the EA sells EURGBP (sell EURUSD, buy GBPUSD, buy EURGBP); conversely, when the inverse difference exceeds costs, it buys EURGBP (buy EURUSD, sell GBPUSD, sell EURGBP). Exit conditions: when an opposite arbitrage signal appears, the EA first closes the corresponding side positions before opening the reverse leg. Position sizing is calculated based on account balance multiplied by Lot_Size_Per_Thousand per thousand dollars, capped at the EURGBP symbol's maximum volume. Money management includes the CheckVolumeValue function which validates minimum/maximum volume constraints, volume step compliance, and available free margin. However, the strategy lacks any stop-loss mechanism, and the closing logic only triggers upon detecting a reverse arbitrage signal, creating risk of prolonged open positions.
Strengths
- Employs triangular arbitrage which is theoretically market-neutral, carrying lower risk than directional trading
- Accounts for commission and spread costs, only entering when arbitrage profit exceeds total costs
- Includes margin check and volume compliance validation to prevent order failures due to insufficient funds or invalid lot sizes
- Simultaneous three-leg execution design properly captures the pricing inefficiency as required by arbitrage logic
Weaknesses
- No stop-loss mechanism; if the price difference fails to converge, positions are held indefinitely with floating losses
- Typo 'GPBUSD' instead of 'GBPUSD' in CheckVolumeValue calls causes volume validation to always fail for that symbol, effectively blocking the buy-EURGBP arbitrage leg from executing
- Using SymbolInfoDouble for live prices introduces slippage risk; if all three legs cannot be filled simultaneously, unhedged exposure results
- Arbitrage windows are extremely brief in efficient markets, and OnTick-level detection may not capture opportunities fast enough
- Position closing logic iterating over PositionsTotal may skip positions due to index shifts when positions are closed during iteration
Possible improvements
- Fix the 'GPBUSD' typo to 'GBPUSD', otherwise the buy-EURGBP arbitrage direction is completely non-functional
- Add stop-loss or maximum holding period limits to prevent prolonged loss positions when spreads fail to converge
- Iterate positions in reverse order (from total-1 to 0) when closing to avoid index skipping issues caused by position removal during iteration
- Add slippage control and retry mechanisms to ensure all three legs are filled as simultaneously as possible
- Consider using limit orders instead of market orders for arbitrage execution to better control fill prices
Risk assessment
Overall risk: High risk
- Critical typo 'GPBUSD' causes the buy-EURGBP arbitrage path to fail validation, but the code still attempts to open EURUSD and GBPUSD positions, potentially creating unhedged directional exposure
- No stop-loss mechanism; positions held indefinitely when price difference fails to converge
- Three-leg arbitrage may result in unhedged directional exposure due to slippage or partial fills
- Incorrect iteration order when closing positions may cause some positions to be skipped
Evaluation scores
Parameters
| Parameter | Default | Description |
|---|---|---|
Lot_Size_Per_Thousand | 0.01 | Lot size per $1000 account balance |
Total_Commission_for_Lot_Traded | 7.0 | Total commission cost per traded lot |
Plot_Max_Difference | false | Whether to plot/log max spread for analysis |
Similar Statistical Arbitrage EAs
Backtests are historical simulations and do not guarantee future results. Not financial advice.