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

Liquidity Reaper [JOAT]

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

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

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

О программе

Liquidity Reaper [JOAT] — это индикатор TradingView, который выявляет уровни ликвидности на основе пивотов свинг-хай и свинг-лоу и отслеживает их «захват» ценой. Когда внутренняя свеча пробивает уровень пивота, а затем закрывается обратно внутри него в заданном окне подтверждения, индикатор фиксирует подтверждённый захват ликвидности и отображает соответствующие сигналы на графике.

Для каждого захвата индикатор рисует горизонтальные линии рейлов, зоны затопления в виде полупрозрачных прямоугольников, а также подписи и треугольники с указанием направления и относительного объёма. Все элементы визуализации настраиваются через параметры: цвета, стили линий, прозрачность и размеры меток.

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

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

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

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

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

indicator('Liquidity Reaper [JOAT]', shorttitle='REAPER [JOAT] ', 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 @free_fx_pro", 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, ext

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

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

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

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

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

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

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