Relative Volume at Time

Questions about MultiCharts and user contributed studies.
Bthomas
Posts: 3
Joined: 15 Jul 2022

Relative Volume at Time

Postby Bthomas » 21 Jul 2022

Hi, I’m trying to write a code to display the average volume of n session.

I think that can be interesting know if the current session open out the average or below to determine the risk of high volatility.
On tradingview I founded a indicator called “relative sessione volume at time” that display exactly what I trying to write.
Here the code of volume at session, someone can help me to have the average of all volume session and display on each session?

Code: Select all

variables: SessionVolume(0); if BarType = 0 and BarType <= 2 then SessionVolume = Volume else SessionVolume = Ticks; if date <> date[1] then begin value2= 0; end; if SessionVolume > 0 then value2 = value2 + SessionVolume; plot1( value2, "Volume Session");
trading view indicator: Relative Volume at Time
Image

pine script code od Relative Volume at Time:

Code: Select all

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // REUSING THIS CODE: You are welcome to reuse this code without permission, as long as it is used in open-source publications. Credits are appreciated. //@version=4 //@author=e2e4mfck and LucF, for TradingView // Relative Volume at Time // v1.1 2021.01.24 08:42 // This code was written using the following standards: // • PineCoders Coding Conventions for Pine: http://www.pinecoders.com/coding_conventions/ // • A modified version of the PineCoders MTF Selection Framework: https://www.tradingview.com/script/90mqACUV-MTF-Selection-Framework-PineCoders-FAQ/ MAX_BARS_BACK = 5000 study("Relative Volume at Time", "RelVol at Time", false, max_labels_count = 500, max_bars_back = MAX_BARS_BACK) // —————————— Constants and inputs { // ————— Color constants for input default values. var color c_BULL = color.new(color.teal, 20) var color c_BEAR = color.new(color.red, 20) var color c_BULL_BRIGHT = color.new(color.lime, 00) var color c_BEAR_BRIGHT = color.new(color.red, 00) var color c_NEUTRAL = color.new(color.gray, 20) var color c_PASTVOL = color.new(color.gray, 80) var color c_OUTLINES = color.new(color.black, 20) var color c_MARKER_UP = color.new(color.lime, 00) var color c_MARKER_DN = color.new(color.fuchsia, 00) var color c_TF_TRANSITIONS = color.new(color.silver, 90) var color c_THRESHOLD_CHANNEL = color.new(color.orange, 00) var color c_THRESHOLD_FILL = color.new(color.silver, 70) var color c_HIGH_VOLATILITY = color.new(color.gray, 40) // ————— String constants used in input options. // Boolean inputs. var string ON = "On" var string OFF = "Off" // Display modes. var string MD1 = "Current Volume Columns" var string MD2 = "Relative Volume Columns" var string MD3 = "Relative Volume Columns With Average" var string MD4 = "Directional Relative Volume Average" var string MD5 = "Relative Volume Average" // Calculation modes. var string CM1 = "Cumulate from Beginning of TF to Current Bar" var string CM2 = "Point-to-Point Bars at Same Offset from Beginning of TF" // TF selection modes. var string TF1 = "Auto-Steps Timeframe" var string TF2 = "Fixed Timeframe" var string TF3 = "Time (only works with intraday timeframes)" // Threshold modes. var string TM1 = "Fixed Value" var string TM2 = "Standard Deviation Channel From Fixed Lookback" var string TM3 = "High/Low Channel From Beginning of TF" var string TM4 = "High/Low Channel From Beginning of Past Volume Lookback" var string TM5 = "High/Low Channel From Fixed Lookback" // Volatility filter modes. var string VT1 = "All" var string VT2 = "High only" var string VT3 = "Low only" // ————— Inputs _10 = input(true, "═════════════ Display ══════════════") string i_mode = input(MD1, "Mode", options = [MD1, MD2, MD3, MD4, MD5]) bool i_showRatio = input(OFF, "Relative Volume Value", options = [ON, OFF]) == ON bool i_showtfTransitions = input(ON, "TF transitions", options = [ON, OFF]) == ON bool i_showtfReminder = input(OFF, "TF Unit Reminder", options = [ON, OFF]) == ON bool i_showThreshold = input(OFF, "Threshold", options = [ON, OFF]) == ON bool i_showMarkersUp = input(OFF, "Up Markers On Color Transitions", options = [OFF, ON]) == ON bool i_showMarkersDn = input(OFF, "Down Markers On Color Transitions", options = [OFF, ON]) == ON bool i_ShowHiVolatility = input(OFF, "High Volatility", options = [OFF, ON]) == ON _20 = input(true, "═════════════ Settings  ═════════════") string i_calcMode = input(CM1, "Calculation Mode", options = [CM1, CM2]) int i_period = input(5, "Past Volume Lookback in TF units", minval = 1) string i_tfType = input(TF1, "Define Timeframes Units Using", options = [TF1, TF2, TF3]) string i_tf = input("D", "  Fixed", type = input.resolution) int i_hour = input(09, "  Time (hour)", minval = 0, maxval = 23) int i_minute = input(30, "  Time (minute)", minval = 0, maxval = 59) string i_thresholdMode = input(TM1, "Threshold Mode", options = [TM1, TM2, TM3, TM4, TM5]) float i_thresholdFixedVal = input(2.0, "  Fixed Threshold", minval = 1, step = 0.1) int i_thresholdLookback = input(100, "  Channel Lookback", minval = 1) float i_thresholdStdevFac = input(1.0, "  StDev Factor", minval = 0, step = 0.1) int i_avgPeriod = input(14, "Period of RelVol Moving Average", minval = 1) int i_fastVolatility = input(7, "High Volatility When Short-term ATR", minval = 1) int i_slowVolatility = input(40, "  Is Higher Than Long-term ATR", minval = 2) _30 = input(true, "═══════ Column Coloring Conditions ═══════") bool i_colorCond1 = input(ON, "Current Chart Bar's Up/Dn State", options = [OFF, ON]) == ON bool i_colorCond2 = input(OFF, "RelVol > 1.0", options = [OFF, ON]) == ON bool i_colorCond3 = input(OFF, "RelVol > or < RelVol Average", options = [OFF, ON]) == ON bool i_colorCond4 = input(OFF, "RelVol > or < Threshold", options = [OFF, ON]) == ON bool i_colorCond5 = input(OFF, "Dir. RelVol Avg is Bull/Bear", options = [OFF, ON]) == ON bool i_colorCond6 = input(OFF, "Dir. RelVol Avg > or < Threshold", options = [OFF, ON]) == ON bool i_colorCond7 = input(OFF, "RelVol Avg > or < 1.0", options = [OFF, ON]) == ON bool i_colorCond8 = input(OFF, "RelVol Avg > or < Threshold", options = [OFF, ON]) == ON string i_colorFilter1 = input(VT1, "Filter Conditions On Volatility", options = [VT1, VT2, VT3]) _40 = input(true, "═════════════  Colors  ══════════════") color i_c_bull = input(c_BULL, "High Relative Volume") color i_c_bear = input(c_BEAR, "Low Relative Volume") color i_c_neutral = input(c_NEUTRAL, "Neutral") color i_c_bullBright = input(c_BULL_BRIGHT, "Brighter Highs") color i_c_bearBright = input(c_BEAR_BRIGHT, "Brighter Lows") color i_c_pastVol = input(c_PASTVOL, "Past Volume") color i_c_outlines = input(c_OUTLINES, "RelVol Column Outlines") color i_c_markerUp = input(c_MARKER_UP, "Marker Up") color i_c_markerDn = input(c_MARKER_DN, "Marker Down") color i_c_tfTransitions = input(c_TF_TRANSITIONS, "TF transitions") color i_c_thresholdChannel= input(c_THRESHOLD_CHANNEL,"Threshold Channel") color i_c_thresholdFill = input(c_THRESHOLD_FILL, "Threshold Channel Fill") color i_c_highVolatility = input(c_HIGH_VOLATILITY, "High Volatility") // } // —————————— Functions { // ————— Returns 1 when `_c` boolean is true, 0 if false. f_01(_c) => _c ? 1 : 0 // ————— Converts current chart timeframe into a float minutes value. f_chartTfInMinutes() => float _resInMinutes = timeframe.multiplier * ( timeframe.isseconds ? 1. / 60 : timeframe.isminutes ? 1. : timeframe.isdaily ? 60. * 24 : timeframe.isweekly ? 60. * 24 * 7 : timeframe.ismonthly ? 60. * 24 * 30.4375 : na) // ————— Returns `_tf` timeframe in float minutes. f_tfInMinutes(_tf) => // _tf: TF (in `timeframe.period` string format) to be converted in float minutes. // Dependency: f_chartTfInMinutes() security(syminfo.tickerid, _tf, f_chartTfInMinutes(), lookahead = true) // ————— Given a `_res` timeframe in float minutes, returns the ideal timeframe to use in calcs. f_tfAutoSteps(_tf) => // _tf: chart's TF in fractional minutes from which to derive a HTF. _tf <= 0.02 ? "1" : _tf <= 1 ? "60" : _tf < 60. * 24 ? "1D" : _tf == 60. * 24 ? "1W" : _tf < 60. * 24 * 30.4375 ? "1M" : "12M" // ————— Function rounding OHLC values to tick precision. f_ohlcRoundedToTick() => [round(open / syminfo.mintick) * syminfo.mintick, round(high / syminfo.mintick) * syminfo.mintick, round(low / syminfo.mintick) * syminfo.mintick, round(close / syminfo.mintick) * syminfo.mintick] [o, h, l, c] = f_ohlcRoundedToTick() // —————————— Bar up/dn states. // ————— Returns true when a bar is considered to be an up bar. f_barUp() => // Dependencies: `o` and `c`, which are the `open` and `close` values rounded to tick precision. // Account for the normal "close > open" condition, but also for zero movement bars when their close is higher than previous close. _barUp = c > o or (c == o and c > nz(c[1], c)) // ————— Returns true when a bar is considered to be a down bar. f_barDn() => // Dependencies: `o` and `c`, which are the `open` and `close` values rounded to tick precision. // Account for the normal "close < open" condition, but also for zero movement bars when their close is lower than previous close. _barDn = c < o or (c == o and c < nz(c[1], c)) // ————— Function displays a label containing `_txt` at position `_y` in `_color` and at bar `_offset` from last bar. No background is used. f_print(_txt, _y, _color, _offset) => // Keep track of minimum time between bars (chart's timeframe in ms) using `abs()` so this works with pre-1970 negative times. var _tf = 10e15, _tf := min(abs(time - nz(time[1])), _tf) // Calculate time offset for x position. _t = int(time + _tf * _offset) // Create the label on the first bar and only update it when on the dataset's last bar; it's more efficient. var label _lbl = label.new(_t, _y, _txt, xloc.bar_time, yloc.price, #00000000, label.style_label_left, _color, size.large, text.align_left) if barstate.islast label.set_xy(_lbl, _t, _y) label.set_text(_lbl, _txt) label.set_textcolor(_lbl, _color) // ————— Function appends the `_text` error message to the `_msg` string when `_error` is true. f_checkError(_error, _msg, _text) => _error ? _msg + _text + "\n" : _msg // ————— Function returns the farthest usable lookback, givne a user-selected number of periods. f_optimalLookback(_barNosAtTfTransitions, _userPeriods) => // _barNosAtTfTransitions: Id of array containing bar nos of past TF transitions. // _userPeriods : User-selected number of TF units to look back. // Dependency: MAX_BARS_BACK int _return = 0 // Loop from now to past TFs until we find a point back that's too far. for _i = _userPeriods - 1 to 0 if bar_index - array.get(_barNosAtTfTransitions, _i) > MAX_BARS_BACK - 1 break _return := _return + 1 _return // ————— Function returning the average of past point-to-point volume, i.e., for the bars with the same offset from the beginning of the TF. f_pastVolPtp(_msSinceStartOfTf, _timeAtFarthest, _periods) => // _msSinceStartOfTf: Bar's offset in milliseconds since the beginning of the TF. // _timeAtFarthest : UTC time at the beginning of the lookback periods, so the farthest back we will be analyzing. // _periods : number of past TFs units to average. // Dependency: MAX_BARS_BACK // Note that if bars with the same offset from the beginning of the TF are missing in the past TFs, the average will be calculated for a smaller number of TFs. // Array holding the cumulative volume for each of the `_periods` TFs in our lookback, // but only counting the bars within the current offset from the beginning of the current TF's beginning. // We start with an empty array and add an element containing the cumulative volume for each TF in history we use. float[] _volumes = array.new_float(0) int _tfNo = 0 for _i = 1 to MAX_BARS_BACK - 2 if time[_i] < _timeAtFarthest or _tfNo >= _periods // We are farther back than the beginning of the lookback, or the required qty of TFs has been processed; exit loop. break if _msSinceStartOfTf == nz(_msSinceStartOfTf[_i]) // A bar with the same time offset was found; add its volume. _tfNo := _tfNo + 1 // Save the cumulated volume for the TF. array.push(_volumes, volume[_i]) // ————— Return the avg of point-to-point volume. float _return = nz(array.avg(_volumes)) // ————— Function returning the average of cumulative past volume, i.e., // the total volume from the beginning of each TF in the past until the point in that TF // corresponding to where the current bar is with regards to the beginning of the current TF. f_pastVolCum(_msSinceStartOfTf, _timeAtFarthest, _periods, _timesAtTfTransitions) => // _msSinceStartOfTf : Bar's offset in milliseconds since the beginning of the TF. // _timeAtFarthest : UTC time at the beginning of the lookback periods, so the farthest back we will be analyzing. // _periods : number of past TFs units to average. // _timesAtTfTransitions: Array id containing the time at TF transitions, so we know where to reset volume. // Dependency: MAX_BARS_BACK // Array holding the cumulative volume for each of the `_periods` TFs in our lookback, // but only counting the bars within the current offset from the beginning of the current TF's beginning. // We start with an empty array and add an element containing the cumulative volume for each TF in history we use. float[] _volumes = array.new_float(0) // Holds cumulative volume for the TF being cumulated in the loop. float _cumVolTot = 0. // Count of historical TFs we have analyzed. int _tfNo = 1 // Non-capped no of user-selected periods. var int _userSelectedNoOfPeriods = array.size(_timesAtTfTransitions) - 1 // Time at beginning of the TF the current bar belongs to; we will skip calcs until we're past that point. float _timeAtStartOfCurrentTf = array.get(_timesAtTfTransitions, _userSelectedNoOfPeriods) // Time at beginning of the TF the loop is calculating. float _timeAtStartOfPastTf = array.get(_timesAtTfTransitions, _userSelectedNoOfPeriods - 1) for _i = 1 to MAX_BARS_BACK - 2 float _time = time[_i] if _time < _timeAtFarthest or _tfNo > _periods // We are farther back than the beginning of the lookback, or the required qty of TFs has been processed; exit loop. break if _time < _timeAtStartOfCurrentTf // We are past the current TF; we can calculate cumulative past volume. if _time - _timeAtStartOfPastTf <= _msSinceStartOfTf // The bar is in our scope; add its volume. _cumVolTot := _cumVolTot + volume[_i] if _time == _timeAtStartOfPastTf // ————— We have reached the beginning of one of the TFs in our lookback; update/reset our numbers. // Save the cumulated volume for the TF. array.push(_volumes, _cumVolTot) // Qty of processed TFs. _tfNo := _tfNo + 1 // Get next TF's beginning time. _timeAtStartOfPastTf := nz(array.get(_timesAtTfTransitions, max(0, _userSelectedNoOfPeriods - _tfNo))) // Reset the TF's cum volume. _cumVolTot := 0. // ————— Return the avg of cumulative past volume. float _return = nz(array.avg(_volumes)) // ————— Function returning true when a high volatility condition is detected. f_highVolatility() => // Dependencies : i_fastVolatility, i_slowVolatility atr(i_fastVolatility) > atr(i_slowVolatility) // } // —————————— Calculations { // ————— Determine timeframe from user selection. var string tf = i_tfType == TF2 ? i_tf : f_tfAutoSteps(f_chartTfInMinutes()) // ————— Detect new TF. // Logic for TOD TF units. var int dailyTodTriggers = 0 float timeMark = timestamp(year, month, dayofmonth, i_hour, i_minute, 00) float timeDailyClose = security(syminfo.tickerid, "D", time_close, lookahead = true) bool beginTime = time == timeMark bool pastTime = time > timeMark bool lastBarofDay = time_close == timeDailyClose bool newday = change(time("D")) bool atOrPastBeginTime = false if barstate.isfirst atOrPastBeginTime := true dailyTodTriggers := 1 else if newday dailyTodTriggers := 0 if (not beginTime[1] and beginTime) or (dailyTodTriggers == 0 and (pastTime or lastBarofDay)) // The user-defined TOD was reached, or it's the first time in the day that we are past it, // or we are on the day's last bar and no suitable bar has been detected yet. dailyTodTriggers := dailyTodTriggers + 1 atOrPastBeginTime := true // TF resets using user-selected mode. bool tfReset = nz(i_tfType == TF3 and timeframe.isminutes ? atOrPastBeginTime : change(time(tf)), true) // ————— Manage TF transitions and cumulate volume of current TF. // Array holding the time and bar_index at TF transitions. var float[] timesAtTfTransitions = array.new_float(i_period + 1, time) var int[] barNosAtTfTransitions = array.new_int(i_period + 1, 0) // Cumulative volume of current TF. var float cumVolume = 0. // Time at point from where we calculate the time offset between the current bar and the beginning of the current TF. var int timeAtStartOfTf = time // Handle TF transition calcs. if tfReset // Maintain queues of the time and bar_index at which our last `i_period` TFs begin. We'll need this when calculating the cumulative past volume. // The last element always contains the info for the current TF, which won't be used in calcs of past volume. If the period is capped, we won't be using all elements. array.push(timesAtTfTransitions, time) array.shift(timesAtTfTransitions) array.push(barNosAtTfTransitions, bar_index) array.shift(barNosAtTfTransitions) // Reset cumulative volume from beginning of current TF. cumVolume := volume else // Keep track of total volume from beginning of current TF. cumVolume := cumVolume + volume // ————— Get new time offsets. // Cap period if user-selected one causes us to look back too far away. int cappedPeriod = min(i_period, f_optimalLookback(barNosAtTfTransitions, i_period)) // Bar no at beginning of current TF. int barAtStartOfTf = array.get(barNosAtTfTransitions, i_period) // Save time on first bar. var float timeAtBarZero = time // Time at `cappedPeriod` * TF units back, which is the furthest in past we will look back. float timeAtFarthestLookback = array.get(timesAtTfTransitions, i_period - cappedPeriod) // Bar's offset in milliseconds since the beginning of the current TF. float msSinceStartOfTf = time - array.get(timesAtTfTransitions, i_period) // ————— Relative volume. // Get past and current volume as per user-selected calc mode. float pastVolume = i_calcMode == CM1 ? f_pastVolCum(msSinceStartOfTf, timeAtFarthestLookback, cappedPeriod, timesAtTfTransitions) : f_pastVolPtp(msSinceStartOfTf, timeAtFarthestLookback, cappedPeriod) float currentVolume = i_calcMode == CM1 ? cumVolume : volume float relVol = pastVolume == 0 ? 0. : currentVolume / pastVolume // ————— Directional relvol avg. float relVolDir = f_barUp() ? relVol : - relVol float relVolAvgDir = hma(relVolDir, i_avgPeriod) // ————— Relvol avg. float relVolAvg = hma(relVol, i_avgPeriod) // ————— Threshold // Highs/Lows. // Bar no at `cappedPeriod` TF units back. int barAtFarthestLookback = array.get(barNosAtTfTransitions, i_period - cappedPeriod) int hiLoLookback = i_thresholdMode == TM3 ? (bar_index - barAtStartOfTf + 1) : i_thresholdMode == TM4 ? bar_index - barAtFarthestLookback + 1 : i_thresholdLookback hiLoLookback := int(min(max(1, nz(hiLoLookback)), MAX_BARS_BACK -1)) float hiLoHigh = highest(relVol, hiLoLookback) float hiLoLow = lowest( relVol, hiLoLookback) // Stdev. float relVolStDev = stdev(relVol, i_thresholdLookback) float relVolSma = sma(relVol, i_thresholdLookback) float relVolStDevHigh = relVolSma + relVolStDev * i_thresholdStdevFac float relVolStDevLow = max(0, relVolSma - relVolStDev * i_thresholdStdevFac) [thresholdHi, thresholdLo] = if i_thresholdMode == TM1 [i_thresholdFixedVal, i_thresholdFixedVal] else if i_thresholdMode == TM2 [relVolStDevHigh, relVolStDevLow] else if i_thresholdMode == TM3 or i_thresholdMode == TM4 or i_thresholdMode == TM5 [hiLoHigh, hiLoLow] // ————— Error conditions // Critical errors causing plots to be hidden. bool chartTfIsTooLow = f_chartTfInMinutes() > f_tfInMinutes(tf) bool noRelVol = na(relVol) bool noTfUnits = barAtStartOfTf == 0 and bar_index > MAX_BARS_BACK bool noVolume = na(volume) bool dontPlot = chartTfIsTooLow or noRelVol or noTfUnits or noVolume // Non-critical errors. bool lookbackIsTooBig = i_period != cappedPeriod bool noThreshold = i_showThreshold and i_mode == MD1 bool cantUseTod = i_tfType == TF3 and not timeframe.isminutes // } // —————————— Plot colors and Plots { // —————————— Colors // ————— Function returning +1/0/-1 as per bull/neutral/bear state of `_condNo` if `_useCond` is true. f_conditionState(_condNo, _useCond) => // _condNo : condition to be evaluated. // _useCond : boolean determining if the condition must be evaluated. // Dependencies : relVol, relVolAvgDir, relVolAvg, thresholdHi, thresholdLo, f_barUp(), f_barDn(). bool _barUp = f_barUp() bool _barDn = f_barDn() if _useCond if _condNo == 1 _barUp ? 1 : _barDn? -1 : 0 else if _condNo == 2 sign(relVol - 1) else if _condNo == 3 sign(relVol - relVolAvg) else if _condNo == 4 relVol > thresholdHi[1] ? 1 : relVol < thresholdLo[1] ? -1 : 0 else if _condNo == 5 sign(relVolAvgDir - 0) else if _condNo == 6 relVolAvgDir > thresholdHi[1] ? 1 : relVolAvgDir < -thresholdHi[1] ? -1 : 0 else if _condNo == 7 sign(relVolAvg - 1) else if _condNo == 8 relVolAvg > thresholdHi[1] ? 1 : relVolAvg < thresholdLo[1] ? -1 : 0 else 0 else 0 // ————— Determine column color from bull/bear/neutral states of user-selected coloring conditions. // The Volatility selection in Inputs is applied as a filter, as opposed to a bull/neutral/bear color selection criterion. bool filterOk = (i_colorFilter1 == VT1 or (i_colorFilter1 == VT2 and f_highVolatility()) or (i_colorFilter1 == VT3 and not f_highVolatility())) // Count how many conditions user has turned on. int qtyOfConditions = f_01(i_colorCond1) + f_01(i_colorCond2) + f_01(i_colorCond3) + f_01(i_colorCond4) + f_01(i_colorCond5) + f_01(i_colorCond6) + f_01(i_colorCond7) + f_01(i_colorCond8) // Add states of all coloring condition. float conditionsStates = f_conditionState(1, i_colorCond1) + f_conditionState(2, i_colorCond2) + f_conditionState(3, i_colorCond3) + f_conditionState(4, i_colorCond4) + f_conditionState(5, i_colorCond5) + f_conditionState(6, i_colorCond6) + f_conditionState(7, i_colorCond7) + f_conditionState(8, i_colorCond8) // Bull/Bear state triggers when all selected conditions are in agreement. bool stateBull = qtyOfConditions > 0 and conditionsStates == qtyOfConditions bool stateBear = qtyOfConditions > 0 and conditionsStates == - qtyOfConditions // Build color using compound coloring conditions and filter. color c_currentVol = not filterOk ? i_c_neutral : stateBull ? i_c_bull : stateBear ? i_c_bear: i_c_neutral color c_pastVolMark = relVol > 1 ? i_c_bullBright : i_c_bearBright color c_ratio = relVol > 1 ? i_c_bull : i_c_bear color c_candle = i_mode == MD2 ? i_c_pastVol : na color c_candleBorder = i_mode == MD2 ? i_c_outlines : na color c_relVolAvgDir = relVolAvgDir > 0 ? i_c_bullBright : i_c_bearBright color c_relVolAvg = relVolAvg > 1 ? color.new(color.gray, 0) : color.new(color.gray, 50) // ————— Plots // Data Window. plotchar(pastVolume, "Past Volume", "", location.top, size = size.tiny) plotchar(currentVolume, "Current Volume", "", location.top, size = size.tiny) plotchar(relVol, "Relative Volume", "", location.top, c_ratio, size = size.tiny) plotchar(volume, "Volume", "", location.top, c_currentVol, size = size.tiny) plotchar(na, "──────────────", "", location.top, size = size.tiny) plotchar(relVolAvgDir, "Directional RelVol Avg", "", location.top, c_relVolAvgDir, size = size.tiny) plotchar(relVolAvg, "RelVol Avg", "", location.top, c_relVolAvg, size = size.tiny) plotchar(na, "══════════════", "", location.top, size = size.tiny) // Levels. hline(i_mode == MD4 ? 0 : na, "Level 0", color.gray, hline.style_dotted) hline(i_mode == MD2 or i_mode == MD3 or i_mode == MD5 ? 1 : na, "Level 1", color.gray, hline.style_dotted) // Columns. plot(dontPlot ? na : i_mode == MD1 ? pastVolume : na, "Past Volume Column", i_c_pastVol, 1, plot.style_columns) plot(dontPlot ? na : i_mode == MD1 ? currentVolume : i_mode == MD2 or i_mode == MD3 ? relVol : na, "Current Volume Column", c_currentVol, 1, plot.style_columns) plotcandle(i_mode == MD1 ? 0 : na, i_mode == MD1 ? pastVolume : na, i_mode == MD1 ? 0 : na, i_mode == MD1 ? pastVolume : na, "Past Volume Candle", c_candle, bordercolor = i_c_outlines) plotchar(dontPlot ? na : i_mode == MD1 ? pastVolume : na, "Past Volume Mark", "—", location.absolute, c_pastVolMark) // Ratio display. if (i_mode == MD1 or i_mode == MD2 or i_mode == MD3) and i_showRatio and not dontPlot label.new(bar_index, i_mode == MD1 ? max(currentVolume, pastVolume) : i_mode == MD2 or i_mode == MD3 ? relVol : na, tostring(relVol, "0.00") + "\n", style = label.style_none, textcolor = c_ratio, size = size.small) // Directional relvol avg. plot(dontPlot ? na : i_mode == MD4 ? relVolAvgDir : na, "Directional RelVol Avg Plot", c_relVolAvgDir) // Relvol avg. plot(dontPlot ? na : i_mode == MD3 or i_mode == MD5 ? relVolAvg : na, "RelVol Avg Plot", c_relVolAvg, 2) // ————— Threshold p_hi = plot(dontPlot or i_mode == MD1 ? na : i_showThreshold ? thresholdHi : na, "Channel High", i_c_thresholdChannel) p_lo = plot(dontPlot or i_mode == MD1 ? na : i_showThreshold ? thresholdLo : na, "Channel Low", i_c_thresholdChannel) fill(p_hi, p_lo, i_c_thresholdFill, title = "Channel Fill") p_hiNeg = plot(dontPlot or i_mode != MD4 ? na : i_showThreshold ? - thresholdHi : na, "Channel High Negative", i_c_thresholdChannel) p_loNeg = plot(dontPlot or i_mode != MD4 ? na : i_showThreshold ? - thresholdLo : na, "Channel Low Negative", i_c_thresholdChannel) fill(p_hiNeg, p_loNeg, i_c_thresholdFill, title = "Channel Fill Negative") // ————— High volatility plotchar(i_ShowHiVolatility and f_highVolatility(), "High Volatility", "•", location.top, i_c_highVolatility, size = size.tiny) // ————— Markers bool markerUp = i_showMarkersUp and c_currentVol == i_c_bull and c_currentVol[1] != i_c_bull bool markerDn = i_showMarkersDn and c_currentVol == i_c_bear and c_currentVol[1] != i_c_bear plotchar(markerUp, "Marker Up", "▲", location.top, i_c_markerUp, size = size.tiny) plotchar(markerDn, "Marker Dn", "▼", location.top, i_c_markerDn, size = size.tiny) // } // —————————— Alert and error messages { // ————— Alert. alertcondition(markerUp or markerDn, "Relative Volume", "RelVol") // ————— Error messages // Build aggregate error message on detected errors. string msg = "" msg := f_checkError(chartTfIsTooLow, msg, "Chart TF must be lower than\nthe TF used for the lookback period.") msg := f_checkError(noRelVol, msg, "Relative Volume\ncannot be calculated.") msg := f_checkError(noTfUnits, msg, "No timeframe units can be detected.") msg := f_checkError(noVolume, msg, "No volume is detected.") msg := f_checkError(lookbackIsTooBig, msg, "Lookback of " + tostring(i_period, "#") + " is too large.\n" + (cappedPeriod != 0 ? "Using " + tostring(cappedPeriod, "#") + " instead." : "")) msg := f_checkError(noThreshold, msg, "Can't display threshold at this scale.") msg := f_checkError(cantUseTod, msg, "TOD only works on intraday charts.\nUsing Auto-steps instead.") msg := f_checkError(i_showtfReminder, msg, i_tfType == TF3 ? tostring(i_hour, "00:") + tostring(i_minute, "00") : tf) msg := f_checkError(msg != "", msg, "\n") f_print(msg, 0, color.red, 0) // Background (used for serious error conditions and timeframe transitions). bgcolor(dontPlot ? color.new(color.red, 60) : i_showtfTransitions and tfReset ? i_c_tfTransitions : na) // }

Return to “MultiCharts”