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