0% found this document useful (0 votes)
21 views10 pages

Script Popv3

Uploaded by

Aj Deshmukh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views10 pages

Script Popv3

Uploaded by

Aj Deshmukh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

//@version=5

indicator("SMC+ICT+PA Suite (v1) — Real-time BOS/CHOCH, OBs, FVG, MTF OB, Liquidity
Sweeps, Signals", overlay=true, max_bars_back=5000)

// -----------------------------
// === USER SETTINGS
// -----------------------------
showMarketStructure = [Link](true, "Show Market Structure (HH/HL/LH/LL &
BOS/CHOCH)")
ms_lookback = [Link](5, "MS swing lookback (bars)", minval=2)

showOrderBlocks = [Link](true, "Show Order Blocks


(Standard/Mitigation/Breaker/Propulsion)")
ob_lookahead = [Link](12, "OB confirmation lookahead (bars)", minval=3)
ob_move_factor = [Link](1.5, "OB confirmation move (x ATR)", minval=0.5,
step=0.1)

showFVG = [Link](true, "Show Fair Value Gaps (FVG)")


fvg_lookback = [Link](50, "FVG lookback (bars)", minval=10)

showMTF_OB = [Link](true, "Show Multi-Timeframe OB (4H and 1D)")


mtf1 = [Link]("240", "MTF 1 (e.g., 240)")
mtf2 = [Link]("D", "MTF 2 (e.g., D)")

showLiquidity = [Link](true, "Show Liquidity Sweeps & Equal High/Low


Detection")
ls_lookback = [Link](50, "Liquidity lookback (bars)", minval=5)

showSignals = [Link](true, "Show Buy/Sell Signals")

atr_len = [Link](14, "ATR length")


atr_mult = [Link](1.5, "ATR multiplier for sweep detection")
signal_strength_min = [Link](2, "Min subsystems confirming signal", minval=1,
maxval=6)

// Drawing limits (memory optimization)


max_boxes = [Link](60, "Max drawn zones/boxes", minval=10, maxval=200)
max_lines = [Link](80, "Max drawn lines", minval=10, maxval=300)

// -----------------------------
// === UTILITIES
// -----------------------------
var box[] ob_boxes = array.new_box()
var line[] struct_lines = array.new_line()
var label[] sig_labels = array.new_label()

// prune function to limit drawings


f_prune_boxes(_max) =>
while [Link](ob_boxes) > _max
b = [Link](ob_boxes)
[Link](b)

f_prune_lines(_max) =>
while [Link](struct_lines) > _max
l = [Link](struct_lines)
[Link](l)

f_prune_labels(_max) =>
while [Link](sig_labels) > _max
la = [Link](sig_labels)
[Link](la)

// ATR
atr = [Link](atr_len)

// -----------------------------
// === MARKET STRUCTURE (MS) + BOS / CHoCH
// -----------------------------
// We'll define swings by highest high / lowest low in lookback window.
// Then detect structure and breaks.

var float lastSwingHigh = na


var int lastSwingHighBar = na
var float lastSwingLow = na
var int lastSwingLowBar = na

isSwingHigh(src_high, lb) =>


hh = [Link](src_high, lb, lb)
not na(hh)

isSwingLow(src_low, lb) =>


ll = [Link](src_low, lb, lb)
not na(ll)

var string ms_state = "undefined" // "up", "down", "side"


var int lastBOSBar = na
var string lastBOS = "" // "BOS_UP" or "BOS_DOWN"
var string lastCHoCH = "" // "CHoCH_UP" or "CHoCH_DOWN"

// Find swings
ph = [Link](high, ms_lookback, ms_lookback)
pl = [Link](low, ms_lookback, ms_lookback)

if not na(ph)
lastSwingHigh := ph
lastSwingHighBar := bar_index - ms_lookback
if not na(pl)
lastSwingLow := pl
lastSwingLowBar := bar_index - ms_lookback

// Determine HH/HL/LH/LL using last two valid swings


var float s1_h = na
var float s1_l = na
var int s1_bar = na
var float s2_h = na
var float s2_l = na
var int s2_bar = na
// Update swings arrays using pivot detection
if not na(ph) or not na(pl)
// store the most recent two structural points (high or low)
// We'll use a simple approach: when a new pivot is found, shift previous
s2_h := s1_h
s2_l := s1_l
s2_bar := s1_bar
if not na(ph)
s1_h := ph
s1_l := na
s1_bar := bar_index - ms_lookback
if not na(pl)
s1_l := pl
s1_h := na
s1_bar := bar_index - ms_lookback

// Determine structure (simple inference)


ms_type = "?"
if not na(s1_h) and not na(s2_h)
// two highs => compare
ms_type := s1_h > s2_h ? "HH" : "LH"
if not na(s1_l) and not na(s2_l)
ms_type := s1_l > s2_l ? "LL" : "HL"

// Detect Break of Structure (BOS)


// Price break above previous significant high => BOS_UP.
// Price break below previous significant low => BOS_DOWN.

recentHigh = [Link](high, ms_lookback*2)


recentLow = [Link](low, ms_lookback*2)

bos_up = false
bos_down = false
choch_up = false
choch_down = false

// BOS up: price breaks above last swing high (s2_h)


if not na(lastSwingHigh) and high > lastSwingHigh
bos_up := true
lastBOSBar := bar_index
lastBOS := "BOS_UP"
// If prior structure was down, then CHoCH
if ms_state == "down"
choch_up := true
lastCHoCH := "CHoCH_UP"
ms_state := "up"

if not na(lastSwingLow) and low < lastSwingLow


bos_down := true
lastBOSBar := bar_index
lastBOS := "BOS_DOWN"
if ms_state == "up"
choch_down := true
lastCHoCH := "CHoCH_DOWN"
ms_state := "down"

// Draw Market Structure markers


if showMarketStructure
// mark last known swing highs/lows
if not na(lastSwingHigh)
l1 = [Link](x1=lastSwingHighBar, y1=lastSwingHigh, x2=bar_index,
y2=lastSwingHigh, color=[Link], width=1, extend=[Link])
[Link](struct_lines, l1)
if not na(lastSwingLow)
l2 = [Link](x1=lastSwingLowBar, y1=lastSwingLow, x2=bar_index,
y2=lastSwingLow, color=[Link], width=1, extend=[Link])
[Link](struct_lines, l2)
// prune
f_prune_lines(max_lines)
// -----------------------------
// === FAIR VALUE GAPS (FVG)
// -----------------------------
// Classic 3-candle FVG: If candle A's high/low leaves an unfilled area between A
and C
// We'll search backwards for such gaps and draw rectangles.

type fvg_zone
var fvg_zone[] fvg_list = [Link]<fvg_zone>()

f_create_fvg(top, bottom, startBar, endBar, dir) =>


[top, bottom, startBar, endBar, dir]

fvg_detect() =>
// scan last fvg_lookback bars for 3-bar imbalances
for i = 2 to fvg_lookback by 1
// indices: i bars ago
A_hi = high[i]
A_lo = low[i]
B_hi = high[i-1]
B_lo = low[i-1]
C_hi = high[i-2]
C_lo = low[i-2]
// Bullish FVG: A_low > C_high -> gap between C_high and A_low
if A_lo > C_hi
top = A_lo
bottom = C_hi
// store zone anchored at bars
[Link](fvg_list, f_create_fvg(top, bottom, bar_index - i, bar_index
- i + 2, "bull"))
// Bearish FVG: A_high < C_low -> gap between A_high and C_low
if A_hi < C_lo
top = C_lo
bottom = A_hi
[Link](fvg_list, f_create_fvg(top, bottom, bar_index - i, bar_index
- i + 2, "bear"))

fvg_detect()

// draw FVG (only recent unique ones)


drawnFVG = 0
for idx = 0 to [Link](fvg_list)-1
if drawnFVG >= 30
break
z = [Link](fvg_list, idx)
top = z[0]
bottom = z[1]
sb = z[2]
eb = z[3]
dir = z[4]
col = dir == "bull" ? [Link]([Link], 80) : [Link]([Link], 80)
b = [Link](left=sb, top=top, right=eb, bottom=bottom, bgcolor=col,
border_color=[Link](col,50))
[Link](ob_boxes, b)
drawnFVG += 1

f_prune_boxes(max_boxes)

// -----------------------------
// === ORDER BLOCKS (OB) — Core detection
// -----------------------------
// We'll detect "Mother" OBs as the last bearish/bullish candle before a swift move
of > ob_move_factor * ATR within ob_lookahead bars.
// This is a heuristic and meant to run live (confirmed once move happens).

isBullishCandle(i) => close[i] > open[i]


isBearishCandle(i) => close[i] < open[i]

// function to check if within next N bars price moves by X*ATR from this candle
close
f_confirm_move_from(idx, dirUp, lookaheadBars, factor) =>
found = false
for k = 1 to lookaheadBars
if dirUp
if high[idx - k] - close[idx] >= factor * atr
found := true
else
if close[idx] - low[idx - k] >= factor * atr
found := true
found

// Identify OBs historically (confirmed)


var array<tuple> ob_list = [Link]<tuple>() // tuple:
[top,bottom,bar,dir,confirmedBar]
type tuple
f_create_ob(top, bottom, baridx, dir, confBar) =>
[top, bottom, baridx, dir, confBar]

for i = 1 to ob_lookahead by 1
// examine candle i bars ago as potential OB origin
// caution: ensure enough lookahead exists (we're scanning historical bars)
if bar_index - i - ob_lookahead < 0
// not enough history further back
break
// We'll scan the last ob_lookahead*3 bars for potential confirmed OBs
scan_range = [Link](200, bar_index)
for idx = 2 to scan_range by 1
// idx = bars ago
// check if candle at idx is bullish or bearish and followed by a move
bullish = isBullishCandle(idx)
bearish = isBearishCandle(idx)
if bullish and f_confirm_move_from(idx, true, ob_lookahead, ob_move_factor)
// bullish OB: zone = candle low -> candle high (or extend into wick)
top = high[idx]
bottom = low[idx]
confBar = bar_index - idx + 1
[Link](ob_list, f_create_ob(top, bottom, bar_index - idx, "bull",
confBar))
if bearish and f_confirm_move_from(idx, false, ob_lookahead, ob_move_factor)
top = high[idx]
bottom = low[idx]
confBar = bar_index - idx + 1
[Link](ob_list, f_create_ob(top, bottom, bar_index - idx, "bear",
confBar))

// Reduce duplicates by simple uniqueness (top/bottom tolerance)


f_ob_unique(_list) =>
out = [Link]<tuple>()
tol = atr * 0.2
for i = 0 to [Link](_list)-1
t = [Link](_list, i)
ok = true
top = t[0]
bottom = t[1]
for j = 0 to [Link](out)-1
o = [Link](out, j)
if [Link](o[0] - top) < tol and [Link](o[1] - bottom) < tol
ok := false
if ok
[Link](out, t)
out

uniq_obs = f_ob_unique(ob_list)

// Draw OBs (last N)


drawn_ob = 0
for i = [Link](uniq_obs)-1 to 0 by -1
if drawn_ob >= max_boxes
break
ob = [Link](uniq_obs, i)
top = ob[0]
bottom = ob[1]
dir = ob[3]
col = dir == "bull" ? [Link]([Link], 85) : [Link]([Link],85)
b = [Link](left=ob[2], top=top, right=bar_index, bottom=bottom, bgcolor=col,
border_color=[Link](col,60))
[Link](ob_boxes, b)
drawn_ob += 1

f_prune_boxes(max_boxes)

// -----------------------------
// === Multi-Timeframe OB (MTF OB) using pivot zones on HTF
// -----------------------------
mtf_zone_draw(_tf, _color) =>
// compute pivot high/low on higher timeframe and draw small boxes as zones
htf_high = [Link]([Link], _tf, [Link](high, 3, 3))
htf_high_bar = [Link]([Link], _tf, bar_index - 3)
htf_low = [Link]([Link], _tf, [Link](low, 3, 3))
// [Link] returns value aligned to current bar; we will simply draw
horizontal lines for recent pivot values
if not na(htf_high)
line_new = [Link](x1=bar_index-1, y1=htf_high, x2=bar_index, y2=htf_high,
color=_color, width=2, extend=[Link])
[Link](struct_lines, line_new)
if not na(htf_low)
line_new2 = [Link](x1=bar_index-1, y1=htf_low, x2=bar_index, y2=htf_low,
color=_color, width=2, extend=[Link])
[Link](struct_lines, line_new2)

if showMTF_OB
// draw for mtf1 and mtf2
mtf_zone_draw(mtf1, [Link]([Link], 60))
mtf_zone_draw(mtf2, [Link]([Link], 60))
f_prune_lines(max_lines)

// -----------------------------
// === LIQUIDITY SWEEPS & EQUAL HIGH/LOW Detection
// -----------------------------
equalHighs = false
equalLows = false
liquidity_sweep_buy = false
liquidity_sweep_sell = false

// detect equal highs/lows in lookback window


eh_val = na
el_val = na
for i = 1 to ls_lookback
if high[i] == high[0]
equalHighs := true
eh_val := high[i]
if low[i] == low[0]
equalLows := true
el_val := low[i]

// Liquidity sweep: price makes a wick beyond recent swing high/low and then
reverses significantly (>= atr_mult*ATR)
recentSwingHigh = [Link](high, ls_lookback)
recentSwingLow = [Link](low, ls_lookback)

if showLiquidity
// buy-side sweep (stop hunt below recent low then reclaim)
if low < recentSwingLow and close > recentSwingLow + (atr_mult * atr * 0.2)
liquidity_sweep_buy := true
if high > recentSwingHigh and close < recentSwingHigh - (atr_mult * atr * 0.2)
liquidity_sweep_sell := true

// draw liquidity markers


if showLiquidity and liquidity_sweep_buy
l = [Link](bar_index, low, "Buy Sweep", style=label.style_labelup,
color=[Link], textcolor=[Link], yloc=[Link])
[Link](sig_labels, l)
if showLiquidity and liquidity_sweep_sell
l2 = [Link](bar_index, high, "Sell Sweep", style=label.style_labeldown,
color=[Link], textcolor=[Link], yloc=[Link])
[Link](sig_labels, l2)
f_prune_labels(max_lines)

// -----------------------------
// === SWING POINTS, EQUAL HIGH/LOW detection (visual)
// -----------------------------
plotshape(showMarketStructure and not na(ph), title="Pivot High",
location=[Link], color=[Link], style=[Link],
size=[Link], offset=-ms_lookback)
plotshape(showMarketStructure and not na(pl), title="Pivot Low",
location=[Link], color=[Link], style=[Link],
size=[Link], offset=-ms_lookback)

if equalHighs
plotshape(showLiquidity and equalHighs, title="Equal High",
location=[Link], color=[Link], style=[Link], size=[Link])
if equalLows
plotshape(showLiquidity and equalLows, title="Equal Low",
location=[Link], color=[Link], style=[Link], size=[Link])

// -----------------------------
// === BUY / SELL SIGNAL (High-level composite)
// -----------------------------
// Combine subsystems: (1) BOS/CHoCH, (2) OB proximity (price inside/near OB), (3)
FVG presence near price, (4) Liquidity sweep, (5) MTF OB alignment.
// We score each subsystem and issue signal when score >= threshold.

score = 0
// 1) Market structure: bullish bias if lastBOS == BOS_UP or ms_state == "up"
if lastBOS == "BOS_UP" or ms_state == "up"
score += 1
else
score -= 0

// 2) Price inside or near a bullish OB


nearOB_range = atr * 1.5
nearBullOB = false
nearBearOB = false
for i = 0 to [Link](uniq_obs)-1
ob = [Link](uniq_obs, i)
if ob[3] == "bull"
if low <= ob[0] + nearOB_range and high >= ob[1] - nearOB_range and close
>= ob[1] - nearOB_range
nearBullOB := true
if ob[3] == "bear"
if high >= ob[1] - nearOB_range and low <= ob[0] + nearOB_range and close
<= ob[0] + nearOB_range
nearBearOB := true

if nearBullOB
score += 1
if nearBearOB
score -= 1

// 3) FVG presence near price


nearFVG = false
for i = 0 to [Link](fvg_list)-1
z = [Link](fvg_list, i)
top = z[0]
bottom = z[1]
if close >= bottom - atr and close <= top + atr
nearFVG := true

if nearFVG
score += 1

// 4) Liquidity sweep detection supports direction


if liquidity_sweep_buy
score += 1
if liquidity_sweep_sell
score -= 1

// 5) MTF alignment: check if HTF pivot implies same direction as local OB / MS


mtf_bull = false
mtf_bear = false
// crude HTF alignment: if HTF pivot low exists recently => bullish bias
htf1_pivotlow = [Link]([Link], mtf1, [Link](low, 3, 3))
htf1_pivothigh = [Link]([Link], mtf1, [Link](high, 3, 3))
if not na(htf1_pivotlow)
mtf_bull := true
if not na(htf1_pivothigh)
mtf_bear := true

if mtf_bull
score += 1
if mtf_bear
score -= 1

// Final signal
buySignal = (score >= signal_strength_min)
sellSignal = (score <= -signal_strength_min)

// Plot signals
plotshape(showSignals and buySignal, title="Buy Signal",
location=[Link], color=[Link], style=[Link], text="BUY",
textcolor=[Link], size=[Link], offset=0)
plotshape(showSignals and sellSignal, title="Sell Signal",
location=[Link], color=[Link], style=[Link], text="SELL",
textcolor=[Link], size=[Link], offset=0)

// Add label with score


if showSignals and (buySignal or sellSignal)
l = [Link](bar_index, close, text="Score: " + [Link](score),
style=label.style_label_center, color=buySignal ? [Link] : [Link],
textcolor=[Link], yloc=[Link])
[Link](sig_labels, l)
f_prune_labels(max_lines)

// -----------------------------
// === ATR Range, Support/Resistance & Retests (simple pivot SR)
// -----------------------------
res_high = [Link](high, 50)
res_low = [Link](low, 50)
plot(res_high, title="Resistance (50)", color=[Link]([Link],80), linewidth=1)
plot(res_low, title="Support (50)", color=[Link]([Link],80), linewidth=1)

// ATR bands for precision


plot(close + atr * atr_mult, title="ATR Upper", color=[Link]([Link], 90),
linewidth=1, style=plot.style_line)
plot(close - atr * atr_mult, title="ATR Lower", color=[Link]([Link], 90),
linewidth=1, style=plot.style_line)

// -----------------------------
// === FINAL RECOMMENDATION BOX (on-chart label)
// -----------------------------
if [Link]
// Compose concise summary near last bar
txt = "SMC+ICT Summary\n"
txt += "MS: " + ms_state + " | Last BOS: " + lastBOS + "\n"
txt += "Score: " + [Link](score) + " | Buy: " + (buySignal ? "YES" :
"NO") + " Sell: " + (sellSignal ? "YES" : "NO") + "\n"
txt += "Near Bull OB: " + (nearBullOB ? "Y" : "N") + " Near FVG: " +
(nearFVG ? "Y" : "N") + "\n"
// create persistent label
var label summaryLabel = na
if not na(summaryLabel)
[Link](summaryLabel)
summaryLabel := [Link](bar_index, high, txt, xloc=xloc.bar_index,
yloc=[Link], style=label.style_label_left, color=[Link]([Link], 70),
textcolor=[Link], size=[Link])

// -----------------------------
// === NOTES, LIMITATIONS & USAGE
// -----------------------------
// This script is a best-effort, single-file Pine v5 implementation that
approximates many SMC/ICT constructs.
// Limitations / important notes:
// - Order Block detection is heuristic: it finds candles followed by a fast move
(>= ob_move_factor * ATR).
// - FVG detection uses a simple 3-candle imbalance scan; user may want more
advanced logic.
// - MTF OB is approximated by HTF pivots drawn as lines; building exact HTF OB
boxes requires advanced syncing.
// - Liquidity sweeps are detected as wick exhaustion beyond recent swing and quick
reclaim; this can be tuned.
// - This script tries to balance performance (scanning limited lookbacks, pruning
drawings). Increase lookbacks at cost of memory.
// - Treat signals as trade ideas; always combine with your risk management and
manual review.
// - For production-grade institutional orderflow, pair this with tape/DOM or
broker-level data.
//
// Feel free to request enhancements: e.g., more accurate OB types
(Breaker/Mitigation/Propulsion), FVG filling logic, integrated volume-profile,
footprint/volume-delta integration, configurable drawing styles, alerts, or
fewer/more aggressive heuristics.

You might also like