How bid/ask quotes are actually formed, why spreads widen around news and at rollover, and the detail most backtests miss: charts draw bid prices while long entries fill at the ask, so the spread is an invisible per-trade cost that flatters every bid-only backtest. Includes the arithmetic for pricing spread cost per trade and how to charge it inside a Pine Script strategy. Educational material only, not financial advice; trading carries a real risk of loss.
Spreads widen when the liquidity providers quoting the market either raise the price of taking your trade or stop quoting altogether. Around scheduled news, the risk of being on the wrong side of a violent repricing spikes, so market makers widen their quotes to charge for that risk — or pull them entirely, thinning the book. At rollover (around 5pm New York), the trading day changes hands: swap charges are processed, many providers reduce or reset their quoting, and liquidity hits its daily minimum, so even routine flow moves the visible spread.
It helps to be precise about what a spread is. At any moment an instrument has a bid — the best price someone will pay you when you sell — and an ask (or offer) — the best price someone will sell to you when you buy. The spread is the gap between them, and it exists because whoever quotes both sides is running inventory risk: they may buy from you moments before the market drops. The spread is their compensation for standing in the middle, and it is priced like any risk premium — cheap when the market is calm and deep, expensive when it is fast and thin.
That is why spread widening is not broker misbehaviour in itself (though execution quality varies): it is the quoted price of immediacy going up when immediacy is genuinely riskier to provide. The practical consequences for a systematic trader are twofold: your cost per trade is not a constant, and the moments your strategy is most likely to transact — breakouts, news, session opens — are often exactly the moments the spread is at its widest.
Retail forex quotes are the end of a pipeline. Banks and non-bank market makers stream bids and offers into aggregators; your broker takes some subset of those feeds, adds its own markup or commission model, and shows you a single best bid and best ask. When you trade, your broker either passes the order through to a provider or internalises it against its own book — but in both cases the price you see was assembled from quotes that real counterparties can pull or reprice at any moment.
Two properties of this pipeline explain most of what traders observe about spreads. First, quotes have size attached. The advertised spread applies to the top of the book; a large order consumes that size and fills the remainder at worse levels. Retail sizes on majors rarely hit this, but it is why "the spread" and "your effective cost" diverge as size grows.
Second, quoting is voluntary. Nothing obliges a market maker to keep streaming prices into a data release where they could be run over. Seconds before a rate decision, providers widen defensively or step away; the aggregate book thins; the surviving quotes define a much wider spread. The same dynamic drives the rollover widening — it is not one provider being greedy, it is most providers simultaneously reducing risk at the day boundary while swaps are applied.
Understanding this removes some magical thinking. A "raw spread" account does not abolish the spread — it moves the broker's compensation into a per-lot commission. And a spread that averages tight can still be expensive to your strategy specifically if your entries cluster in wide-spread windows. The average is not what you pay; the conditional spread at your trading times is.
Here is the mechanical detail that silently flatters backtests: most forex charts, and the historical data behind them, are built from bid prices only — while half of your order flow executes at the ask.
Walk through a long trade. You buy at the ask, which sits one spread above the bid your chart is drawing — so at the instant of entry you are already down the spread relative to the chart. Your long's stop-loss and take-profit then execute at the bid, which is what the chart shows, so exits look faithful. Now mirror it for a short: you sell at the bid (matches the chart), but you exit — stop or target — by buying at the ask, one spread above the line you were watching. Buy-stop entries trigger off the ask too, which is why a short squeeze can trigger your buy stop even though the bid chart never quite touched your level.
A backtester running on bid data with no spread model therefore fills long entries and short exits at prices that were never available to you. Every round trip is flattered by roughly one spread — which is negligible for a system trading weekly and decisive for one trading twenty times a day. This is also the origin of a classic MetaTrader head-scratcher: "my stop was hit but price never reached it on the chart." It did — on the other side of the quote your chart doesn't draw.
The fix is not exotic: know which side of the quote each order type fills on, charge the spread explicitly in your tester, and when validating stop behaviour, check it against ask-side levels for anything that buys. ForexCodes' spread-cost calculator exists precisely to make this invisible line item visible before the tester flatters it away.
The arithmetic is short enough to do in your head, which makes it strange how rarely it is done. Spread cost per round trip = spread (in price terms) × position size (in units). You pay it once per round trip: you buy at the ask, and the position is marked — and later closed — against the bid.
Concretely, on EUR/USD quoted with a 0.6-pip spread, one standard lot (100,000 units) costs 0.00006 × 100,000 = $6 per round trip. A 0.1-lot position costs $0.60. Nothing about the position being profitable or not changes this; it is charged at entry, win or lose.
The number only becomes meaningful when you multiply by trade frequency and compare it to your average trade. A strategy that trades once a week on a standard lot pays roughly $300 a year in spread — probably noise. The same spread charged to a scalper taking 20 trades a day is $120 per day, roughly $30,000 a year per lot of size — a figure that many scalping backtests would not survive if it were charged honestly. As a rule of thumb worth making explicit: divide your backtest's average profit per trade by the spread cost per trade. If the ratio is small — your average trade is only a few spreads — your reported edge lives in the same order of magnitude as your costs, and any widening (news, rollover, regime change) eats it.
And remember the conditionality from earlier: the spread you pay is the spread at your trading times, not the advertised average. A breakout system transacting into fast markets should budget the widened figure, not the brochure figure. Run your own numbers through a spread-cost calculator before trusting any equity curve.
TradingView's standard chart feeds are effectively one-sided prices, and the broker emulator will happily fill both sides of your trades on them. The pragmatic fix is to charge the spread as an explicit cost in the strategy() declaration — either as commission or as tick slippage. Charging half the spread per side via slippage is the closest structural match, since it moves each fill against you the way crossing the quote does:
//@version=6
// Educational only — validate before trading; not financial advice.
// Charge ~half the spread per side as adverse ticks.
// E.g. a 0.6-pip spread on a 5-decimal pair = 6 ticks total → 3 per side.
strategy("Spread-charged baseline", overlay = true, slippage = 3)
stopPts = input.int(250, "Stop loss (points)", minval = 1)
longSig = ta.crossover(close, ta.sma(close, 50))
if longSig and barstate.isconfirmed and strategy.position_size == 0
strategy.entry("Long", strategy.long)
if strategy.position_size > 0
strategy.exit("Exit", "Long",
stop = strategy.position_avg_price - stopPts * syminfo.mintick)The unit discipline matters: slippage is in ticks (syminfo.mintick), so on a five-decimal forex feed one pip is ten ticks. Set it per symbol, and set it to the spread you expect at your trading times, not the tightest advertised figure. If you also budget genuine slippage (the fill-quality kind from our slippage guide), add the two — they are separate costs that both land on your fills.
In MetaTrader, the MT5 tester lets you pin a custom spread for a test run instead of the recorded one, which is the cleanest way to stress the widened case; MT4's fixed-spread testing makes the same point coarsely. Whichever platform: run the test tight, run it wide, and look at which trades disappear. A strategy whose edge evaporates when the spread doubles is not robust — it is a bet that markets stay quiet. Educational only; a cost-honest backtest is still a description of the past, not a promise about the future.
Educational only — not financial advice. Trading involves substantial risk of loss.