Log Pose

ICT backtesting

FVG Backtesting: A Repeatable Test for Fair Value Gaps

Turn a fair value gap into a reproducible backtest with fixed formation, entry, invalidation, expiry, session, and look-ahead rules.

Editorial illustration of a three-bar fair value gap with a return path and invalidation mark
A gap becomes testable only after its formation and execution rules are fixed.

Define the pattern in code-sized language#

A common bullish FVG definition uses three candles: the low of candle i is above the high of candle i-2. The interval between those two prices is the gap. A bearish FVG reverses the inequality.

That definition still produces many tiny gaps caused by normal price increments. Add a minimum-size rule. Log Pose uses:

minimum gap = max($0.01, 0.10 × ATR)

This is a test setting, not a universal ICT threshold. Write down your own threshold and keep it unchanged for the comparison you are running.

The pattern is known only after candle i closes. If a backtest enters during that same candle using its final low, high, or close, it has used information that was not yet complete.

Synthetic three-candle sequence showing gap formation, confirmation, and later retracement
Synthetic example. Formation on bar three cannot authorize an earlier fill.

An FVG is not an entry rule#

Choose exactly how the simulated order is created:

  • next-bar open: enter at the next bar's open after confirmation;
  • midpoint limit: place a limit at 50% of the gap;
  • proximal edge: use the first edge price touched on retracement;
  • close confirmation: require a later close inside or back out of the zone.

These models answer different questions. Next-bar open measures continuation after formation. A midpoint limit measures a retracement that may never fill. Do not combine their trades in one summary.

For a limit model, define the order's lifetime. Log Pose's default test keeps an FVG midpoint limit active for at most 20 bars and cancels it sooner if invalidation occurs. Report expired orders as unfilled, not as wins, losses, or zero-return trades.

Fix invalidation before choosing the stop#

Pattern invalidation and trade stop are related but not identical.

Possible FVG invalidation rules include:

  • any touch of the far edge;
  • a wick through the entire gap;
  • a close through the far edge;
  • acceptance beyond the impulse origin;
  • a separate structure break.

Choose one. Then define where the simulated stop executes and how gaps through the stop are handled. If the backtest assumes every stop fills exactly at its level, disclose that optimistic assumption.

The order of events inside one OHLC candle can be unknowable. If a bar touches both the entry and stop, a bar-based engine cannot prove which happened first. Use a conservative rule, lower-timeframe data, or mark the trade ambiguous. Do not choose the favorable sequence.

Control context one variable at a time#

An FVG can be filtered by direction, session, structure, displacement, premium/discount, or prior liquidity. Testing every combination and reporting only the winner is data mining.

Start with a base sample, then compare one prespecified filter:

Test Fixed conditions Variable under review
A symbol universe, timeframe, entry, stop, target all qualifying FVGs
B same as A only FVGs after qualifying displacement
C same as B NY AM versus NY PM

If B was invented after inspecting A's losers, validate B on later or held-out data. The original sample is discovery data, not proof.

Process from defining the pattern and execution through exclusions and held-out validation
Changing one item after seeing results creates a new test.

Report the path, not only win rate#

At minimum, record:

  • candidate count;
  • eligible orders;
  • filled and unfilled orders;
  • ambiguous bars;
  • excluded corporate-action or missing-data windows;
  • win rate on filled trades;
  • average win and average loss in R;
  • expectancy in R;
  • maximum drawdown in R;
  • result by session and year;
  • assumed fees and slippage.

An illustrative result might show 120 candidates, 82 eligible midpoint orders, 49 fills, and 33 expirations. A 60% win rate on 49 fills is not a 60% win rate on 120 pattern occurrences. Keep the denominators visible.

Expectancy is:

P(win) × average win − P(loss) × average loss

A high win rate can have negative expectancy if losses are much larger. A lower win rate can have positive expectancy if the payoff is larger. Report both.

Run a falsification pass#

Before accepting the result, try to break it:

  1. shift the sample forward in time;
  2. test nearby but not hand-picked symbols;
  3. add one tick or a realistic slippage assumption;
  4. remove the best five trades and recompute expectancy;
  5. compare the chosen threshold with nearby thresholds;
  6. inspect every ambiguous same-bar entry and stop;
  7. verify that no candidate entered before confirmation.

If a small threshold change flips the result, the rule may be fragile. That does not make the observation worthless, but it changes what you can claim.

FVG backtesting is most useful when it narrows uncertainty. It cannot guarantee that the next gap will behave like the historical sample.

Sources and methodology#

Product details and workflows can change. Links below are the primary references checked for this page; the analysis and operational definitions are Log Pose’s.

  1. CFTC Rule 4.41 — hypothetical performance limitations — U.S. CFTC / eCFR
  2. Log Pose Terms of Service — backtest limitations — Log Pose

Log Pose is not affiliated with Robinhood, Inner Circle Trader, or the products discussed on this page. This material is for education and recordkeeping, not investment advice. Historical and hypothetical results do not predict future performance.