Strategy · Pine Script v6 · On the chart

Liquidity Sweep, MSS and FVG Entry Model

by guillemustafa-ux

This strategy for index futures models an ICT sequence on the price chart.

View on GitHub

Repaints

GitHub stars1on the repository
Pine versionv6current
Lines of code414
Settings28inputs
LicenceMIT
Last update4 days ago25 Oct 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new strategy, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart. The trades and results appear in the Strategy Tester tab; adjust the settings with the gear icon.

Source Code

414 lines of Pine Script v6 from ict-sweep-mss-fvg.pine, published under MIT. Keep the author's credit and licence lines when you reuse it.

ict-sweep-mss-fvg.pine
//@version=6
strategy("Liquidity Sweep, MSS and FVG Entry Model with Look-ahead A/B",
     shorttitle = "SWEEP-MSS-FVG",
     overlay = true,
     initial_capital = 100000,  // one NQ or ES contract at 5% margin fits; micros need about a tenth
     default_qty_type = strategy.fixed,
     default_qty_value = 1,
     margin_long = 5,       // futures margin is ~4-5% of notional; the v5+
     margin_short = 5,      // default of 100% silently rejects every order
     commission_type = strategy.commission.cash_per_contract,
     commission_value = 2.25,
     slippage = 1,
     calc_on_every_tick = false,
     process_orders_on_close = true)

//──────────────────────────────────────────────────────────────────────────────
// Liquidity sweep → Market Structure Shift → Fair Value Gap entry.
//
// Setup lifecycle:  Pool identified → Sweep → MSS (displacement) → FVG →
//                   limit order in the gap → stop beyond the sweep extreme.
// Each setup is tracked by an explicit state machine, so a stale or
// invalidated setup can never leak into a trade.
//
// Every rule below is stated as a testable condition. Where a concept has more
// than one defensible definition (what confirms a sweep, which FVG edge is the
// entry, what the target is) the choice is an input, not a silent default.
//
// Anti-repaint rules used throughout:
//   · Daily pools read the last CLOSED daily bar (`high[1]` + lookahead_on).
//   · Swing pools come from ta.pivothigh/pivotlow, which confirm `pivotRight`
//     bars after the extreme — lagging, but immutable once set.
//   · Every state transition is evaluated on bar close; nothing intrabar.
//   · Entries are resting limit orders, so a fill is a real touch of the gap,
//     not a same-bar assumption.
//
// The "Look-ahead A/B demo" input group deliberately reintroduces the classic
// request.security() leak so the two equity curves can be compared side by
// side in the Strategy Tester. See REPAINTING.md.
//──────────────────────────────────────────────────────────────────────────────

// ── Inputs ───────────────────────────────────────────────────────────────────
grpP = "Liquidity pools (BSL / SSL)"
usePrevDay  = input.bool(true,  "Previous day high / low", group = grpP)
useSwings   = input.bool(true,  "Confirmed swing highs / lows", group = grpP)
pivL        = input.int(5, "Pivot left bars",  minval = 1, group = grpP)
pivR        = input.int(5, "Pivot right bars", minval = 1, group = grpP)
requireEqual= input.bool(false, "Only sweep equal highs / equal lows", group = grpP,
     tooltip = "Two consecutive confirmed swings within the tolerance below. Fewer setups, cleaner pools.")
eqTicks     = input.int(8, "Equal-high/low tolerance (ticks)", minval = 1, group = grpP)

grpS = "Sweep"
sweepConfirm = input.string("Close back inside", "A sweep is confirmed by",
     options = ["Close back inside", "Defer to MSS displacement"], group = grpS,
     tooltip = "Close back inside: the sweeping bar must trade through the pool and CLOSE back on the origin side. " +
               "Defer: the wick through the pool arms the setup and the displacement of the MSS is the only confirmation.")
sweepMaxBars = input.int(12, "Bars allowed from sweep to MSS", minval = 1, group = grpS)

grpM = "Market Structure Shift"
dispMult = input.float(1.0, "Displacement: body ≥ ATR ×", minval = 0.1, step = 0.1, group = grpM)
atrLen   = input.int(14, "ATR length", minval = 2, group = grpM)

grpF = "Fair Value Gap & entry"
fvgSearchBars = input.int(6, "Bars after MSS to find the FVG", minval = 1, group = grpF)
fvgEdge       = input.string("Proximal", "Enter at which gap edge",
     options = ["Proximal", "Distal", "Midpoint"], group = grpF,
     tooltip = "Proximal = the near edge price reaches first. Distal = the far edge (full gap fill). Fewer fills, better price.")
minGapTicks   = input.int(4, "Ignore gaps thinner than (ticks)", minval = 1, group = grpF)
armedMaxBars  = input.int(20, "Cancel the order if unfilled after (bars)", minval = 1, group = grpF)

grpX = "Risk & exits"
stopBufferAtr = input.float(0.25, "Stop buffer beyond sweep extreme (ATR ×)", minval = 0.0, step = 0.05, group = grpX)
targetMode    = input.string("Opposing liquidity", "Target",
     options = ["Opposing liquidity", "R multiple"], group = grpX)
rMult         = input.float(2.0, "R multiple (fallback when no pool)", minval = 0.5, step = 0.25, group = grpX)

grpK = "Sessions & kill zones"
requireKz = input.bool(true, "Only take setups inside a kill zone", group = grpK)
tz        = input.string("America/New_York", "Session timezone", group = grpK)
useLondon = input.bool(true, "London kill zone", group = grpK)
londonKz  = input.session("0200-0500", "London window", group = grpK)
useNy     = input.bool(true, "New York kill zone", group = grpK)
nyKz      = input.session("0830-1100", "New York window", group = grpK)

grpG = "Risk guards"
useDailyLock = input.bool(true, "Stop trading after a daily loss", group = grpG)
maxDailyLoss = input.float(600, "Daily loss limit (account currency)", minval = 1, group = grpG)
useFlatten   = input.bool(true, "Flatten at a fixed time", group = grpG)
flattenSess  = input.session("1555-1600", "Flatten window", group = grpG)

grpD = "Look-ahead A/B demo"
leakMode = input.bool(false, "DEMO — leak the CURRENT day's high/low into history", group = grpD,
     tooltip = "This is a demonstration only: keep it OFF for any real evaluation. " +
               "OFF (default) is the honest build: pools are the PREVIOUS day's extremes. " +
               "ON reproduces the classic request.security() look-ahead bug, where every historical intraday bar " +
               "already knows its day's final high and low. Compare the two equity curves in the Strategy Tester: " +
               "the difference is the size of the lie, not the size of the edge.")

// ── Daily liquidity pools ────────────────────────────────────────────────────
// `expr[1]` + lookahead_on is the documented NON-repainting form: it returns
// the last COMPLETED daily bar on both historical and realtime bars.
// Dropping the [1] is the bug — on historical bars it hands back the finished
// value of the day the bar belongs to, i.e. the future.
pdhHonest = request.security(syminfo.tickerid, "D", high[1], lookahead = barmerge.lookahead_on)
pdlHonest = request.security(syminfo.tickerid, "D", low[1],  lookahead = barmerge.lookahead_on)
pdhLeaked = request.security(syminfo.tickerid, "D", high,    lookahead = barmerge.lookahead_on)
pdlLeaked = request.security(syminfo.tickerid, "D", low,     lookahead = barmerge.lookahead_on)
pdh = usePrevDay ? (leakMode ? pdhLeaked : pdhHonest) : na
pdl = usePrevDay ? (leakMode ? pdlLeaked : pdlHonest) : na

// ── Confirmed swing pools ────────────────────────────────────────────────────
ph = ta.pivothigh(high, pivL, pivR)
pl = ta.pivotlow(low,  pivL, pivR)
var float swingHigh     = na
var float swingLow      = na
var float prevSwingHigh = na
var float prevSwingLow  = na
if not na(ph)
    prevSwingHigh := swingHigh
    swingHigh     := ph
if not na(pl)
    prevSwingLow := swingLow
    swingLow     := pl

eqTol   = eqTicks * syminfo.mintick
// `not na(...) and` first: a comparison against na is itself na, which is
// falsy — the guard has to special-case the virgin state explicitly.
eqHighs = not na(swingHigh) and not na(prevSwingHigh) and math.abs(swingHigh - prevSwingHigh) <= eqTol
eqLows  = not na(swingLow)  and not na(prevSwingLow)  and math.abs(swingLow  - prevSwingLow)  <= eqTol

swingHighPool = useSwings and (not requireEqual or eqHighs) ? swingHigh : na
swingLowPool  = useSwings and (not requireEqual or eqLows)  ? swingLow  : na
// Previous-day levels are pools in their own right; the "equal" filter is a
// property of paired swings and does not apply to them.
dayHighPool   = requireEqual ? na : pdh
dayLowPool    = requireEqual ? na : pdl

// Liquidity gets taken nearest-first, so the active pool is the closest level
// on each side of price, not the most recent one.
nearestAbove(float a, float b, float px) =>
    ca = not na(a) and a > px ? a : na
    cb = not na(b) and b > px ? b : na
    na(ca) ? cb : na(cb) ? ca : math.min(ca, cb)

nearestBelow(float a, float b, float px) =>
    ca = not na(a) and a < px ? a : na
    cb = not na(b) and b < px ? b : na
    na(ca) ? cb : na(cb) ? ca : math.max(ca, cb)

bslPool = nearestAbove(dayHighPool, swingHighPool, close)
sslPool = nearestBelow(dayLowPool,  swingLowPool,  close)

// ── Sessions, guards ─────────────────────────────────────────────────────────
atr      = ta.atr(atrLen)
inLondon = useLondon and not na(time(timeframe.period, londonKz, tz))
inNy     = useNy     and not na(time(timeframe.period, nyKz,     tz))
inKz     = inLondon or inNy
kzOk     = not requireKz or inKz

var float dayStartEquity = na
if na(dayStartEquity) or timeframe.change("D")
    dayStartEquity := strategy.equity
dayPnl     = strategy.equity - dayStartEquity
lossLocked = useDailyLock and dayPnl <= -maxDailyLoss

// A session window shorter than the chart bar never contains a bar OPEN, and
// time(timeframe.period, session, tz) tests the open: with the default
// 15:55-16:00 on a 15-minute chart it was na on every bar, so nothing was ever
// flattened. The window is tested against the bar's whole span instead, and
// fires on the bar that covers any part of it, closing at that bar's close.
// The optional days suffix of the session string (":23456", 1 = Sunday) is
// kept and tested on the day of the bar's open.
sessParts(string s) =>
    p    = str.split(s, ":")
    hhmm = str.split(array.get(p, 0), "-")
    a    = str.tonumber(array.get(hhmm, 0))
    b    = str.tonumber(array.get(hhmm, 1))
    days = array.size(p) > 1 ? array.get(p, 1) : "1234567"
    [math.floor(a / 100) * 60 + a % 100, math.floor(b / 100) * 60 + b % 100, days]

barSpans(float startMin, float endMin) =>
    openMin  = hour(time, tz) * 60 + minute(time, tz)
    closeMin = hour(time_close, tz) * 60 + minute(time_close, tz)
    // A bar that closes inside the minute it opened (seconds charts) counts as one minute.
    closeMin := closeMin < openMin ? closeMin + 1440 : closeMin == openMin ? closeMin + 1 : closeMin
    endMin > startMin ? (openMin < endMin and closeMin > startMin) : (openMin < endMin or closeMin > startMin)

[flatStart, flatEnd, flatDays] = sessParts(flattenSess)
flatDayOk = str.contains(flatDays, str.tostring(dayofweek(time, tz)))
inFlatten = useFlatten and timeframe.isintraday and flatDayOk and barSpans(flatStart, flatEnd)
if inFlatten and strategy.position_size != 0
    strategy.close_all("flatten", alert_message = '{"strategy":"SWEEP-MSS-FVG","action":"flatten","symbol":"' + syminfo.ticker + '"}')

// ── Setup state machine ──────────────────────────────────────────────────────
ST_IDLE  = 0
ST_SWEPT = 1
ST_MSS   = 2
ST_ARMED = 3

type Setup
    int   state    = 0
    int   dir      = 0     // +1 long (SSL swept) · -1 short (BSL swept)
    float pool     = na    // the liquidity level that was taken
    float sweepExt = na    // extreme printed while taking it — the stop anchor
    float oppPool  = na    // liquidity on the other side — the target
    float gapTop   = na
    float gapBot   = na
    int   stateBar = 0

method reset(Setup s) =>
    s.state    := ST_IDLE
    s.dir      := 0
    s.pool     := na
    s.sweepExt := na
    s.oppPool  := na
    s.gapTop   := na
    s.gapBot   := na
    s.stateBar := 0

method entryPrice(Setup s) =>
    switch fvgEdge
        "Proximal" => s.dir > 0 ? s.gapTop : s.gapBot
        "Distal"   => s.dir > 0 ? s.gapBot : s.gapTop
        => (s.gapTop + s.gapBot) / 2

var Setup su = Setup.new()

// Bracket levels survive the setup that produced them: once filled, the trade
// is managed from these, not from the (already reset) setup object.
var float liveStop = na
var float liveTgt  = na
var string liveId  = na

// Each pool fires at most one setup: a sweep is an event, not a state.
var float usedBsl = na
var float usedSsl = na

// Funnel counters — how far setups get before they die.
var int nSweep = 0
var int nMss   = 0
var int nFvg   = 0
var int nExpire= 0

stateBefore = su.state
expired = su.state != ST_IDLE and bar_index - su.stateBar >
     (su.state == ST_SWEPT ? sweepMaxBars : su.state == ST_MSS ? fvgSearchBars : armedMaxBars)

// One setup, one trade. A trade that enters and exits between two bar closes
// (an entry on a bar's close stopped out inside the next bar, or a fill and
// an exit inside one bar) is never an open position at any close, so the
// armed setup would place the same order again. The trade count catches it:
// closedtrades + opentrades grows by one at every entry fill.
int tradesNow = strategy.closedtrades + strategy.opentrades
var int tradesSeen = 0
tradeHappened = tradesNow > tradesSeen
tradesSeen := tradesNow

if strategy.position_size != 0 or tradeHappened
    // A live trade owns the chart, and a setup that already had its trade is
    // done: the next setup starts from scratch.
    su.reset()
    if strategy.position_size == 0
        liveId   := na
        liveStop := na
        liveTgt  := na
else
    if expired
        strategy.cancel("ICT-L")
        strategy.cancel("ICT-S")
        liveId  := na
        liveStop := na
        liveTgt  := na
        nExpire += 1
        su.reset()
    else
        switch su.state

            ST_IDLE =>
                if kzOk and not lossLocked and not inFlatten
                    // A sweep of BSL trades through the pool and, in the strict
                    // mode, closes back below it. The signal stamps on that
                    // bar's close and never moves again.
                    throughBsl = not na(bslPool) and high > bslPool and (na(usedBsl) or bslPool != usedBsl)
                    throughSsl = not na(sslPool) and low  < sslPool and (na(usedSsl) or sslPool != usedSsl)
                    strict     = sweepConfirm == "Close back inside"
                    sweptBsl   = throughBsl and (not strict or close < bslPool)
                    sweptSsl   = throughSsl and (not strict or close > sslPool)
                    // If both sides are taken on one bar the bar is noise, not
                    // a sweep — skip it rather than pick a side arbitrarily.
                    if sweptBsl != sweptSsl
                        su.dir      := sweptBsl ? -1 : 1
                        su.pool     := sweptBsl ? bslPool : sslPool
                        su.sweepExt := sweptBsl ? high : low
                        su.oppPool  := sweptBsl ? sslPool : bslPool
                        su.state    := ST_SWEPT
                        su.stateBar := bar_index
                        if sweptBsl
                            usedBsl := bslPool
                        else
                            usedSsl := sslPool
                        nSweep += 1

            ST_SWEPT =>
                // The extreme can still extend while price hunts stops.
                su.sweepExt := su.dir < 0 ? math.max(su.sweepExt, high) : math.min(su.sweepExt, low)
                // MSS = a displacement close through the opposing confirmed
                // swing, in the direction away from the swept pool.
                body    = math.abs(close - open)
                disp    = body >= atr * dispMult
                mssRef  = su.dir < 0 ? swingLow : swingHigh
                broke   = not na(mssRef) and (su.dir < 0 ? close < mssRef : close > mssRef)
                if disp and broke
                    su.state    := ST_MSS
                    su.stateBar := bar_index
                    nMss += 1

            ST_MSS =>
                // FVG = the 3-bar imbalance left by the displacement leg,
                // known in full at the close of the third bar.
                gapUp   = su.dir > 0 and high[2] < low
                gapDn   = su.dir < 0 and low[2]  > high
                gTop    = su.dir > 0 ? low  : low[2]
                gBot    = su.dir > 0 ? high[2] : high
                thick   = (gTop - gBot) >= minGapTicks * syminfo.mintick
                // The gap has to sit inside the leg that came off the sweep,
                // otherwise it belongs to some earlier move.
                inLeg   = su.dir > 0 ? gBot >= su.sweepExt : gTop <= su.sweepExt
                if (gapUp or gapDn) and thick and inLeg
                    su.gapTop   := gTop
                    su.gapBot   := gBot
                    su.state    := ST_ARMED
                    su.stateBar := bar_index
                    nFvg += 1

            ST_ARMED =>
                isLong  = su.dir > 0
                px      = su.entryPrice()
                stopPx  = isLong ? su.sweepExt - atr * stopBufferAtr : su.sweepExt + atr * stopBufferAtr
                riskPx  = math.abs(px - stopPx)
                poolOk  = not na(su.oppPool) and (isLong ? su.oppPool > px : su.oppPool < px)
                byPool  = targetMode == "Opposing liquidity" and poolOk
                tgtPx   = byPool ? su.oppPool : (isLong ? px + riskPx * rMult : px - riskPx * rMult)
                id      = isLong ? "ICT-L" : "ICT-S"
                // JSON payload for the webhook → broker bridge. Dedupe,
                // position sync and bracket placement happen server-side;
                // Pine only signals.
                msg = '{"strategy":"SWEEP-MSS-FVG","id":"' + str.tostring(bar_index) +
                     '","side":"' + (isLong ? "buy" : "sell") +
                     '","symbol":"' + syminfo.ticker +
                     '","entry":' + str.tostring(px) +
                     ',"stop":' + str.tostring(stopPx) +
                     ',"target":' + str.tostring(tgtPx) + '}'
                if riskPx > 0
                    liveStop := stopPx
                    liveTgt  := tgtPx
                    liveId   := id
                    strategy.entry(id, isLong ? strategy.long : strategy.short, limit = px, alert_message = msg)

// The bracket is (re)issued on every bar the order or the position is alive.
// Placing it once inside the state machine would leave the trade unprotected
// the moment the setup object resets on fill.
if not na(liveId) and (strategy.position_size != 0 or su.state == ST_ARMED)
    strategy.exit("brk", liveId, stop = liveStop, limit = liveTgt,
         alert_message = '{"strategy":"SWEEP-MSS-FVG","action":"flatten","symbol":"' + syminfo.ticker + '"}')

// Entry fills, one per trade (no pyramiding), read from the trade lists for
// the reason given above the state machine.
nFill = tradesNow

// Margin one contract needs at the header's 5%. Pine cannot read margin_long
// back, so keep MARGIN_PCT equal to it (if Properties change the margin, this
// row is off). Room = equity minus margin, the available funds once one
// contract is open: when they run out, a margin call liquidates the position.
// A room under one ATR means an adverse move of about one ATR does it.
MARGIN_PCT = 5.0
marginPerContract = strategy.convert_to_account(syminfo.pointvalue * close) * MARGIN_PCT / 100
roomBeforeCall    = strategy.equity - marginPerContract
roomLow           = roomBeforeCall < strategy.convert_to_account(atr * syminfo.pointvalue)

// ── Visuals ──────────────────────────────────────────────────────────────────
plot(bslPool, "BSL pool", style = plot.style_linebr, color = color.new(color.red,  40), linewidth = 1)
plot(sslPool, "SSL pool", style = plot.style_linebr, color = color.new(color.teal, 40), linewidth = 1)
bgcolor(inKz ? color.new(color.gray, 92) : na, title = "Kill zone")
bgcolor(lossLocked ? color.new(color.red, 85) : na, title = "Daily loss lock")

showGap = su.state == ST_ARMED
gT = plot(showGap ? su.gapTop : na, "FVG top", style = plot.style_linebr, color = color.new(color.orange, 30))
gB = plot(showGap ? su.gapBot : na, "FVG bottom", style = plot.style_linebr, color = color.new(color.orange, 30))
fill(gT, gB, color = color.new(color.orange, 85), title = "Fair value gap")
plot(su.state != ST_IDLE ? su.sweepExt : na, "Sweep extreme", style = plot.style_linebr, color = color.fuchsia, linewidth = 2)

if su.state != stateBefore and su.state != ST_IDLE
    txt = su.state == ST_SWEPT ? "Sweep" : su.state == ST_MSS ? "MSS" : "FVG"
    label.new(bar_index, su.dir > 0 ? low : high, txt,
         style = su.dir > 0 ? label.style_label_up : label.style_label_down,
         color = color.new(color.gray, 30), textcolor = color.white, size = size.small)

var table hud = table.new(position.middle_left, 1, 5, border_width = 1)
if barstate.islast
    stName = su.state == ST_IDLE ? "Idle" : su.state == ST_SWEPT ? "Swept" : su.state == ST_MSS ? "MSS" : "Armed"
    table.cell(hud, 0, 0, (leakMode ? "⚠ LOOK-AHEAD DEMO" : "Honest build"),
         text_color = leakMode ? color.black : color.white,
         bgcolor = leakMode ? color.yellow : color.new(color.gray, 20), text_size = size.small)
    table.cell(hud, 0, 1, "Setup: " + stName + (su.state != ST_IDLE ? (su.dir > 0 ? " ▲" : " ▼") : ""),
         text_color = color.white, bgcolor = color.new(color.gray, 20), text_size = size.small)
    table.cell(hud, 0, 2, "Sweep " + str.tostring(nSweep) + " → MSS " + str.tostring(nMss) +
         " → FVG " + str.tostring(nFvg) + " → Fill " + str.tostring(nFill),
         text_color = color.yellow, bgcolor = color.new(color.gray, 20), text_size = size.small)
    table.cell(hud, 0, 3, "Unfilled/expired " + str.tostring(nExpire) + " · Day P&L " + str.tostring(math.round(dayPnl)),
         text_color = lossLocked ? color.red : color.orange, bgcolor = color.new(color.gray, 20), text_size = size.small)
    roomTxt = "Margin/contract at 5% " + str.tostring(math.round(marginPerContract)) + " · Equity " + str.tostring(math.round(strategy.equity)) +
         " · Room " + str.tostring(math.round(roomBeforeCall))
    table.cell(hud, 0, 4, roomLow ? "⚠ " + roomTxt + (roomBeforeCall < 0 ? " (margin above equity)" : " (< 1 ATR)") + ": use MNQ/MES or raise the capital" : roomTxt,
         text_color = roomLow ? color.black : color.white,
         bgcolor = roomLow ? color.yellow : color.new(color.gray, 20), text_size = size.small)

Overview

Price sweeps a liquidity pool, either the previous day high or low or confirmed swings. A displacement close then shifts market structure, and a limit order is placed at the fair value gap left by that move. The stop sits beyond the sweep extreme with an ATR buffer, and the target is the opposing pool or an R multiple. Kill zones, a daily loss lock and a timed flatten are optional. A demo mode deliberately leaks current-day data to compare look-ahead effects.

Details

Published by

guillemustafa-ux on GitHub

Draws

On the price chart

Markets

Indices

Timeframes

M1-M5, M15-H1

Risk Notes

  • Reads higher-timeframe data with lookahead on, so the history can show signals that were not there in real time

Topics

backtestingfuturesictpine-scriptsmart-money-conceptstradingview

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Previous day high / lowbooltrueusePrevDay
Confirmed swing highs / lowsbooltrueuseSwings
Pivot left barsint5pivL
Pivot right barsint5pivR
Only sweep equal highs / equal lowsboolfalserequireEqual
Equal-high/low tolerance (ticks)int8eqTicks
A sweep is confirmed bystringClose back insidesweepConfirm
Bars allowed from sweep to MSSint12sweepMaxBars
Displacement: body ≥ ATR ×float1.0dispMult
ATR lengthint14atrLen
Bars after MSS to find the FVGint6fvgSearchBars
Enter at which gap edgestringProximalfvgEdge
Show all 28 settings
SettingTypeDefaultVariable
Ignore gaps thinner than (ticks)int4minGapTicks
Cancel the order if unfilled after (bars)int20armedMaxBars
Stop buffer beyond sweep extreme (ATR ×)float0.25stopBufferAtr
TargetstringOpposing liquiditytargetMode
R multiple (fallback when no pool)float2.0rMult
Only take setups inside a kill zonebooltruerequireKz
Session timezonestringAmerica/New_Yorktz
London kill zonebooltrueuseLondon
London windowsession0200-0500londonKz
New York kill zonebooltrueuseNy
New York windowsession0830-1100nyKz
Stop trading after a daily lossbooltrueuseDailyLock
Daily loss limit (account currency)float600maxDailyLoss
Flatten at a fixed timebooltrueuseFlatten
Flatten windowsession1555-1600flattenSess
DEMO — leak the CURRENT day's high/low into historyboolfalseleakMode
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

Daily Bias + FVG Strategy

by TradersPost
228 stars

This overlay strategy plots previous-day high and low, the daily open, and fair value gap zones on the price chart. It takes entries on a selectable timeframe when the FVG requirement and an optional session window allow them, then uses an ATR or fixed pip sto

Strategy v6 SMC / ICT / price actionSupport & resistance Repaints
Updated 3 months ago · None stated GitHub repository of Daily Bias + FVG Strategy
105 stars

Gold Scalping BOS & CHoCH is an overlay strategy designed for detecting market structure shifts. It calculates rolling swing highs and lows to identify Break of Structure (BOS) and Change of Character (CHoCH) events. Long signals trigger when bullish BOS and C

Strategy v6 SMC / ICT / price actionSupport & resistance
Updated 1 year ago · None stated GitHub repository of Gold Scalping BOS & CHoCH
57 stars

This strategy identifies trend reversals through market structure changes (CHoCH) filtered by MACD momentum. It initiates long positions on bullish structure breaks when MACD is positive and above its signal line, and short positions on bearish breaks when MAC

Strategy v6 SMC / ICT / price actionOscillators & momentum Repaints
Updated 1 year ago · Apache-2.0 GitHub repository of Market Structure MACD 4H + Trailing
43 stars

Donald - AI Futures is a price-chart strategy that estimates inner and outer high-low zones and a smoothed close with rational quadratic kernel regression. It builds bullish and bearish momentum signals, optionally compares volume with a volume-weighted moving

Strategy v5 Oscillators & momentumSMC / ICT / price action Repaints
Updated 2 years ago · None stated GitHub repository of Donald - AI Futures

More SMC / ICT scripts

Related on ForexR

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers