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

Liquidity Reaper

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

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

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

О программе

Индикатор «Liquidity Reaper» — это инструмент анализа ликвидности для TradingView, написанный на Pine Script v6. Он обнаруживает свинг-хаи и свинг-лоу как пулы ликвидности и отслеживает моменты, когда цена «рейдит» (пробивает по фити) эти уровни. При подтверждении возвратом закрытия внутрь пула в заданном окне индикатор фиксирует валидный спрей и отображает его на графике.

Визуализация включает горизонтальные линии непролитой ликвидности (rails), подсвеченные зоны спрея (swept zones) и подписи сигналов с указанием направления и относительного объёма. Доступен фильтр объёма, требующий расширения торгового объёма выше среднего.

Индикатор также содержит движок TP/SL с настраиваемыми уровнями стоп-лосса и трёх целей на основе ATR или процентов, а также панель дашборда с информацией о количестве пулов, ближайших уровнях, импульсе объёма, статистике рейдов, статусе позиции и ожидающих спреях. Доступны условие оповещения для покупательских и продавательских рейдов.

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

НастройкаОписание
pivotLen Количество баров слева и справа для подтверждения свинг-хая или свинг-лоу как пула ликвидности. Больше значение — меньше, но более значимых пулов.
confirmWindow Количество баров, в течение которых после пробития пула закрытие должно вернуться внутрь пула для подтверждения спрея.
maxPools Максимальное количество активных линий пулов ликвидности с каждой стороны. При превышении старейшие линии удаляются.
minWickPct Минимальный процент фити пробития от диапазона свечи, необходимый для признания спрея валидным. Фильтрует слабые зондирования.
useVolFilter Включает или отключает фильтр расширения объёма. При включении сигналы спрея требуют объём выше среднего значения.
volLen Период скользящей средней объёма, используемой для фильтра расширения.
volMultReq Минимальный множитель объёма относительно средней, требуемый для подтверждения сигнала при включённом фильтре.
showSignalLabels Включает или отключает подписи сигналов спрея, показывающие направление и относительный объём рейда.
labelSizeStr Размер подписей сигналов спрея: Tiny, Small или Normal.
showTriangles Включает или отключает графические треугольники-индикаторы сигналов спрея на графике.
showRails Включает или отключает отображение линий непролитой ликвидности (rails).
railStyleStr Стиль линий непролитой ликвидности: Solid, Dashed или Dotted.
railTransp Прозрачность линий непролитой ликвидности (0 — непрозрачные, 100 — полностью прозрачные).
showZones Включает или отключает отображение зон спрея (frost box) от уровня пула до крайней точки фити.
zoneTransp Прозрачность зон спрея (0 — непрозрачные, 100 — полностью прозрачные).
zoneLifeBars Время жизни зон спрея в барах. После истечения зоны автоматически удаляются.
buyColor Цвет для обозначения покупательской (бычьей) ликвидности — линий пулов и зон спрея снизу.
sellColor Цвет для обозначения продавательской (медвежьей) ликвидности — линий пулов и зон спрея сверху.
labelTextColor Цвет текста подписей сигналов спрея.
show_targets Включает или отключает отображение уровней TP/SL на графике.
use_atr_sl Переключает способ расчёта стоп-лосса: по множителю ATR или по проценту от цены входа.
tp_atr_period Период ATR, используемый для расчёта уровней TP/SL.
sl_atr_mult Множитель ATR для расчёта стоп-лосса, если включён режим ATR вместо процентов.
sl_percent Процент от цены входа для расчёта стоп-лосса, если режим ATR отключён.
rr_tp1 Соотношение риск/прибыль для первой цели (TP1).
rr_tp2 Соотношение риск/прибыль для второй цели (TP2).
rr_tp3 Соотношение риск/прибыль для третьей цели (TP3).
show_sl_level Включает или отключает отображение уровня стоп-лосса на графике.
show_tp1_level Включает или отключает отображение первой цели (TP1) на графике.
show_tp2_level Включает или отключает отображение второй цели (TP2) на графике.
show_tp3_level Включает или отключает отображение третьей цели (TP3) на графике.
showDash Включает или отключает панель дашборда «Liquidity Reaper» на графике.
dashPos Позиция панели дашборда на графике: верхний левый, верхний правый, нижний левый, нижний правый и другие варианты.
dashSize Размер текста в панели дашборда: Tiny, Small, Normal или Large.
Получить полный код

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

indicator('Liquidity Reaper', shorttitle='REAPER', overlay = true,
     max_lines_count = 500, max_labels_count = 500, max_boxes_count = 500)

pivotLen = input.int(8, 'Swing Strength (bars each side)', minval = 2, maxval = 50, group = 'Liquidity Detection',
     tooltip = 'Bars to the left and right required to confirm a swing high/low as a liquidity pool.\n\nHigher = fewer, more significant pools.')
confirmWindow = input.int(3, 'Sweep Confirmation Window', minval = 1, maxval = 20, group = 'Liquidity Detection',
     tooltip = 'After price wicks through a pool, a confirming close back inside must occur within this many bars for a valid sweep.')
maxPools = input.int(12, 'Max Live Pools Per Side', minval = 2, maxval = 40, group = 'Liquidity Detection',
     tooltip = 'Oldest liquidity rails are recycled once this limit is reached — keeps the chart clean on all timeframes.')
minWickPct = input.float(25, 'Min Sweep Wick (% of range)', minval = 0, maxval = 90, step = 5, group = 'Liquidity Detection',
     tooltip = 'The sweep candle must reject with a wick of at least this % of its range beyond the pool — filters weak pokes.')

useVolFilter = input.bool(true, 'Require Volume Expansion', group = 'Volume Filter',
     tooltip = 'Sweep signals require volume above its average × multiplier.')
volLen = input.int(20, 'Volume MA Length', minval = 1, group = 'Volume Filter')
volMultReq = input.float(1.1, 'Volume Multiplier', minval = 0.5, step = 0.1, group = 'Volume Filter')

showSignalLabels = input.bool(true, 'Show Sweep Labels', group = 'Signals',
     tooltip = 'Labels show direction plus relative volume of the raid, e.g. "RAID BUY · 2.3x".')
labelSizeStr = input.string('Small', 'Label Size', options = ['Tiny', 'Small', 'Normal'], group = 'Signals')
showTriangles = input.bool(false, 'Show Triangle Signals', group = 'Signals')

showRails = input.bool(true, 'Show Unswept Liquidity Rails', group = 'Rails and Zones')
railStyleStr = input.string('Dotted', 'Rail Style', options = ['Solid', 'Dashed', 'Dotted'], group = 'Rails and Zones')
railTransp = input.int(45, 'Rail Transparency', minval = 0, maxval = 100, group = 'Rails and Zones')
showZones = input.bool(true, 'Show Swept Zones', group = 'Rails and Zones',
     tooltip = 'Paints a frost box across the raided range (pool level → sweep wick extreme).')
zoneTransp = input.int(78, 'Zone Transparency', minval = 0, maxval = 100, group = 'Rails and Zones')
zoneLifeBars = input.int(120, 'Zone Lifetime (bars)', minval = 10, maxval = 500, group = 'Rails and Zones')

buyColor = input.color(#38bdf8, 'Buy / Bull Liquidity Color', group = 'Visuals')
sellColor = input.color(#e11d48, 'Sell / Bear Liquidity Color', group = 'Visuals')
labelTextColor = input.color(color.white, 'Label Text Color', group = 'Visuals')

show_targets = input.bool(true, 'Show TP/SL Levels', group = 'TP/SL')
use_atr_sl = input.bool(true, 'SL = ATR × instead of %', group = 'TP/SL')
tp_atr_period = input.int(14, 'ATR Period For TP/SL', minval = 1, group = 'TP/SL')
sl_atr_mult = input.float(1.5, 'ATR Multiplier For SL', step = 0.1, group = 'TP/SL')
sl_percent = input.float(1.0, 'SL % From Entry', step = 0.1, group = 'TP/SL')
rr_tp1 = input.float(1.0, 'RR For TP1', step = 0.1, group = 'TP/SL')
rr_tp2 = input.float(2.0, 'RR For TP2', step = 0.1, group = 'TP/SL')
rr_tp3 = input.float(3.0, 'RR For TP3', step = 0.1, group = 'TP/SL')
show_sl_level = input.bool(true, 'Show SL Level', group = 'TP/SL Display')
show_tp1_level = input.bool(true, 'Show TP1 Level', group = 'TP/SL Display')
show_tp2_level = input.bool(true, 'Show TP2 Level', group = 'TP/SL Display')
show_tp3_level = input.bool(true, 'Show TP3 Level', group = 'TP/SL Display')

showDash = input.bool(true, 'Show Reaper Dashboard', group = 'Reaper Dashboard')
dashPos = input.string('Top Right', 'Dashboard Position',
     options = ['Top Left', 'Top Right', 'Bottom Left', 'Bottom Right', 'Top Center', 'Bottom Center', 'Middle Left', 'Middle Right'],
     group = 'Reaper Dashboard')
dashSize = input.string('Normal', 'Dashboard Text Size', options = ['Tiny', 'Small', 'Normal', 'Large'], group = 'Reaper Dashboard')

type Pool
    line rail
    float lvl
    int born_bar
    bool is_high

type PendingSweep
    float lvl
    float wick_extreme
    int break_bar
    float raid_range
    bool is_high

type SweptZone
    box bx
    int born_bar

var array<Pool> highPools = array.new<Pool>()
var array<Pool> lowPools = array.new<Pool>()
var array<SweptZone> zones = array.new<SweptZone>()
var PendingSweep pendHigh = na
var PendingSweep pendLow = na

float atr_val = ta.atr(tp_atr_period)
float volMA = ta.sma(volume, volLen)
float volMult = volMA > 0 ? volume / volMA : 1.0
bool volOK = not useVolFilter or volMult >= volMultReq

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

railStyle = railStyleStr == 'Solid' ? line.style_solid : railStyleStr == 'Dashed' ? line.style_dashed : line.style_dotted

f_labelSize(string s) =>
    s == 'Tiny' ? size.tiny : s == 'Small' ? size.small : size.normal

if not na(ph)
    line r = na
    if showRails
        r := line.new(bar_index - pivotLen, ph, bar_index, ph, extend = extend.right,
             color = color.new(sellColor, railTransp), style = railStyle, width = 1)
    array.push(highPools, Pool.new(r, ph, bar_index - pivotLen, true))
    if array.size(highPools) > maxPools
        Pool old = array.shift(highPools)
        line.delete(old.rail)

if not na(pl)
    line r = na
    if showRails
        r := line.new(bar_index - pivotLen, pl, bar_index, pl, extend = extend.right,
             color = color.new(buyColor, railTransp), style = railStyle, width = 1)
    array.push(lowPools, Pool.new(r, pl, bar_index - pivotLen, false))
    if array.size(lowPools) > maxPools
        Pool old = array.shift(lowPools)
        line.delete(old.rail)

if array.size(highPools) > 0
    for i = array.size(highPools) - 1 to 0
        Pool p = array.get(highPools, i)
        if high > p.lvl

            if not na(p.rail)
                line.set_extend(p.rail, extend.none)
                line.set_x2(p.rail, bar_index)

            pendHigh := PendingSweep.new(p.lvl, high, bar_index, math.max(high - low, syminfo.mintick), true)
            array.remove(highPools, i)

if array.size(lowPools) > 0
    for i = array.size(lowPools) - 1 to 0
        Pool p = array.get(lowPools, i)
        if low < p.lvl
            if not na(p.rail)
                line.set_extend(p.rail, extend.none)
                line.set_x2(p.rail, bar_index)
            pendLow := PendingSweep.new(p.lvl, low, bar_index, math.max(high - low, syminfo.mintick), false)
            array.remove(lowPools, i)

if not na(pendHigh)
    pendHigh.wick_extreme := math.max(pendHigh.wick_extreme, high)
if not na(pendLow)
    pendLow.wick_extreme := math.min(pendLow.wick_extreme, low)

bool sellSignal = false
bool buySignal = false
float sweepLvlSell = na
float sweepWickSell = na
float sweepLvlBuy = na
float sweepWickBuy = na

if not na(pendHigh)
    int elapsed = bar_index - pendHigh.break_bar

    bool wickOK = (pendHigh.wick_extreme - pendHigh.lvl) / pendHigh.raid_range * 100 >= minWickPct
    if elapsed >= 1 and elapsed <= confirmWindow
        if close < pendHigh.lvl and close < open and volOK and wickOK
            sellSignal := true
            sweepLvlSell := pendHigh.lvl
            sweepWickSell := pendHigh.wick_extreme
            pendHigh := na
    else if elapsed > confirmWindow
        pendHigh := na

if not na(pendLow)
    int elapsed = bar_index - pendLow.break_bar
    bool wickOK = (pendLow.lvl - pendLow.wick_extreme) / pendLow.raid_range * 100 >= minWickPct
    if elapsed >= 1 and elapsed <= confirmWindow
        if close > pendLow.lvl and close > open and volOK and wickOK
            buySignal := true
            sweepLvlBuy := pendLow.lvl
            sweepWickBuy := pendLow.wick_extreme
            pendLow := na
    else if elapsed > confirmWindow
        pendLow := na

if sellSignal and showZones and not na(sweepLvlSell) and sweepWickSell > sweepLvlSell
    box b = box.new(bar_index - confirmWindow, sweepWickSell, bar_index + zoneLifeBars, sweepLvlSell,
         border_color = color.new(sellColor, 55), border_width = 1,
         bgcolor = color.new(sellColor, zoneTransp))
    array.push(zones, SweptZone.new(b, bar_index))
if buySignal and showZones and not na(sweepLvlBuy) and sweepWickBuy < sweepLvlBuy
    box b = box.new(bar_index - confirmWindow, sweepLvlBuy, bar_index + zoneLifeBars, sweepWickBuy,
         border_color = color.new(buyColor, 55), border_width = 1,
         bgcolor = color.new(buyColor, zoneTransp))
    array.push(zones, SweptZone.new(b, bar_index))

if array.size(zones) > 0
    for i = array.size(zones) - 1 to 0
        SweptZone z = array.get(zones, i)
        if bar_index - z.born_bar > zoneLifeBars
            box.delete(z.bx)
            array.remove(zones, i)

if buySignal and showSignalLabels
    label.new(bar_index, low, 'RAID BUY · ' + str.tostring(volMult, '#.#') + 'x',
         style = label.style_label_up, color = color.new(buyColor, 8),
         textcolor = labelTextColor, size = f_labelSize(labelSizeStr))
if sellSignal and showSignalLabels
    label.new(bar_index, high, 'RAID SELL · ' + str.tostring(volMult, '#.#') + 'x',
         style = label.style_label_down, color = color.new(sellColor, 8),
         textcolor = labelTextColor, size = f_labelSize(labelSizeStr))

plotshape(showTriangles and buySignal, title = 'Raid Buy', style = shape.triangleup, location = location.belowbar, color = buyColor, size = size.tiny)
plotshape(showTriangles and sellSignal, title = 'Raid Sell', style = shape.triangledown, location = location.abovebar, color = sellColor, size = size.tiny)
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)

buyLabelColor = buyColor
sellLabelColor = sellColor
buyColorLight = color.new(buyLabelColor, 40)
sellColorLight = color.new(sellLabelColor, 40)
buyFill = color.new(buyLabelColor, 76)
sellFill = color.new(sellLabelColor, 76)

var int trade_dir = 0
var float sl_level = na
var float extreme_level = na
var line entry_line = na
var label entry_label = na
var line sl_line = na
var label sl_label = na
var line tp1_line = na
var label tp1_label = na
var line tp2_line = na
var label tp2_label = na
var line tp3_line = na
var label tp3_label = na
var line extreme_line = na
var linefill risk_fill = na
var linefill reward_fill = na
var int entry_bar = na

if (buySignal or sellSignal) and show_targets
    line.delete(entry_line)
    label.delete(entry_label)
    line.delete(sl_line)
    label.delete(sl_label)
    line.delete(tp1_line)
    label.delete(tp1_label)
    line.delete(tp2_line)
    label.delete(tp2_label)
    line.delete(tp3_line)
    label.delete(tp3_label)
    line.delete(extreme_line)
    linefill.delete(risk_fill)
    linefill.delete(reward_fill)

    trade_dir := buySignal ? 1 : -1
    entry_bar := bar_index
    float entry_price = close
    float risk_dist = use_atr_sl ? atr_val * sl_atr_mult : entry_price * (sl_percent / 100)

    float tp1_p = na
    float tp2_p = na
    float tp3_p = na

    if trade_dir == 1
        sl_level := entry_price - risk_dist
        tp1_p := entry_price + risk_dist * rr_tp1
        tp2_p := entry_price + risk_dist * rr_tp2
        tp3_p := entry_price + risk_dist * rr_tp3
        extreme_level := show_tp3_level ? tp3_p : show_tp2_level ? tp2_p : show_tp1_level ? tp1_p : na

        entry_line := line.new(bar_index, entry_price, bar_index + 1, entry_price, color = buyLabelColor, width = 2, extend = extend.none)
        entry_label := label.new(bar_index, entry_price, 'BUY ' + str.tostring(entry_price, format.mintick), style = label.style_label_left, color = buyLabelColor, textcolor = color.rgb(6, 22, 32), size = size.small)

        if show_sl_level
            sl_line := line.new(bar_index, sl_level, bar_index + 1, sl_level, color = sellColorLight, width = 1, style = line.style_dashed, extend = extend.none)
            sl_label := label.new(bar_index, sl_level, 'SL ' + str.tostring(sl_level, format.mintick), style = label.style_label_left, color = sellColorLight, textcolor = color.white, size = size.small)
        if show_tp1_level
            tp1_line := line.new(bar_index, tp1_p, bar_index + 1, tp1_p, color = buyColorLight, width = 1, extend = extend.none)
            tp1_label := label.new(bar_index, tp1_p, 'TP1 ' + str.tostring(tp1_p, format.mintick), style = label.style_label_left, color = buyColorLight, textcolor = color.white, size = size.small)
        if show_tp2_level
            tp2_line := line.new(bar_index, tp2_p, bar_index + 1, tp2_p, color = buyColorLight, width = 1, extend = extend.none)
            tp2_label := label.new(bar_index, tp2_p, 'TP2 ' + str.tostring(tp2_p, format.mintick), style = label.style_label_left, color = buyColorLight, textcolor = color.white, size = size.small)
        if show_tp3_level
            tp3_line := line.new(bar_index, tp3_p, bar_index + 1, tp3_p, color = buyColorLight, width = 1, style = line.style_dotted, extend = e

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

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

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

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

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

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

Стоимость полного кода
2 107,10₽ ≈ $25.75