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

POC Volume Profile

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

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

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

О программе

POC Volume Profile — это индикатор для TradingView, отображающий профиль объёмов на выбранном диапазоне ценовых баров. Индикатор рассчитывает точку контроля (POC) — уровень цены с наибольшим объёмом торгов, а также зону стоимости (Value Area) по заданному проценту от общего объёма. Визуализация включает горизонтальные столбцы профильного объёма, линии POC, VAH/VAL и опционально VWAP.

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

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

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

НастройкаОписание
startTimeInput Начальная дата — Начальная дата ручного диапазона для расчёта профиля объёмов.
endTimeInput Конечная дата — Конечная дата ручного диапазона для расчёта профиля объёмов.
autoRangeInput Включить авторежим диапазона — Включает автоматический определение диапазона профиля по пивотам высоких и низких цен вместо ручного диапазона дат.
pivotLenInput Длина пивота — Количество баров с каждой стороны для обнаружения пивотов высоких и низких цен.
showPivotHighInput Показать маркеры пивотов высоких цен — Отображать ли маркеры пивотов высоких цен зелёными кружками над барами.
showPivotLowInput Показать маркеры пивотов низких цен — Отображать ли маркеры пивотов низких цен красными кружками под барами.
nthPivotInput Номер ближайшего N-го пивота — Номер пивота, используемого как начальная точка автоматического диапазона. Пивоты высоких и низких цен ранжируются в зависимости от включённых переключателей.
binCountInput Количество корзин профиля — Количество ценовых корзин (уровней) для построения профиля объёмов. Больше значений — больше деталей, меньше — более сглаженный профиль.
vaPercentInput Процент зоны стоимости — Процент от общего объёма, определяющий границы зоны стоимости. По умолчанию 68%.
showProfileInput Показать профиль объёма — Отображать ли профиль объёма в виде горизонтальных столбцов.
showDeltaInput Показать дельта-профиль — Отображать ли дельта-профиль с разделением объёма на покупательский и продавательский.
showPocInput Показать линию POC — Отображать ли линию и метку точки контроля (POC).
showPocFillInput Показать заливку зоны POC — Отображать ли заливку зоны точки контроля.
showVaInput Показать зону стоимости — Отображать ли линии зоны стоимости (VAH и VAL).
showVwapInput Показать VWAP — Отображать ли линию VWAP для рассчитанного диапазона.
showLabelsInput Показать метку диапазона — Отображать ли метку диапазона с информацией о количестве баров, общем объёме, дельте, POC и VWAP.
themeInput Тема оформления — Тема отображения элементов индикатора: Авто, Тёмная или Светлая.
showDashInput Показать дашборд — Отображать ли информационную панель дашборда с основными метриками.
dashPosInput Положение дашборда — Положение информационной панели дашборда на графике.
bullColorInput Цвет покупок (бычий объём) — Цвет покупательского объёма в дельта-профиле.
bearColorInput Цвет продаж (медвежий объём) — Цвет продавательского объёма в дельта-профиле.
baseColorInput Цвет базового объёма — Цвет базового объёма при отображении профиля без дельты.
pocColorInput Цвет линии POC — Цвет линии точки контроля (POC).
vaHighColor Цвет линии VAH — Цвет линии верхней границы зоны стоимости (VAH).
vaLowColor Цвет линии VAL — Цвет линии нижней границы зоны стоимости (VAL).
vwapColorInput Цвет VWAP — Цвет линии VWAP.
Получить полный код

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

indicator(
     title              = "POC Volume Profile",
     shorttitle         = "POC",
     overlay            = true,
     max_labels_count   = 500,
     max_lines_count    = 100,
     max_boxes_count    = 100,
     max_bars_back      = 4900,
     calc_bars_count    = 5000   
)

GRP_TIME   = "📅 Date Range"
GRP_AUTO   = "🔄 Auto Range Mode"
GRP_MAIN   = "⚙️ Main Settings"
GRP_VISUAL = "🎨 Visual Settings"
GRP_DASH   = "📊 Dashboard"
GRP_COLORS = "🎨 Colors"

TRANSPARENT = color.new(#000000, 100)

startTimeInput = input.time(timestamp("2026-05-25T00:00:00"), "Start Date", group = GRP_TIME, tooltip = "Start date for volume profile calculation.")
endTimeInput   = input.time(timestamp("2026-06-31T23:59:59"), "End Date",   group = GRP_TIME, tooltip = "End date for volume profile calculation.")

autoRangeInput     = input.bool(true, "Enable Auto Range Mode", group = GRP_AUTO,
     tooltip = "ON: Profile range is determined by pivot highs/lows instead of the date range.\nOFF: Manual date range is used.")

pivotLenInput      = input.int(5, "Pivot Length", minval = 1, maxval = 50, group = GRP_AUTO,
     tooltip = "Number of bars used on each side for pivot high/low detection.")

showPivotHighInput = input.bool(true, "Show Pivot High Markers (🟢)", group = GRP_AUTO,
     tooltip = "Mark pivot highs above bars with a green circle.")
showPivotLowInput  = input.bool(true, "Show Pivot Low Markers (🔴)",  group = GRP_AUTO,
     tooltip = "Mark pivot lows below bars with a red circle.")

nthPivotInput      = input.int(5, "Nearest Nth Pivot", minval = 1, maxval = 100, group = GRP_AUTO,
     tooltip = "Select the starting pivot.\n• Only High enabled → only pivot highs are ranked, Nth high is used as start.\n• Only Low enabled → only pivot lows are ranked, Nth low is used as start.\n• Both enabled → pivot highs and lows are combined into one list and ranked together; whichever is Nth becomes the start.\nDefault: 3")

binCountInput  = input.int(40, "Profile Bins", minval = 10, maxval = 100, step = 5, group = GRP_MAIN,
     tooltip = "Number of price levels. Higher value = more detail, lower value = smoother profile.")
vaPercentInput = input.float(68.0, "Value Area %", minval = 1.0, maxval = 100.0, step = 1.0, group = GRP_MAIN,
     tooltip = "Percentage of total volume that defines the Value Area. Default: 68")

VA_PERCENT = vaPercentInput / 100.0

showProfileInput = input.bool(true,  "Show Volume Profile", group = GRP_VISUAL)
showDeltaInput   = input.bool(true,  "Show Delta Profile",  group = GRP_VISUAL)
showPocInput     = input.bool(true,  "Show POC Line",       group = GRP_VISUAL)
showPocFillInput = input.bool(true,  "Show POC Zone Fill",  group = GRP_VISUAL)
showVaInput      = input.bool(true,  "Show Value Area",     group = GRP_VISUAL)
showVwapInput    = input.bool(false, "Show VWAP",           group = GRP_VISUAL)
showLabelsInput  = input.bool(true,  "Show Range Label",    group = GRP_VISUAL)

themeInput    = input.string("Auto", "Theme", options = ["Auto", "Dark", "Light"], group = GRP_VISUAL)
showDashInput = input.bool(true, "Show Dashboard", group = GRP_DASH)
dashPosInput  = input.string("Top Right", "Dashboard Position",
     options = ["Top Left", "Top Right", "Bottom Left", "Bottom Right"], group = GRP_DASH)

bullColorInput = input.color(#2979FF, "Buy Volume (Blue)",    inline = "colors",  group = GRP_COLORS)
bearColorInput = input.color(#FF9100, "Sell Volume (Red)",    inline = "colors",  group = GRP_COLORS)
baseColorInput = input.color(#90CAF9, "Base Volume",          inline = "colors2", group = GRP_COLORS)
pocColorInput  = input.color(#FF1744, "POC Line (Red)",       inline = "colors2", group = GRP_COLORS)
vaHighColor    = input.color(#2979FF, "VAH Line (Blue)",      inline = "colors3", group = GRP_COLORS)
vaLowColor     = input.color(#FF9100, "VAL Line (Orange)",    inline = "colors3", group = GRP_COLORS)
vwapColorInput = input.color(#AB47BC, "VWAP",                 inline = "colors4", group = GRP_COLORS)

isDark = switch themeInput
    "Dark"  => true
    "Light" => false
    => color.r(chart.bg_color) < 128

TEXT_COLOR    = isDark ? #E0E0E0 : #1A1A1A
TEXT_MUTED    = isDark ? color.new(#9E9E9E, 0) : color.new(#757575, 0)
TABLE_BG      = isDark ? color.new(#131722, 5) : color.new(#FFFFFF, 5)
TABLE_BORDER  = isDark ? color.new(#2A2E39, 0) : color.new(#D0D0D0, 0)
TABLE_ROW_ALT = isDark ? color.new(#1C2030, 0) : color.new(#F0F4F8, 0)
HEADER_BG     = color.new(#2962FF, 0)
POC_FILL      = color.new(pocColorInput, 85)

safeDiv(float num, float den, float fallback = 0.0) =>
    den != 0 and not na(num) and not na(den) ? num / den : fallback

getDashPos(string s) =>
    switch s
        "Top Left"     => position.top_left
        "Bottom Left"  => position.bottom_left
        "Bottom Right" => position.bottom_right
        => position.top_right

distributeVolume(float cOpen, float cClose, float cHigh, float cLow, float cVol, float bottom, float step, int bins, array<float> volArr, array<float> buyArr, array<float> sellArr) =>
    float candleTop   = math.max(cHigh, cLow)
    float candleBot   = math.min(cHigh, cLow)
    float candleRange = candleTop - candleBot
    bool isBullCandle = cClose >= cOpen
    if candleRange > 0 and cVol > 0
        for k = 0 to bins - 1
            float binLow  = bottom + k * step
            float binHigh = binLow + step
            float overlap = math.max(0.0, math.min(candleTop, binHigh) - math.max(candleBot, binLow))
            if overlap > 0
                float portion  = overlap / candleRange
                float allocVol = cVol * portion
                volArr.set(k, volArr.get(k) + allocVol)
                if isBullCandle
                    buyArr.set(k, buyArr.get(k) + allocVol)
                else
                    sellArr.set(k, sellArr.get(k) + allocVol)

calcValueArea(array<float> volArr, float totalVol, int pocBin, float bottom, float step, int bins) =>
    float target      = totalVol * VA_PERCENT
    float accumulated = volArr.get(pocBin)
    int   upperBin    = pocBin
    int   lowerBin    = pocBin
    int   safety      = 0
    while accumulated < target and safety < bins
        safety += 1
        float upVol   = upperBin + 1 < bins ? volArr.get(upperBin + 1) : 0.0
        float downVol = lowerBin - 1 >= 0   ? volArr.get(lowerBin - 1) : 0.0
        if upVol >= downVol and upperBin + 1 < bins
            upperBin    += 1
            accumulated += upVol
        else if lowerBin - 1 >= 0
            lowerBin    -= 1
            accumulated += downVol
        else if upperBin + 1 < bins
            upperBin    += 1
            accumulated += upVol
        else
            break
    float vaHigh = bottom + (upperBin + 1) * step
    float vaLow  = bottom + lowerBin * step
    [vaHigh, vaLow]

int   pLen = pivotLenInput

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

if autoRangeInput and showPivotHighInput and not na(ph)
    label.new(bar_index[pLen], ph, "●",
         style     = label.style_none,
         textcolor = color.new(#00E676, 0),
         size      = size.tiny,
         yloc      = yloc.abovebar)

if autoRangeInput and showPivotLowInput and not na(pl)
    label.new(bar_index[pLen], pl, "●",
         style     = label.style_none,
         textcolor = color.new(#FF1744, 0),
         size      = size.tiny,
         yloc      = yloc.belowbar)

var array<int>   phBars   = array.new<int>()
var array<float> phPrices = array.new<float>()
var array<int>   plBars   = array.new<int>()
var array<float> plPrices = array.new<float>()

if not na(ph)
    phBars.push(bar_index[pLen])
    phPrices.push(ph)

if not na(pl)
    plBars.push(bar_index[pLen])
    plPrices.push(pl)

var int   startIdx  = na
var int   endIdx    = na
var float rangeHigh = na
var float rangeLow  = na

if autoRangeInput
    if barstate.islast
        int nth = nthPivotInput

        bool useHigh = showPivotHighInput or not showPivotLowInput
        bool useLow  = showPivotLowInput  or not showPivotHighInput

        array<int> combinedBars = array.new<int>()

        if useHigh
            int sz = phBars.size()
            for i = 0 to sz - 1
                combinedBars.push(phBars.get(i))

        if useLow
            int sz = plBars.size()
            for i = 0 to sz - 1
                combinedBars.push(plBars.get(i))

        int csz = combinedBars.size()
        if csz > 1
            for i = 1 to csz - 1
                int key = combinedBars.get(i)
                int j   = i - 1
                while j >= 0 and combinedBars.get(j) < key
                    combinedBars.set(j + 1, combinedBars.get(j))
                    j -= 1
                combinedBars.set(j + 1, key)

        int autoStart = na
        if csz >= nth
            autoStart := combinedBars.get(nth - 1)

        if not na(autoStart)
            startIdx  := autoStart
            endIdx    := bar_index

            float rH = low[bar_index - autoStart]
            float rL = high[bar_index - auto

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

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

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

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

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

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

Стоимость полного кода
1 316,90₽ ≈ $16.10