← К каталогу
Исходный код · ID 4174

Smart Money Concepts Engine

indicator smart money concepts engine for tradingview.pine
Вы автор или правообладатель?

Сообщите нам, если считаете, что материал размещён без разрешения.

Краткий обзор

О программе

Smart Money Concepts Engine — это индикатор для TradingView (Pine Script v6), который отображает на графике ключевые элементы анализа по методологии smart money: структуру рынка, ордер-блоки, справедливые ценовые разрывы (FVG) и уровни ликвидности. Индикатор рисует свинговые и внутренние точки разворота, определяет пробития структуры (BoS/CHoCH) на подтверждённых барах, визуализирует зоны ордер-блоков с информацией о объёмном отношении и отслеживает инверсии разрывов.

На графике отображаются равные максимумы и минимумы как уровни ликвидности с отслеживанием их снятия, а также карта премии и дисконта, показывающая положение цены внутри свингового диапазона. При касании ордер-блоков с совпадающей структурой появляются сигналы зонального taps с индикатором конfluence-скора.

Встроенный дашборд в виде таблицы отображает текущее направление свинговой и внутренней структуры, последнее событие, диапазон цены (премия/дисконт), статус ликвидности, количество свежих зон и разрывов, конfluence-скор и текстовую сводку состояния рынка. Индикатор поддерживает 9 условий оповещений для автоматических уведомлений TradingView.

Настройки программы

НастройкаОписание
sLen Длина свинговой структуры для определения точек разворота swing high и swing low.
iLen Длина внутренней структуры для определения внутренних точек разворота (pivot high/pivot low).
showSwing Включает или отключает отображение событий свинговой структуры (линии и подписи BoS/CHoCH).
showInt Включает или отключает отображение внутренних событий структуры (внутренние пробития).
keepStruct Максимальное количество сохраняемых событий структуры (линии и подписи BoS/CHoCH) на графике.
showOB Включает или отключает отображение ордер-блоков (зон с высоким/низким объёмом) на графике.
obLookback Глубина поиска исходной свечи для определения ордер-блока (количество баров назад, в пределах которых ищется свеча формирования).
keepOB Максимальное количество отображаемых ордер-блоков на графике. Старые объекты удаляются.
showFvg Включает или отключает отображение справедливых ценовых разрывов (Fair Value Gaps) на графике.
showInv Включает или отключает отслеживание и маркировку инверсий справедливых ценовых разрывов.
fvgMinAtr Минимальный размер ценового разрыва (FVG) в долях среднего истинного диапазона (ATR), ниже которого разрыв не фиксируется.
keepFvg Максимальное количество отображаемых справедливых ценовых разрывов (FVG) на графике. Старые объекты удаляются.
showLiq Включает или отключает отображение равных максимумов и минимумов (уровней ликвидности) на графике.
eqTol Допуск для определения равных максимумов и минимумов, выраженный в долях среднего истинного диапазона (ATR).
keepLiq Максимальное количество отображаемых уровней ликвидности (равных максимумов/минимумов) на графике.
showPd Включает или отключает отображение карты премии и дисконта (цветовые зоны внутри свингового диапазона).
pdExt Горизонтальное расширение карты премии/дисконта в барах от текущего бара.
showSigs Включает или отключает отображение сигналов касания ордер-блоков с совпадающей структурой.
keepSigs Максимальное количество отображаемых сигналов касания зон на графике.
bullCol Цвет бычьих элементов на графике (ордер-блоки бычьего направления, линии и подписи бычьей структуры).
bearCol Цвет медвежьих элементов на графике (ордер-блоки медвежьего направления, линии и подписи медвежьей структуры).
goldCol Акцентный цвет, используемый для специальных меток (премиальные сигналы, скор 80+).
silvCol Нейтральный цвет, используемый для элементов, не относящихся к бычьему или медвежьему направлению (уровни ликвидности, линии равновесия).
showDash Включает или отключает отображение таблицы дашборда с информацией о структуре, зонах и скоре.
showNarr Включает или отключает отображение строки повествования (текстовой сводки текущего состояния рынка) в дашборде.
dashPos Позиция таблицы дашборда на графике: верхний правый, верхний левый, нижний правый или нижний левый угол.
dashSize Размер текста в таблице дашборда: крошечный, малый, нормальный или большой.
dashTitleBg Цвет фона заголовочной полосы в таблице дашборда.
dashBg Цвет фона таблицы дашборда.
dashFrame Цвет рамки таблицы дашборда.
dashGrid Цвет линий сетки (границ ячеек) в таблице дашборда.
dashHeadTxt Цвет текста заголовков в таблице дашборда.
dashBodyTxt Цвет основного текста в таблице дашборда.
dashMuteTxt Цвет приглушённого (вспомогательного) текста в таблице дашборда.
Получить полный код

Поиск по коду файла

indicator("Smart Money Concepts Engine", overlay = true, max_boxes_count = 500, max_lines_count = 500, max_labels_count = 500, max_bars_back = 500)

grpS = "Market Structure"
sLen       = input.int(15, "Swing Structure Length", minval = 5, maxval = 60, group = grpS)
iLen       = input.int(5, "Internal Structure Length", minval = 2, maxval = 20, group = grpS)
showSwing  = input.bool(true, "Show Swing Events", group = grpS)
showInt    = input.bool(true, "Show Internal Events", group = grpS)
keepStruct = input.int(8, "Structure Events To Keep", minval = 2, maxval = 30, group = grpS, tooltip = "Older structure lines and labels beyond this count are deleted so the chart stays clean and the auto-scale stays anchored to current price.")

grpO = "Order Blocks"
showOB     = input.bool(true, "Show Order Blocks", group = grpO)
obLookback = input.int(30, "Origin Candle Lookback", minval = 5, maxval = 100, group = grpO)
keepOB     = input.int(6, "Order Blocks To Keep", minval = 2, maxval = 20, group = grpO)

grpG = "Fair Value Gaps"
showFvg   = input.bool(false, "Show Fair Value Gaps", group = grpG)
showInv   = input.bool(true, "Track Inversions", group = grpG)
fvgMinAtr = input.float(0.15, "Minimum Gap Size (Average True Range Ratio)", step = 0.05, minval = 0.0, group = grpG)
keepFvg   = input.int(8, "Fair Value Gaps To Keep", minval = 2, maxval = 30, group = grpG)

grpL = "Liquidity"
showLiq  = input.bool(true, "Show Equal Highs / Equal Lows", group = grpL)
eqTol    = input.float(0.25, "Equal Level Tolerance (Average True Range Ratio)", step = 0.05, minval = 0.05, group = grpL)
keepLiq  = input.int(6, "Liquidity Levels To Keep", minval = 2, maxval = 20, group = grpL)

grpPD = "Premium & Discount"
showPd = input.bool(true, "Show Premium / Discount Map", group = grpPD)
pdExt  = input.int(12, "Map Extension (Bars)", minval = 4, maxval = 60, group = grpPD)

grpX = "Signals"
showSigs = input.bool(true, "Show Zone Tap Signals", group = grpX)
keepSigs = input.int(6, "Signals To Keep", minval = 2, maxval = 20, group = grpX)

grpV = "Chart Visuals"
bullCol = input.color(#00a89d, "Bullish Color", group = grpV)
bearCol = input.color(#e8365f, "Bearish Color", group = grpV)
goldCol = input.color(#d99b1e, "Accent Color", group = grpV)
silvCol = input.color(#5c6b80, "Neutral Color", group = grpV)

grpT = "Dashboard"
showDash    = input.bool(true, "Show Dashboard", group = grpT)
showNarr    = input.bool(true, "Show Narrative Row", group = grpT)
dashPos     = input.string("Top Right", "Position", options = ["Top Right", "Top Left", "Bottom Right", "Bottom Left"], group = grpT)
dashSize    = input.string("Small", "Text Size", options = ["Tiny", "Small", "Normal", "Large"], group = grpT)
dashTitleBg = input.color(color.new(#231a08, 0), "Title Band", group = grpT)
dashBg      = input.color(color.new(#171207, 8), "Background", group = grpT)
dashFrame   = input.color(color.new(#d99b1e, 15), "Frame", group = grpT)
dashGrid    = input.color(color.new(#d99b1e, 80), "Grid", group = grpT)
dashHeadTxt = input.color(color.new(#f0c05a, 0), "Header Text", group = grpT)
dashBodyTxt = input.color(color.new(#eef2f7, 5), "Body Text", group = grpT)
dashMuteTxt = input.color(color.new(#cdb87e, 15), "Muted Text", group = grpT)

atr    = ta.atr(14)
volSma = ta.sma(volume, 20)

f_rep(string s, int n) =>
    out = ""
    if n > 0
        for i = 1 to n
            out += s
    out

var float swingHigh = na
var int   swingHighBar = na
var bool  swingHighBroken = false
var float swingLow = na
var int   swingLowBar = na
var bool  swingLowBroken = false
var int   sDir = 0

var float intHigh = na
var bool  intHighBroken = false
var float intLow = na
var bool  intLowBroken = false
var int   iDir = 0

var int lastBuySweepBar  = -10000
var int lastSellSweepBar = -10000
var bool swingHighSwept  = false
var bool swingLowSwept   = false
var int  lastSweepLabBar = -10000
var string lastEvent = "—"
var string liqStatus = "Resting"

var array<line>  stLines  = array.new<line>()
var array<label> stLabels = array.new<label>()
var array<label> inLabels = array.new<label>()
var array<box>   obBoxes  = array.new<box>()
var array<int>   obDir    = array.new<int>()
var array<int>   obState  = array.new<int>()   // 0 fresh · 1 tested · 2 mitigated
var array<box>   fvgBoxes = array.new<box>()
var array<int>   fvgDir   = array.new<int>()
var array<int>   fvgState = array.new<int>()   // 0 fresh · 1 inverted · 2 dead
var array<line>  lqLines  = array.new<line>()
var array<label> lqLabels = array.new<label>()
var array<float> lqPrice  = array.new<float>()
var array<int>   lqDir    = array.new<int>()
var array<int>   lqActive = array.new<int>()
var array<label> sgLabels = array.new<label>()
var array<box>   pdB = array.new<box>()
var array<line>  pdL = array.new<line>()
var array<label> pdT = array.new<label>()

bool evBosBull   = false
bool evBosBear   = false
bool evChochBull = false
bool evChochBear = false
bool evSweepBuy  = false
bool evSweepSell = false
bool evTapBull   = false
bool evTapBear   = false
bool evInvFvg    = false

f_findOrigin(bool bull_) =>
    int idx = na
    for b = 1 to math.min(obLookback, bar_index)
        if bull_ ? close[b] < open[b] : close[b] > open[b]
            idx := b
            break
    idx

f_makeOB(bool bull_) =>
    idx = f_findOrigin(bull_)
    if showOB and not na(idx)
        obT = high[idx]
        obB = low[idx]
        rv  = na(volume[idx]) or na(volSma[idx]) or volSma[idx] == 0 ? na : volume[idx] / volSma[idx]
        txt = (bull_ ? "Demand" : "Supply") + (na(rv) ? "" : " · " + str.tostring(rv, "#.0") + "× Volume")
        c   = bull_ ? bullCol : bearCol
        obBoxes.push(box.new(bar_index - idx, obT, bar_index + 2, obB, border_color = color.new(c, 0), bgcolor = color.new(c, 70), text = txt, text_size = size.small, text_color = color.new(c, 0), text_halign = text.align_right, text_valign = bull_ ? text.align_top : text.align_bottom))
        obDir.push(bull_ ? 1 : -1)
        obState.push(0)

sph = ta.pivothigh(high, sLen, sLen)
spl = ta.pivotlow(low, sLen, sLen)
iph = ta.pivothigh(high, iLen, iLen)
ipl = ta.pivotlow(low, iLen, iLen)

if not na(sph)

    if showLiq and not na(swingHigh) and math.abs(sph - swingHigh) <= atr * eqTol
        lvl = math.max(sph, swingHigh)
        lqLines.push(line.new(swingHighBar, lvl, bar_index - sLen, lvl, color = color.new(bearCol, 5), style = line.style_dotted, width = 2))
        lqLabels.push(label.new(bar_index - sLen, lvl, "EQH", style = label.style_label_left, color = color.new(color.black, 100), textcolor = color.new(bearCol, 0), size = size.small))
        lqPrice.push(lvl)
        lqDir.push(1)
        lqActive.push(1)
    swingHigh := sph
    swingHighBar := bar_index - sLen
    swingHighBroken := false
    swingHighSwept := false
if not na(spl)

    if showLiq and not na(swingLow) and math.abs(spl - swingLow) <= atr * eqTol
        lvl = math.min(spl, swingLow)
        lqLines.push(line.new(swingLowBar, lvl, bar_index - sLen, lvl, color = color.new(bullCol, 5), style = line.style_dotted, width = 2))
        lqLabels.push(label.new(bar_index - sLen, lvl, "EQL", style = label.style_label_left, color = color.new(color.black, 100), textcolor = color.new(bullCol, 0), size = size.small))
        lqPrice.push(lvl)
        lqDir.push(-1)
        lqActive.push(1)
    swingLow := spl
    swingLowBar := bar_index - sLen
    swingLowBroken := false
    swingLowSwept := false
if not na(iph)
    intHigh := iph
    intHighBroken := false
if not na(ipl)
    intLow := ipl
    intLowBroken := false

if barstate.isconfirmed

    if not na(swingHigh) and not swingHighBroken and close > swingHigh
        isCh = sDir == -1
        if isCh
            evChochBull := true
            lastEvent := "CHoCH ↑"
        else
            evBosBull := true
            lastEvent := "BoS ↑"
        if showSwing
            stLines.push(line.new(swingHighBar, swingHigh, bar_index, swingHigh, color = color.new(bullCol, 0), width = 2, style = isCh ? line.style_dashed : line.style_solid))
            stLabels.push(label.new(int(math.avg(swingHighBar, bar_index)), swingHigh, isCh ? "CHoCH" : "BoS", style = label.style_label_down, color = color.new(color.black, 100), textcolor = color.new(bullCol, 0), size = size.small))
        f_makeOB(true)
        sDir := 1
        swingHighBroken := true

    if not na(swingLow) and not swingLowBroken and close < swingLow
        isCh = sDir == 1
        if isCh
            evChochBear := true
            lastEvent := "CHoCH ↓"
        else
            evBosBear := true
            lastEvent := "BoS ↓"
        if showSwing
            stLines.push(line.new(swingLowBar, swingLow, bar_index, swingLow, color = color.new(bearCol, 0), width = 2, style = isCh ? line.style_dashed : line.style_solid))
            stLabels.push(label.new(int(math.avg(swingLowBar, bar_index)), swingLow, isCh ? "CHoCH" : "BoS", style = label.style_label_up, color = color.new(color.black, 100), textcolor = color.new(bearCol, 0), size = size.small))
        f_makeOB(false)
        sDir := -1
        swingLowBroken := true

    if not na(intHigh) and not intHighBroken and close > intHigh
        if showInt
            inLabels.push(label.new(bar_index, intHigh, iDir == -1 ? "choch" : "bos", style = label.style_label_down, color = color.new(color.black, 100), textcolor = color.new(bullCol, 20), size = size.tiny))
        iDir := 1
        intHighBroken := true
    if not na(intLow) and not intLowBroken and close < intLow
        if showInt
            inLabels.push(label.new(bar_index, intLow, iDir == 1 ? "choch" : "bos", style = label.style_label_up, color = color.new(color.black, 100), textcolor = color.new(bearCol, 20), size = size.tiny))
        iDir := -1
        intLowBroken := true

    if not na(swingHigh) and not swingHighBroken and not swingHighSwept and high > swingHigh and close < swingHigh and bar_index - lastSweepLabBar >= 5
        evSweepBuy := true
        swingHighSwept := true
        lastSweepLabBar := bar_index
        lastBuySweepBar := bar_index
        liqStatus := "Buy swept"
        if showLiq
            sgLabels.push(label.new(bar_index, high, "Liquidity Sweep ✕", style = label.style_label_down, color = color.new(bearCol, 5), textcolor = color.new(#ffffff, 0), size = size.small))
    if not na(swingLow) and not swingLowBroken and not swingLowSwept and low < swingLow and close > swingLow and bar_index - lastSweepLabBar >= 5
        evSweepSell := true
        swingLowSwept := true
        lastSweepLabBar := bar_index
        lastSellSweepBar := bar_index
        liqStatus := "Sell swept"
        if showLiq
            sgLabels.push(label.new(bar_index, low, "Liquidity Sweep ✕", style = label.style_label_up, color = color.new(bullCol, 5), textcolor = color.new(#ffffff, 0), size = size.small))
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)

if lqLines.size() > 0
    for i = 0 to lqLines.size() - 1
        if lqActive.get(i) == 1
            ln = lqLines.get(i)
            lb = lqLabels.get(i)
            pr = lqPrice.get(i)
            line.set_x2(ln, bar_index + 2)
            label.set_x(lb, bar_index + 2)
            if barstate.isconfirmed
                if lqDir.get(i) == 1
                    if high > pr and close < pr
                        line.set_color(ln, color.new(silvCol, 60))
                        line.set_style(ln, line.style_dashed)
                        label.set_text(lb, "EQH Swept ✕")
                        label.set_textcolor(lb, color.new(silvCol, 35))
                        lqActive.set(i, 0)
                        evSweepBuy := true
                        lastBuySweepBar := bar_index
                        liqStatus := "Buy swept"
                    else if close > pr
                        line.set_color(ln, color.new(silvCol, 70))
                        label.set_textcolor(lb, color.new(silvCol, 55))
                        lqActive.set(i, 0)
                else
                    if low < pr and close > pr
                        line.set_color(ln, color.new(silvCol, 60))
                        line.set_style(ln, line.style_dashed)
                        label.set_text(lb, "EQL Swept ✕")
                        label.set_textcolor(lb, color.new(silvCol, 35))
                        lqActive.set(i, 0)
                        evSweepSell := true
                        lastSellSweepBar := bar_index
                        liqStatus := "Sell swept"
                    else if close < pr
                        line.set_color(ln, color.new(silvCol, 70))
      

Показано первые 50% кода (символов: 19033)

Открыть по тарифу

Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.

Разовая покупка файла

На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.

Чтобы оформить заказ, введите email и перейдите к оплате.

Стоимость полного кода
1 903,30₽ ≈ $23.26