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

AetherEdge - Liquidity Sweep & Raid Detector

aetheredge liquidity sweep for tradingview.pine
Вы автор или правообладатель?

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

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

О программе

AetherEdge — Liquidity Sweep & Raid Detector — это индикатор для TradingView, написанный на Pine Script v5. Он анализирует структуру цены и уровни ликвидности на графике, отображая линии, метки и информационную панель. Индикатор предназначен для визуального анализа свопов ликвидности, равных уровней и зон охоты на стопы.

Основные функции индикатора: обнаружение точек разворота (сплайнов) с фильтрацией по значимости через ATR; определение равных максимумов и минимумов (пулов ликвидности) с настраиваемым допуском; выявление ликвидность-свипов, когда цена пробивает уровень сплайна и возвращается обратно; проецирование зон охоты на стопы с настраиваемым затуханием; маркировка точек пробоя структуры (BOS).

Визуализация включает настраиваемую информационную панель с статистикой по свипам и пулам ликвидности, цветовые настройки для всех элементов, тёмную и светлую тему. Индикатор поддерживает условия оповещений TradingView для бычьих и медвежьих свипов, пробоя структуры и формирования равных уровней.

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

НастройкаОписание
pivLen Количество баров слева и справа от точки для определения сплайнов (точек разворота) на графике.
useATRFilter Включает фильтрацию сплайнов по значимости: сплайны с движением меньше заданного кратного ATR игнорируются.
atrLen Период расчёта ATR (среднего истинного диапазона), используемого для фильтрации значимости сплайнов и определения размеров зон.
atrMinMult Минимальный размер сплайна в кратных ATR. Сплайны меньше этого значения считаются незначительными и не учитываются.
useEQ Включает обнаружение равных максимумов и минимумов (Equal Highs/Lows) — пулов ликвидности.
eqTolerance Допуск равенства уровней в кратных ATR. Если разница между двумя максимумами или минимумами не превышает это значение, они считаются равными.
eqLookback Глубина поиска в барах для сравнения текущего пивота с предыдущими при обнаружении равных уровней.
eqMinDistance Минимальное количество баров между соседними равными уровнями для их признания отдельными.
extendEQ Продлевать линии равных максимумов и минимумов вправо по графику.
useSweep Включает обнаружение ликвидность-свипов — случаев, когда цена временно пробивает уровень сплайна и возвращается обратно.
sweepMode Режим подтверждения ликвидность-свипа: только по хигу (Wick Only), по закрытию внутри уровня (Close Back) или комбинация обоих условий (Wick + Close Back).
sweepMaxBars Максимальное количество баров, в течение которых ожидается возврат закрытия внутрь уровня для подтверждения свипа.
sweepMinWick Минимальный размер хига свечи в кратных ATR, необходимый для признания свипа ликвидности.
requireReverse Требовать свечной разворот (закрытие противоположно направлению свипа) для подтверждения ликвидность-свипа.
useStopHunt Включает проецирование и отображение зон охоты на стопы (Stop Hunt Zones) на графике.
zoneExtend Продление зон охоты на стопы вправо от точки обнаружения в барах.
zoneHeightATR Высота зон охоты на стопы в кратных ATR от уровня пробоя.
mitigateMode Режим обработки зон охоты на стопы при касании цены: сохранение (Keep), затухание (Fade on Touch) или удаление (Remove on Touch).
darkMode Включает тёмную тему отображения информационной панели и графических элементов.
showPivots Отображать графические маркеры точек разворота (сплайнов) на графике.
showLabels Отображать текстовые подписи (метки) свипов ликвидности на графике.
showBOS Отображать маркеры точек пробоя структуры (Break of Structure) на графике.
showDash Отображать информационную панель со статистикой по свипам, пулам ликвидности и текущему состоянию рынка.
dashPos Положение информационной панели на графике: верхний правый, верхний левый, средний правый, средний левый, нижний правый или нижний левый угол.
maxObjects Максимальное количество исторических объектов (линий, меток, коробок), отображаемых на графике. Старые объекты удаляются при превышении лимита.
cBullSweep Цвет линий и меток бычьих свипов (захват минимумов цены).
cBearSweep Цвет линий и меток медвежьих свипов (захват максимумов цены).
cEQHigh Цвет линий, обозначающих равные максимумы (Equal Highs).
cEQLow Цвет линий, обозначающих равные минимумы (Equal Lows).
cStopHunt Цвет зон охоты на стопы (Stop Hunt Zones).
cBOS Цвет линий и маркеров точек пробоя структуры (Break of Structure).
Получить полный код

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

indicator("AetherEdge - Liquidity Sweep & Raid Detector", "AE-LiqSweep",
     overlay=true,
     max_lines_count=500,
     max_labels_count=500,
     max_boxes_count=500,
     max_bars_back=1000)

grpPv = "① Pivot / Swing Structure"
pivLen       = input.int(10, "Swing Lookback (left/right)", minval=2, maxval=50, group=grpPv,
                 tooltip="Number of left and right bars for detecting swing points")
useATRFilter = input.bool(true, "Use ATR Filter for Significance", group=grpPv)
atrLen       = input.int(14, "ATR Length", minval=1, group=grpPv)
atrMinMult   = input.float(0.3, "Min Swing Size (x ATR)", minval=0.1, step=0.1, group=grpPv,
                 tooltip="How many times the ATR movement is considered a significant swing")

grpEq = "② Equal Highs / Lows (Liquidity Pools)"
useEQ         = input.bool(true, "Detect Equal Highs/Lows", group=grpEq)
eqTolerance   = input.float(0.1, "Equal Tolerance (x ATR)", minval=0.01, step=0.01, group=grpEq,
                 tooltip="Within this range, values are considered equal (ATR multiplier)")
eqLookback    = input.int(50, "Equal Pivot Scan Range (bars)", minval=5, group=grpEq)
eqMinDistance = input.int(3, "Min Bars Between Equals", minval=1, group=grpEq)
extendEQ      = input.bool(true, "Extend EQ Lines Right", group=grpEq)

grpSweep = "③ Liquidity Sweep / Grab Detection"
useSweep      = input.bool(true, "Detect Liquidity Sweeps", group=grpSweep)
sweepMode     = input.string("Wick + Close Back", "Sweep Confirmation",
                 options=["Wick Only","Close Back","Wick + Close Back"], group=grpSweep,
                 tooltip="Wick Only: updated by wick / Close Back: close returns inside / Wick + Close Back: both")
sweepMaxBars  = input.int(3, "Max Bars for Close-Back Confirm", minval=1, maxval=10, group=grpSweep)
sweepMinWick  = input.float(0.3, "Min Wick Size (x ATR)", minval=0.0, step=0.05, group=grpSweep,
                 tooltip="Minimum wick size to be judged as a sweep")
requireReverse= input.bool(true, "Require Reversal Candle", group=grpSweep)

grpStopHunt = "④ Stop Hunt Zone"
useStopHunt   = input.bool(true, "Project Stop Hunt Zones", group=grpStopHunt)
zoneExtend    = input.int(20, "Zone Extension (bars)", minval=5, group=grpStopHunt)
zoneHeightATR = input.float(0.4, "Zone Height (x ATR)", minval=0.1, step=0.1, group=grpStopHunt)
mitigateMode  = input.string("Fade on Touch", "Zone Fade Mode",
                 options=["Keep","Fade on Touch","Remove on Touch"], group=grpStopHunt)

grpD = "🎨 Display"
darkMode     = input.bool(true, "Dark Mode", group=grpD)
showPivots   = input.bool(false, "Show Pivot Markers", group=grpD)
showLabels   = input.bool(true, "Show Sweep Labels", group=grpD)
showBOS      = input.bool(true, "Mark Break of Structure", group=grpD)
showDash     = input.bool(true, "Show Dashboard", group=grpD)
dashPos      = input.string("Top Right", "Dashboard Position",
                 options=["Top Right","Top Left","Middle Right","Middle Left","Bottom Right","Bottom Left"], group=grpD)
maxObjects   = input.int(30, "Max Historical Objects", minval=5, maxval=100, group=grpD,
                 tooltip="Maximum number of past sweep/EQ lines to keep")

grpC = "🎨 Colors"
cBullSweep  = input.color(#00d4a0, "Bullish Sweep (Low Grab)",  group=grpC, inline="c1")
cBearSweep  = input.color(#ff5577, "Bearish Sweep (High Grab)", group=grpC, inline="c1")
cEQHigh     = input.color(#ff9500, "Equal Highs",               group=grpC, inline="c2")
cEQLow      = input.color(#4dabf7, "Equal Lows",                group=grpC, inline="c2")
cStopHunt   = input.color(#c084fc, "Stop Hunt Zone",            group=grpC, inline="c3")
cBOS        = input.color(#ffd43b, "BOS Line",                  group=grpC, inline="c3")

cBg     = darkMode ? color.new(#0b1221, 10) : color.new(#f7f9fc, 10)
cBgAlt  = darkMode ? color.new(#111a2e, 15) : color.new(#ffffff, 0)
cBorder = darkMode ? color.new(#1f2a44, 0)  : color.new(#d8dee9, 0)
cText   = darkMode ? color.new(#e6edf7, 0)  : color.new(#1a202c, 0)
cMute   = darkMode ? color.new(#8892b0, 0)  : color.new(#64748b, 0)
cAccent = color.new(#00d4ff, 0)

atr = ta.atr(atrLen)
atrSig = atr * atrMinMult

ph = ta.pivothigh(high, pivLen, pivLen)
pl = ta.pivotlow(low,   pivLen, pivLen)

phValid = not na(ph) and (not useATRFilter or (ph - ta.lowest(low, pivLen * 2) >= atrSig))
plValid = not na(pl) and (not useATRFilter or (ta.highest(high, pivLen * 2) - pl >= atrSig))

var array<float> phPrice = array.new<float>()
var array<int>   phBar   = array.new<int>()
var array<bool>  phSwept = array.new<bool>()
var array<float> plPrice = array.new<float>()
var array<int>   plBar   = array.new<int>()
var array<bool>  plSwept = array.new<bool>()

if phValid
    array.push(phPrice, ph)
    array.push(phBar,   bar_index - pivLen)
    array.push(phSwept, false)
    if array.size(phPrice) > 50
        array.shift(phPrice)
        array.shift(phBar)
        array.shift(phSwept)

if plValid
    array.push(plPrice, pl)
    array.push(plBar,   bar_index - pivLen)
    array.push(plSwept, false)
    if array.size(plPrice) > 50
        array.shift(plPrice)
        array.shift(plBar)
        array.shift(plSwept)

plotshape(showPivots and phValid ? ph : na, "PH", shape.triangledown, location.abovebar,
     color=color.new(cBearSweep, 50), size=size.tiny, offset=-pivLen)
plotshape(showPivots and plValid ? pl : na, "PL", shape.triangleup,   location.belowbar,
     color=color.new(cBullSweep, 50), size=size.tiny, offset=-pivLen)

var array<line> eqHighLines = array.new<line>()
var array<line> eqLowLines  = array.new<line>()

f_pruneLineArr(arr, maxN) =>
    while array.size(arr) > maxN
        oldest = array.shift(arr)
        line.delete(oldest)

if useEQ and phValid and array.size(phPrice) >= 2
    curPrice = ph
    curBar = bar_index - pivLen
    tolerance = atr * eqTolerance

    for i = array.size(phPrice) - 2 to math.max(0, array.size(phPrice) - eqLookback) by 1
        prevPrice = array.get(phPrice, i)
        prevBar = array.get(phBar, i)
        if (curBar - prevBar) >= eqMinDistance and math.abs(curPrice - prevPrice) <= tolerance
            midPrice = (curPrice + prevPrice) / 2
            ln = line.new(prevBar, midPrice, curBar, midPrice,
                 color=color.new(cEQHigh, 20), width=2, style=line.style_dashed,
                 extend=extendEQ ? extend.right : extend.none)
            array.push(eqHighLines, ln)
            if showLabels
                label.new(curBar, midPrice, "EQH",
                     color=color.new(cEQHigh, 30), textcolor=color.white,
                     style=label.style_label_down, size=size.small)
            break

if useEQ and plValid and array.size(plPrice) >= 2
    curPrice = pl
    curBar = bar_index - pivLen
    tolerance = atr * eqTolerance
    for i = array.size(plPrice) - 2 to math.max(0, array.size(plPrice) - eqLookback) by 1
        prevPrice = array.get(plPrice, i)
        prevBar = array.get(plBar, i)
        if (curBar - prevBar) >= eqMinDistance and math.abs(curPrice - prevPrice) <= tolerance
            midPrice = (curPrice + prevPrice) / 2
            ln = line.new(prevBar, midPrice, curBar, midPrice,
                 color=color.new(cEQLow, 20), width=2, style=line.style_dashed,
                 extend=extendEQ ? extend.right : extend.none)
            array.push(eqLowLines, ln)
            if showLabels
                label.new(curBar, midPrice, "EQL",
                     color=color.new(cEQLow, 30), textcolor=color.white,
                     style=label.style_label_up, size=size.small)
            break

f_pruneLineArr(eqHighLines, maxObjects)
f_pruneLineArr(eqLowLines,  maxObjects)

var array<int>   pendingSwHBar    = array.new<int>()
var array<float> pendingSwHLevel  = array.new<float>()
var array<int>   pendingSwHOrigin = array.new<int>()
var array<int>   pendingSwLBar    = array.new<int>()
var array<float> pendingSwLLevel  = array.new<float>()
var array<int>   pendingSwLOrigin = array.new<int>()

var int totalBullSweeps = 0
var int totalBearSweeps = 0
var int totalEQH = 0
var int totalEQL = 0
var int activeStopHunts = 0

var string lastSweepType = "—"
var int    lastSweepBar  = 0
var float  lastSweepLvl  = na

var array<line>  sweepLines = array.new<line>()
var array<label> sweepLabels = array.new<label>()
var array<box>   stopHuntBoxes = array.new<box>()

f_pruneLineArrSim(arr, maxN) =>
    while array.size(arr) > maxN
        oldest = array.shift(arr)
        line.delete(oldest)

f_pruneLabelArr(arr, maxN) =>
    while array.size(arr) > maxN
        oldest = array.shift(arr)
        label.delete(oldest)

f_pruneBoxArr(arr, maxN) =>
    while array.size(arr) > maxN
        oldest = array.shift(arr)
        box.delete(oldest)

if useSweep and array.size(phPrice) > 0
    wickSize = high - math.max(open, close)
    wickOK = wickSize >= atr * sweepMinWick
    for i = array.size(phPrice) - 1 to 0
        pvPrice = array.get(phPrice, i)
        pvBar   = array.get(phBar, i)
        wasSwept = array.get(phSwept, i)
        if not wasSwept and high > pvPrice and (bar_index - pvBar) <= 200

            array.set(phSwept, i, true)
            if wickOK
                if sweepMode == "Wick Only"

                    if close < pvPrice and (not requireReverse or close < open)
                        ln = line.new(pvBar, pvPrice, bar_index, pvPrice,
                             color=color.new(cBearSweep, 0), width=2, style=line.style_solid)
                        array.push(sweepLines, ln)
                        if showLabels
                            lb = label.new(bar_index, high, "✗ Sweep H",
                                 color=color.new(cBearSweep, 10), textcolor=color.white,
                                 style=label.style_label_down, size=size.small)
                            array.push(sweepLabels, lb)
                        if useStopHunt
                            topZ = high
                            botZ = high - atr * zoneHeightATR
                            bx = box.new(bar_index, topZ, bar_index + zoneExtend, botZ,
                                 border_color=color.new(cStopHunt, 40),
                                 bgcolor=color.new(cStopHunt, 85),
                                 border_width=1)
                            array.push(stopHuntBoxes, bx)
                            activeStopHunts += 1
                        totalBearSweeps += 1
                        lastSweepType := "Bearish (High Grab)"
                        lastSweepBar  := bar_index
                        lastSweepLvl  := pvPrice
                else

                    array.push(pendingSwHBar, bar_index)
                    array.push(pendingSwHLevel, pvPrice)
                    array.push(pendingSwHOrigin, pvBar)
            break

if useSweep and array.size(plPrice) > 0
    wickSize = math.min(open, close) - low
    wickOK = wickSize >= atr * sweepMinWick
    for i = array.size(plPrice) - 1 to 0
        pvPrice = array.get(plPrice, i)
        pvBar   = array.get(plBar, i)
        wasSwept = array.get(plSwept, i)
        if not wasSwept and low < pvPrice and (bar_index - pvBar) <= 200
            array.set(plSwept, i, true)
            if wickOK
                if sweepMode == "Wick Only"
                    if close > pvPrice and (not requireReverse or close > open)
                        ln = line.new(pvBar, pvPrice, bar_index, pvPrice,
                             color=color.new(cBullSweep, 0), width=2, style=line.style_solid)
                        array.push(sweepLines, ln)
                        if showLabels
                            lb = label.new(bar_index, low, "✗ Sweep L",
                                 color=color.new(cBullSweep, 10), textcolor=color.white,
                                 style=label.style_label_up, size=size.small)
                            array.push(sweepLabels, lb)
                        if useStopHunt
                            topZ = low + atr * zoneHeightATR
                            botZ = low
                            bx = box.new(bar_index, topZ, bar_index + zoneExtend, botZ,
                                 border_color=color.new(cStopHunt, 40),
                                 bgcolor=color.new(cStopHunt, 85),
                                 border_width=1)
                            array.push(stopHuntBoxes, bx)
                            activeStopHunts += 1
                        totalBullSweeps += 1
                        lastSweepType := "Bullish (Low Grab)"
                        lastSweepBar  := bar_index
                        lastSweepLvl  := pvPrice
                else
                    array.push(pendingSwLBar, bar_index)
                    array.push(pendingSwLLevel, pvPrice)
                    array.push(pendingSwLOrigin, pvBar)
            break

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

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

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

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

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

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

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