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

FX EVO Delta Profile

indicator fx evo delta profile for tradingview.pine
Вы автор или правообладатель?

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

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

О программе

FX EVO Delta Profile — индикатор для TradingView, построенный на Pine Script v6. Он анализирует ликвидностные зоны на графике, разделяя их на квадранты и отслеживая объёмный дельта-профиль внутри каждой зоны.

Индикатор строит зоны покупки (BSL) на основе значимых максимумов и зоны продажи (SSL) на основе значимых минимумов. Каждая зона разбивается на четыре квадранта, цвет которых отражает доминирование покупательского или продавательского объёма. По мере поглощения объёма «здоровье» зоны снижается от 100% до 0%.

При снятии ликвидности индикатор проверяет паттерны объёма и генерирует четыре типа сигналов: ABS (поглощение на экстремуме), EXH (исчерпание), DIV (дивергенция дельты) и REJ (откат). Результаты отображаются на информационной панели с расчётом процента побед по каждому типу сигнала.

Дельта оценивается на основе OHLCV данных свечей, а не реального стакана заявок. Индикатор носит исключительно образовательный характер и не является финансовой рекомендацией.

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

НастройкаОписание
length Длина поиска пивотов для определения основных максимумов и минимумов на графике.
maxZones Максимальное количество активных и исторических зон покупки и продажи, отображаемых одновременно на графике.
showSwept Отображение зон после того, как цена их прошла (прорвала), с пунктирным контуром и сниженной непрозрачностью.
filterOverlaps При включении предотвращает создание новых зон, пересекающихся с активными. Сохраняется только наиболее значимый уровень.
showDecay Отображение оставшегося «здоровья» активных зон в процентах рядом с зоной.
zoneCapacity Множитель среднего объёма, определяющий, сколько объёма зона может поглотить до полной потери «здоровья».
enableReversals Включение обнаружения разворотных сигналов при снятии ликвидности с зон. Отображает метки ABS, EXH, DIV, REJ.
dashboardInput Включение или отключение информационной панели с результатами сигналов на графике.
dashboardPositionInput Расположение информационной панели на графике: верхний правый, нижний правый или нижний левый угол.
dashboardSizeInput Размер текста в информационной панели: от очень маленького до очень большого.
dashboardWindowInput Максимальное количество баров для ожидания разворота после генерации сигнала.
dashboardHoldInput Количество последовательных баров, в течение которых цена должна удерживаться в прибыли для признания сигнала победившим.
dashboardHighlightInput Подсветка баров, находящихся в процессе оценки: жёлтым при оценке и аквамариновым при удержании в прибыли.
bslColor Цвет контура зон покупки (BSL), расположенных выше текущей цены.
sslColor Цвет контура зон продажи (SSL), расположенных ниже текущей цены.
buyDeltaColor Цвет заливки квадрантов при доминировании покупательского объёма внутри зоны.
sellDeltaColor Цвет заливки квадрантов при доминировании продавательского объёма внутри зоны.
showBrand Отображение водяного знака бренда FX EVO на графике.
brandPos Положение водяного знака бренда на графике: внизу по центру или вверху по центру.
Получить полный код

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

indicator("FX EVO Delta Profile", "FX EVO DP", overlay = true, max_boxes_count = 500, max_labels_count = 500)

color DATA              = #DBDBDB
color HEADERS           = #808080
color BACKGROUND        = #151922
color BORDERS           = #5C4A1A
color BRAND_GOLD        = #FBBD23
color BRAND_DEEP        = color.new(#151922, 8)

string BRAND_NAME       = 'FX EVO Delta Profile'

string TOP_RIGHT        = 'Top Right'
string BOTTOM_RIGHT     = 'Bottom Right'
string BOTTOM_LEFT      = 'Bottom Left'

string TINY             = 'Tiny'
string SMALL            = 'Small'
string NORMAL           = 'Normal'
string LARGE            = 'Large'
string HUGE             = 'Huge'

string DASHBOARD_GROUP  = 'Dashboard'
string BRAND_GROUP      = '⚡ Branding'

length = input.int(15, "Pivot Length", minval = 2, tooltip = "Lookback and lookforward length for detecting major swing highs/lows.")
maxZones = input.int(10, "Max Zones per Type", minval = 1, maxval = 40, tooltip = "Maximum number of active/historical buy and sell zones to keep on the chart.")
showSwept = input.bool(true, "Show Swept Zones", tooltip = "Keep zones visible (with dashed outlines and reduced opacity) after price sweeps them.")
filterOverlaps = input.bool(true, "Filter Overlapping Zones", tooltip = "When enabled, prevents creating new zones that overlap with existing active zones. Only the most significant (highest for BSL, lowest for SSL) level is kept.")

showDecay = input.bool(true, "Show Zone Decay", tooltip = "Displays the remaining 'health' of active zones based on the volume traded inside them. Health drops from 100% to 0%.")
zoneCapacity = input.float(5.0, "Zone Volume Capacity", minval = 1.0, tooltip = "Multiplier for average volume to determine how much volume a zone can absorb before reaching 0% health.")

enableReversals = input.bool(true, "Enable Reversal Detection", group = "Reversals", tooltip = "Detects unusual volume delta patterns during liquidity sweeps to signal potential reversals. Plots a bubble with signal type (ABS, EXH, DIV, REJ) and hover tooltip.")

dashboardInput          = input.bool(   true,       'Show Dashboard',    group = DASHBOARD_GROUP, tooltip = 'Enable or disable the dashboard.')
dashboardPositionInput  = input.string( TOP_RIGHT,  'Position',          group = DASHBOARD_GROUP, tooltip = 'Select the dashboard location.', options = [TOP_RIGHT, BOTTOM_RIGHT, BOTTOM_LEFT])
dashboardSizeInput      = input.string( TINY,       'Size',              group = DASHBOARD_GROUP, tooltip = 'Select the dashboard size.', options = [TINY, SMALL, NORMAL, LARGE, HUGE])
dashboardWindowInput    = input.int(    10,         'Eval Window (Bars)', group = DASHBOARD_GROUP, minval = 1, tooltip = 'Maximum number of bars to wait for the reversal to occur.')
dashboardHoldInput      = input.int(    3,          'Hold Time (Bars)',   group = DASHBOARD_GROUP, minval = 1, tooltip = 'Number of consecutive bars price must stay in profit (opposite direction) to be considered a win.')
dashboardHighlightInput = input.bool(   false,      'Highlight Eval Bars',group = DASHBOARD_GROUP, tooltip = 'Highlights bars actively evaluated. Yellow = Evaluating, Aqua = Holding in profit.')

bslColor = input.color(color.new(#f23645, 0), "BSL Outline Color", group = "Style", tooltip = "Color for Buy-Side Liquidity zones (above price).")
sslColor = input.color(color.new(#089981, 0), "SSL Outline Color", group = "Style", tooltip = "Color for Sell-Side Liquidity zones (below price).")

buyDeltaColor = input.color(color.new(#089981, 0), "Buy Delta Fill", group = "Style", tooltip = "Fill color when buy volume dominates a zone quadrant.")
sellDeltaColor = input.color(color.new(#f23645, 0), "Sell Delta Fill", group = "Style", tooltip = "Fill color when sell volume dominates a zone quadrant.")

showBrand = input.bool(true, "Show FX EVO Watermark", group = BRAND_GROUP, tooltip = "Display the FX EVO Delta Profile brand badge on the chart.")
brandPos = input.string("Bottom Center", "Watermark Position", options = ["Bottom Center", "Top Center"], group = BRAND_GROUP)

type Zone
    float top
    float bottom
    int left
    int right
    bool swept
    bool signaled
    box[] quads
    float[] deltas
    box outline
    float volumeTraded
    float capacity
    bool wasHit
    label decayLabel

type Trade
    string type
    int dir
    float entry
    int entryBar
    bool active
    bool won
    int consecBars

var Zone[] bslZones = array.new<Zone>()
var Zone[] sslZones = array.new<Zone>()

var activeTrades = array.new<Trade>()

var int absTotal = 0
var int absWins = 0
var int exhTotal = 0
var int exhWins = 0
var int divTotal = 0
var int divWins = 0
var int rejTotal = 0
var int rejWins = 0

var string parsedDashboardPosition = switch dashboardPositionInput
    TOP_RIGHT       => position.top_right
    BOTTOM_RIGHT    => position.bottom_right
    BOTTOM_LEFT     => position.bottom_left
    => position.top_right

var string parsedDashboardSize     = switch dashboardSizeInput
    TINY            => size.tiny
    SMALL           => size.small
    NORMAL          => size.normal
    LARGE           => size.large
    HUGE            => size.huge
    => size.normal

var table t_able = table.new(parsedDashboardPosition, 4, 11, bgcolor = dashboardInput ? BACKGROUND : na, border_width = 0, frame_color = dashboardInput ? BORDERS : na, frame_width = 1, force_overlay = true)

cell(table t_able, int col, int r, string data, color txtColor = color.white, string align = text.align_right, color background = na, float h = 0) =>
    t_able.cell(col, r, data, text_color = txtColor, text_size = parsedDashboardSize, text_halign = align, bgcolor = background, height = h)

divider(table t_able, int r, int lastColumn) =>
    string rowDivider = '━━━━━━━━━━━━━━━━'
    t_able.merge_cells(0, r, lastColumn, r)
    cell(t_able, 0, r, rowDivider, txtColor = BORDERS, align = text.align_center, h = 0.5)

method evaluateReversals(Zone z, bool isBsl, float barH, float barL, float barC, float barO, float barDelta, float barVol) =>
    if enableReversals and not z.signaled
        float totalD = 0.0
        float absTotalD = 0.0
        for d in z.deltas
            totalD += d
            absTotalD += math.abs(d)

        if absTotalD > 0
            int outerIdx = isBsl ? 3 : 0
            float outerD = z.deltas.get(outerIdx)

            bool isSweeping = isBsl ? barH > z.top : barL < z.bottom
            bool closesInside = isBsl ? (barC <= z.top and barC >= z.bottom) : (barC >= z.bottom and barC <= z.top)
            float midPoint = (z.top + z.bottom) / 2
            bool closesRejecting = isBsl ? barC < midPoint : barC > midPoint

            string signalType = ""
            string tooltipTxt = ""
            float significance = 0.0
            color sigColor = isBsl ? color.red : color.green // Reversing from Resistance is Bearish (Red), from Support is Bullish (Green)

            if isSweeping and ((isBsl and outerD < 0) or (not isBsl and outerD > 0))
                float ratio = math.abs(outerD) / (absTotalD + 0.0001)
                if ratio > 0.2
                    signalType := "ABS"
                    tooltipTxt := "Absorption at Extreme\n" + (isBsl ? "Sellers" : "Buyers") + " aggressively absorbed the sweep.\nOuter Quadrant Delta: " + str.tostring(outerD, format.volume)
                    significance := ratio * 2

            if signalType == "" and isSweeping
                float ratio = math.abs(outerD) / (absTotalD + 0.0001)
                if ratio < 0.1
                    signalType := "EXH"
                    tooltipTxt := "Exhaustion (Dry Sweep)\nMinimal volume at the extreme edge.\nOuter Quadrant Delta: " + str.tostring(outerD, format.volume)
                    significance := 1.0 - (ratio * 5)

            if signalType == "" and closesInside
                float ratio = math.abs(outerD) / (absTotalD + 0.0001)
                if ratio > 0.6 and ((isBsl and outerD > 0) or (not isBsl and outerD < 0))
                    signalType := "DIV"
                    tooltipTxt := "Delta Divergence (FOMO)\nHigh volume trapped at the extreme, but price failed to breakout.\nOuter Quadrant Delta: " + str.tostring(outerD, format.volume)
                    significance := ratio

            if signalType == "" and isSweeping and closesRejecting
                float barRatio = math.abs(barDelta) / (barVol + 0.0001)
                if ((isBsl and barDelta < 0) or (not isBsl and barDelta > 0)) and barRatio > 0.2
                    signalType := "REJ"
                    tooltipTxt := "Snapback Rejection\nSweep followed by immediate strong rejection.\nBar Delta: " + str.tostring(barDelta, format.volume)
                    significance := barRatio * 2

            if signalType != ""
                z.signaled := true
                alert(BRAND_NAME + ": Reversal Signal (" + signalType + ") detected at " + str.tostring(barC), alert.freq_once_per_bar)

                significance := math.min(math.max(significance, 0.0), 1.0)
                string sSize = size.tiny
                int trans = 50

                if significance > 0.7
                    sSize := size.normal
                    trans := 10
                else if significance > 0.4
                    sSize := size.small
                    trans := 30

                color finalColor = color.new(sigColor, trans)
                float yLoc = isBsl ? barH : barL
                string labelStyle = isBsl ? label.style_label_down : label.style_label_up

                label.new(bar_index, yLoc, text=signalType, color=finalColor, style=labelStyle, textcolor=color.white, size=sSize, tooltip=tooltipTxt)

                float entry = barC
                activeTrades.push(Trade.new(signalType, isBsl ? -1 : 1, entry, bar_index, true, false, 0))

method updateVisuals(Zone z, bool isBsl, bool showS, color buyC, color sellC, color bslC, color sslC) =>
    float maxD = 0.0
    for d in z.deltas
        maxD := math.max(maxD, math.abs(d))

    for i = 0 to 3
        float d = z.deltas.get(i)
        color c = na
        string txt = ""
        color tColor = na
        if maxD > 0 and math.abs(d) > 0.001
            color baseC = d > 0 ? buyC : sellC
            int trans = z.swept ? 90 : 100 - int((math.abs(d) / maxD) * 60)
            c := color.rgb(color.r(baseC), color.g(baseC), color.b(baseC), trans)
            txt := (d > 0 ? "+" : d < 0 ? "-" : "") + str.tostring(math.abs(d), format.volume)
            tColor := color.new(baseC, z.swept ? 50 : 0)
        else
            color baseC = isBsl ? bslC : sslC
            int defaultTrans = 60 + (isBsl ? (3 - i) : i) * 10
            c := color.rgb(color.r(baseC), color.g(baseC), color.b(baseC), z.swept ? 90 : defaultTrans)
            txt := "0"
            tColor := color.new(baseC, z.swept ? 80 : 50)

        box q = z.quads.get(i)
        q.set_bgcolor(not showS and z.swept ? na : c)
        q.set_text(not showS and z.swept ? "" : txt)
        q.set_text_color(not showS and z.swept ? na : tColor)

        if z.swept
            q.set_border_color(not showS ? na : color.new(isBsl ? bslC : sslC, 80))
            q.set_border_style(line.style_dashed)
        else
            q.set_border_color(color.new(isBsl ? bslC : sslC, 60))
            q.set_border_style(line.style_solid)

    if z.swept
        if showS
            z.outline.set_border_style(line.style_dashed)
            z.outline.set_border_color(color.new(isBsl ? bslC : sslC, 80))
        else
            z.outline.set_border_color(na)

barOverlap(float barH, float barL, float qTop, float qBot) =>
    float overlapTop = math.min(barH, qTop)
    float overlapBot = math.max(barL, qBot)
    overlapTop > overlapBot ? (overlapTop - overlapBot) : 0.0

float atr = ta.atr(14)
float ph = ta.pivothigh(high, length, length)
float pl = ta.pivotlow(low, length, length)
float avgVol = nz(ta.sma(volume, length))
if avgVol == 0
    avgVol := 1
float currentZoneCap = avgVol * zoneCapacity

if not na(ph) and bar_index >= length
    int pivotIdx = bar_index - length
    float pHigh = high[length]
    float pBot = math.max(close[length], open[length])
    if pHigh - pBot < atr[length] * 0.1
        pBot := pHigh - atr[length] * 0.1

    bool skip = false
    if filterOverlaps and bslZones.size() > 0
        for i = bslZones.size() - 1 to 0
            if i < bslZones.size()
                Zone ex = bslZones.get(i)
                if not ex.swept
                    bool overlaps = math.max(pBot, ex.bottom) <= math.min(pHigh, ex.top)
                    if overlaps
                        if pHigh > ex.top
                            for b in ex.quads
                                b.delete()
                            ex.outline.delete()
                            ex.decayLabel.delete()
                            bslZones.remove(i)
                        else
                            skip := true
                            break

    if not skip
        box[] quads = array.new<box>(4)
        float[] deltas = array.new<float>(4, 0.0)
        float step = (pHigh - pBot) / 4
        for i = 0 to 3
            float qBot = pBot + i * step
            float qTop = pBot + (i + 1) * step
            color baseC = bslColor
            int trans = 

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

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

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

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

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

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

Стоимость полного кода
1 767₽ ≈ $22