🔥Black Friday Sale: Get 25% OFF Premium with code BLACKFRIDAY — Sale ends December 1st!🎉
Backtesting Smart Money Concepts — How to Validate SMC Strategies Before Risking Real Capital

Backtesting Smart Money Concepts — How to Validate SMC Strategies Before Risking Real Capital

By HorizonAI Team

Everyone has screenshots of “perfect” Smart Money Concepts (SMC) setups.
Almost nobody has 100+ trade samples proving their BOS/CHOCH + OB + FVG model actually works.

If you want to trade ICT‑style SMC with confidence, you need a way to backtest your ideas systematically instead of trusting cherry‑picked examples.

This guide shows you how to:

  • Translate SMC concepts (BOS, CHOCH, liquidity grabs, order blocks, FVGs, premium/discount) into testable rules
  • Choose markets and timeframes for SMC backtesting (Forex, indices, crypto, stocks; 1m to D1)
  • Avoid the biggest backtesting mistakes SMC traders make
  • Build simple Pine Script v6 harnesses on EURUSD to collect statistics
  • Use HorizonAI to quickly generate and iterate on SMC backtests without hand‑coding everything

Why Backtesting SMC Is Harder Than It Looks

Traditional indicator strategies are easy to test:

  • “Buy when 9 EMA crosses above 21 EMA, sell when it crosses below.”

SMC is messier:

  • What exactly counts as a BOS or CHOCH?
  • How strict is your definition of an order block?
  • Which fair value gaps matter, and which are noise?
  • How do you define liquidity grabs around different sessions?

Key idea:
You don’t have to automate all of SMC at once. Start by testing small, clear pieces.

Step 1: Define the SMC Building Blocks You Care About

For backtesting, focus on a short list of core SMC elements:

  • Market structure
    • HH/HL (bullish), LH/LL (bearish)
    • BOS (trend continuation), CHOCH (potential reversal)
  • Liquidity
    • Prior day high/low
    • Session highs/lows (London, New York)
    • Equal highs/lows
  • Premium / discount
    • 50% mean of a swing (buy discount, sell premium)
  • Order blocks
    • Last opposite candle before strong displacement that breaks structure
  • Fair value gaps (FVGs)
    • Basic 3‑candle imbalance zones, no need for extreme strictness

You don’t need a perfect, universal definition.
You just need consistent rules you can test.

Step 2: Pick Markets and Timeframes for SMC Backtesting

SMC traders typically focus on:

  • Markets:
    • Forex: EURUSD, GBPUSD, indices (DAX, US100), etc.
    • Crypto: BTCUSDT, ETHUSDT
    • Stocks/indices: ES, NQ, liquid large caps
  • Timeframes:
    • 1m–5m: scalping
    • 15m–1H: intraday
    • 4H–D1: swing

For this guide we’ll anchor examples on EURUSD in Pine Script, but the principles apply everywhere.

Recommendation:

  • Start your SMC backtests on 15m and 1H:
    • Enough structure to see HH/HL / LH/LL clearly
    • Less micro noise than 1m, more samples than D1

Step 3: Turn Liquidity Grabs Into Simple Rules

Let’s take one SMC idea and make it concrete:

“If New York takes out the previous day’s high on EURUSD and then price closes back inside the range, look for shorts.”

This involves:

  • Previous day’s high = liquidity pool
  • New York session = specific time window
  • Stop hunt = wick above high, close back below

You don’t need to capture every nuance. You just need something you can test consistently.

Pine Script Skeleton: Previous Day High/Low + Session Filter (EURUSD)

//@version=5
indicator("SMC Backtest Harness: Session Liquidity (EURUSD)", overlay = true)

// --- Previous day high/low ---
var float prevHigh = na
var float prevLow  = na

isNewDay = ta.change(time("D"))

if isNewDay
    prevHigh := high[1]
    prevLow  := low[1]
else
    prevHigh := math.max(prevHigh, high)
    prevLow  := math.min(prevLow, low)

plot(prevHigh, "Prev Day High", color = color.red)
plot(prevLow,  "Prev Day Low",  color = color.green)

// --- New York session filter (approx. 13:00–21:00 UTC) ---
nySessionStart = 13
nySessionEnd   = 21

barHour   = tonumber(str.format("{0,time,HH}", time))
inNewYork = barHour >= nySessionStart and barHour < nySessionEnd

bgcolor(inNewYork ? color.new(color.blue, 94) : na, title = "New York Session")

This doesn’t trade yet. It gives you:

  • Visual previous day high/low (liquidity pools)
  • New York session shading

From here you can start defining liquidity grabs algorithmically.

Example Rule: Simple Liquidity Grab Short Condition

You might define a short idea as:

  • During New York
  • High of the bar goes above previous day high
  • Close ends back below previous day high
liqGrabShort = inNewYork and high > prevHigh and close < prevHigh
plotshape(liqGrabShort, title = "NY Liquidity Grab (Short Idea)",
     style = shape.triangledown, location = location.abovebar,
     color = color.red, size = size.small)

Now you can scroll through the chart and see how often this pattern:

  • Leads to impulsive moves away from the high
  • Fails and gets run over by trend

Later, HorizonAI can help you turn this into a full strategy with stop loss and targets.

Step 4: Add Premium/Discount Context

SMC isn’t just “grab liquidity and fade it.”
You also care about whether price is in premium or discount relative to a swing.

Simple Premium/Discount Filter

//@version=5
indicator("Premium/Discount Filter", overlay = true)

len = input.int(50, "Swing Lookback (Bars)")
swHigh = ta.highest(high, len)
swLow  = ta.lowest(low, len)
mid    = (swHigh + swLow) / 2.0

isPremium = close > mid
isDiscount = close < mid

plot(swHigh, "Swing High", color = color.red)
plot(swLow,  "Swing Low",  color = color.green)
plot(mid,    "Mean (50%)", color = color.yellow, style = plot.style_dashed)

Combine this with your liquidity grab condition:

  • Short bias: only take New York liquidity grab shorts when EURUSD is in premium
  • Long bias: only take liquidity grabs at prior day low when price is in discount

This is how you turn vague SMC ideas into binary filters a backtest can understand.

Step 5: Decide What You’ll Actually Measure

Before you code a full strategy, decide:

What questions are you trying to answer?

Examples:

  • After a New York liquidity grab at previous day high:
    • How often does price move at least 1R in your favor before hitting stop?
    • What’s the average excursion (max favorable vs max adverse move)?
  • How does performance change if:
    • You only trade in premium/discount?
    • You only trade when 4H structure is bullish/bearish?
    • You skip Asia and only trade London/New York?

You can start by logging simple metrics per trade and then analyze them:

  • Entry price
  • Stop loss level
  • Target level (e.g. 2R)
  • Max favorable excursion (MFE)
  • Max adverse excursion (MAE)
  • Outcome (win/loss, RR)

HorizonAI can generate strategies that track and print these for you in Pine Script.

Step 6: Avoid the Big SMC Backtesting Traps

❌ Trap #1: Repainting SMC Logic

If your code:

  • Uses current, still‑forming candles for BOS/CHOCH decisions
  • Re‑labels structure after the fact
  • Depends on look‑ahead calculations for highs/lows

…your results will be fake.

Use:

  • barstate.isconfirmed to ensure the bar is closed
  • Swing logic that only confirms after a few bars (like ta.pivothigh, ta.pivotlow)

❌ Trap #2: Overfitting to One Pair and Timeframe

A model that looks perfect on EURUSD 15m from 2021–2022, but fails on:

  • GBPUSD
  • BTCUSDT
  • 5m or 1H

…is probably overfit to a specific regime.

You want patterns that:

  • Still work (even if slightly worse) on other pairs and timeframes
  • Survive different volatility environments (trending vs ranging)

❌ Trap #3: Only Testing One Piece of SMC

If you test “order blocks” or “FVG fills” in isolation, results may look terrible.

SMC concepts are meant to work together:

  • Higher‑timeframe bias (4H/D1 structure)
  • Session timing (kill zones)
  • Liquidity grabs
  • Premium/discount
  • OB / FVG refinement for entries

Backtest combinations step‑by‑step:

  1. Liquidity grab alone
  2. Liquidity grab + session filter
  3. Liquidity grab + session + premium/discount
  4. Add OB/FVG refinement last

Step 7: Build a Simple SMC Strategy Shell (Then Let AI Take Over)

Here’s a very simple Pine Script strategy shell for EURUSD 15m using the earlier liquidity idea.

This is not production‑ready—just a starting point:

//@version=5
strategy("SMC Liquidity Grab Test (EURUSD 15m)", overlay = true,
     initial_capital = 10000, commission_type = strategy.commission.percent, commission_value = 0.01)

// --- Previous day high/low ---
var float prevHigh = na
var float prevLow  = na

isNewDay = ta.change(time("D"))

if isNewDay
    prevHigh := high[1]
    prevLow  := low[1]
else
    prevHigh := math.max(prevHigh, high)
    prevLow  := math.min(prevLow, low)

// --- New York session (13:00–21:00 UTC approx.) ---
barHour   = tonumber(str.format("{0,time,HH}", time))
inNewYork = barHour >= 13 and barHour < 21

// --- Simple premium/discount (last 50 bars) ---
len    = 50
swHigh = ta.highest(high, len)
swLow  = ta.lowest(low, len)
mid    = (swHigh + swLow) / 2.0

isPremium  = close > mid
isDiscount = close < mid

// --- Short idea: NY liquidity grab above prev high in premium ---
liqGrabShort = inNewYork and isPremium and high > prevHigh and close < prevHigh

// --- Risk management: fixed RR ---
riskPercent     = input.float(1.0, "Risk per Trade (%)", minval = 0.1, maxval = 5.0)
rewardMultiple  = input.float(2.0, "Target RR", minval = 1.0, maxval = 5.0)
stopPips        = input.float(10.0, "Stop (pips)", minval = 2.0)

tickSize = syminfo.mintick
pip      = tickSize * 10.0

if liqGrabShort and barstate.isconfirmed
    entryPrice = close
    stopPrice  = entryPrice + stopPips * pip
    targetPrice = entryPrice - stopPips * rewardMultiple * pip

    riskAmount = strategy.equity * riskPercent / 100.0
    qty        = riskAmount / (stopPips * pip)

    strategy.entry("Short", strategy.short, qty = qty)
    strategy.exit("TP/SL", "Short", stop = stopPrice, limit = targetPrice)

This is intentionally simple:

  • No BOS/CHOCH logic yet
  • No complex OB/FVG detection
  • Just one SMC‑inspired idea (NY liquidity short in premium) with fixed RR

Now you can:

  • Run backtests on EURUSD 15m
  • See win rate, profit factor, drawdown
  • Adjust:
    • Time windows (London vs NY)
    • Premium/discount settings
    • Stop/target parameters

And once you know what you want to explore next, you can let HorizonAI handle the more advanced coding.

Use HorizonAI to Backtest SMC Without Drowning in Code

Manually coding full SMC logic (BOS/CHOCH, OB, FVG, session filters, multi‑timeframe bias) is:

  • Time‑consuming
  • Easy to get wrong
  • Hard to keep consistent across markets and timeframes

With HorizonAI you can:

  • Describe your SMC ideas in plain English
  • Generate Pine Script strategies that:
    • Detect simplified BOS/CHOCH
    • Mark liquidity grabs and FVG fills
    • Apply premium/discount and session filters
    • Use proper risk management and realistic costs
  • Access prebuilt SMC scripts you can drop straight into TradingView

Example prompts:

"Create a Pine Script v6 strategy for EURUSD 15m that shorts New York liquidity grabs above the previous day’s high, only when price is in premium relative to the last 50 bars, using 1% risk per trade and 2:1 RR."

"Build an SMC backtest that logs win rate and average RR for CHOCH‑based entries after a London session liquidity sweep, with results printed in a table."

"Generate an indicator that marks BOS and CHOCH on 4H and allows me to filter 15m entries by higher‑timeframe bias."

Backtest your SMC ideas with HorizonAI →

Final Thoughts

Smart Money Concepts can absolutely be tested—but only if you:

  1. Break them down into clear, rule‑based components (liquidity, structure, OB/FVG, premium/discount)
  2. Start with simple pieces (like session liquidity grabs) instead of full “perfect SMC models”
  3. Avoid repainting and overfitting to one pair or timeframe
  4. Focus on metrics (win rate, RR, drawdown, expectancy) instead of screenshots
  5. Use automation to explore variations quickly instead of spending weeks hand‑coding every tweak

If you’re serious about validating SMC instead of just believing it, HorizonAI can help you turn your ICT‑style theories into real Pine Script strategies and backtests—so you see what actually works before risking live capital.

Have questions about backtesting SMC or want feedback on your rules? Join our Discord community to discuss with other traders building and testing SMC systems.