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

Relative Volume Breakout Context

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

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

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

О программе

Индикатор «Relative Volume Breakout Context» анализирует относительный объём в рамках торговой сессии и выявляет пробои предшествующего ценового диапазона с учётом объёмной статистики. Он рассчитывает Z-оценку объёма для каждого слота сессии, сравнивая текущий объём с историческим средним по той же позиции в рамках обменного окна.

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

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

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

НастройкаОписание
sessionStartHour Час начала торговой сессии в часовом поясе символа.
sessionStartMinute Минута начала торговой сессии в часовом поясе символа.
sessionLength Длительность торговой сессии в минутах, в рамках которой рассчитывается объёмная статистика.
memorySessions Количество сессий, учитываемых в экспоненциальной памяти при расчёте среднего и дисперсии объёма для каждого слота.
minimumSamples Минимальное количество предшествующих наблюдений объёма в слоте, необходимое для расчёта надёжной Z-оценки.
dispersionFloorPct Минимальная дисперсия в процентах от среднего значения, предотвращающая нестабильность Z-оценки при малом объёме истории.
volumeZThreshold Порог Z-оценки объёма, при котором текущий объём считается достаточным для подтверждения пробоя.
decayZThreshold Порог Z-оценки объёма, при котором фиксируется затухание участия в рамках активного пробоя.
breakoutLength Количество предшествующих баров для определения верхнего и нижнего уровней ценового диапазона.
atrLength Количество баров для расчёта индикатора средних истинных диапазонов (ATR), используемого для оценки глубины пробоя.
minimumBreakAtr Минимальное расстояние пробоя за пределы диапазона, выраженное в единицах ATR, для признания события валидным.
trackingBars Количество баров, в течение которых отслеживается состояние активного пробоя до автоматической инвалидации.
showScorePane Отображение линии совместного контекстного скоринга в отдельном окне индикатора.
showVolumeZ Отображение гистограммы Z-оценки объёма в отдельном окне индикатора.
showCandidateRails Отображение уровней верхнего и нижнего предшествующего ценового диапазона на графике.
showStateWash Цветовая заливка графика, отражающая текущее состояние отслеживания пробоя.
showEventLabels Отображение меток с информацией об относительном объёме и Z-оценке для подтверждённых событий пробоя.
showDashboard Отображение информационного дашборда с текущими параметрами объёма и состояния в углу графика.
maximumLabels Максимальное количество меток событий, отображаемых на графике одновременно.
bullColor Цвет визуальных элементов, обозначающих бычье принятие пробоя.
bearColor Цвет визуальных элементов, обозначающих медвежье принятие пробоя.
decayColor Цвет элементов, указывающих на затухание участия после подтверждённого пробоя.
volumeColor Цвет гистограммы относительного объёма и Z-оценки.
neutralColor Цвет элементов, используемых для нейтрального состояния или разогрева базы.
Получить полный код

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

indicator("Relative Volume Breakout Context", shorttitle="RV Breakout", overlay=false, max_labels_count=100)

string GROUP_SESSION = "Exchange session model"
string GROUP_BASELINE = "Same-position volume baseline"
string GROUP_BREAKOUT = "Breakout context"
string GROUP_VISUALS = "Visual system"

sessionStartHour = input.int(9, "Session start hour", minval=0, maxval=23, group=GROUP_SESSION, tooltip="Hour in the symbol exchange timezone.")
sessionStartMinute = input.int(30, "Session start minute", minval=0, maxval=59, group=GROUP_SESSION, tooltip="Minute in the symbol exchange timezone.")
sessionLength = input.int(390, "Session length (minutes)", minval=30, maxval=1440, group=GROUP_SESSION)

memorySessions = input.int(30, "Baseline memory (sessions)", minval=5, maxval=120, group=GROUP_BASELINE, tooltip="Controls the exponential memory of each same-position volume baseline.")
minimumSamples = input.int(10, "Minimum prior samples", minval=3, maxval=60, group=GROUP_BASELINE)
dispersionFloorPct = input.float(10.0, "Dispersion floor (% of mean)", minval=1.0, maxval=100.0, step=1.0, group=GROUP_BASELINE, tooltip="Prevents a nearly constant volume history from producing unstable Z scores.")
volumeZThreshold = input.float(1.5, "Breakout volume Z threshold", minval=0.25, maxval=5.0, step=0.05, group=GROUP_BASELINE)
decayZThreshold = input.float(0.0, "Post-breakout decay Z threshold", minval=-3.0, maxval=3.0, step=0.1, group=GROUP_BASELINE)

breakoutLength = input.int(30, "Prior price range bars", minval=5, maxval=300, group=GROUP_BREAKOUT)
atrLength = input.int(14, "ATR length", minval=2, maxval=100, group=GROUP_BREAKOUT)
minimumBreakAtr = input.float(0.10, "Minimum close beyond range (ATR)", minval=0.0, maxval=3.0, step=0.05, group=GROUP_BREAKOUT)
trackingBars = input.int(12, "Event tracking bars", minval=2, maxval=100, group=GROUP_BREAKOUT)

showScorePane = input.bool(true, "Show context score", group=GROUP_VISUALS)
showVolumeZ = input.bool(true, "Show relative-volume Z score", group=GROUP_VISUALS)
showCandidateRails = input.bool(true, "Show prior breakout rails", group=GROUP_VISUALS)
showStateWash = input.bool(true, "Show tracked-state wash", group=GROUP_VISUALS)
showEventLabels = input.bool(true, "Show confirmed event labels", group=GROUP_VISUALS)
showDashboard = input.bool(true, "Show context dashboard", group=GROUP_VISUALS)
maximumLabels = input.int(30, "Maximum event labels", minval=5, maxval=100, group=GROUP_VISUALS)

bullColor = input.color(color.rgb(16, 185, 129), "Bullish acceptance", group=GROUP_VISUALS)
bearColor = input.color(color.rgb(239, 92, 118), "Bearish acceptance", group=GROUP_VISUALS)
decayColor = input.color(color.rgb(245, 158, 11), "Participation decay", group=GROUP_VISUALS)
volumeColor = input.color(color.rgb(56, 189, 248), "Relative volume", group=GROUP_VISUALS)
neutralColor = input.color(color.rgb(148, 163, 184), "Neutral / warming", group=GROUP_VISUALS)

int MAX_SESSION_SLOTS = 1440
var array<int> slotCounts = array.new_int(MAX_SESSION_SLOTS, 0)
var array<float> slotMeans = array.new_float(MAX_SESSION_SLOTS, 0.0)
var array<float> slotVariances = array.new_float(MAX_SESSION_SLOTS, 0.0)
var array<label> eventLabels = array.new<label>()

f_clamp(float value, float lower, float upper) =>
    math.min(math.max(value, lower), upper)

f_update_slot(int index, float observation) =>
    int oldCount = array.get(slotCounts, index)
    float oldMean = array.get(slotMeans, index)
    float oldVariance = array.get(slotVariances, index)
    float alpha = oldCount < memorySessions ? 1.0 / float(oldCount + 1) : 2.0 / float(memorySessions + 1)
    float delta = observation - oldMean
    float nextMean = oldCount == 0 ? observation : oldMean + alpha * delta
    float nextVariance = oldCount == 0 ? 0.0 : (1.0 - alpha) * (oldVariance + alpha * delta * delta)
    array.set(slotCounts, index, math.min(oldCount + 1, 1000000))
    array.set(slotMeans, index, nextMean)
    array.set(slotVariances, index, math.max(nextVariance, 0.0))

f_push_label(label eventLabel) =>
    array.push(eventLabels, eventLabel)
    if array.size(eventLabels) > maximumLabels
        label.delete(array.shift(eventLabels))

float chartMinutes = float(timeframe.in_seconds()) / 60.0
bool validTimeframe = timeframe.isintraday and chartMinutes >= 1.0 and chartMinutes <= 30.0 and math.abs(chartMinutes - math.round(chartMinutes)) < 0.001
int minuteOfDay = hour(time, syminfo.timezone) * 60 + minute(time, syminfo.timezone)
int sessionStartMinuteOfDay = sessionStartHour * 60 + sessionStartMinute
int elapsedMinute = (minuteOfDay - sessionStartMinuteOfDay + 1440) % 1440
bool inSession = validTimeframe and elapsedMinute < sessionLength
int slotIndex = inSession ? int(math.floor(float(elapsedMinute) / chartMinutes)) : na
bool validSlot = inSession and slotIndex >= 0 and slotIndex < MAX_SESSION_SLOTS
bool volumeValid = validSlot and not na(volume) and volume >= 0.0

int slotSamples = validSlot ? array.get(slotCounts, slotIndex) : 0
float expectedVolume = validSlot and slotSamples > 0 ? array.get(slotMeans, slotIndex) : na
float rawDispersion = validSlot and slotSamples > 1 ? math.sqrt(array.get(slotVariances, slotIndex)) : na
float dispersionFloor = not na(expectedVolume) ? expectedVolume * dispersionFloorPct * 0.01 : na
float effectiveDispersion = not na(rawDispersion) and not na(dispersionFloor) ? math.max(rawDispersion, dispersionFloor) : na
bool baselineReady = volumeValid and slotSamples >= minimumSamples and expectedVolume > 0.0 and effectiveDispersion > 0.0
float volumeZ = baselineReady ? f_clamp((volume - expectedVolume) / effectiveDispersion, -5.0, 5.0) : na
float relativeVolume = baselineReady ? volume / expectedVolume : na
float reliability = baselineReady ? f_clamp(float(slotSamples) / float(minimumSamples * 2), 0.0, 1.0) : 0.0

float upperRail = ta.highest(high, breakoutLength)[1]
float lowerRail = ta.lowest(low, breakoutLength)[1]
float atr = ta.atr(atrLength)
bool priceReady = not na(upperRail) and not na(lowerRail) and not na(atr) and atr > 0.0
bool bullOutside = priceReady and close > upperRail
bool bearOutside = priceReady and close < lowerRail
bool freshBullBreak = bullOutside and close[1] <= upperRail
bool freshBearBreak = bearOutside and close[1] >= lowerRail
float bullDistanceAtr = bullOutside ? (close - upperRail) / atr : 0.0
float bearDistanceAtr = bearOutside ? (lowerRail - close) / atr : 0.0
float signedBreakDistanceAtr = bullOutside ? bullDistanceAtr : bearOutside ? -bearDistanceAtr : 0.0

float volumeComponent = baselineReady ? f_clamp(math.max(volumeZ, 0.0) / math.max(volumeZThreshold, 0.01), 0.0, 2.0) * 50.0 : 0.0
float distanceComponent = f_clamp(math.abs(signedBreakDistanceAtr) / math.max(minimumBreakAtr, 0.05), 0.0, 2.0) * 50.0
float jointMagnitude = math.sqrt(volumeComponent * distanceComponent) * reliability
float contextScore = bullOutside ? jointMagnitude : bearOutside ? -jointMagnitude : 0.0

var int activeDirection = 0
var int eventAge = 0
var float eventRail = na
var float eventFrontier = na
var bool decayLatched = false

bool confirmedBullEvent = barstate.isconfirmed and activeDirection == 0 and baselineReady and freshBullBreak and bullDistanceAtr >= minimumBreakAtr and volumeZ >= volumeZThreshold
bool confirmedBearEvent = barstate.isconfirmed and activeDirection == 0 and baselineReady and freshBearBreak and bearDistanceAtr >= minimumBreakAtr and volumeZ >= volumeZThreshold
bool confirmedBreakoutEvent = confirmedBullEvent or confirmedBearEvent
bool confirmedDecayEvent = false
bool confirmedInvalidation = false

if barstate.isconfirmed
    if confirmedBreakoutEvent
        activeDirection := confirmedBullEvent ? 1 : -1
        eventAge := 0
        eventRail := confirmedBullEvent ? upperRail : lowerRail
        even

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

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

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

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

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

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

Стоимость полного кода
1 347,80₽ ≈ $16.47