1. Mô tả chỉ báo — Ideal SMC – Clean Pro
Bộ công cụ SMC “tất cả trong một”: Order Block, FVG, Liquidity Pools, BOS, HTF, Trend Filter & Setups. Gọn, sạch, rõ ràng.
1.1 Concept của chỉ báo
Chỉ báo dựa trên tư duy Smart Money Concepts (SMC): giá di chuyển vì mất cân bằng cung–cầu và hành trình đi tìm thanh khoản. Từ đó, ta tập trung vào 4 “cột mốc” quan trọng:
- Order Block (OB): vùng đặt lệnh lớn của tổ chức; giá hay quay lại retest trước khi đi tiếp.
- Fair Value Gap (FVG): khoảng trống giá (3 nến) thể hiện mất cân bằng; giá thường lấp dần.
- Liquidity Pools (EQH/EQL): cụm đỉnh đáy bằng nhau (Equal Highs/Lows) gom thanh khoản.
- Break of Structure (BOS): phá cấu trúc tăng/giảm, xác nhận thay đổi xu hướng ngắn hạn.
Chỉ báo gom các khái niệm trên thành vùng giao dịch rõ ràng và tín hiệu setup, có Trend Filter, HTF (Higher Timeframe), TTL, Merge… để bạn nhìn biểu đồ sạch, dễ hành động, không rối.
1.2 Chức năng của chỉ báo
- Tự nhận diện Order Block (tăng/giảm), lọc theo ATR, gộp vùng trùng (Merge), đánh dấu khi đã chạm (Mitigated), giới hạn vòng đời (TTL), và kiểm soát kéo dài đến nến hiện tại (extendToLive) hay dừng sau boxWidthBars.
- Tự phát hiện FVG (bull/bear), có ngưỡng tối thiểu theo ATR, theo dõi lấp gap (mitigation) & TTL tương tự OB.
- Liquidity Pools (EQH/EQL):
- Dùng dung sai theo ATR (useATRTol, tolATRmult) hoặc theo ticks (tolTicks).
- BOS hiển thị trực tiếp bằng mũi tên (Up/Down) để xác nhận thay đổi cấu trúc.
- Multi-Timeframe (useHTF, htfTf): dùng dữ liệu khung cao (ví dụ H4/Daily) để vẽ vùng chắc hơn.
- Trend Filter: chỉ hiển thị vùng theo hướng xu hướng hiện tại (useTrendFilter, obInTrendOnly, fvgInTrendOnly).
- Trade Setups “OB Retest + Trend”:
- Tự vẽ Entry / SL / TP, cho phép chỉ báo xuất hiện khi nến đóng (onlyConfirmed), đặt mục tiêu theo tỉ lệ R:R (rrTarget).
- Tuỳ chọn hiển thị icon, nhãn, đường (showIcons/showLabels/showLines).
- Tối ưu hiển thị: giới hạn số vùng đang hoạt động (maxOBKeep, maxFVGKeep), kéo dài vùng chỉ khi chưa bị chạm (extendOnlyUnmitigated).
1.3 Cách dùng chỉ báo
- Xác định bias: xem BOS + vùng HTF để biết ưu tiên mua hay bán.
- Kiên nhẫn: chờ giá quay về OB/FVG chưa bị chạm (unmitigated) theo đúng hướng Trend Filter.
- Vào lệnh: dùng tín hiệu “OB Retest + Trend” của chỉ báo. Entry thường ở giữa vùng; SL ở biên còn lại.
- Quản trị rủi ro: TP theo rrTarget (mặc định 2R), có thể dời SL theo cấu trúc.
- Tùy chỉnh phong cách:
Scalpgiảm pivotLen, boxWidthBars nhỏ, ttl ngắn, yêu cầu minOBatr/minFVGatr thấp. Intradaycân bằng giữa độ nhạy và độ sạch, kết hợp useHTF = H1/H4. Swingtăng pivotLen, dùng HTF D/W, ttl dài hơn, vùng rộng hơn.
1.4 Cách hoạt động của chỉ báo
Đầu vào & vai trò
- Core: pivotLen (độ dài xoay đỉnh/đáy), bodyLookback (soát thân nến để tìm OB), atrLen (ATR), minOBatr, minFVGatr (ngưỡng tối thiểu).
- Hiển thị: ttlOBBars, ttlFVGBars, maxOBKeep, maxFVGKeep, extendOnlyUnmitigated, extendToLive, boxWidthBars.
- Liquidity Pools: showLP, useATRTol, tolATRmult, tolTicks.
- Bộ lọc: useTrendFilter, obInTrendOnly, fvgInTrendOnly.
- HTF: useHTF, htfTf (ví dụ: “240”=H4).
- Setups: showSetups, showIcons, showLabels, showLines, onlyConfirmed, rrTarget.
Các khối logic chính
- Phát hiện Pivot & BOS: dùng ta.pivothigh / ta.pivotlow trên srcH/srcL (chọn HTF nếu bật), sau đó đánh dấu bosUp/bosDown khi phá đỉnh/đáy gần nhất.
- Order Block:
- Tìm thân nến giảm/gia tăng gần nhất (hàm fLastBearBody*/fLastBullBody*) làm biên OB; lọc theo ATR & xu hướng (allowBull/allowBear).
- Tạo box, lưu mảng (obBox, obType, obMit, obBirth); giới hạn số lượng và TTL; Merge vùng trùng (fMergeOBs).
- Đánh dấu “đã chạm” (mitigated) khi high/low giao cắt biên vùng; làm mờ màu.
- FVG:
- Điều kiện 3 nến: bullFVG khi srcL > srcH[2]; bearFVG khi srcH < srcL[2]; lọc theo ATR & trend.
- Tạo box, theo dõi mitigation, TTL và điều khiển kéo dài cạnh phải như OB.
- Liquidity Pools: phát hiện EQH/EQL bằng cách so sánh các pivot lân cận trong dung sai tol (ATR hoặc ticks), kẻ đường chấm kéo phải.
- Setups:
- Tìm OB chưa bị chạm gần nhất theo hướng trend (fFindRecentOB), kiểm tra giá chạm lại vùng và xác nhận nến.
- Tính Entry (giữa vùng), SL (biên đối diện), TP = Entry ± rrTarget × Risk; vẽ đường/nhãn nếu bật.
Đầu ra & vai trò trong sử dụng
- Hộp vùng (OB/FVG) có màu theo hướng; vùng đã mitigated sẽ mờ đi để tránh nhiễu.
- Đường LP (EQH/EQL) chấm chấm để định vị nơi dễ có “rũ bỏ” thanh khoản.
- Mũi tên BOS giúp xác nhận bias ngắn hạn.
- Đường Entry/SL/TP + icon/nhãn (nếu bật) phục vụ lập kế hoạch và theo dõi lệnh.
Dùng phân tích trên + Code phía dưới để ra lệnh cho AI chỉnh sửa chỉ báo, chuyển thành bot trade mà không cần biết code!
Cách làm tại đây -> 👉ZERO2HERO👈
//@version=5
indicator("Ideal SMC – Clean Pro (Trend, Merge, TTL, HTF, Compact + Setups) [Stable + Floating Boxes]", overlay=true, max_boxes_count=500, max_labels_count=500, max_lines_count=500)
//================ Inputs ================
pivotLen = input.int(6, "Swing Length (pivot detection)", minval=2, group="Core")
bodyLookback = input.int(20, "Body Lookback (OB search)", minval=3, group="Core")
atrLen = input.int(14, "ATR Length", minval=5, group="Core")
minOBatr = input.float(0.80, "Min OB Size (x ATR)", step=0.05, group="Core")
minFVGatr = input.float(0.35, "Min FVG Size (x ATR)", step=0.05, group="Core")
ttlOBBars = input.int(300, "OB TTL (Bars; 0 = unlimited)", minval=0, group="Display")
ttlFVGBars = input.int(300, "FVG TTL (Bars; 0 = unlimited)", minval=0, group="Display")
maxOBKeep = input.int(12, "Max active OBs", minval=1, maxval=200, group="Display")
maxFVGKeep = input.int(8, "Max active FVGs", minval=1, maxval=200, group="Display")
extendOnlyUnmitigated = input.bool(true, "Extend boxes only while unmitigated", group="Display")
// >>> Neu: Steuerung, ob Zonen bis zur Live-Kerze verlängern <<<
extendToLive = input.bool(true, title="Extend zones to live bar", group="Display")
boxWidthBars = input.int(80, title="Max box width (bars) when not extended", minval=5, group="Display")
showLP = input.bool(true, "Show Liquidity Pools (EQH/EQL)", group="LP")
useATRTol = input.bool(true, "LP tolerance uses ATR (else ticks)", group="LP")
tolATRmult = input.float(0.05, "LP tolerance ATR multiplier", step=0.01, group="LP")
tolTicks = input.int(3, "LP tolerance ticks", minval=1, group="LP")
useTrendFilter = input.bool(true, "Filter: show zones only in trend direction", group="Filters")
obInTrendOnly = input.bool(true, "Filter OBs by trend", group="Filters")
fvgInTrendOnly = input.bool(true, "Filter FVGs by trend", group="Filters")
useHTF = input.bool(false, "Use HTF data for zones", group="HTF")
htfTf = input.timeframe("240", "HTF timeframe", group="HTF")
// Setups
showSetups = input.bool(true, "Show Setups (OB Retest + Trend)", group="Setups")
showIcons = input.bool(true, "Setups: show icons", group="Setups")
showLabels = input.bool(false, "Setups: show labels (text)", group="Setups")
showLines = input.bool(true, "Setups: draw Entry/SL/TP lines", group="Setups")
onlyConfirmed = input.bool(true, "Only on confirmed bar close", group="Setups")
rrTarget = input.float(2.0, "TP Risk Reward (R multiple)", minval=1.0, step=0.5, group="Setups")
//================ Colors ================
color colBU = color.new(color.lime, 80)
color colB = color.new(color.red, 80)
color colFU = color.new(color.teal, 80)
color colFD = color.new(color.orange, 80)
color colEQH = color.new(color.fuchsia, 0)
color colEQL = color.new(color.aqua, 0)
//================ Core Series (typed) ================
float atrVal = ta.atr(atrLen)
float tick = syminfo.mintick
float tol = useATRTol and not na(atrVal) ? atrVal * tolATRmult : tick * tolTicks
float htfHigh = request.security(syminfo.tickerid, htfTf, high, barmerge.gaps_off, barmerge.lookahead_off)
float htfLow = request.security(syminfo.tickerid, htfTf, low, barmerge.gaps_off, barmerge.lookahead_off)
float htfClose = request.security(syminfo.tickerid, htfTf, close, barmerge.gaps_off, barmerge.lookahead_off)
float srcH = useHTF ? htfHigh : high
float srcL = useHTF ? htfLow : low
float srcC = useHTF ? htfClose : close
float ph = ta.pivothigh(srcH, pivotLen, pivotLen)
float pl = ta.pivotlow(srcL, pivotLen, pivotLen)
var float lastHigh = na
var float lastLow = na
if not na(ph)
lastHigh := srcH[pivotLen]
if not na(pl)
lastLow := srcL[pivotLen]
bool bosUp = not na(lastHigh) and srcC > lastHigh
bool bosDown = not na(lastLow) and srcC < lastLow
var string msTrend = "none"
if bosUp
msTrend := "up"
if bosDown
msTrend := "down"
//================ Containers ================
var box[] obBox = array.new_box()
var string[] obType = array.new_string() // "BU"/"B"
var bool[] obMit = array.new_bool()
var int[] obBirth = array.new_int()
var box[] fvgBox = array.new_box()
var string[] fvgType = array.new_string() // "FU"/"FD"
var bool[] fvgMit = array.new_bool()
var int[] fvgBirth = array.new_int()
//================ Helpers ================
fLastBearBodyLo() =>
float lo = na
for k = 1 to bodyLookback
if close[k] < open[k]
lo := math.min(open[k], close[k])
break
lo
fLastBearBodyHi() =>
float hi = na
for k = 1 to bodyLookback
if close[k] < open[k]
hi := math.max(open[k], close[k])
break
hi
fLastBullBodyLo() =>
float lo = na
for k = 1 to bodyLookback
if close[k] > open[k]
lo := math.min(open[k], close[k])
break
lo
fLastBullBodyHi() =>
float hi = na
for k = 1 to bodyLookback
if close[k] > open[k]
hi := math.max(open[k], close[k])
break
hi
fMergeOBs() =>
int n = array.size(obBox)
if n > 1
for i = n - 1 to 1
string ti = array.get(obType, i)
box bi = array.get(obBox, i)
float itop = box.get_top(bi)
float ibot = box.get_bottom(bi)
for k = i - 1 to 0
string tk = array.get(obType, k)
if tk == ti
box bk = array.get(obBox, k)
float ktop = box.get_top(bk)
float kbot = box.get_bottom(bk)
bool overlap = not (ibot > ktop or itop < kbot)
if overlap
float ntop = math.max(itop, ktop)
float nbot = math.min(ibot, kbot)
box.set_top(bk, ntop)
box.set_bottom(bk, nbot)
box.delete(bi)
array.remove(obBox, i)
array.remove(obType, i)
array.remove(obMit, i)
array.remove(obBirth, i)
break
//================ OB Logic ================
bool allowBull = not useTrendFilter or msTrend == "up"
bool allowBear = not useTrendFilter or msTrend == "down"
if bosUp and allowBull and not na(atrVal)
float loB = fLastBearBodyLo()
float hiB = fLastBearBodyHi()
if not na(loB) and not na(hiB) and (hiB - loB) >= atrVal * minOBatr
box b = box.new(bar_index, hiB, bar_index, loB, bgcolor=colBU)
array.push(obBox, b)
array.push(obType, "BU")
array.push(obMit, false)
array.push(obBirth, bar_index)
while array.size(obBox) > maxOBKeep
box old = array.shift(obBox)
box.delete(old)
array.shift(obType)
array.shift(obMit)
array.shift(obBirth)
if bosDown and allowBear and not na(atrVal)
float loS = fLastBullBodyLo()
float hiS = fLastBullBodyHi()
if not na(loS) and not na(hiS) and (hiS - loS) >= atrVal * minOBatr
box b2 = box.new(bar_index, hiS, bar_index, loS, bgcolor=colB)
array.push(obBox, b2)
array.push(obType, "B")
array.push(obMit, false)
array.push(obBirth, bar_index)
while array.size(obBox) > maxOBKeep
box old2 = array.shift(obBox)
box.delete(old2)
array.shift(obType)
array.shift(obMit)
array.shift(obBirth)
// OB maintain (Guards + floating right edge)
int nOb = array.size(obBox)
if nOb > 0
for i = nOb - 1 to 0
box bb = array.get(obBox, i)
float top = box.get_top(bb)
float bot = box.get_bottom(bb)
bool m = array.get(obMit, i)
if not m and not na(top) and not na(bot) and high >= bot and low <= top
array.set(obMit, i, true)
color dimCol = array.get(obType, i) == "BU" ? color.new(color.lime, 90) : color.new(color.red, 90)
box.set_bgcolor(bb, dimCol)
// >>> HIER: rechte Kante abhängig von extendToLive / boxWidthBars <<<
int bornX = array.get(obBirth, i)
int rightX = extendToLive ? bar_index : bornX + boxWidthBars
if extendOnlyUnmitigated ? not array.get(obMit, i) : true
box.set_right(bb, rightX)
if ttlOBBars > 0
int n2 = array.size(obBox)
if n2 > 0
for i = n2 - 1 to 0
int born = array.get(obBirth, i)
if bar_index - born > ttlOBBars
box.delete(array.get(obBox, i))
array.remove(obBox, i)
array.remove(obType, i)
array.remove(obMit, i)
array.remove(obBirth, i)
fMergeOBs()
//================ FVG Logic ================
if bar_index >= 2 and not na(atrVal)
bool bullFVG = srcL > srcH[2]
if bullFVG and (not fvgInTrendOnly or allowBull)
float topFU = srcL
float botFU = srcH[2]
if (topFU - botFU) >= atrVal * minFVGatr
box bxU = box.new(bar_index, topFU, bar_index, botFU, bgcolor=colFU)
array.push(fvgBox, bxU)
array.push(fvgType, "FU")
array.push(fvgMit, false)
array.push(fvgBirth, bar_index)
while array.size(fvgBox) > maxFVGKeep
box ofu = array.shift(fvgBox)
box.delete(ofu)
array.shift(fvgType)
array.shift(fvgMit)
array.shift(fvgBirth)
bool bearFVG = srcH < srcL[2]
if bearFVG and (not fvgInTrendOnly or allowBear)
float topFD = srcH
float botFD = srcL[2]
if (botFD - topFD) >= atrVal * minFVGatr
box bxD = box.new(bar_index, topFD, bar_index, botFD, bgcolor=colFD)
array.push(fvgBox, bxD)
array.push(fvgType, "FD")
array.push(fvgMit, false)
array.push(fvgBirth, bar_index)
while array.size(fvgBox) > maxFVGKeep
box ofd = array.shift(fvgBox)
box.delete(ofd)
array.shift(fvgType)
array.shift(fvgMit)
array.shift(fvgBirth)
// FVG maintain (floating right edge)
int nF = array.size(fvgBox)
if nF > 0
for i = nF - 1 to 0
box fb = array.get(fvgBox, i)
float ftop = box.get_top(fb)
float fbot = box.get_bottom(fb)
bool fm = array.get(fvgMit, i)
if not fm and not na(ftop) and not na(fbot) and high >= fbot and low <= ftop
array.set(fvgMit, i, true)
color dim = array.get(fvgType, i) == "FU" ? color.new(color.teal, 90) : color.new(color.orange, 90)
box.set_bgcolor(fb, dim)
// >>> HIER: rechte Kante abhängig von extendToLive / boxWidthBars <<<
int bornXF = array.get(fvgBirth, i)
int rightXF = extendToLive ? bar_index : bornXF + boxWidthBars
if extendOnlyUnmitigated ? not array.get(fvgMit, i) : true
box.set_right(fb, rightXF)
if ttlFVGBars > 0
int nF2 = array.size(fvgBox)
if nF2 > 0
for i = nF2 - 1 to 0
int bornF = array.get(fvgBirth, i)
if bar_index - bornF > ttlFVGBars
box.delete(array.get(fvgBox, i))
array.remove(fvgBox, i)
array.remove(fvgType, i)
array.remove(fvgMit, i)
array.remove(fvgBirth, i)
//================ LPs ================
if showLP
float phL = ta.pivothigh(high, pivotLen, pivotLen)
float plL = ta.pivotlow(low, pivotLen, pivotLen)
if not na(phL) and not na(phL[1]) and math.abs(phL - phL[1]) <= tol
line.new(bar_index, phL, bar_index, phL, extend=extend.right, color=colEQH, style=line.style_dotted)
if not na(plL) and not na(plL[1]) and math.abs(plL - plL[1]) <= tol
line.new(bar_index, plL, bar_index, plL, extend=extend.right, color=colEQL, style=line.style_dotted)
//================ BOS arrows ================
plotshape(bosUp, "BOS Up", location=location.abovebar, style=shape.triangleup, color=color.lime, size=size.tiny)
plotshape(bosDown, "BOS Down", location=location.belowbar, style=shape.triangledown, color=color.red, size=size.tiny)
//================ Helper: find recent OB ================
fFindRecentOB(isBull) =>
bool found = false
float top = na
float bot = na
int n = array.size(obBox)
if n > 0
string want = isBull ? "BU" : "B"
for i = n - 1 to 0
if array.get(obType, i) == want and not array.get(obMit, i)
box b = array.get(obBox, i)
top := box.get_top(b)
bot := box.get_bottom(b)
found := true
break
[found, top, bot]
//================ Setups (OB Retest + Trend) ================
var float longEntry = na
var float longSL = na
var float longTP = na
var float riskL = na
var float shortEntry = na
var float shortSL = na
var float shortTP = na
var float riskS = na
var bool longSigSeries = false
var bool shortSigSeries = false
bool okBar = true
bool fL = false
bool fS = false
float topL = na
float botL = na
float topS = na
float botS = na
bool longSigTmp = false
bool shortSigTmp = false
if showSetups
okBar := onlyConfirmed ? barstate.isconfirmed : true
[fL, topL, botL] = fFindRecentOB(true)
longSigTmp := fL and not na(topL) and not na(botL) and high >= botL and low <= topL and close > open and msTrend == "up" and okBar
if longSigTmp
longEntry := (topL + botL) / 2.0
longSL := botL
riskL := longEntry - longSL
longTP := longEntry + rrTarget * riskL
longSigSeries := true
if showLines
line.new(bar_index, longEntry, bar_index + 20, longEntry, extend=extend.none, color=color.lime)
line.new(bar_index, longSL, bar_index + 20, longSL, extend=extend.none, color=color.red)
line.new(bar_index, longTP, bar_index + 20, longTP, extend=extend.none, color=color.teal)
else
longSigSeries := false
[fS, topS, botS] = fFindRecentOB(false)
shortSigTmp := fS and not na(topS) and not na(botS) and high >= botS and low <= topS and close < open and msTrend == "down" and okBar
if shortSigTmp
shortEntry := (topS + botS) / 2.0
shortSL := topS
riskS := shortSL - shortEntry
shortTP := shortEntry - rrTarget * riskS
shortSigSeries := true
if showLines
line.new(bar_index, shortEntry, bar_index + 20, shortEntry, extend=extend.none, color=color.red)
line.new(bar_index, shortSL, bar_index + 20, shortSL, extend=extend.none, color=color.lime)
line.new(bar_index, shortTP, bar_index + 20, shortTP, extend=extend.none, color=color.orange)
else
shortSigSeries := false
// Icons/Labels
plotshape(showSetups and showIcons and longSigSeries, "Long Setup", style=shape.diamond, size=size.tiny, color=color.lime, location=location.belowbar)
plotshape(showSetups and showIcons and shortSigSeries, "Short Setup", style=shape.diamond, size=size.tiny, color=color.red, location=location.abovebar)
if showSetups and showLabels and longSigSeries
label.new(bar_index, close, "Long: OB Retest + Trend\nE:"+str.tostring(longEntry)+" SL:"+str.tostring(longSL)+" TP:"+str.tostring(longTP),
style=label.style_label_up, color=color.new(color.lime, 70), textcolor=color.black)
if showSetups and showLabels and shortSigSeries
label.new(bar_index, close, "Short: OB Retest + Trend\nE:"+str.tostring(shortEntry)+" SL:"+str.tostring(shortSL)+" TP:"+str.tostring(shortTP),
style=label.style_label_down, color=color.new(color.red, 70), textcolor=color.white)
Indicator Insider

3 HẠN CHẾ CỦA AI ĐÃ CẢI THIỆN ĐỂ DÙNG TRONG TRADING
1. Trade với AI – Bình CŨ rượu MỚI !? Nói bình CŨ rượu MỚI bởi lẽ, quant trading (giao dịch định lượng) ứng dụng trí tuệ nhân tạo (AI), máy học (Machine Learning), mô hình học sâu (deep learning) và học tăng cường (reinforcement learning) được ứng dụng từ

Smart Money Concepts Pro – OB, FVG, Liquidity + Trade Setups
Chỉ báo dựa trên tư duy Smart Money Concepts (SMC): giá di chuyển vì mất cân bằng cung–cầu và hành trình đi tìm thanh khoản. Từ đó, ta tập trung vào 4 “cột mốc” quan trọng:
Order Block (OB)
Fair Value Gap (FVG)
Liquidity Pools (EQH/EQL)

Elliott Wave
Chỉ báo này dựa trên Lý thuyết sóng Elliott (Elliott Wave Theory) – một trong những nguyên lý phân tích kỹ thuật nổi tiếng nhất, cho rằng thị trường di chuyển theo các mô hình sóng có thể dự đoán được.