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? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.