Session Volume Profile — Intraday
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «indicator session volume profile - intraday for tradingview.pine» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
Индикатор «Session Volume Profile — Intraday» отображает профиль объёма внутри торговой сессии на графике TradingView. Он разбивает диапазон цен сессии на горизонтальные ряды и распределяет объём по ним, выделяя точку максимального объёма (POC) и зону ценности (Value Area) с границами VAH и VAL. Профиль рисуется цветными полосами: покупательский объём в одном цвете, продавательский — в другом, с градиентной яркостью, зависящей от доли объёма в ряду.
Индикатор поддерживает несколько сессионных профилей, настраиваемый таймфрейм якоря и количество сохранённых исторических сессий. В качестве дополнительных уровней отображаются сессионный VWAP (с опциональными полосами ±StdDev), начальный баланс (Initial Balance) за заданное число минут, а также уровни предыдущей сессии и предыдущего торгового дня. Непроверенные POC предыдущих сессий отмечаются отдельными линиями.
Встроенный дашборд показывает текущие сессионные уровни, расположение цены относительно зоны ценности и количество непроверенных POC. Индикатор предоставляет набор условий для оповещений TradingView: пересечение POC, пробой зоны ценности, тест предыдущего POC, пробой PDH/PDL и пересечение VWAP. Все расчёты выполняются на подтверждённых барах, что исключает перерисовку.
Настройки программы
| Настройка | Описание |
|---|---|
| profileTF | Таймфрейм якоря сессии — период, после начала которого начинается новый профиль. Например, «D» — один профиль в день, внутридневные таймфреймы — более частые профили. |
| profileRows | Количество горизонтальных рядов, на которые разбивается диапазон цен сессии. Определяет вертикальное разрешение профиля. |
| valueArea | Процент объёма сессии, который охватывает зона ценности (Value Area). Определяет границы VAH и VAL. |
| maxSessions | Максимальное количество завершённых сессий, отображаемых на графике. При превышении лимита в 500 прямоугольников старые профили удаляются. |
| widthPct | Ширина самой широкой полосы (POC-ряд) как доля от ширины свечи сессии (от 0.05 до 1.0). |
| maxWidthBar | Максимальная ширина профиля в барах, ограничивающая визуальный размер полос при широких сессиях. |
| showLive | Включает или отключает отрисовку текущего развивающегося профиля на активной сессии. |
| colBuy | Цвет полос, отображающих покупательский (растущий) объём. Каждая полоса рисуется от центральной линии вправо. |
| colSell | Цвет полос, отображающих продавательский (падающий) объём. Каждая полоса рисуется от центральной линии влево. |
| colPOC | Цвет точки контроля (POC) — горизонтальной линии и полупрозрачной полосы на уровне максимального объёма сессии. |
| colVA | Цвет заливки зоны ценности (Value Area) — диапазона, охватывающего заданный процент объёма сессии. |
| colVWAP | Цвет линии сессионного VWAP (средневзвешенной цены по объёму). |
| vaBoost | Множитель яркости полос внутри зоны ценности (значение от 1.0 до 2.0). Усиливает визуальное выделение VA. |
| showBackdrop | Включает или отключает полупрозрачную заливку полного ценового диапазона сессии для визуальной глубины. |
| showPrev | Включает или отключает отображение уровней POC, VAH и VAL предыдущей завершённой сессии. |
| showPDHL | Включает или отключает отображение уровней предыдущего торгового дня: максимума (PDH) и минимума (PDL). |
| showNaked | Включает или отключает отображение непроверенных (нетестированных) POC предыдущих сессий — уровней, которых цена ещё не достигала. |
| showVWAP | Включает или отключает отображение линии сессионного VWAP. |
| vwapSrc | Источниковая серия данных для расчёта VWAP (например, hlc3 — типичная цена). |
| vwapAnchor | Таймфрейм, на котором сбрасывается расчёт VWAP. Например, «D» — ежедневный сброс, внутридневные значения — более частые пересчёты. |
| vwapWidth | Толщина линии сессионного VWAP в пикселях (от 1 до 4). |
| vwapBands | Включает или отключает отображение верхней и нижней полос VWAP, рассчитанных как VWAP ± стандартное отклонение. |
| vwapMult | Множитель стандартного отклонения для расчёта верхней и нижней полос VWAP. |
| showIB | Включает или отключает отображение уровней начального баланса (Initial Balance High / Low) за первые заданные минуты сессии. |
| ibMinutes | Количество минут с начала сессии, в течение которых рассчитывается начальный баланс (Initial Balance) — диапазон максимума и минимума. |
| levelExt | Количество баров вправо, на которые продлеваются горизонтальные уровни от правого края профиля. |
| showDash | Включает или отключает таблицу дашборда с текущими сессионными уровнями и информацией о расположении цены. |
| dashPos | Положение таблицы дашборда на графике: верхний правый, верхний левый, нижний правый или нижний левый угол. |
Поиск по коду файла
indicator("Session Volume Profile — Intraday", "HexaTrades Session Volume Profile - Intraday", overlay = true, behind_chart = true, max_lines_count = 500, max_boxes_count = 500, max_labels_count = 200)
grpP = "═══ Profile ═══"
profileTF = input.timeframe("D", "Session Anchor", group = grpP, tooltip = "Each profile resets on a new period. 'D' = one profile per day. Use '240'/'60' for finer intraday profiles.")
profileRows = input.int(20, "Rows per Profile", minval = 8, maxval = 100, group = grpP, tooltip = "Vertical resolution of each profile (higher = finer). Each session draws roughly Rows×2 boxes and a script is capped at 500 boxes total, so high Rows + many Sessions will silently drop the OLDEST profiles. Guide: Rows 20 → keep ~8 sessions; Rows 40 → keep ~5 sessions; Rows 100 → keep ~2 sessions.")
valueArea = input.float(70, "Value Area %", minval = 50, maxval = 95, step = 1, group = grpP)
maxSessions = input.int(5, "Historical Sessions to Keep", minval = 1, maxval = 10, group = grpP, tooltip = "How many completed sessions to keep on the chart. Higher values + high Rows can exceed the 500-box limit, dropping the oldest profiles. ~5–6 sessions at 24 rows is a safe, clean setup.")
widthPct = input.float(0.32, "Profile Width (% of session)", minval = 0.05, maxval = 1.0, step = 0.02, group = grpP, tooltip = "Width of the widest (POC) row as a fraction of the session's bar-width.")
maxWidthBar = input.int(90, "Max Profile Width (bars)", minval = 10, maxval = 300, group = grpP)
showLive = input.bool(true, "Show Developing (current) Profile", group = grpP)
grpC = "═══ Colors / Gradient ═══"
colBuy = input.color(#90bff9, "Buy (up) Volume", group = grpC, inline = "c1", tooltip = "Buy volume — extends from the spine to the right of each row.")
colSell = input.color(#b39ddb, "Sell (down) Volume", group = grpC, inline = "c1", tooltip = "Sell volume — sits at the left of each row.")
colPOC = input.color(#5b6472, "POC", group = grpC, inline = "c2")
colVA = input.color(#60a5fa, "Value Area", group = grpC, inline = "c2")
colVWAP = input.color(#ab47bc, "VWAP", group = grpC, inline = "c3")
gPeak = 3 // transparency of the highest-volume (POC) rows — lower = darker
gEdge = 68 // transparency of the lowest-volume rows — higher = more faded
vaBoost = input.float(1.18, "Value Area Emphasis", minval = 1.0, maxval = 2.0, step = 0.02, group = grpC, tooltip = "Extra brightness for rows inside the value area.")
showBackdrop= input.bool(true, "Soft Range Backdrop", group = grpC)
grpL = "═══ Intraday Levels ═══"
showPrev = input.bool(true, "Prev Session POC / VAH / VAL", group = grpL)
showPDHL = input.bool(true, "Prev Day High / Low (PDH/PDL)", group = grpL)
showNaked = input.bool(false, "Naked / Untested POCs", group = grpL)
showVWAP = input.bool(true, "Session VWAP", group = grpL)
vwapSrc = input.source(hlc3, " VWAP Source", group = grpL, tooltip = "Price series the VWAP is built from. Default hlc3 (typical price).")
vwapAnchor = input.timeframe("D", " VWAP Anchor", group = grpL, tooltip = "When the VWAP resets. 'D' = daily (a fresh VWAP each day). Use 'W'/'M' for weekly/monthly, or '60'/'240' for intraday anchors.")
vwapWidth = input.int(2, " VWAP Width", minval = 1, maxval = 4, group = grpL)
vwapBands = input.bool(false, " VWAP ± StdDev Bands", group = grpL)
vwapMult = input.float(1.0, " Band StdDev Multiplier", minval = 0.1, maxval = 5.0, step = 0.1, group = grpL)
showIB = input.bool(true, "Initial Balance", group = grpL)
ibMinutes = input.int(60, "Initial Balance Minutes", minval = 5, maxval = 240, group = grpL)
levelExt = input.int(12, "Level Extend (bars right)", minval = 0, maxval = 60, group = grpL)
grpD = "═══ Dashboard / Alerts ═══"
showDash = input.bool(true, "Show Dashboard", group = grpD)
dashPos = input.string("Top Right", "Dashboard Position", options = ["Top Right", "Top Left", "Bottom Right", "Bottom Left"], group = grpD)
f_maxIdx(array<float> a) =>
mi = 0
mv = array.get(a, 0)
if array.size(a) > 1
for i = 1 to array.size(a) - 1
v = array.get(a, i)
if v > mv
mv := v
mi := i
mi
f_clearBoxes(array<box> a) =>
if array.size(a) > 0
for i = 0 to array.size(a) - 1
box.delete(array.get(a, i))
array.clear(a)
f_clearLines(array<line> a) =>
if array.size(a) > 0
for i = 0 to array.size(a) - 1
line.delete(array.get(a, i))
array.clear(a)
f_clearLabels(array<label> a) =>
if array.size(a) > 0
for i = 0 to array.size(a) - 1
label.delete(array.get(a, i))
array.clear(a)
f_levels(array<float> H, array<float> L, array<float> V) =>
n = array.size(V)
float top = array.get(H, 0)
float bot = array.get(L, 0)
if n > 1
for i = 1 to n - 1
top := math.max(top, array.get(H, i))
bot := math.min(bot, array.get(L, i))
rows = profileRows
rh = (top - bot) / rows
vr = array.new<float>(rows, 0.0)
if rh > 0
for i = 0 to n - 1
rB = math.min(rows - 1, math.max(0, int(math.floor((array.get(L, i) - bot) / rh))))
rT = math.min(rows - 1, math.max(0, int(math.floor((array.get(H, i) - bot) / rh))))
ve = array.get(V, i) / (rT - rB + 1)
for r = rB to rT
array.set(vr, r, array.get(vr, r) + ve)
pIdx = f_maxIdx(vr)
tot = array.sum(vr)
target = tot * valueArea / 100.0
vaVol = array.get(vr, pIdx)
up = pIdx
dn = pIdx
while vaVol < target and (up < rows - 1 or dn > 0)
uV = up < rows - 1 ? array.get(vr, up + 1) : -1.0
dV = dn > 0 ? array.get(vr, dn - 1) : -1.0
if uV >= dV
up += 1
vaVol += uV
else
dn -= 1
vaVol += dV
[bot + (pIdx + 0.5) * rh, bot + (up + 1) * rh, bot + dn * rh]
f_draw(int x1, int x2, array<float> H, array<float> L, array<float> V, array<float> U, array<box> bp, array<line> lp) =>
n = array.size(V)
float top = array.get(H, 0)
float bot = array.get(L, 0)
if n > 1
for i = 1 to n - 1
top := math.max(top, array.get(H, i))
bot := math.min(bot, array.get(L, i))
rows = profileRows
rh = (top - bot) / rows
vr = array.new<float>(rows, 0.0) // total volume per row
ur = array.new<float>(rows, 0.0) // up (buy) volume per row
dr = array.new<float>(rows, 0.0) // down (sell) volume per row
if rh > 0
for i = 0 to n - 1
bv = array.get(V, i)
isUp = array.get(U, i) > 0.5
rB = math.min(rows - 1, math.max(0, int(math.floor((array.get(L, i) - bot) / rh))))
rT = math.min(rows - 1, math.max(0, int(math.floor((array.get(H, i) - bot) / rh))))
ve = bv / (rT - rB + 1)
for r = rB to rT
array.set(vr, r, array.get(vr, r) + ve)
if isUp
array.set(ur, r, array.get(ur, r) + ve)
else
array.set(dr, r, array.get(dr, r) + ve)
pIdx = f_maxIdx(vr)
maxV = array.max(vr)
tot = array.sum(vr)
target = tot * valueArea / 100.0
vaVol = array.get(vr, pIdx)
up = pIdx
dn = pIdx
while vaVol < target and (up < rows - 1 or dn > 0)
uV = up < rows - 1 ? array.get(vr, up + 1) : -1.0
dV = dn > 0 ? array.get(vr, dn - 1) : -1.0
if uV >= dV
up += 1
vaVol += uV
else
dn -= 1
vaVol += dV
float pocP = bot + (pIdx + 0.5) * rh
float vahP = bot + (up + 1) * rh
float valP = bot + dn * rh
int sessW = math.max(1, x2 - x1)
int wMax = math.min(maxWidthBar, math.max(3, int(sessW * widthPct)))
if showBackdrop
array.push(bp, box.new(x1, top, x2, bot, border_width = 0, bgcolor = color.new(colVA, 95)))
array.push(bp, box.new(x1, vahP, x2, valP, border_width = 0, bgcolor = color.new(colVA, 87)))
if maxV > 0 and rh > 0
for r = 0 to rows - 1
tv = array.get(vr, r)
if tv > 0
w = math.max(1, int(tv / maxV * wMax))
dW = int(array.get(dr, r) / tv * w) // sell width
uW = w - dW // buy width
rTopP = bot + (r + 1) * rh
rBotP = bot + r * rh
inVA = r >= dn and r <= up
shr = math.min(1.0, (tv / maxV) * (inVA ? vaBoost : 1.0))
tr = int(gEdge - shr * (gEdge - gPeak)) // gEdge -> gPeak as shr 0 -> 1
sellC = color.new(colSell, tr)
buyC = color.new(colBuy, tr)
if dW > 0
array.push(bp, box.new(x1, rTopP, x1 + dW, rBotP, border_width = 0, bgcolor = sellC))
if uW > 0
array.push(bp, box.new(x1 + dW, rTopP, x1 + dW + uW, rBotP, border_width = 0, bgcolor = buyC))
array.push(bp, box.new(x1, pocP + rh * 0.5, x2, pocP - rh * 0.5, border_width = 0, bgcolor = color.new(colPOC, 62)))
array.push(lp, line.new(x1, pocP, x2, pocP, color = color.new(colPOC, 15), width = 4))
var array<float> pH = array.new<float>() // current session bar highs
var array<float> pL = array.new<float>() // current session bar lows
var array<float> pV = array.new<float>() // current session bar volumes
var array<float> pU = array.new<float>() // 1.0 = up bar, 0.0 = down bar
var int sStart = bar_index // current session start bar_index
var int barsInS = 0
var float curHi = na
var float curLo = na
var float ibHi = na
var float ibLo = na
var float pPoc = na
var float pVah = na
var float pVal = na
var float pdh = na
var float pdl = na
var float cPoc = na
var float cVah = na
var float cVal = na
var array<float> nakedP = array.new<float>()
var array<int> nakedX = array.new<int>()
var array<box> histB = array.new<box>()
var array<line> histL = array.new<line>()
var array<int> batchB = array.new<int>()
var array<int> batchL = array.new<int>()
var array<box> liveB = array.new<box>()
var array<line> liveL = array.new<line>()
var array<line> lvlL = array.new<line>()
var array<label> lvlLbl = array.new<label>()
ibBars = math.max(1, int(ibMinutes / math.max(1, timeframe.in_seconds() / 60.0)))
newSession = timeframe.change(profileTF)
if barstate.isconfirmed
if newSession
Показано первые 50% кода (символов: 15287)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.