MT5 XAUUSD EAs: The Cost Stack That Decides Survival — Spread, Slippage, Swap

A gold EA is priced by its costs, not its entry rule: what a point is worth on XAUUSD, how to read spread, slippage, commission and swap as a fraction of R, and the MT5 Strategy Tester settings that make a losing system look profitable.

Most gold expert advisors do not die from bad entries. They die from the cost of doing business, and XAUUSD charges more for it than any FX pair most retail systems were written for. This is the cost side of the EA board: the real toll on a gold round trip, how to gate on it in MQL5, and the tester settings that quietly delete it from your results. Sizing and regime gating are settled in our volatility-normalized sizing and setfile write-up.

1. One point is one dollar

On XAUUSD one lot is 100 ounces and the tick is 0.01, so one point is worth $1.00 per lot — $0.10 on a 0.01 lot. A 25-point spread costs $25 per lot per round trip, and a 35-point broker versus a 12-point broker is $23 per lot, every trade. Measured retail gold spreads run 15–35 points during London and New York hours, and the cheapest ECN account measured all-in at $13 per lot round turn — a ~6-cent average spread plus $7 commission — against $24 at the wide end. Spot gold traded $4,160–$4,200 on 16 October 2026, so read these as bands, not ticks.

2. Price everything in R, never in points

Points are how brokers quote costs; R is how you pay them.

cost/R = [(spread points + slippage points) x $1 + commission per lot] / stop distance in dollars

A normal-regime toll — 25 points of spread, 2 points of slippage, $7 round-turn commission — is $34 per lot per trade. Against stops that is 1.2% of R at 2,730 points, 5.7% at 600 and 11.3% at 300. The last figure decides whether a strategy exists: a 1:1 system on a 300-point stop needs roughly a 56% win rate before entry logic gets a say. Your broker's spread table, not your preference for tight risk, sets the viable stop floor. Frequency multiplies it: 60 trades a month at 0.10 lots is $204, or 2% of a $10,000 account, spent before the EA has a view.

3. Around a release it is a different market

Inside seconds of a CPI, payrolls or FOMC release, gold spreads have been measured jumping to $1–$5 — 100 to 500 points — and stops fill wherever the next print is. A 200-point spread plus a 100-point slip is $300 per lot: 11% of R at a 2,730-point stop, half your risk at 600, the whole budget at 300, paid on the exit rather than the entry. A wider stop only changes which strategy you are running; the answer is a blackout that refuses new entries either side of a tier-one print — the same arithmetic that has our own signal protocol stand flat through a release instead of guessing a direction into it.

4. Swap is the swing trader's tax

Spread is charged per round trip; swap per night. Measured tables put a long XAUUSD position at roughly −$60 to −$95 per lot per night, with shorts from −$30 to +$40, and one broker lists long −$72.26 against short +$28.29 per lot. Wednesday settles triple, so a five-night hold pays seven nights, and one long lot extrapolates to $1,600–$2,965 of financing across a month.

  • The asymmetry is directional. Longs carry; shorts can be paid to wait. If an edge only shows on longs, financing may be why the live curve trails the backtest.
  • Check whether your symbol types swap in points or annual percentage — a percentage swap grows with the metal's price, and the tester charges only what the loaded spec says.

5. Four tester settings between you and the truth

  • Modelling. Use every tick based on real ticks. MetaTrader's own comparison of 1-minute OHLC, generated ticks and real ticks shows material divergence, and 99% "quality" measures coverage of M1 bars, not whether the tick set matches your broker's book.
  • Spread. In generated modes the Spread field is the cost (current, or a pessimistic 50-point gold default). In real-tick mode the recorded bid/ask in the tick stream wins, so your conservative number can be silently discarded. Enable spread visualisation and compare the report's average to a live measurement.
  • Commission. The tester charges what the loaded symbol specification carries, so on a raw-spread account insert the per-lot fee or you are backtesting a broker $7 per lot cheaper than yours.
  • Delay and forward. Zero latency flatters every market-order gold EA; use random, and fix the forward split before optimising.

Then the blind spot: the calendar functions read the terminal's live calendar, and historical testing has no calendar feed — which is why the MQL5 community builds CSV news sources for tester runs. An EA that blocks around releases trades straight through every one of them in a backtest, so model the blackout from a dated release list.

6. Gate at runtime, in code

mql5
bool CostGate()                                    // call before every entry
{
   double pt  = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   if(pt <= 0.0 || ask <= 0.0 || bid <= 0.0) return false;
   if((ask - bid) / pt > (double)InpMaxSpreadPts) return false;   // cost model broken
   if(InNewsBlackout(TimeTradeServer()))          return false;   // release window
   return (StopDistancePoints() > StopsFloor() && StopDistancePoints() > FreezeLevel());
}

bool SendChecked(ENUM_ORDER_TYPE type, double price, double sl, double tp, double lots)
{
   MqlTradeRequest req; MqlTradeCheckResult chk; MqlTradeResult res;
   ZeroMemory(req); ZeroMemory(chk); ZeroMemory(res);
   long modes = SymbolInfoInteger(_Symbol, SYMBOL_FILLING_MODE);

   req.action    = TRADE_ACTION_DEAL;
   req.symbol    = _Symbol;
   req.volume    = lots;
   req.type      = type;
   req.price     = price;
   req.sl        = sl;
   req.tp        = tp;
   req.deviation = (ulong)MathMax(5, InpSlippagePts);   // slip budget, in points
   req.magic     = InpMagic;
   req.type_filling = (modes & SYMBOL_FILLING_IOC) != 0 ? ORDER_FILLING_IOC :
                      (modes & SYMBOL_FILLING_FOK) != 0 ? ORDER_FILLING_FOK :
                      ORDER_FILLING_RETURN;

   if(!OrderCheck(req, chk))       // 10014 volume, 10016 stops, 10019 no money
   { PrintFormat("OrderCheck %u %s", chk.retcode, chk.comment); return false; }
   if(!OrderSend(req, res) || (res.retcode != TRADE_RETCODE_DONE &&
                               res.retcode != TRADE_RETCODE_PLACED))
   { PrintFormat("OrderSend %u %s", res.retcode, res.comment); return false; }
   return true;
}

StopsFloor() is the broker's SYMBOL_TRADE_STOPS_LEVEL plus a 3-point buffer for news-time spread, and FreezeLevel() reads SYMBOL_TRADE_FREEZE_LEVEL — inside that band the server refuses stop modifications, which is where trailing logic breaks. req.deviation is your slippage budget in the same unit as the spread, and OrderCheck() catches bad volume or bad stops before the server does. The filling mode is a broker setting, so hard-coding FOK is the classic "unsupported filling mode" rejection on an IOC-only server.

7. The cost pre-flight

Before a gold EA goes live: real-tick run on your broker's own data with the report's average spread checked against a live measurement; commission and swap set correctly, triple-swap weekday included; stops asserted against the broker's stops and freeze levels; blackout modelled from dated releases rather than inherited from the calendar. Then print total costs divided by total risked and rerun at 1.3x — if the system dies there, the edge was in your assumptions, not in the market.

More on the execution and backtesting topic hubs.

Sources

Educational analysis. Cost figures are broker-dependent measurements, not guarantees for your account, and past performance does not indicate future results. Validate every assumption on your own broker's data before risking capital.

Trading these levels? XM — MT5, gold, demo first paid link