SMC Order Block Scorer
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «indicator smc order block scorer for tradingview.pine» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
Индикатор «SMC Order Block Scorer» анализирует рыночную структуру на основе свинг-пивотов, определяя сигналы Break of Structure (BOS) и Change of Character (CHoCH). Он автоматически находит Order Blocks — последние свечи противоположного направления перед структурным пробоем — и оценивает каждый из них по шкале от 0 до 100 на основе профилей объёма (POC, Value Area, HVN), всплесков объёма и величины смещения. Order Blocks получают буквенную оценку от A+ до C и отображаются на графике в виде цветных блоков.
Встроенный профиль объёма отображает зоны POC, Value Area и High Volume Node с возможностью выделения HVN по всей шкале графика. Система митигации отслеживает пересечение ценой ранее созданных Order Blocks и позволяет скрыть или «затушить» их в зависимости от выбранного триггера. Индикатор также содержит таблицу статуса с ранжированием активных Order Blocks по оценке и набор условных оповещений для CHoCH, BOS, новых Order Blocks и событий митигации.
Примечание: оценка Order Blocks представляет собой правила-based рейтинг конфлюэнса, а не результат бэктеста или вероятностную модель. Индикатор работает поверх графика и не выполняет симуляцию торговых операций.
Настройки программы
| Настройка | Описание |
|---|---|
| swingLen | Длина отступа (количество баров) для поиска основных свинг-пивотов, определяющих структуру BOS/CHoCH и триггер появления Order Blocks. |
| showStructure | Главный переключатель: включает или отключает отображение всей рыночной структуры (BOS, CHoCH, линии). |
| showBOS | Включает или отключает отображение меток Break of Structure (BOS) на графике. |
| showCHoCH | Включает или отключает отображение меток Change of Character (CHoCH) на графике. |
| showLines | Включает или отключает отрисовку линий разрыва структуры (продолжение уровня пивота при BOS/CHoCH). |
| bullColor | Цвет отрисовки элементов и меток бычьего направления (ростящий тренд). |
| bearColor | Цвет отрисовки элементов и меток медвежьего направления (нисходящий тренд). |
| showInt | Включает или отключает отображение внутренней структуры (мелких пивотов) — косметическая функция. |
| intLen | Длина отступа (количество баров) для поиска внутренних свинг-пивотов, используемых только в косметических целях. |
| intColor | Цвет меток внутренней структуры (мелких пивотов), если соответствующая настройка включена. |
| showOB | Включает или отключает автоматическое обнаружение и отображение Order Blocks. |
| obMax | Максимальное количество одновременно отображаемых Order Blocks на одну сторону (бычью или медвежью). |
| obLookback | Количество баров назад, в пределах которых ищется последняя противоположная свеча для формирования Order Block. |
| mitigateBy | Тип триггера митигации: Touch — цена касается зоны, 50% — цена достигает середины зоны, Wick — свеча проходит через дальнюю сторону, Close — свеча закрывается за дальней стороной. |
| showMitigated | Если включено, митигированные (затушённые) Order Block остаются на графике в сером цвете вместо удаления. |
| hideOverlap | Если включено, новые Order Blocks не создаются при перекрытии зоной другого Order Blocks того же направления. |
| obShowMid | Если включено, для каждого Order Block отображается пунктирная линия на уровне 50% (середина зоны). |
| minScore | Минимальная оценка Order Block: блоки с оценкой ниже этого значения не отображаются на графике. |
| showLabels | Включает или отключает текстовые метки с оценкой и классом на Order Blocks. |
| labelSizeIn | Размер меток Order Blocks на графике: tiny, small или normal. |
| showProfile | Включает или отключает отображение профиля объёма на графике. |
| showHvnZones | Если включено, зоны High Volume Node (HVN) выделяются заливкой на всём графике, а не только в профиле. |
| profLookback | Количество баров назад, используемых для построения профиля объёма. |
| profRows | Количество строк (уровней), на которые разбивается диапазон цен профиля объёма. |
| vaPct | Процент объёма, определяющий границы Value Area (например, 70 означает, что Value Area охватывает 70% объёма). |
| hvnMult | Множитель для определения HVN: строка профиля считается зоной высокого объёма, если её объём превышает средний объём строки, умноженный на это значение. |
| profWidth | Ширина столбцов профиля объёма в барах. |
| profOffset | Смещение столбцов профиля объёма от последнего бара графика (вправо). |
| volLen | Период скользящей средней для расчёта среднего объёма, используемый при определении всплесков объёма. |
| volMult | Множитель для определения всплеска объёма: текущий объём считается всплеском, если превышает среднее, умноженное на это значение. |
| wPOC | Вес (бонусные баллы), добавляемый к оценке Order Block при наличии POC внутри зоны. |
| wVA | Вес (бонусные баллы), добавляемый к оценке Order Block при пересечении зоны Value Area. |
| wHVN | Вес (бонусные баллы), добавляемый к оценке Order Block при пересечении зоны HVN. |
| pocCol | Цвет отрисовки и маркировки зоны Point of Control (POC) в профиле объёма. |
| vaCol | Цвет отрисовки и заливки зоны Value Area в профиле объёма. |
| hvnCol | Цвет заливки и маркировки зон High Volume Node (зон с высоким объёмом). |
| nvCol | Цвет для строк профиля объёма, не являющихся POC, Value Area или HVN. |
| showTable | Включает или отключает таблицу статуса с ранжированием активных Order Blocks по оценке. |
| tablePos | Позиция таблицы статуса на графике: верхний правый, верхний левый, нижний правый или нижний левый угол. |
Поиск по коду файла
indicator("SMC Order Block Scorer", shorttitle="SMC OB Scorer", overlay=true, max_boxes_count=500, max_lines_count=500, max_labels_count=500, max_bars_back=1000)
grpSwing = "Swing Structure (drives CHoCH / BOS / OB)"
swingLen = input.int(50, "Swing Lookback (pivot strength)", minval=2, group=grpSwing)
showStructure = input.bool(true, "Show market structure (master toggle)", group=grpSwing)
showBOS = input.bool(true, "Show BOS labels", group=grpSwing)
showCHoCH = input.bool(true, "Show CHoCH labels", group=grpSwing)
showLines = input.bool(true, "Draw structure break lines", group=grpSwing)
bullColor = input.color(color.new(color.teal, 0), "Bullish color", group=grpSwing)
bearColor = input.color(color.new(color.red, 0), "Bearish color", group=grpSwing)
grpInt = "Internal Structure (optional, cosmetic only)"
showInt = input.bool(false, "Show internal structure (minor pivots)", group=grpInt)
intLen = input.int(5, "Internal Lookback (pivot strength)", minval=1, group=grpInt)
intColor = input.color(color.new(color.gray, 55), "Internal label color", group=grpInt)
grpOB = "Order Blocks"
showOB = input.bool(true, "Show Order Blocks", group=grpOB)
obMax = input.int(10, "Max active OBs per side", minval=1, maxval=50, group=grpOB)
obLookback = input.int(50, "OB search lookback (bars)", minval=5, maxval=200, group=grpOB)
mitigateBy = input.string("Touch", "Mitigation trigger", options=["Touch", "50%", "Wick", "Close"], group=grpOB, tooltip="Touch = price revisits the zone (any wick inside)\n50% = price reaches the middle of the zone\nWick = wick trades through the far side\nClose = candle closes beyond the far side")
showMitigated = input.bool(false, "Keep mitigated OBs (faded)", group=grpOB)
hideOverlap = input.bool(true, "Skip OBs overlapping a same-side OB", group=grpOB)
obShowMid = input.bool(true, "Show OB 50% equilibrium line", group=grpOB)
minScore = input.float(0, "Hide OBs below score", minval=0, maxval=100, group=grpOB)
showLabels = input.bool(true, "Show OB labels", group=grpOB)
labelSizeIn = input.string("small", "Label size", options=["tiny", "small", "normal"], group=grpOB)
grpVP = "Volume Profile / Zones"
showProfile = input.bool(true, "Show volume profile", group=grpVP)
showHvnZones = input.bool(true, "Shade HVN zones across chart", group=grpVP)
profLookback = input.int(150, "Profile lookback (bars)", minval=30, maxval=500, group=grpVP)
profRows = input.int(30, "Profile rows", minval=10, maxval=80, group=grpVP)
vaPct = input.float(70, "Value area %", minval=50, maxval=95, group=grpVP) / 100.0
hvnMult = input.float(1.3, "HVN threshold (x avg row volume)", minval=1.0, step=0.1, group=grpVP)
profWidth = input.int(25, "Profile width (bars)", minval=5, maxval=100, group=grpVP)
profOffset = input.int(6, "Profile offset from last bar", minval=1, maxval=100, group=grpVP)
grpVol = "Volume Confirmation"
volLen = input.int(20, "Volume average length", minval=1, group=grpVol)
volMult = input.float(1.5, "Spike threshold (x average)", minval=0.1, step=0.1, group=grpVol)
grpW = "Scoring weights"
wPOC = input.float(25, "OB contains POC", minval=0, group=grpW)
wVA = input.float(15, "OB overlaps Value Area", minval=0, group=grpW)
wHVN = input.float(20, "OB overlaps HVN (extra credit)", minval=0, group=grpW)
grpSty = "Profile colors"
pocCol = input.color(#ff3d71, "POC", group=grpSty, inline="p1")
vaCol = input.color(#4c8dff, "Value area", group=grpSty, inline="p1")
hvnCol = input.color(#ffb300, "HVN", group=grpSty, inline="p2")
nvCol = input.color(#7b8494, "Other rows", group=grpSty, inline="p2")
grpInfo = "Info Table"
showTable = input.bool(true, "Show status table", group=grpInfo)
tablePos = input.string("Top Right", "Table position", options=["Top Right", "Top Left", "Bottom Right", "Bottom Left"], group=grpInfo)
var string txtSz = labelSizeIn == "tiny" ? size.tiny : labelSizeIn == "normal" ? size.normal : size.small
var string posMap = tablePos == "Top Right" ? position.top_right : tablePos == "Top Left" ? position.top_left : tablePos == "Bottom Right" ? position.bottom_right : position.bottom_left
type Profile
array<float> vols
array<bool> hvn
float lo
float step
int pocIdx
int vahIdx
int valIdx
float total
type OB
box bx
line ml
label lb
bool bull
float top
float bot
float score
string txt
float atrVal = ta.atr(14)
float volAvg = ta.sma(volume, volLen)
bool volSpike = volume > volAvg * volMult
var array<OB> obs = array.new<OB>()
var array<box> profBoxes = array.new<box>()
var array<line> profLines = array.new<line>()
var array<label> profLabels = array.new<label>()
f_buildProfile(int lookback, int rows, float vaFrac, float hvnMul) =>
int n = math.min(lookback, bar_index + 1)
float hiP = high
float loP = low
for i = 0 to n - 1
hiP := math.max(hiP, high[i])
loP := math.min(loP, low[i])
float stp = math.max((hiP - loP) / rows, syminfo.mintick)
array<float> vols = array.new<float>(rows, 0.0)
for i = 0 to n - 1
float bl = low[i]
float bh = high[i]
float v = nz(volume[i])
float rng = math.max(bh - bl, syminfo.mintick)
int i0 = math.max(0, math.min(rows - 1, int(math.floor((bl - loP) / stp))))
int i1 = math.max(0, math.min(rows - 1, int(math.floor((bh - loP) / stp))))
for r = i0 to i1
float rl = loP + r * stp
float rh = rl + stp
float sh = i0 == i1 ? 1.0 : math.max(0.0, math.min(bh, rh) - math.max(bl, rl)) / rng
vols.set(r, vols.get(r) + v * sh)
float total = vols.sum()
int poc = vols.indexof(vols.max())
int up = poc
int dn = poc
float acc = vols.get(poc)
while acc < total * vaFrac and (up < rows - 1 or dn > 0)
float vu = up < rows - 1 ? vols.get(up + 1) : -1.0
float vd = dn > 0 ? vols.get(dn - 1) : -1.0
if vu >= vd
up += 1
acc += vu
else
dn -= 1
acc += vd
array<bool> hvn = array.new<bool>(rows, false)
float avg = total / rows
for r = 0 to rows - 1
float v = vols.get(r)
float pv = r > 0 ? vols.get(r - 1) : 0.0
float nx = r < rows - 1 ? vols.get(r + 1) : 0.0
if total > 0 and v >= avg * hvnMul and v >= pv and v >= nx
hvn.set(r, true)
Profile.new(vols, hvn, loP, stp, poc, up, dn, total)
f_confluence(Profile p, float zTop, float zBot) =>
bool hasPoc = false
bool hasHvn = false
float share = 0.0
float tot = p.total
if tot > 0
for r = 0 to p.vols.size() - 1
float rl = p.lo + r * p.step
float rh = rl + p.step
if rl < zTop and rh > zBot
share += p.vols.get(r) * (math.min(zTop, rh) - math.max(zBot, rl)) / p.step
if r == p.pocIdx
hasPoc := true
if p.hvn.get(r)
hasHvn := true
float vaLo = p.lo + p.valIdx * p.step
float vaHi = p.lo + (p.vahIdx + 1) * p.step
bool inVa = tot > 0 and zBot < vaHi and zTop > vaLo
float shr = tot > 0 ? share / tot : 0.0
[hasPoc, inVa, hasHvn, shr]
f_overlap(bool bull, float t, float b) =>
bool res = false
if obs.size() > 0
for i = 0 to obs.size() - 1
OB o = obs.get(i)
if o.bull == bull and t > o.bot and b < o.top
res := true
res
f_kill(OB o) =>
box.delete(o.bx)
line.delete(o.ml)
label.delete(o.lb)
true
f_findOB(bool bull) =>
float obH = na
float obL = na
int obB = na
for i = 1 to obLookback
bool opp = bull ? close[i] < open[i] : close[i] > open[i]
if opp
obH := high[i]
obL := low[i]
obB := bar_index - i
break
[obH, obL, obB]
f_createOB(bool bull, float zTop, float zBot, int zBar, bool isChoch, bool spike) =>
float atrv = nz(atrVal, syminfo.mintick)
bool made = false
bool ovl = hideOverlap and f_overlap(bull, zTop, zBot)
if not ovl
Profile p = f_buildProfile(profLookback, profRows, vaPct, hvnMult)
[hasPoc, inVa, hasHvn, share] = f_confluence(p, zTop, zBot)
int off = bar_index - zBar
float vRatio = nz(volume[off]) / math.max(nz(volAvg[off]), 1e-10)
float ptsVol = math.min(vRatio / 2.0, 1.0) * 5.0 + (spike ? 5.0 : 0.0)
float dispAtr = bull ? (close - zBot) / atrv : (zTop - close) / atrv
float ptsDisp = math.min(math.max(dispAtr / 4.0, 0.0), 1.0) * 10.0
float ptsStr = isChoch ? 6.0 : 10.0
float ptsShr = math.min(share / 0.15, 1.0) * 10.0
float raw = ptsStr + ptsVol + ptsDisp + ptsShr + (hasPoc ? wPOC : 0.0) + (inVa ? wVA : 0.0) + (hasHvn ? wHVN : 0.0)
float maxRaw = 40.0 + wPOC + wVA + wHVN
float score = math.min(100.0, raw / maxRaw * 100.0)
if score >= minScore
color base = bull ? bullColor : bearColor
int bgT = score >= 75 ? 66 : score >= 60 ? 76 : score >= 45 ? 85 : 92
int brT = score >= 75 ? 10 : score >= 60 ? 30 : score >= 45 ? 50 : 70
string grade = score >= 75 ? "A+" : score >= 60 ? "A" : score >= 45 ? "B" : "C"
array<string> tg = array.new<string>()
if hasPoc
tg.push("POC")
if inVa
tg.push("VA")
if hasHvn
tg.push("HVN")
string tags = tg.join(" · ")
string txt = (bull ? "▲ " : "▼ ") + grade + " " + str.tostring(math.round(score)) + "%" + (tags == "" ? "" : "\n" + tags)
float midY = (zTop + zBot) / 2
box bx = box.new(zBar, zTop, bar_index + 20, zBot, border_color=color.new(base, brT), border_width=1, bgcolor=color.new(base, bgT))
line ml = obShowMid ? line.new(zBar, midY, bar_index + 20, midY, color=color.new(base, 30), style=line.style_dotted) : na
label lb = showLabels ? label.new(bar_index + 20, midY, txt, style=label.style_label_left, color=color.new(base, 35), textcolor=color.white, size=txtSz) : na
obs.push(OB.new(bx, ml, lb, bull, zTop, zBot, score, txt))
int cnt = 0
for q in obs
if q.bull == bull
cnt += 1
while cnt > obMax
for i = 0 to obs.size() - 1
OB old = obs.get(i)
if old.bull == bull
f_kill(old)
obs.remove(i)
cnt -= 1
break
made := true
made
var table wm = table.new(position.bottom_right, 1, 1)
if barstate.isfirst
table.cell(wm, 0, 0, "Telegram @SimpleForexTools", text_color = color.new(color.gray, 70), text_size = size.large)
float inPH = ta.pivothigh(high, intLen, intLen)
float inPL = ta.pivotlow(low, Показано первые 50% кода (символов: 16142)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.