Strategies we backtested fair value gap (FVG) retest

Tested by BacktestingMax

Fair value gap (FVG) retest strategy backtest

Does the fair value gap (FVG) retest strategy make money?

No, not in most of our tests. A fair value gap (FVG) is a gap in price that forms when one candle moves up or down very fast: in three candles in a row, the price ranges (low to high) of the first and the third candle do not overlap. The retest strategy waits for price to come back to the gap and enters there with a limit order (an order that waits at a set price). It puts the stop-loss just beyond the first candle and takes profit at 2R: twice the distance from the entry to the stop-loss. We call these our standard rules. We tested them on 8 markets (EUR/USD, GBP/USD, USD/JPY, GBP/JPY, gold, the Nasdaq 100, the S&P 500 and the DAX), each on 5-minute, 15-minute and 1-hour charts, at any time of day, risking 1% of the account on each trade. After trading costs, 5 of the 24 backtests made money from 2020 to 2025. Only 2 made money in both the older years (2020–2023) and the newer years (2024–2025): the S&P 500 and USD/JPY on 15-minute charts. In all 24 tests, about 1 trade in 3 reached the take-profit. With a 2R take-profit, one winning trade pays for two losing trades, so that is about the break-even point before costs. After trading costs, most tests lost money. On 5-minute charts, the stop-loss is closest to the entry, so trading costs take a bigger share of the money each trade risks. There, all 8 markets lost more than 98% of the account.

24 backtests 2020–2025 Trading costs included Tested 19 October 2026

Where it worked 24 backtests
Made money
5
of 24 tests, with the standard rules
Made money in both periods
2
2020–2023 and again 2024–2025
Best backtest
+124%
S&P 500, 15-minute chart: account growth 2020–2025
Only big gaps (1 ATR or more)
3
tests made money in both periods, compared with 2 with the standard rules

Made money in both periods

  • USD/JPY, 15-minute
  • S&P 500, 15-minute

Lost money on every market

  • 5-minute charts

The results

Results on every market

Each box shows one backtest of the fair value gap (FVG) retest with the standard rules, from 2020 to 2025, after trading costs: the % result, and a small chart of the account balance. The solid line is the account balance and the dashed line is the starting balance. Green results made money; red results lost money. Under each result: whether it made money in both 2020–2023 and 2024–2025, or passed all four of our checks (see "How a test passes" further down).

Market 5-minute 15-minute 1-hour
EUR/USD −100% Lost money. Account down 90% by Sept 2021 −69% Lost money −44% Lost money
GBP/USD −100% Lost money. Account down 90% by May 2021 −93% Lost money. Account down 90% by Oct 2023 −33% Lost money
USD/JPY −100% Lost money. Account down 90% by Mar 2022 +113% Made money in both periods +74% Made money overall, lost in one period
GBP/JPY −100% Lost money. Account down 90% by Apr 2021 −96% Lost money. Account down 90% by Sept 2024 +20% Made money overall, lost in one period
Gold −99% Lost money. Account down 90% by Jun 2021 −58% Lost money +69% Made money overall, lost in one period
Nasdaq 100 −99% Lost money. Account down 90% by Oct 2022 −41% Lost money −7% Lost money
S&P 500 −99% Lost money. Account down 90% by Oct 2023 +124% Made money in both periods −21% Lost money
DAX −99% Lost money. Account down 90% by Apr 2022 −62% Lost money −25% Lost money
All the numbers, test by test
Market Chart Trades Win rate Profit factor Result Max drawdown 2020–2023 2024–2025 Monte Carlo drawdown Trading costs
EUR/USD 5-minute 9,556 32.8% 0.90 −99.7% −99.7% −99.3% −48.1% −99.8% $5,739
EUR/USD 15-minute 3,863 33.5% 0.95 −68.7% −78.9% −41.7% −46.3% −87.7% $5,102
EUR/USD 1-hour 1,125 32.4% 0.92 −44.1% −57.4% −38.6% −9.0% −65.4% $1,080
GBP/USD 5-minute 6,678 32.3% 0.91 −99.6% −99.6% −99.6% 0.0% −99.7% $6,882
GBP/USD 15-minute 4,496 32.5% 0.92 −92.9% −94.4% −91.3% −18.2% −96.2% $4,408
GBP/USD 1-hour 1,168 32.9% 0.95 −33.0% −64.6% −40.9% +13.5% −62.3% $1,218
USD/JPY 5-minute 10,880 33% 0.94 −99.7% −99.7% −98.0% −83.8% −99.8% $11,236
USD/JPY 15-minute 4,424 35% 1.02 +113.4% −53.9% +55.0% +37.7% −72.9% $15,881
USD/JPY 1-hour 1,154 35.4% 1.08 +73.5% −37.5% −1.6% +76.2% −44.4% $1,435
GBP/JPY 5-minute 5,482 32.7% 0.89 −99.6% −99.6% −99.6% 0.0% −99.7% $9,213
GBP/JPY 15-minute 4,818 32.6% 0.93 −96.1% −96.5% −79.2% −81.0% −97.8% $8,593
GBP/JPY 1-hour 1,122 34.8% 1.02 +20.0% −51.5% +62.7% −26.3% −50.7% $2,845
Gold 5-minute 5,999 32.8% 0.90 −99.4% −99.5% −99.4% 0.0% −99.6% $7,949
Gold 15-minute 4,528 34% 0.96 −58.0% −83.8% −78.8% +97.6% −85.1% $6,256
Gold 1-hour 1,057 35.8% 1.07 +69.1% −31.3% +70.4% −0.8% −41.3% $1,894
Nasdaq 100 5-minute 11,910 33.2% 0.95 −98.9% −99.2% −96.8% −66.1% −99.6% $9,709
Nasdaq 100 15-minute 4,157 33.7% 0.98 −40.5% −70.6% −3.7% −38.2% −82.1% $6,153
Nasdaq 100 1-hour 1,236 33.6% 0.99 −6.7% −39.1% −24.0% +22.8% −54.8% $827
S&P 500 5-minute 13,376 33.7% 0.96 −98.6% −99.0% −91.4% −84.0% −99.6% $11,851
S&P 500 15-minute 4,433 34.8% 1.02 +124.2% −58.6% +60.1% +40.0% −71.4% $16,493
S&P 500 1-hour 1,139 33% 0.97 −21.4% −48.1% −22.3% +1.2% −58.7% $874
DAX 5-minute 10,862 32.6% 0.98 −99.3% −99.8% −98.8% −44.7% −99.7% $15,768
DAX 15-minute 4,646 33.3% 0.96 −62.3% −86.3% −75.1% +51.6% −87.3% $2,566
DAX 1-hour 1,242 32.8% 0.96 −25.4% −42.0% −29.2% +5.4% −59.9% $540

Profit factor is the money won divided by the money lost. Above 1 means the test made money. Max drawdown is the biggest fall from the highest balance. 2020–2023 and 2024–2025 show the result in each period on its own. Monte Carlo drawdown: we shuffled the trades into a random order 1,000 times; in 95% of those runs, the worst drawdown was this number or less. Result is the change in the account, with the risk of each trade set to 1% of the account at that time.

The account balance

The best test and the middle test

Best test S&P 500, 15-minute chart +124.2% from 2020 to 2025
Middle test (median): half of the 24 did better, half did worse Gold, 15-minute chart −58.0% from 2020 to 2025

What we found

What the 24 backtests show

  1. About 1 trade in 3 reached the take-profit: 33.2% of all 119,351 trades, and in each of the 24 tests, between 32.3% and 35.8% of the trades made money. With the take-profit at 2R, that is about the break-even rate, so before trading costs the average trade was close to zero: −0.007R on 5-minute charts, +0.011R on 15-minute charts and +0.017R on 1-hour charts (see the table below). R is the money one trade risks, 1% of the account, so +0.017R means that the average trade made 1.7% of the money it risked.

  2. On 5-minute charts, all 8 markets lost more than 98% of the account from 2020 to 2025. This strategy enters and takes profit with limit orders, which pay no spread in our test, so its trading costs came from the stop-loss exits: half the spread each. Its stop-loss sits just beyond the first candle of the gap, only 9 times the spread away on a typical 5-minute trade, so these costs took 0.039R per trade on 5-minute charts, compared with 0.023R on 15-minute charts and 0.011R on 1-hour charts.

  3. With the standard rules, 5 of the 24 tests made money from 2020 to 2025. On 15-minute charts, the S&P 500 backtest grew the account by 124.2% and the USD/JPY backtest by 113.4%. These were the only 2 tests that made money in both 2020–2023 and 2024–2025. On 1-hour charts, the USD/JPY backtest made +73.5%, gold +69.1% and GBP/JPY +20.0%. But the 1-hour USD/JPY test lost money in 2020–2023, and the 1-hour gold and GBP/JPY tests lost money in 2024–2025. Even the 2 tests that made money in both periods fell more than 50% from their highest balance at some point: 58.6% on the S&P 500 and 53.9% on USD/JPY.

  4. The size of the gap, the trend and how soon price came back made little difference (see 'Results by kind of gap' below). At gaps 2 ATR or taller, 31.8% of the trades reached the take-profit, compared with 33.4% at gaps 0.25 to 0.5 ATR tall. ATR is the size of an average candle. Trades with the trend of the 200 EMA (an average of the last 200 closing prices) reached it 33.3% of the time, and trades against it 33.1%. When price came back 6 to 20 candles after the gap formed, 34.7% of the trades reached it, compared with 33.0% within 5 candles. Sells lost more than buys: −0.048R per trade, compared with −0.017R.

  5. With all 8 markets taken together, the trades on 5-minute charts lost money at every time of day. They lost the least in the hours around the New York stock market open: −0.004R per trade from 12:00 to 15:00 London time and −0.010R from 15:00 to 18:00. They lost the most from 21:00 to 24:00 London time, after the New York stock market closes: −0.144R per trade, and only 29.2% of those trades reached the take-profit (see the chart below).

Before and after trading costs

Before costs, the average trade was close to zero on every chart. After costs, only 1-hour charts stayed above zero

This table shows all 24 backtests with the standard rules, from 2020 to 2025, grouped by chart: 5-minute, 15-minute and 1-hour. R is the money one trade risks: 1% of the account at the time of the trade. For example, +0.017R means that the average trade made 1.7% of the money it risked. The trading cost is the spread (the gap between the buy price and the sell price). In our test, a trade pays half the spread when it closes at the stop-loss, and nothing when it reaches the take-profit.

Chart Tests that made money Trades Reached the take-profit Average trade before costs Trading costs per trade Average trade after costs
5-minute 0 of 8 74,743 33.0% −0.007R 0.039R −0.046R
15-minute 2 of 8 35,365 33.7% +0.011R 0.023R −0.012R
1-hour 3 of 8 9,243 33.7% +0.017R 0.011R +0.006R

Every R figure on this page is a trade's result in money divided by 1% of the account at the time of the trade. Most trades made about 2R or lost about 1R, so the trades break even before costs when about 1 in 3 of them (33.3%) reach the take-profit. The averages differ a little from that for two reasons. Trade sizes are rounded down to the smallest step the broker allows, so many trades risked a little less than 1%, most of all on 5-minute charts once the account had shrunk: there, before costs, the average winning trade made 1.81R and the average losing trade lost 0.90R. And about 2 trades in 100 filled at a better price, when a candle opened beyond the order's price.

Results by kind of gap

At every kind of gap, about 1 trade in 3 reached the take-profit

This table shows all 119,351 trades of the 24 backtests with the standard rules, from 2020 to 2025, grouped by the gap each trade came from. 'Reached the take-profit' is the share of trades that reached 2R before the stop-loss. ATR is the size of an average candle over the last 14 candles. The 200 EMA is an average of the last 200 closing prices that gives more weight to recent prices. The average trade is after trading costs, in R (the money one trade risks: 1% of the account at the time of the trade).

Trades at Trades Reached the take-profit Average trade
All gaps 119,351 33.2% −0.032R
Gaps 0.25 to 0.5 ATR tall 53,662 33.4% −0.032R
Gaps 0.5 to 1 ATR tall 45,054 33.5% −0.027R
Gaps 1 to 2 ATR tall 17,513 32.5% −0.044R
Gaps 2 ATR or taller 3,122 31.8% −0.043R
Gaps price came back to on the next candle 64,362 33.0% −0.039R
Gaps price came back to 2 to 5 candles later 38,356 33.0% −0.038R
Gaps price came back to 6 to 20 candles later 16,633 34.7% +0.007R
Gaps with the 200 EMA trend 81,698 33.3% −0.029R
Gaps against the 200 EMA trend 37,491 33.1% −0.039R
Bullish gaps (buys) 61,233 33.8% −0.017R
Bearish gaps (sells) 58,118 32.6% −0.048R

'With the 200 EMA trend' means a bullish gap whose third candle closed above the 200 EMA, or a bearish gap whose third candle closed below it. 162 trades came from gaps at the very start of a test, before the 200 EMA had a value, so the two 200 EMA rows add up to 119,189 trades. Most of the trades are on 5-minute charts, where trading costs were highest, so most of the averages here are below zero. We also tested a 100-candle limit instead of 20 (see 'Can the fair value gap (FVG) retest be improved?' below). With that limit, price came back 21 to 100 candles after the gap formed in 9,637 trades, and 34.5% of those trades reached the take-profit.

Time of day

On 5-minute charts, the trades lost money at every time of day

Each bar shows the average trade after trading costs, by the time the trade opened (London time). The bars use all 74,743 trades on 5-minute charts with the standard rules, on all 8 markets, from 2020 to 2025. R is the money one trade risks: 1% of the account at the time of the trade.

  • 00:00 to 03:009,514 trades −0.072R
  • 03:00 to 06:007,659 trades −0.043R
  • 06:00 to 09:0012,012 trades −0.042R
  • 09:00 to 12:009,591 trades −0.029R
  • 12:00 to 15:0011,894 trades −0.004R
  • 15:00 to 18:009,695 trades −0.010R
  • 18:00 to 21:008,321 trades −0.079R
  • 21:00 to 24:006,057 trades −0.144R

From 21:00 to 24:00 London time, after the New York stock market closes, only 29.2% of the trades reached the take-profit, and the trades in those 3 hours lost money on all 8 markets. On 6 of the 8 markets, the worst 3-hour period of the day was 18:00 to 21:00 or 21:00 to 24:00 London time. Our test charges the same spread at every hour. At many brokers the spread is wider late at night, so a real result at that time could be worse.

The strategy

What the fair value gap (FVG) retest is

A fair value gap (FVG) is a gap in price that forms when one candle moves up or down very fast. Look at three candles in a row. In a bullish (upward) gap, the middle candle rises so fast that the low of the third candle is still above the high of the first candle. The gap is the price range between those two prices. A bearish (downward) gap is the opposite: the high of the third candle is below the low of the first candle. The idea comes from ICT (The Inner Circle Trader, the online name of the trading teacher Michael Huddleston) and is part of smart money concepts (SMC). Traders who use it expect price to come back to the gap later and turn there, in the same direction as the fast candle. The retest strategy trades that return: it buys when price falls back to a bullish gap, and it sells short (sells first, to make money if price falls) when price rises back to a bearish gap. ICT and SMC teachers draw and trade gaps in slightly different ways. We tested a plain version, which this page calls the standard rules: no trend filter, no time-of-day filter and no other signal before the entry. 'The rules we tested' lists our exact rules.

Gap size
At least 0.25 × ATR(14), measured when the gap forms. A gap with a flat candle in it (high = low) does not count
Entry
A limit order at the near edge of the gap: the top of a bullish gap, the bottom of a bearish gap
Stop-loss
1 pip beyond the first candle of the gap: below its low for a buy, above its high for a sell. 1 pip is 0.0001 on EUR/USD and GBP/USD, 0.01 on USD/JPY and GBP/JPY, $0.01 on gold and 0.1 point on the indices
Take-profit
2R: twice the distance from the entry to the stop-loss
Gap valid for
The 20 candles after the gap forms
Time of day
Any time the market is open. No time-of-day filter
Order of events inside a candle
We use 1-minute data to see which price came first. On the candle where an order fills, only the prices after the fill count. If the stop-loss is reached in the same minute as the entry or as the take-profit, the test counts the trade as a loss
Risk per trade
1% of the account, which started at $10,000
Trading costs
Each market's usual spread (the gap between the buy price and the sell price): 0.8 pips on EUR/USD, 1.2 on GBP/USD, 0.9 on USD/JPY, 2.5 on GBP/JPY, $0.30 on gold, 1.5 points on the Nasdaq 100, 0.4 on the S&P 500 and 1.0 on the DAX. In our test, a limit order fills at its own price as soon as the chart price touches it, so the entry and the take-profit pay no spread. Our test treats chart prices as the middle between the buy price and the sell price, so a trade that closes at the stop-loss pays half the spread. No commission. Real trading can be harder: a real limit order fills only when the buy price or the sell price reaches it, not the middle price. So real results could be worse, most of all on 5-minute charts

The rules we tested

  1. A bullish fair value gap is three candles in a row where the low of the third candle is above the high of the first candle. A bearish fair value gap is three candles in a row where the high of the third candle is below the low of the first candle. The gap is the price range between those two prices.
  2. Only gaps at least 0.25 ATR tall count. ATR is an indicator of how far price moves in an average candle, measured over the last 14 candles. A gap also does not count if one of its three candles is flat (its high equals its low). A flat candle means the price did not move at all, for example on a holiday, so a gap next to it does not come from a fast candle.
  3. A bullish gap is a place to buy. The buy limit order goes at the top of the gap: the low of the third candle. A limit order waits at a set price and fills when price comes back to it. Put the stop-loss 1 pip below the low of the first candle, and the take-profit at 2R. R is the distance from the entry to the stop-loss (in money, 1% of the account), so 2R is twice that distance.
  4. A bearish gap is a place to sell. The sell limit order goes at the bottom of the gap: the high of the third candle. Put the stop-loss 1 pip above the high of the first candle, and the take-profit at 2R.
  5. A gap is valid for the 20 candles after it forms. After that, it no longer counts, and any order waiting at it is cancelled.
  6. Trade each gap only once: the first time price comes back to it. If price comes back to a gap while another trade is open, skip that gap.
  7. Take one trade at a time. While no trade is open, only two orders wait: one buy order at the top of the nearest valid bullish gap below the current price, and one sell order at the bottom of the nearest valid bearish gap above the current price, because price reaches those gaps first. When one order fills, the other is cancelled.
  8. Size every trade so that, if the stop-loss is hit, the trade loses 1% of the account.

The method

How we tested it

The test

Markets
EUR/USD, GBP/USD, USD/JPY, GBP/JPY, Gold, Nasdaq 100, S&P 500 and DAX
Charts
5-minute, 15-minute and 1-hour candles
Dates
January 2020 to December 2025
Account
$10,000, risking 1% of the account on each trade
Trading costs
Included. Every trade pays that market's normal trading cost: the spread, which is the gap between the buy price and the sell price.

How a test passes

We call a test passed only if it meets all four checks. A strategy can make money in one backtest and still fail one of these checks.

  • At least 100 trades. With fewer trades, a good result could be luck.
  • It made money from 2020 to 2023 and again from 2024 to 2025. This shows whether the strategy kept working in the newer years, not only in the older ones.
  • A profit factor (the money won divided by the money lost) of at least 1.2 from 2024 to 2025, after trading costs.
  • In 95% of 1,000 random shuffles of the trades, the account must not fall more than 30% from its highest point.

Improvements

Can the fair value gap (FVG) retest be improved?

We tried four changes that traders often make, one at a time, on the same 24 tests: only gaps in the direction of the 200 EMA trend, only big gaps, and a shorter or a longer time limit for each gap (5 or 100 candles instead of 20). The table below explains each one. If you pick the best change and then judge it on the same years you used to pick it, it almost always looks better than it really is. So we picked the best change using 2020–2023 only: the change that made money in the most tests, and in a tie, the one with the better middle test (the median: half of the tests did better, half did worse). Then we checked it on 2024–2025, the years we did not use to pick it.

Version Made money 2020–2023years used to pick the best version Made money 2024–2025years not used to pick it Made money in both periods Passed all four checks
Standard rules The rules under 'The rules we tested': every gap at least 0.25 ATR tall, valid for 20 candles, at any time of day. 4 of 24middle test −58.4% 9 of 24middle test −0.4% 2 0
With the 200 EMA trend Only buy at a bullish gap whose third candle closed above the 200 EMA, and only sell at a bearish gap whose third candle closed below it. The 200 EMA is an average of the last 200 closing prices that gives more weight to recent prices. Many traders only trade gaps in the direction of the trend. 5 of 24middle test −65.5% 6 of 24middle test −14.1% 1 0
Only big gaps (1 ATR or more)Best on 2020–2023 Only trade gaps at least 1 ATR tall (as tall as an average candle), instead of 0.25 ATR. Many traders only trade gaps made by a big, fast candle. 7 of 24middle test −24.1% 7 of 24middle test −11.5% 3 0
Gap valid for 5 candles A gap counts for only 5 candles after it forms, instead of 20. 5 of 24middle test −51.2% 8 of 24middle test −1.4% 3 0
Gap valid for 100 candles A gap counts for up to 100 candles after it forms, instead of 20: about 8 hours on 5-minute charts, 25 hours on 15-minute charts and 4 trading days on 1-hour charts. 4 of 24middle test −63.0% 9 of 24middle test −3.5% 3 0

The version with only big gaps (1 ATR or more) did best in 2020–2023, the years we used to pick: 7 of 24 tests made money with it, compared with 4 with the standard rules. In 2024–2025, the years we kept for the check, it made money in 7 tests, compared with 9 with the standard rules. So in this backtest, it did not make the strategy clearly better. Over the whole test, it made money in 5 of 24 tests, the same as the standard rules, and 3 tests made money in both periods, compared with 2. On 5-minute charts, it lost 37.7% to 97.6% of the account instead of 98.6% to 99.7%. The other changes made little difference: 5 of 24 tests made money with the 200 EMA trend rule, 4 with a 5-candle limit and 6 with a 100-candle limit. No version passed all four of our checks. With the standard rules, 3 tests on 5-minute charts had lost more than 99% by the end of 2023 and took no trades after that, so they count as not making money in 2024–2025.

Questions

Questions traders ask

Does the fair value gap (FVG) strategy work?

Not in most of our tests. Our standard rules put a limit order at the near edge of the gap (the edge that price reaches first), the stop-loss just beyond the first candle, and the take-profit at 2R: twice the distance from the entry to the stop-loss. With these rules, 5 of 24 tests made money from 2020 to 2025, after trading costs. We tested 8 markets, each on 5-minute, 15-minute and 1-hour charts. Only the S&P 500 and USD/JPY on 15-minute charts made money in both 2020–2023 and 2024–2025. On 5-minute charts, all 8 markets lost more than 98% of the account. We also tried four common changes: only gaps in the direction of the 200 EMA trend (an average of the last 200 closing prices), only gaps at least 1 ATR tall (as tall as an average candle), and a 5-candle or a 100-candle limit for each gap. With each change, 4 to 6 of the 24 tests made money, compared with 5 with the standard rules, so none of the changes made a big difference.

What is the win rate of a fair value gap retest?

About 1 trade in 3, with the take-profit at 2R (twice the distance from the entry to the stop-loss). In our backtest, 33.2% of the 119,351 trades reached the take-profit before the stop-loss, and in each of the 24 tests, between 32.3% and 35.8% of the trades made money. With a 2R take-profit, a win rate of 33.3% only breaks even before trading costs: one winning trade pays for two losing trades. In every group of gaps we looked at (by size, by how soon price came back, and with or against the trend of the 200 EMA, an average of the last 200 closing prices), 31.8% to 34.7% of the trades reached the take-profit.

What is the best timeframe for fair value gaps?

In our backtest, no timeframe made money on most markets, and 5-minute charts did worst. 1-hour charts had the most tests that made money and the best average trade, but the only 2 tests that made money in both 2020–2023 and 2024–2025 were on 15-minute charts (the S&P 500 and USD/JPY). On 1-hour charts, 3 of 8 markets made money from 2020 to 2025 (USD/JPY, gold and GBP/JPY), but each of them lost money in one of the two periods. R is the money one trade risks: 1% of the account. After trading costs, the average trade on 1-hour charts made +0.006R. On 15-minute charts, 2 of 8 markets made money. On 5-minute charts, none did: all 8 lost more than 98% of the account. About half of the difference came from trading costs, which this strategy pays when a trade hits its stop-loss: they took 0.039R per trade on 5-minute charts, where the stop-loss is closest to the entry, and 0.011R on 1-hour charts. The other half was there before costs: the average trade made −0.007R on 5-minute charts and +0.017R on 1-hour charts.

How long does a fair value gap stay valid?

Traders use different time limits, and in our backtest the limit made little difference. With our standard rules, a gap was valid for 20 candles, and 5 of 24 tests made money from 2020 to 2025. With a 5-candle limit, 4 of 24 made money, and with a 100-candle limit, 6 of 24. Most trades opened soon after the gap formed: in 53.9% of the trades, price came back on the very next candle. When price came back 6 to 20 candles later, the trades reached the 2R take-profit a little more often: 34.7%, compared with 33.0% when it came back within 5 candles. With the 100-candle limit, the trades where price came back 21 to 100 candles later reached it 34.5% of the time.

Keep exploring

Related strategies we tested

ICT & smart money ICT Silver Bullet backtest on NQ and ES futures Made money in 0 of 10 tests, 0 of them in both periods. Best: MGC (Micro Gold), 5-minute, −2% ICT & smart money ICT Power of 3 (AMD) backtest on NQ, ES and gold futures Made money in 4 of 10 tests, 2 of them in both periods. Best: YM (Dow futures), 15-minute, +46% ICT & smart money Change of character (CHoCH) and market structure shift (MSS) backtest Made money in 7 of 40 tests, 5 of them in both periods. Best: USD/JPY, 1-hour, +66%
The strategy code we ran

This is the exact code from the BacktestingMax strategy engine. Paste it into the strategy editor in the app to run it on any market.

class FairValueGapRetest(Strategy):
    """Fair value gap (FVG) retest, at any time of day: buy when price comes back to a
    bullish gap, sell when it comes back to a bearish gap.
    A bullish gap (builtin:fair_value_gaps): three candles in a row where the third
    candle's low is above the first candle's high. The gap is the price range between
    them, and it must be at least 0.25 x ATR(14) tall. A bearish gap is the mirror: the
    third candle's high is below the first candle's low. A gap with a flat candle in it
    (high = low: no price moved, e.g. a holiday in the data) does not count.
    Standard (all settings at their defaults):
      1. When a bullish gap forms, place a buy limit order at the top of the gap (the third
         candle's low). Stop-loss 1 pip below the first candle's low. Take-profit at 2R:
         twice the distance from the entry to the stop-loss.
      2. A bearish gap mirrors it: a sell limit order at the bottom of the gap (the third
         candle's high), stop-loss 1 pip above the first candle's high, take-profit at 2R.
      3. A gap stays valid for the 20 candles after it forms. If price has not come back
         to it by then, the order is cancelled.
      4. Each gap is traded only once, on the first return of price. A gap that price
         reaches while another trade is open is skipped.
      5. One trade at a time. While no trade is open, one buy order waits at the nearest
         valid bullish gap below the price and one sell order at the nearest valid bearish
         gap above it, because price reaches those gaps first.
      6. Size every trade so that the stop-loss costs 1% of the account.
    The changes, one at a time:
      trend   = 1    only buy at gaps whose third candle closed above the 200 EMA, and only
                     sell at gaps whose third candle closed below it
      min_gap = 1.0  only gaps at least 1 x ATR(14) tall (standard: 0.25)
      expiry  = 5    a gap stays valid for 5 candles (standard: 20)
      expiry  = 100  a gap stays valid for 100 candles
    """
    params = {"min_gap": Param(type=float, default=0.25, min=0.0, max=5.0),
              "expiry": Param(type=int, default=20, min=1, max=500),
              "rr": Param(type=float, default=2.0, min=0.5, max=10.0),
              "trend": Param(type=int, default=0, min=0, max=1)}
    lookback = 5
    def init(self, ctx):
        # Only gaps that form on the current candle are read, so the indicator need not
        # track old ones (max_age); this strategy keeps its own list of gaps to trade.
        self.fvg = ctx.indicator("builtin:fair_value_gaps", min_size_atr=ctx.params.min_gap, max_age=5)
        self.ema = ctx.ema(source=ctx.close, period=200)
        self.gaps = []     # gaps not reached yet: [side (+1 buy, -1 sell), entry, stop, bar formed]
        self.orders = {}   # side -> [gap, order] resting now
    def on_bar(self, ctx):
        k = ctx.bar_index
        # Gaps price came back to on this candle are used up: traded, or skipped because a
        # trade was open. Gaps older than the expiry are dropped.
        live = []
        for gap in self.gaps:
            side, entry, stop, formed = gap
            reached = ctx.low[0] <= entry if side > 0 else ctx.high[0] >= entry
            if not reached and k - formed < ctx.params.expiry:
                live.append(gap)
        self.gaps = live
        # New gaps that formed on this candle (it is the third candle). The first candle is
        # two candles back. A flat candle (high = low) means no price moved, e.g. a holiday in
        # the data, so a gap with one in it is not a real fast move: skip it.
        ema = self.ema.value
        trend = ctx.params.trend == 1
        moving = all(ctx.high[i] > ctx.low[i] for i in range(3))
        for g in self.fvg.now("fvg_bull"):
            if not ctx.gate("no_flat_candle", moving):
                continue
            if ctx.gate("trend_up", not trend or (ema is not None and ctx.close[0] > ema)):
                self.gaps.append([1, g.top, ctx.low[2] - ctx.pip_size, k])
        for g in self.fvg.now("fvg_bear"):
            if not ctx.gate("no_flat_candle", moving):
                continue
            if ctx.gate("trend_down", not trend or (ema is not None and ctx.close[0] < ema)):
                self.gaps.append([-1, g.bottom, ctx.high[2] + ctx.pip_size, k])
        if ctx.position is not None:
            # One trade at a time: no other order waits while a trade is open.
            for side, (gap, order) in list(self.orders.items()):
                ctx.cancel_order(order.order_id)
            self.orders = {}
            return
        for side in (1, -1):
            mine = [g for g in self.gaps if g[0] == side]
            # The nearest gap: the highest bullish gap below the price, the lowest bearish
            # gap above it.
            best = None
            if mine:
                best = max(mine, key=lambda g: g[1]) if side > 0 else min(mine, key=lambda g: g[1])
            current = self.orders.get(side)
            if current is not None and current[0] is not best:
                ctx.cancel_order(current[1].order_id)  # filled, expired, or a nearer gap formed
                del self.orders[side]
            if not ctx.gate("gap_waiting", best is not None) or side in self.orders:
                continue
            _, entry, stop, _ = best
            risk = entry - stop if side > 0 else stop - entry
            if risk <= 0:
                continue
            size = ctx.size_by_risk_pct(0.01, stop=stop, entry=entry)
            if side > 0:
                order = ctx.buy(size=size, limit=entry, sl=stop, tp=entry + ctx.params.rr * risk,
                                tag="fvg_long")
            else:
                order = ctx.sell(size=size, limit=entry, sl=stop, tp=entry - ctx.params.rr * risk,
                                 tag="fvg_short")
            if order is not None:
                self.orders[side] = [best, order]

Your turn

Test the fair value gap (FVG) retest yourself

Change the settings, the market or the stop-loss and see the result in seconds. Ask the BacktestingMax AI: Backtest a fair value gap retest on the S&P 500 15-minute chart with a 2R take-profit.

Try it free in BacktestingMax

Free account. No credit card needed.

See every strategy we tested Browse strategies shared by traders

Backtest on historical data with trading costs, run by BacktestingMax. Past results do not guarantee future results, and nothing here is financial advice. Updated 19 October 2026.