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

Liquidity Sweep Hunter

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

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

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

О программе

Liquidity Sweep Hunter — это индикатор для TradingView, который отслеживает уровни ликвидности на коротких, средних и длинных таймфреймах и отображает их в виде цветной тепловой карты прямо на графике цены. Индикатор определяет ситуации, когда цена пробивает сразу несколько видимых уровней ликвидности за один бар и затем возвращается обратно за ними, выдавая при этом сигналы разворота с маркерами на графике. При этом можно фильтровать сигналы по минимальной средней силе, настраиваемой пользователем.

Индикатор позволяет включить отрисовку торговых уровней с целью и стоп-лоссом, а также с промежуточными milestone-линиями, которые обновляются по мере достижения цены целевых отметок. Все уровни автоматически удаляются по истечении заданного срока активности или при срабатывании условия митигации (пробой по телу или по фитилям). Поддерживаются пользовательские оповещения TradingView для различных событий: обнаружение новых уровней, их удаление и сигналы разворота.

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

НастройкаОписание
shortBars Короткий период — Количество баров для определения краткосрочных максимумов и минимумов ликвидности.
mediumBars Средний период — Количество баров для определения среднесрочных максимумов и минимумов ликвидности.
longBars Длинный период — Количество баров для определения основных максимумов и минимумов ликвидности. Большее значение требует более широких ценовых экстремумов.
keepLevelsForBars Максимальный возраст — Максимальное количество баров, в течение которых хранимый уровень ликвидности остаётся активным, прежде чем быть удалённым.
removeLevelWhen Удаление при — Определяет, уровень митигируется сразу при пробое цены по фитилям или только после закрытия свечи за ним.
heatmapLookback Просмотр ценового диапазона — Количество последних баров для измерения ценового диапазона, определяющего высоту каждой ячейки тепловой карты.
heatmapResolution Разрешение цены — Количество вертикальных делений в измеренном ценовом диапазоне. Большее значение делает каждую полосу тепловой карты тоньше.
heatmapCellBars Ширина ячейки — Горизонтальная ширина каждой ячейки тепловой карты в барах. Большее значение создаёт более длинные ячейки и реже обновляет цвет.
filterSweepsByStrength Фильтровать спреды по силе — Включает или отключает фильтрацию сигналов по минимальной средней силе видимых уровней ликвидности.
minimumSweepStrength Минимальная сила — Минимальная средняя нормализованная сила, требуемая для пройденных уровней ликвидности, при включённом фильтре по силе.
showTradeDrawings Показать торговые отметки — Включает отрисовку торговых уровней с целью, стоп-лоссом и промежуточными линиями после сигнала разворота.
tradeRiskReward Соотношение риск/прибыль — Кратное расстояние финальной цели относительно четырёхбарного стоп-расстояния.
tradeExpiryBars Срок действия сигнала — Количество баров, на которые простираются стоп, цель и линии milestones от цены входа следующего бара.
heatmapWeakColor Слабый цвет — Цвет низкой интенсивности в общей градиентной шкале для боксов ликвидности.
heatmapMidColor Средний цвет — Цвет средней интенсивности в общей градиентной шкале для боксов ликвидности.
heatmapStrongColor Сильный цвет — Цвет высокой интенсивности в общей градиентной шкале для боксов ликвидности.
bullishSignalColor Бычий сигнал — Цвет бычьего сигнала разворота, целевых боксов и линий для сделок.
bearishSignalColor Медвежий сигнал — Цвет медвежьего сигнала разворота и стоп-бокса для сделок.
Получить полный код

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

indicator("Liquidity Sweep Hunter", "Liquidity Sweep Hunter", overlay = true, max_boxes_count = 500, max_lines_count = 500, behind_chart = false)

settingsGroup = "Levels"
signalsGroup = "Signals"
appearanceGroup = "Appearance"

shortBars = input.int(14, "Fast", minval = 1, group = settingsGroup, inline = "lookbacks")
mediumBars = input.int(42, "Mid", minval = 1, group = settingsGroup, inline = "lookbacks")
longBars = input.int(120, "Slow", minval = 1, group = settingsGroup, inline = "lookbacks", tooltip = "Fast, Mid, and Slow set the lookbacks used to detect short-term, medium-term, and major liquidity highs and lows. Higher values require broader price extremes before a new level is created.")
keepLevelsForBars = input.int(1000, "Max Age", minval = 50, maxval = 5000, group = settingsGroup, tooltip = "Maximum number of bars a stored liquidity level can remain active before it is removed from memory.")
removeLevelWhen = input.string("Wick", "Remove On", options = ["Wick", "Close"], group = settingsGroup, tooltip = "Choose whether a level is mitigated as soon as price wicks through it or only after a candle closes beyond it.")
heatmapLookback = input.int(777, "Price Range Lookback", minval = 20, maxval = 5000, group = settingsGroup, tooltip = "Number of recent bars used to measure the price range that determines each heatmap box height. Higher values produce a more slowly changing vertical scale.")
heatmapResolution = input.int(200, "Price Resolution", minval = 2, maxval = 300, group = settingsGroup, tooltip = "Number of vertical divisions across the measured price range. Higher values make each liquidity heatmap band thinner.")
heatmapCellBars = input.int(5, "Cell Width", minval = 1, maxval = 50, group = settingsGroup, tooltip = "Horizontal width of each historical heatmap box, measured in chart bars. Higher values create longer cells and fewer colour updates.")
filterSweepsByStrength = input.bool(true, "Filter Sweeps by Strength", group = signalsGroup, inline = "sweepStrength")
minimumSweepStrength = input.int(33, "Strength", minval = 1, maxval = 90, group = signalsGroup, inline = "sweepStrength", tooltip = "Filter Sweeps by Strength enables or disables the signal filter. Strength sets the minimum average normalized strength, from 1% to 90%, required across the visibly distinct levels swept by the same candle. The value uses the same shared bull/bear scale that determines the box colours.")
showTradeDrawings = input.bool(true, "Show TP/SL", group = signalsGroup, inline = "tradeDrawings")
tradeRiskReward = input.float(3.0, "RR", minval = 0.1, maxval = 20.0, step = 0.1, group = signalsGroup, inline = "tradeDrawings")
tradeExpiryBars = input.int(40, "Signal Expiry", minval = 1, maxval = 500, group = signalsGroup, inline = "tradeDrawings", tooltip = "Show TP/SL enables the post-signal trade drawing. RR sets the final reward distance as a multiple of the four-bar stop distance. Signal Expiry sets how many bars the stop, target, and three milestone lines extend from the next bar's entry open.")

heatmapWeakColor = input.color(color.rgb(140, 0, 255), "Weak", group = appearanceGroup, inline = "boxColors")
heatmapMidColor = input.color(#00ffbb, "Mid", group = appearanceGroup, inline = "boxColors")
heatmapStrongColor = input.color(color.rgb(255, 230, 0), "Strong", group = appearanceGroup, inline = "boxColors", tooltip = "Weak, Mid, and Strong set the low, midpoint, and high colours of the shared strength gradient used for both upper and lower liquidity boxes.")
bullishSignalColor = input.color(#00ffbb, "Bullish Signal", group = appearanceGroup, inline = "signalColors")
bearishSignalColor = input.color(#ff1100, "Bearish Signal", group = appearanceGroup, inline = "signalColors", tooltip = "Bullish Signal and Bearish Signal set the colours of the reversal labels. The bullish colour is also used for both target boxes and all three target lines, while the bearish colour is used for the stop box.")

const int SHIFT_COMPARISON_BARS = 3
const int LEVEL_MERGE_TICKS = 2
const int CLEANUP_BARS = 10
const int VOLUME_AVERAGE_BARS = 100
const float MAX_VOLUME_SCORE_PER_BAR = 3.0
const float FULL_HEATMAP_STRENGTH = 50.0
const float CLOSEST_LEVEL_WEIGHT = 1.0
const float SECOND_LEVEL_WEIGHT = 0.25
const float THIRD_LEVEL_WEIGHT = 0.05
const int MIN_LEVELS_FOR_SIGNAL = 2
const int SIGNAL_RECLAIM_BARS = 2
const int SIGNAL_ATR_LENGTH = 14
const float SIGNAL_OFFSET_MULTIPLIER = 0.15
const int TRADE_STOP_LOOKBACK_BARS = 4
const int TRADE_MILESTONE_COUNT = 3
const int TRADE_STOP_BOX_TRANSPARENCY = 82
const int TRADE_TARGET_BOX_TRANSPARENCY = 90
const int TRADE_PROGRESS_BOX_TRANSPARENCY = 68
const int TRADE_BOX_BORDER_TRANSPARENCY = 100
const int TRADE_TARGET_LINE_TRANSPARENCY = 20

h1_ = ta.highest(high, shortBars)
h2_ = ta.highest(high, mediumBars)
h3_ = ta.highest(high, longBars)

l1_ = ta.lowest(low, shortBars)
l2_ = ta.lowest(low, mediumBars)
l3_ = ta.lowest(low, longBars)

var float h1 = na
var float h2 = na
var float h3 = na

var float l1 = na
var float l2 = na
var float l3 = na

h1Shift = not na(h1_) and (na(h1) or (not na(h1_[SHIFT_COMPARISON_BARS]) and h1_ > h1_[SHIFT_COMPARISON_BARS] and h1_ != h1_[SHIFT_COMPARISON_BARS] and h1_ == h1_[1]))
h2Shift = not na(h2_) and (na(h2) or (not na(h2_[SHIFT_COMPARISON_BARS]) and h2_ > h2_[SHIFT_COMPARISON_BARS] and h2_ != h2_[SHIFT_COMPARISON_BARS] and h2_ == h2_[1]))
h3Shift = not na(h3_) and (na(h3) or (not na(h3_[SHIFT_COMPARISON_BARS]) and h3_ > h3_[SHIFT_COMPARISON_BARS] and h3_ != h3_[SHIFT_COMPARISON_BARS] and h3_ == h3_[1]))

l1Shift = not na(l1_) and (na(l1) or (not na(l1_[SHIFT_COMPARISON_BARS]) and l1_ < l1_[SHIFT_COMPARISON_BARS] and l1_ != l1_[SHIFT_COMPARISON_BARS] and l1_ == l1_[1]))
l2Shift = not na(l2_) and (na(l2) or (not na(l2_[SHIFT_COMPARISON_BARS]) and l2_ < l2_[SHIFT_COMPARISON_BARS] and l2_ != l2_[SHIFT_COMPARISON_BARS] and l2_ == l2_[1]))
l3Shift = not na(l3_) and (na(l3) or (not na(l3_[SHIFT_COMPARISON_BARS]) and l3_ < l3_[SHIFT_COMPARISON_BARS] and l3_ != l3_[SHIFT_COMPARISON_BARS] and l3_ == l3_[1]))

if h1Shift
    h1 := h1_

if h2Shift
    h2 := h2_

if h3Shift
    h3 := h3_

if l1Shift
    l1 := l1_

if l2Shift
    l2 := l2_

if l3Shift
    l3 := l3_

var array<float> upperPrices = array.new<float>()
var array<int> upperBirths = array.new<int>()
var array<float> upperStrengths = array.new<float>()
var array<box> upperLastBoxes = array.new<box>()
var array<float> upperLastNorms = array.new<float>()
var array<float> upperLastCellHeights = array.new<float>()
var array<int> upperLastDrawBars = array.new<int>()

var array<float> lowerPrices = array.new<float>()
var array<int> lowerBirths = array.new<int>()
var array<float> lowerStrengths = array.new<float>()
var array<box> lowerLastBoxes = array.new<box>()
var array<float> lowerLastNorms = array.new<float>()
var array<float> lowerLastCellHeights = array.new<float>()
var array<int> lowerLastDrawBars = array.new<int>()

var array<int> pendingUpperSweepBars = array.new<int>()
var array<float> pendingUpperReclaimLevels = array.new<float>()
var array<int> pendingLowerSweepBars = array.new<int>()
var array<float> pendingLowerReclaimLevels = array.new<float>()

var array<int> tradeDirections = array.new<int>()
var array<int> tradeExpiryBarValues = array.new<int>()
var array<float> tradeEntryPrices = array.new<float>()
var array<float> tradeStopPrices = array.new<float>()
var array<float> tradeTargetLevel1Values = array.new<float>()
var array<float> tradeTargetLevel2Values = array.new<float>()
var array<float> tradeTargetLevel3Values = array.new<float>()
var array<int> tradeReachedMilestones = array.new<int>()
var array<box> tradeStopBoxes = array.new<box>()
var array<box> tradeTargetBoxes = array.new<box>()
var array<box> tradeProgressBoxes = array.new<box>()
var array<line> tradeTargetLine1Values = array.new<line>()
var array<line> tradeTargetLine2Values = array.new<line>()
var array<line> tradeTargetLine3Values = array.new<line>()

f_roundToTick(float value) =>
    math.round(value / syminfo.mintick) * syminfo.mintick

f_findInsertIndex(array<float> prices, float price, bool descending) =>
    int lo = 0
    int hi = array.size(prices)

    while lo < hi
        int mid = int(math.floor((lo + hi) * 0.5))
        float midPrice = array.get(prices, mid)

        if descending
            if midPrice > price
                lo := mid + 1
            else
                hi := mid
        else
            if midPrice < price
                lo := mid + 1
            else
                hi := mid

    lo

f_addLevel(array<float> prices, array<int> births, array<float> strengths, array<box> lastBoxes, array<float> lastNorms, array<float> lastCellHeights, array<int> lastDrawBars, float rawPrice, float tolerance, bool descending) =>
    if not na(rawPrice)
        float price = f_roundToTick(rawPrice)
        int size = array.size(prices)
        int insertIndex = f_findInsertIndex(prices, price, descending)

        int matchIndex = na
        float bestDistance = na

        if insertIndex < size
            float distance = math.abs(array.get(prices, insertIndex) - price)
            if distance <= tolerance
                matchIndex := insertIndex
                bestDistance := distance

        if insertIndex > 0
            float distance = math.abs(array.get(prices, insertIndex - 1) - price)
            if distance <= tolerance and (na(bestDistance) or distance < bestDistance)
                matchIndex := insertIndex - 1

        if na(matchIndex)
            array.insert(prices, insertIndex, price)
            array.insert(births, insertIndex, bar_index)
            array.insert(strengths, insertIndex, 0.0)
            array.insert(lastBoxes, insertIndex, na)
            array.insert(lastNorms, insertIndex, na)
            array.insert(lastCellHeights, insertIndex, na)
            array.insert(lastDrawBars, insertIndex, na)
        else
            array.set(births, matchIndex, bar_index)

f_pruneExpired(array<float> prices, array<int> births, array<float> strengths, array<box> lastBoxes, array<float> lastNorms, array<float> lastCellHeights, array<int> lastDrawBars, int maxAge) =>
    if array.size(prices) > 0
        for i = array.size(prices) - 1 to 0
            if bar_index - array.get(births, i) > maxAge
                array.remove(prices, i)
                array.remove(births, i)
                array.remove(strengths, i)
                array.remove(lastBoxes, i)
                array.remove(lastNorms, i)
                array.remove(lastCellHeights, i)
                array.remove(lastDrawBars, i)

f_extendWickSweptUppers(array<float> prices, array<box> lastBoxes, float wickHigh) =>
    if array.size(prices) > 0
        for i = array.size(prices) - 1 to 0
            float levelPrice = array.get(prices, i)

            if levelPrice <= wickHigh
                box lastBox = array.get(lastBoxes, i)
                if not na(lastBox)
                    box.set_right(lastBox, bar_index)
            else
                break

f_mitigateUppers(array<float> prices, array<int> births, array<float> strengths, array<box> lastBoxes, array<float> lastNorms, array<float> lastCellHeights, array<int> lastDrawBars, float mitigationPrice) =>
    int removed = 0

    while array.size(prices) > 0
        int lastIndex = array.size(prices) - 1
        float levelPrice = array.get(prices, lastIndex)

        if levelPrice <= mitigationPrice
            array.pop(prices)
            array.pop(births)
            array.pop(strengths)
            array.pop(lastBoxes)
            array.pop(lastNorms)
            array.pop(lastCellHeights)
            array.pop(lastDrawBars)
            removed += 1
        else
            break

    removed

f_extendWickSweptLowers(array<float> prices, array<box> lastBoxes, float wickLow) =>
    if array.size(prices) > 0
        for i = array.size(prices) - 1 to 0
            float levelPrice = array.get(prices, i)

            if levelPrice >= wickLow
                box lastBox = array.get(lastBoxes, i)
                if not na(lastBox)
                    box.set_right(lastBox, bar_index)
            else
                break

f_mitigateLowers(array<float> prices, array<int> births, array<float> strengths, array<box> lastBoxes, array<float> lastNorms, array<float> lastCellHeights, array<int> lastDrawBars, float mitigationPrice) =>
    int removed = 0

    while array.size(prices) > 0
        int lastIndex = array.size(prices) - 1
        float levelPrice = array.get(prices, lastIndex)

        if levelPrice >= mitigationPrice
            array.pop(prices)
            array.pop(births)
            array.pop(strengths)
            array.pop(lastBoxes)
            array.pop(lastNorms)
            array.pop(lastCellHeights)
            array.pop(lastDrawBars)
            removed += 1
        else
            break

    removed

f_upperVisibleSweepStats(array<float> prices, array<box> lastBoxes, array<float> lastNorms, array<float> lastCellHeights, array<int> lastDrawBars, float wickHigh, int maxVisibleAge) =>
    int bandCount = 0
    float reclaimLevel = na
    float strengthSum = 0.0
    bool bandOpen = false
    float bandTop = na
    float bandStrength = 0.0

    if array.size(prices) > 0
        for i = array.size(prices) - 1 to 0
            float levelPrice = array.get(prices, i)

            if levelPrice <= wickHigh
                box lastBox = array.get(lastBoxes, i)
                float lastNorm = array.get(lastNorms, i)
                float lastCellHeight = array.get(lastCellHeights, i)
                int lastDrawBar = array.get(lastDrawBars, i)
                bool recentlyDrawn = not na(lastDrawBar) and bar_index - lastDrawBar <= maxVisibleAge
                bool visibleLevel = recentlyDrawn and not na(lastBox) and not na(lastNorm) and not na(lastCellHeight) and lastCellHeight > 0.0

                if visibleLevel
                    float levelBottom = levelPrice - lastCellHeight * 0.5
                    float levelTop = levelPrice + lastCellHeight * 0.5
                    reclaimLevel := na(reclaimLevel) ? levelPrice : math.min(reclaimLevel, levelPrice)

                    if not bandOpen
                        bandOpen := true
                        bandTop := levelTop
                        bandStrength := lastNorm
                    else if levelBottom <= bandTop
                        bandTop := math.max(bandTop, levelTop)
                        bandStrength := math.max(bandStrength, lastNorm)
                    else
                        bandCount += 1
                        strengthSum += bandStrength
                        bandTop := levelTop
                        bandStrength := lastNorm
            else
                break

    if bandOpen
        bandCount += 1
        strengthSum += bandStrength

    float averageStrength = bandCount > 0 ? strengthSum / bandCount : 0.0
    [bandCount, reclaimLevel, averageStrength]

f_lowerVisibleSweepStats(array<float> prices, array<box> lastBoxes, array<float> lastNorms, array<float> lastCellHeights, array<int> lastDrawBars, float wickLow, int maxVisibleAge) =>
    int bandCount = 0
    float reclaimLevel = na
    float strengthSum = 0.0
    bool bandOpen = false
    float bandBottom = na
    float bandStrength = 0.0

    if array.size(prices) > 0
        for i = array.size(prices) - 1 to 0
            float levelPrice = array.get(prices, i)

            if levelPrice >= wickLow
                box lastBox = array.get(lastBoxes, i)
                float lastNorm = array.get(lastNorms, i)
                float lastCellHeight = array.get(lastCellHeights, i)
                int lastDrawBar = array.get(lastDrawBars, i)
                bool recentlyDrawn = not na(lastDrawBar) and bar_index - lastDrawBar <= maxVisibleAge
                bool visibleLevel = recentlyDrawn and not na(lastBox) and not na(lastNorm) and not na(lastCellHeight) and lastCellHeight > 0.0

                if visibleLevel
                    float levelBottom = levelPrice - lastCellHeight * 0.5
                    float levelTop = levelPrice + lastCellHeight * 0.5
                    reclaimLevel := na(reclaimLevel) ? levelPrice : math.max(reclaimLevel, levelPrice)

                    if not bandOpen
                        bandOpen := true
                        bandBottom := levelBottom
                        bandStrength := lastNorm
                    else if levelTop >= bandBottom
                        bandBottom := math.min(bandBottom, levelBottom)
                        bandStrength := math.max(bandStrength, lastNorm)
                    else
                        bandCount += 1
                        strengthSum += bandStrength
                        bandBottom := levelBottom
                        bandStrength := lastNorm
            else
                break

    if bandOpen
        bandCount += 1
        strengthSum += bandStrength

    float averageStrength = bandCount > 0 ? strengthSum / bandCount : 0.0
    [bandCount, reclaimLevel, averageStrength]

f_addStrength(array<float> strengths, int levelIndex, float amount, float cap) =>
    if not na(levelIndex)
        if levelIndex >= 0 and levelIndex < array.size(strengths) and amount > 0.0
            float currentStrength = array.get(strengths, levelIndex)
            array.set(strengths, levelIndex, math.min(currentStrength + amount, cap))

f_getFloat(array<float> values, int index) =>
    float result = na

    if not na(index)
        if index >= 0 and index < array.size(values)
            result := array.get(values, index)

    result

f_resolveUpperSweeps(array<int> sweepBars, array<float> reclaimLevels, float closePrice, int maxBars) =>
    bool signal = false

    if array.size(sweepBars) > 0
        for i = array.size(sweepBars) - 1 to 0
            int age = bar_index - array.get(sweepBars, i)
            float reclaimLevel = array.get(reclaimLevels, i)

            if age > maxBars
                array.remove(sweepBars, i)
                array.remove(reclaimLevels, i)
            else if closePrice < reclaimLevel
                signal := true
                array.remove(sweepBars, i)
                array.remove(reclaimLevels, i)

    signal

f_resolveLowerSweeps(array<int> sweepBars, array<float> reclaimLevels, float closePrice, int maxBars) =>
    bool signal = false

    if array.size(sweepBars) > 0
        for i = array.size(sweepBars) - 1 to 0
            int age = bar_index - array.get(sweepBars, i)
            float reclaimLevel = array.get(reclaimLevels, i)

            if age > maxBars
                array.remove(sweepBars, i)
                array.remove(reclaimLevels, i)
            else if closePrice > reclaimLevel
                signal := true
                array.remove(sweepBars, i)
                array.remove(reclaimLevels, i)

    signal

f_heatmapColor(norm) =>
    clippedNorm = math.max(0.0, math.min(1.0, norm))
    clippedNorm <= 0.5 ? color.from_gradient(clippedNorm, 0.0, 0.5, heatmapWeakColor, heatmapMidColor) : color.from_gradient(clippedNorm, 0.5, 1.0, heatmapMidColor, heatmapStrongColor)

f_heatmapNorm(float levelStrength, float maxStrength) =>
    maxStrength > 0.0 ? math.max(0.0, math.min(1.0, nz(levelStrength, 0.0) / maxStrength)) : 0.0

f_drawHeatmapCell(float levelPrice, float norm, int leftX, int rightX, float cellHeight) =>
    float halfHeight = cellHeight * 0.5
    box.new(left = leftX, top = levelPrice + halfHeight, right = rightX, bottom = levelPrice - halfHeight, border_color = na, bgcolor = color.new(f_heatmapColor(norm), 33))
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)

mergeTolerance = syminfo.mintick * LEVEL_MERGE_TICKS
removeOnWick = removeLevelWhen == "Wick"

upperMitigationPrice = removeOnWick ? high : close
lowerMitigationPrice = removeOnWick ? low : close

bool upperMitigated = false
bool lowerMitigated = false
bool bearishSweepSignal = false
bool bullishSweepSignal = false

if removeOnWick
    f_extendWickSweptUppers(upperPrices, upperLastBoxes, high)
    f_extendWickSweptLowers(lowerPrices, lowerLastBoxes, low)

if barstate.isconfirmed
    [upperVisibleBandCount, upperReclaimLevel, upperAverageStrength] = f_upperVisibleSweepStats(upperPrices, upperLastBoxes, upperLastNorms, upperLastCellHeights, upperLastDrawBars, high, heatmapCellBars)
    [lowerVisibleBandCount, lowerReclaimLevel, lowerAverageStrength] = f_lowerVisibleSweepStats(lowerPrices, lowerLastBoxes, lowerLastNorms, lowerLastCellHeights, lowerLastDrawBars, low, heatmapCellBars)

    int upperRemovedCount = f_mitigateUppers(upperPrices, upperBirths, upperStrengths, upperLastBoxes, upperLastNorms, upperLastCellHeights, upperLastDrawBars, upperMitigationPrice)
    int lowerRemovedCount = f_mitigateLowers(lowerPrices, lowerBirths, lowerStrengths, lowerLastBoxes, lowerLastNorms, lowerLastCellHeights, lowerLastDrawBars, lowerMitigationPrice)

    upperMitigated := upperRemovedCount > 0
    lowerMitigated := lowerRemovedCount > 0

    float minimumSweepStrengthNormalized = minimumSweepStrength / 100.0
    bool upperStrengthQualified = not filterSweepsByStrength or upperAverageStrength >= minimumSweepStrengthNormalized
    bool lowerStrengthQualified = not filterSweepsByStrength or lowerAverageStrength >= minimumSweepStrengthNormalized

    if removeOnWick and upperVisibleBandCount >= MIN_LEVELS_FOR_SIGNAL and upperStrengthQualified and not na(upperReclaimLevel)
        array.push(pendingUpperSweepBars, bar_index)
        array.push(pendingUpperReclaimLevels, upperReclaimLevel)

    if re

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

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

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

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

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

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

Стоимость полного кода
3 467,50₽ ≈ $42.38