quartile-vol-vol-aggregation-range-us-bars-gaps-kioseff.pine
Copy
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © KioseffTrading
//@version=5
indicator("(Quartile Volume; Volume Aggregation; US Range Bars; Gaps) [Kioseff Trading]", overlay = true,
max_labels_count = 500 ,
max_boxes_count = 500 ,
max_lines_count = 500 ,
max_bars_back = 500
)
// ________________________________________________
// | |
// | --------------------------------- |
// | | K̲ i̲ o̲ s̲ e̲ f̲ f̲ T̲ r̲ a̲ d̲ i̲ n̲ g | |
// | | | |
// | | ƃ u ᴉ p ɐ ɹ ꓕ ⅎ ⅎ ǝ s o ᴉ ꓘ | |
// | -------------------------------- |
// | |
// |_______________________________________________|
// _______________________________________________________
//
// Inputs
// _______________________________________________________
// => Range US Params <=
show = input.string(defval = "Quartile Volume", title = "Dataset", options = ["Range US", "Volume Aggregation", "Gaps", "Quartile Volume"] )
fast = input.bool (defval = false , title = "Improve Loading Time?" , tooltip = "Selecting This Box Improves Load Times; However, Data More Than 7,500 Bars Old Will Not be Calculated. This Setting Does Not Improve Initial Compilation Time.")
tra = input.string(defval = "Auto" , title = "Auto Range US Candles? Or User-Defined?" , group = "Range US", options = ["Auto", "Custom"] )
rev = input.float (defval = 22 , title = "Reverse Candle Price Move" , group = "Range US", minval = 0.0000000001 )
tre = input.float (defval = 44 , title = "Trend Candle Price Move" , group = "Range US", minval = 0.0000000001 )
ranShow = input.bool (defval = false , title = "Segment Range US Bars By Date?" , group = "Range US" )
levShow = input.bool (defval = true , title = "Show Trend/Reverse Levels?" , group = "Range US" )
warn1 = input.bool (defval = true , title = "Show Warning?" , group = "Range US" )
sz = input.string(defval = "Tiny" , title = "Box Text Size (Auto Increases Chart Lag)" , group = "Range US", tooltip = "Box Text Size for Range US Candles.'Auto' Size May Cause Chart Lag" ,
options = ["Auto", "Tiny", "Small", "Normal", "Large", "Huge"] )
treShow = input.int(defval= 7 , title = "Number of Congestion Areas to Show (0 = None)" , group = "Range US", minval = 0 )
move = input.bool(defval = true , title = "Move Current Range US Bar to Levels Section?" , group = "Range US")
// => Volume Aggregation Params <=
tra1 = input.string(defval = "Auto" , title = "Auto Volume Aggregation Candles? Or User-Defined?", group = "Volume Aggregation", options = ["Auto", "Custom"] )
volInt = input.int (defval = 1000000 , title = "Required Volume", step = 10000 , group = "Volume Aggregation" )
vShow = input.bool (defval = false , title = "Segment Vol. Aggregation Bars By Date?" , group = "Volume Aggregation" )
sz1 = input.string(defval = "Tiny" , title = "Box Text Size (Auto Increases Chart Lag)" , group = "Volume Aggregation", tooltip = "Box Text Size for Range US Candles.'Auto' Size May Cause Chart Lag",
options = ["Auto", "Tiny", "Small", "Normal", "Large", "Huge"] )
showAl = input.bool (defval = true , title = "Show Largest Increases and Decreases?" , group = "Volume Aggregation" )
showUp = input.int (defval = 15 , title = "Number of Largest Volume Agg. Increases to Show", group = "Volume Aggregation", minval = 1,maxval = 20 )
showDn = input.int (defval = 15 , title = "Number of Largest Volume Agg. Decreases to Show", group = "Volume Aggregation", minval = 1,maxval = 20 )
warn = input.bool (defval = true , title = "Show Warning?" , group = "Volume Aggregation" )
// => Gaps Params <=
perG = input.float (defval = 0 , title = "Percentage Difference For Gap to Appear" , group = "Gaps", step = 0.1, minval = 0 ) /100
old = input.float (defval = -1 , title = "Hide Gaps When Price Deviates by Percentage" , group = "Gaps", minval = -1, tooltip = "Configuring This Setting to “-1” Will Keep All Gaps on the Chart. Configuring This Setting at or Above “0” Will Hide Gap Boxes if Price Moves the Percentage Amount Away From the Box. The “Percentage Amount” Is the Number in Defined for This Setting.") / 100
del = input.bool (defval = false , title = "Delete Filled Gaps?" , group = "Gaps" )
vis = input.bool (defval = false , title = "Visualize Gaps?" , group = "Gaps" )
rec = input.int (defval = 5 , title = "Recent Unfilled Gaps to Show (Table)" , group = "Gaps", minval = 0 )
// => Quartile Volume Params <=
colE = input.color (defval = color.red , title = "Low Volume Quartile Volume Color" ,inline = "1" , group = "Quartile Volume" )
colE1 = input.color (defval = color.lime, title = "High Volume Quartile Volume Color",inline = "1" , group = "Quartile Volume" )
pCalculation = input.int (defval = 10 , title = "% Gain / Loss After 'n' Bars for Exceeded 90th Percentile" , group = "Quartile Volume" , minval = 2 )
log = input.bool (defval = true , title = "Use Log Returns?" , group = "Quartile Volume" )
la = input.bool (defval = false , title = "Show Quartile on Bar?" , group = "Quartile Volume" )
quar = input.bool (defval = false , title = "Color Bars by Volume Quartiles" , group = "Quartile Volume" )
c1 = input.color (defval = #a5d6a7 , title = "First Quartile Color" , group = "Quartile Volume" )
c2 = input.color (defval = #81c784 , title = "Second Quartile Color" , group = "Quartile Volume" )
c3 = input.color (defval = #66bb6a , title = "Third Quartile Color" , group = "Quartile Volume" )
c4 = input.color (defval = #388e3c , title = "90th Percentile" , group = "Quartile Volume" )
c5 = input.color (defval = #1b5e20 , title = "Fourth Quartile Color" , group = "Quartile Volume" )
showIns = input.bool (defval = true , title = "Show Instructions?" , group = "Quartile Volume" )
anch = input.bool (defval = true , title = "Show Anchored VWAP" , group = "Quartile Volume", tooltip = "Adjust Start and End Times Below to Show Anchored VWAP - Drag & Drop the Time Bars On the Chart For Quick Configuration" )
s = input.time (defval = timestamp("20 Jul 1872 00:00 +0300"), title = "Anchored VWAP Start" , group = "Quartile Volume" )
e = input.time (defval = timestamp("20 Jul 2023 00:00 +0300"), title = "Anchored VWAP End" , group = "Quartile Volume" )
// _______________________________________________________
//
// Prerequisite Calculations
// _______________________________________________________
var color colCond = color.yellow
var color finCol = na
var float [] xz = array.new_float()
var float [] vol = array.new_float()
lin() =>
array.push(xz, close)
if array.size(xz) > 50
array.shift(xz)
X = array.sum(xz) / array.size(xz) -
(ta.linreg(close, array.size(xz), 0) -
ta.linreg(close, array.size(xz), 1)) *
math.floor(array.size(xz) / 2) + 0.5 *
(ta.linreg(close, array.size(xz), 0) -
ta.linreg(close, array.size(xz), 1))
Y = (array.sum(xz) / array.size(xz) -
(ta.linreg(close, array.size(xz), 0) -
ta.linreg(close, array.size(xz), 1)) *
math.floor(array.size(xz) / 2)) +
(ta.linreg(close, array.size(xz), 0) -
ta.linreg(close, array.size(xz), 1)) *
(array.size(xz) - 1)
float stDev = ta.stdev(X, array.size(xz) > 0 ? array.size(xz) : 1) * 2
[X, Y, stDev]
[X, Y, stDev] = lin()
atr = ta.atr(14)
tvsVol = request.security(syminfo.ticker + "_SHORT_VOLUME", "D", close, ignore_invalid_symbol = true)
var int loopCount = 0
start() =>
s <= e ? time >= s and time <= e: time <= s and time >= e
var int [] tim = array.new_int(2), var int timFin = 0
if barstate.isfirst
array.set(tim, 0,
math.round(timestamp(year, month, dayofmonth, hour, minute, second)))
if bar_index == 1
array.set(tim, 1,
math.round(timestamp(year, month, dayofmonth, hour, minute, second)))
timFin := array.get(tim, 1) - array.get(tim, 0)
bool loadFast = switch fast
false => bar_index > -1
true => last_bar_index - bar_index <= 7500
// _______________________________________________________
//
// Range US Bars
// _______________________________________________________
[lowClose, lowHigh, lowLow, lowOpen, lowVol, lowATR] = request.security_lower_tf(syminfo.ticker, "1", [close, high, low, open, volume, atr])
if show == "Range US" and loadFast
var float [] trCandle = array.new_float ()
var box [] boxTr = array.new_box()
bool cond = year(time) == year(timenow)
and month(time) == month(timenow)
and dayofmonth(time) == dayofmonth(timenow)
if array.size(lowClose) != 0
var float clo = 0.0
float revFin = switch tra
"Custom" => rev
"Auto" => clo / 150
float treFin = switch tra
"Custom" => tre
"Auto" => clo / 75
var int [] trCount = array.new_int(initial_value = 0)
var color [] col = array.new_color ()
var string [] dNp = array.new_string()
if array.size(trCandle) > 500
for i = 0 to array.size(trCandle) - 500
array.shift(trCandle)
array.shift(trCount)
array.shift(col)
array.shift(dNp)
if na(array.size(lowClose)[1])
array.push(trCandle, array.get(lowHigh, 0))
array.push(col, color(na))
array.push(trCount, 0)
array.push(dNp, "Start")
clo := close
varip dayCount = array.new_float ()
if array.size(trCandle) > 0
string dStri = "\n" +
str.tostring(year, "###") + "/" +
str.tostring(month, "###") + "/" +
str.tostring(dayofmonth, "###")
for i = 0 to array.size(lowClose) - 1
if array.get(trCount, array.size(trCount) - 1) == 0
if array.size(trCandle) == 1
if array.get(lowHigh, i) > array.get(trCandle, array.size(trCandle) - 1) + treFin
array.push(trCandle, array.get(trCandle, array.size(trCandle) - 1) + treFin)
array.push(col, color(na))
array.push(trCount, 0)
array.push(dNp, "+ " + str.tostring(treFin, "###.##") + dStri)
if cond
array.push(dayCount, timFin)
if array.get(lowLow, i) < array.get(trCandle, array.size(trCandle) - 1) - revFin
array.push(trCandle, array.get(trCandle, array.size(trCandle) - 1) - revFin)
array.push(trCount, 1)
array.push(col, color(na))
array.push(dNp, "- " + str.tostring(revFin, "###.##") + dStri)
if cond
array.push(dayCount, timFin)
else if array.size(trCandle) > 1
if array.get(lowHigh, i) >= array.get(trCandle, array.size(trCandle) - 1) + treFin
array.push(trCandle, array.get(trCandle, array.size(trCandle) - 1) + treFin)
array.push(col, color.new(color.lime, 50))
array.push(trCount, 0)
array.push(dNp, "+ " + str.tostring(treFin, "###.##") + dStri)
if cond
array.push(dayCount, timFin)
if array.get(lowLow, i) < array.get(trCandle, array.size(trCandle) - 1) - revFin
array.push(trCandle, array.get(trCandle, array.size(trCandle) - 1) - revFin)
array.push(col, color.new(color.red, 50))
array.push(trCount, 1)
array.push(dNp, "- " + str.tostring(revFin, "###.##") + dStri)
if cond
array.push(dayCount, timFin)
if array.get(trCount, array.size(trCount) - 1) == 1
if array.get(lowLow, i) <= array.get(trCandle, array.size(trCandle) - 1) - treFin
array.push(trCandle, array.get(trCandle, array.size(trCandle) - 1) - treFin)
array.push(col, color.new(color.red, 50))
array.push(trCount, 1)
array.push(dNp, "- " + str.tostring(treFin, "###.##") + dStri)
if cond
array.push(dayCount, timFin)
if array.get(lowHigh, i) > array.get(trCandle, array.size(trCandle) - 1) + revFin
array.push(trCandle, array.get(trCandle, array.size(trCandle) - 1) + revFin)
array.push(col, color.new(color.lime, 50))
array.push(trCount, 0)
array.push(dNp, "+ " + str.tostring(revFin, "###.##") + dStri)
if cond
array.push(dayCount, timFin)
if barstate.islast and array.size(trCandle) > 1
var line [] dayCon = array.new_line ()
color [] colCopy = array.new_color ()
float [] trCandleCopy = array.new_float ()
int [] trCountCopy = array.new_int ()
string [] dNpCopy = array.new_string()
for i = array.size(trCandle) - 1 to 0
array.push(colCopy, array.get(col, i))
array.push(trCandleCopy, array.get(trCandle, i))
array.push(trCountCopy, array.get(trCount, i))
array.push(dNpCopy, array.get(dNp, i))
if array.size(boxTr) > 0
for i = 0 to array.size(boxTr) - 1
box.delete(array.shift(boxTr))
var string [] finReq1 = array.new_string()
array.reverse(finReq1)
string txtSz = switch sz
"Auto" => size.auto
"Tiny" => size.tiny
"Small" => size.small
"Normal" => size.normal
"Large" => size.large
"Huge" => size.huge
for i = 1 to math.min(array.size(trCandleCopy) - 1, 500)
array.push(finReq1, str.substring(array.get(dNpCopy, i - 1), str.pos(array.get(dNpCopy, i - 1), "/") - 4))
array.push(boxTr, box.new(bar_index[i + 1],
array.get(trCandleCopy, i - 1) > array.get(trCandleCopy, i) ? array.get(trCandleCopy, i - 1) : array.get(trCandleCopy, i),
bar_index[i],
array.get(trCandleCopy, i - 1) > array.get(trCandleCopy, i) ? array.get(trCandleCopy, i) : array.get(trCandleCopy, i - 1),
bgcolor = array.get(colCopy, i - 1),
border_color = color.white,
border_width = 1,
xloc = xloc.bar_index,
text = array.get(dNpCopy, i - 1),
text_color = color.white,
text_size = txtSz
))
var float [] cong = array.new_float()
if array.size(boxTr) > 5
for n = 5 to array.size(boxTr) - 1
if math.avg(box.get_top(array.get(boxTr, n)), box.get_bottom(array.get(boxTr, n))) ==
math.avg(box.get_top(array.get(boxTr, n - 5)), box.get_bottom(array.get(boxTr, n - 5)))
and array.includes(cong, math.avg(box.get_top(array.get(boxTr, n)), box.get_bottom(array.get(boxTr, n)))) == false
array.push(cong, math.avg(box.get_top(array.get(boxTr, n)), box.get_bottom(array.get(boxTr, n))))
if ranShow == true
and array.size(finReq1) > 1
var linefill [] dayFill = array.new_linefill()
for n = 1 to array.size(finReq1) - 1
if array.get(finReq1, n - 1) != array.get(finReq1, n)
array.push(dayCon, line.new(box.get_left(array.get(boxTr, n)) + 1,
close[n],
box.get_left(array.get(boxTr, n)) + 1,
close[n] + syminfo.mintick,
extend = extend.both,
xloc = xloc.bar_index,
color = color.new(color.yellow, 50)
))
if array.size(dayCon) > 1
for x = 1 to array.size(dayCon) - 1
array.push(dayFill, linefill.new(array.get(dayCon, x), array.get(dayCon, x - 1), color.new(color.yellow, 90)))
else
z = line.new(box.get_left(array.get(boxTr, array.size(boxTr) - 1)),
close,
box.get_left(array.get(boxTr, array.size(boxTr) - 1)),
close + syminfo.mintick,
color = color.new(color.yellow, 90)
)
z1 = line.new(bar_index,
close,
bar_index,
close + syminfo.mintick,
color = color.new(color.yellow, 90)
)
linefill.new(z, z1, color.new(color.yellow, 90))
var line [] x = array.new_line (2)
var linefill [] xf = array.new_linefill(2)
var label [] xl = array.new_label (1)
if array.size(finReq1) > 0
indexStop = 0
for i = 1 to array.size(finReq1) - 1
if array.get(finReq1, i - 1 ) ==
str.tostring(year(timenow), "###") + "/" +
str.tostring(month(timenow), "###") + "/" +
str.tostring(dayofmonth(timenow), "###")
and array.get(finReq1, i) != array.get(finReq1, i - 1)
indexStop := i + 1
break
if indexStop != 0
array.set(x, 0, line.new(bar_index - indexStop,
close,
bar_index - indexStop,
close + syminfo.mintick, color = color.white, extend = extend.both, xloc = xloc.bar_index
))
array.set(x, 1, line.new(bar_index + 1, close, bar_index + 1, close + syminfo.mintick, color = color.white,
extend = extend.both,
xloc = xloc.bar_index
))
array.set(xf, 0, linefill.new(array.get(x, 0), array.get(x, 1), color.new(color.white, 95)))
array.set(xl, 0, label.new(math.round(math.avg(line.get_x1(array.get(x, 0)),
line.get_x1(array.get(x, 1)))),
close,
text = "Recent Price Action",
xloc = xloc.bar_index,
color = na,
textcolor = color.white,
size = size.huge,
yloc = yloc.abovebar
))
if array.size(dayCon) > 0
array.set(xf, 1, linefill.new(array.get(dayCon, 0), array.get(x, 0), color.new(color.yellow, 90)))
var box [] finBox = array.new_box(0)
var line [] levels = array.new_line()
var label [] levelLabels = array.new_label()
var linefill [] levelsFill = array.new_linefill()
bool cX = array.get(trCountCopy, 0) == 0 and close >= box.get_top(array.get(boxTr, 0))
bool cY = array.get(trCountCopy, 0) == 0 and close < box.get_top(array.get(boxTr, 0))
bool cZ = array.get(trCountCopy, 0) == 1 and close >= box.get_bottom(array.get(boxTr, 0))
if array.size(finBox) == 0
array.push(finBox, box.new(move == false ? bar_index - 1 : bar_index + 4,
cX ? close :
cY ? box.get_top( array.get(boxTr, 0)) :
cZ ? close :
box.get_bottom ( array.get(boxTr, 0)) ,
move == false ? bar_index : bar_index + 5,
cX ? box.get_top( array.get(boxTr, 0)) :
cY ? close :
cZ ? box.get_bottom(array.get(boxTr, 0)) :
close,
border_color = color.white,
text_color = color.white,
bgcolor =
cX ? color.new(color.lime, 50) :
cY ? color.new(color.red, 50) :
cZ ? color.new(color.lime, 50) :
color.new(color.red, 50) ,
text =
cX ? "+ " + str.tostring(close - box.get_top(array.get(boxTr, 0)), format.mintick) :
cY ? str.tostring(close - box.get_top(array.get(boxTr, 0)), format.mintick) :
cZ ? "+ " + str.tostring(close - box.get_bottom(array.get(boxTr, 0)), format.mintick) :
str.tostring(close - box.get_bottom(array.get(boxTr, 0)), format.mintick) ,
xloc = xloc.bar_index
))
else
box.set_left(array.get(finBox, 0) , box.get_right(array.get(finBox , 0)) )
box.set_right(array.get(finBox, 0), box.get_right(array.get(finBox , 0)) + 1)
box.set_top(array.get(finBox, 0),
cX ? close :
cY ? box.get_top( array.get(boxTr, 0)) :
cZ ? close :
box.get_bottom ( array.get(boxTr, 0))
)
box.set_bottom(array.get(finBox, 0),
cX ? box.get_top( array.get(boxTr, 0)) :
cY ? close :
cZ ? box.get_bottom(array.get(boxTr, 0)) :
close
)
box.set_bgcolor(array.get(finBox, 0),
cX ? color.new(color.lime, 50) :
cY ? color.new(color.red, 50) :
cZ ? color.new(color.lime, 50) :
color.new(color.red, 50)
)
box.set_text(array.get(finBox, 0),
cX ? "+ " + str.tostring(close - box.get_top(array.get(boxTr, 0 )), format.mintick) :
cY ? str.tostring(close - box.get_top(array.get(boxTr, 0 )), format.mintick) :
cZ ? "+ " + str.tostring(close - box.get_bottom(array.get(boxTr, 0)), format.mintick) :
str.tostring(close - box.get_bottom(array.get(boxTr, 0)), format.mintick)
)
if array.size(cong) > 0 and treShow > 0
str = ""
for n = 0 to math.min(array.size(cong) - 2, treShow - 1)
str := array.get(cong, n) >= array.get(cong, n + 1) ?
str + str.tostring(array.get(cong, n), format.mintick) + " △\n"
: str + str.tostring(array.get(cong, n), format.mintick) + " ▼\n"
if n == math.min(array.size(cong) - 2, treShow - 1)
str := str + str.tostring(array.get(cong, n + 1), format.mintick)
+ "\n"
var table upRight = table.new(position.top_right, 10, 10, frame_color = color.white, border_color = color.white, frame_width = 1, border_width = 1)
table.cell(upRight, 0, 0, text = "Congestion Areas \n(Reversed Order of Occurrence)", text_color = #00ffff, bgcolor = color.new(#000000, 75))
table.cell(upRight, 0, 1, text = str, text_color = color.red, bgcolor = color.new(#000000, 75))
if tra == "Custom" and warn1 == true
if rev < array.get(lowATR, array.size(lowATR) - 1) * 1.9 or tre < array.get(lowATR, array.size(lowATR) - 1) * 1.9
table.cell(upRight, 1, 1, bgcolor = color.new(#000000, 75), text_color = color.red, text_size = size.small, text = "This Chart Type Is Using 1 Minute OHLC Data; \nNo Tick Data Is Used. \nIf You’re Seeing This Message: \nYour Configurations for a Trend Candle or Reversal Candle Are Likely Too Low. \nFor Instance, if You Set Trend Candles to $1 Then Trend Candles Will \nForm Subsequent a $1 Price Move. This Is Sufficient for Lower Priced Assets; \nHowever, if You Were Trading, for Instance, Bitcoin - \nA $1 Price Move Can Happen Numerous Times in One Minute. \nThis Script Can’t Plot Bars and Record Data Until a 1-Minute \nBar Closes and a New 1-Minute Bar Opens. \nTry Adjusting the Trend Candle and Reversal Candle Settings to Price Level \nThat’s Unlikely to Be Exceeded Numerous Times per Minute. \nThis Message Will Dissapear if \n You Adjust the Price Levels to\n" + str.tostring(array.get(lowATR, array.size(lowATR) - 1) * 2 , format.mintick) + " or Greater")
table.cell(upRight, 1, 0, bgcolor = color.new(#000000, 75), text_color = color.red, text_size = size.normal, text = "Warning")
var table stats = table.new(position.bottom_right, 10, 10, frame_color = color.white, border_color = color.white, frame_width = 1, border_width = 1)
table.cell(stats, 0, 0, "Range US🛈", bgcolor = color.new(#ffffff, 75), text_color = color.white, tooltip = "A Range US Chart Operates Irrespective of Time and Volume - Simply - Bars Move After a User-Defined Price Move Is Achieved/Exceeded in either Direction. A Range US Chart Produces: \n1. “Trend Candles” \n2. “Reversal Candles” \nA Reversal Candle Always Moves Against the Most Immediate Bar; A Trend Candle Always Moves in Favor of the Most Immediate Bar. The User Defines the Dollar Amount Price Must Travel Up/Down for a Trend Candle to Fulfill, and for a Reversal Candle to Fulfill. Note, if a “Down Reversal” Candle (Red) Is Produced, It’s *Impossible* For the Next Candle to Also Be a Down Reversal Candle - For the Downside Move to Continue the Criteria for a Down Trend Candle Must Be Fulfilled. Similarly, if an “Up Reversal” Candle (Green) Is Produced, It’s Impossible for the Next Candle to Also Be an Up Reversal Candle - For the Upside Move to Continue, the Criteria for an Uptrend Trend Candle Must Be Fulfilled. Consequently, Range US Bars Frequently Trade at the Same Level for Extended Periods. This Is Intentional, as This Chart Type Is Theorized to “Filter Noise” - Whether Range US Charts Fulfill This Theory Is to Your Discretion. Lastly, if a Green (Up) Trend Candle Is Produced, the Next Candle Cannot Be up a Reversal Up Candle - Only a Trend Up Candle or Reversal Down Candle Can Produce - Vice Versa for a Trend Down Candle (The Subsequent Candle Cannot Be a Reversal Down Candle). In This Sense, an Uptrend Continues on Successive Trend Up Candles; A Down Trend Continues on Successive Trend Down Candles.")
table.cell(stats, 0, 1, "🛈", bgcolor = color.new(#ffffff, 75), text_color = color.lime, tooltip = "The Dollar Amount Prices Must Increase for a Green Trend Candle to Form - The Precise Price Level Is Included in Parenthesis. Note: If the Current Range Us Bar Is a Trend Down Bar or Down Reverse Bar, an Up Reverse Bar Must First Produce.")
table.cell(stats, 0, 2, "🛈", bgcolor = color.new(#ffffff, 75), text_color = color.lime, tooltip = "The Dollar Amount Prices Must Decrease for a Red Trend Candle to Form - The Precise Price Level Is Included in Parenthesis. Note: If the Current Range Us Bar Is a Trend Up Bar or Up Reverse Bar, a Down Reverse Bar Must First Produce.")
table.cell(stats, 0, 3, "🛈", bgcolor = color.new(#ffffff, 75), text_color = color.lime, tooltip = array.get(trCountCopy, 0) == 0 ? "The Dollar Amount Prices Must Decrease for a Down Reverse Candle to Form - The Precise Price Level Is Included in Parenthesis." : "The Dollar Amount Prices Must Increase for an Up Reverse Candle to Form - The Precise Price Level Is Included in Parenthesis. ")
table.cell(stats, 2, 1, "Trending After $" + str.tostring(treFin, format.mintick) + " Price Move", text_color = color.lime, bgcolor = color.new(#000000, 75))
table.cell(stats, 2, 2, "Reversing After $" + str.tostring(revFin, format.mintick) + " Price Move", text_color = color.lime, bgcolor = color.new(#131722, 75))
table.cell(stats, 1, 1, "$ for Trend Up: " + str.tostring(
(box.get_top(array.get(boxTr, 0)) + treFin) - close, format.mintick) + " Price Move ($"
+ str.tostring((box.get_top(array.get(boxTr, 0)) + treFin), format.mintick) + ")" ,
text_color = color.lime,
bgcolor = color.new(#2a2e39, 75)
)
table.cell(stats, 1, 2, "$ for Trend Down: " + str.tostring(
(box.get_bottom(array.get(boxTr, 0)) - treFin) - close, format.mintick) + " Price Move ($"
+ str.tostring((box.get_bottom(array.get(boxTr, 0)) - treFin), format.mintick) + ")" ,
text_color = color.lime,
bgcolor = color.new(#434651, 75)
)
if array.get(trCountCopy, 0) == 0
table.cell(stats, 1, 3, "$ for Reverse Down: " + str.tostring(
(box.get_top(array.get(boxTr, 0)) - revFin) - close, format.mintick) + " Price Move ($"
+ str.tostring((box.get_top(array.get(boxTr, 0)) - revFin), format.mintick) + ")" ,
text_color = color.lime,
bgcolor = color.new(#5d606b, 75)
)
if levShow == true
array.push(levels, line.new( bar_index + 2,
box.get_top(array.get(boxTr, 0)) - revFin,
bar_index + 8,
box.get_top(array.get(boxTr, 0)) - revFin,
color = color.orange
))
array.push(levels, line.new( bar_index + 2,
math.avg(box.get_top(array.get(boxTr, 0)) - revFin, box.get_bottom(array.get(boxTr, 0)) - treFin),
bar_index + 8,
math.avg(box.get_top(array.get(boxTr, 0)) - revFin, box.get_bottom(array.get(boxTr, 0)) - treFin),
color = na
))
array.push(levelLabels, label.new(bar_index + 8, box.get_top(array.get(boxTr, 0)) - revFin,
"Reverse Down", textcolor = color.orange, color = color.new(color.white, 100),
size = size.small, style = label.style_label_left ))
else
table.cell(stats, 1, 3, "$ for Reverse Up: " + str.tostring(
(box.get_bottom(array.get(boxTr, 0)) + revFin) - close, format.mintick) + " Price Move ($"
+ str.tostring((box.get_bottom(array.get(boxTr, 0)) + revFin), format.mintick) + ")" ,
text_color = color.lime,
bgcolor = color.new(#5d606b, 75) )
if levShow == true
array.push(levels, line.new( bar_index + 2,
box.get_bottom(array.get(boxTr, 0)) + revFin,
bar_index + 8,
box.get_bottom(array.get(boxTr, 0)) + revFin,
color = color.blue
))
array.push(levels, line.new( bar_index + 2,
math.avg(box.get_bottom(array.get(boxTr, 0)) + revFin, box.get_bottom(array.get(boxTr, 0)) - treFin),
bar_index + 8,
math.avg(box.get_bottom(array.get(boxTr, 0)) + revFin, box.get_bottom(array.get(boxTr, 0)) - treFin),
color = na
))
array.push(levelLabels, label.new(bar_index + 8, box.get_bottom(array.get(boxTr, 0)) + revFin,
"Reverse Up", textcolor = color.blue, color = color.new(color.white, 100),
style = label.style_label_left,
size = size.small))
if array.size(cong) > 0
table.cell(stats, 2, 3, "Most Recent Congestion Area: $" + str.tostring(array.get(cong, 0), format.mintick),
text_color = color.lime,
bgcolor = color.new(#5d606b, 75))
table.merge_cells(stats, 0, 0, 2, 0)
if levShow == true
array.push(levels, line.new( bar_index + 2,
box.get_top(array.get(boxTr, 0)) + treFin,
bar_index + 8,
box.get_top(array.get(boxTr, 0)) + treFin,
color = color.lime
))
array.push(levelLabels, label.new(bar_index + 8, box.get_top(array.get(boxTr, 0)) + treFin,
"Trend Up", textcolor = color.lime, color = color.new(color.white, 100),
style = label.style_label_left,
size = size.small))
array.push(levels, line.new( bar_index + 2,
box.get_bottom(array.get(boxTr, 0)) - treFin,
bar_index + 8,
box.get_bottom(array.get(boxTr, 0)) - treFin,
color = color.red
))
array.push(levelLabels, label.new(bar_index + 8, box.get_bottom(array.get(boxTr, 0)) - treFin,
"Trend Down", textcolor = color.red, color = color.new(color.white, 100),
style = label.style_label_left, size = size.small))
array.push(levels, line.new( bar_index + 2,
math.avg(line.get_y1(array.get(levels, 0)), line.get_y1(array.get(levels, 2))),
bar_index + 8,
math.avg(line.get_y1(array.get(levels, 0)), line.get_y1(array.get(levels, 2))),
color = na
))
if array.size(levels) > 5
for i = 0 to 4
line.delete(array.shift(levels))
if array.size(levels) == 5
array.push(levelsFill, linefill.new(array.get(levels, 0), array.get(levels, 2), color.new(color.lime, 90)))
array.push(levelsFill, linefill.new(array.get(levels, 0), array.get(levels, 4), color.new(array.get(trCount, 0) == 0 ? color.orange : color.blue, 90)))
array.push(levelsFill, linefill.new(array.get(levels, 0), array.get(levels, 3), color.new(array.get(trCount, 0) == 0 ? color.orange : color.blue, 90)))
array.push(levelsFill, linefill.new(array.get(levels, 1), array.get(levels, 3), color.new(color.red, 90)))
if array.size(levelsFill) > 4
for i = 0 to 3
linefill.delete(array.shift(levelsFill))
if array.size(levelLabels) > 3
for i = 0 to 2
label.delete(array.shift(levelLabels))
// _______________________________________________________
//
// Volume Aggregation Bars
// _______________________________________________________
if show == "Volume Aggregation" and loadFast
var box finBox = na
var float [] cumVol = array.new_float()
var float [] volC = array.new_float()
var string [] date = array.new_string()
var line [] dayCon = array.new_line()
var float [] volMed = array.new_float()
array.push(volMed, volume)
float volIn = tra1 == "Auto" ? array.percentile_linear_interpolation(volMed, 90) : volInt
string txtSz = switch sz1
"Auto" => size.auto
"Tiny" => size.tiny
"Small" => size.small
"Normal" => size.normal
"Large" => size.large
"Huge" => size.huge
array.push(cumVol, array.size(cumVol) == 0 ? volume : array.get(cumVol, array.size(cumVol) - 1) + volume)
if array.size(cumVol) > 0
if array.get(cumVol, array.size(cumVol) - 1) > volIn
var float calc = 0.0
calc := array.get(cumVol, array.size(cumVol) - 1) - volIn
array.clear(cumVol)
array.push(cumVol, calc)
array.push(volC, close)
array.push(date,
str.tostring(year) + "/"
+ str.tostring(month) + "/"
+ str.tostring(dayofmonth) + "\n$"
+ str.tostring(close, format.mintick))
if array.size(volC) > 0
if array.size(volC) > 502
array.shift(volC)
array.shift(date)
array.shift(volMed)
if barstate.islast
var string [] finReq1 = array.new_string()
var float [] max = array.new_float()
var box [] volBox = array.new_box()
float [] volCopy = array.new_float()
string [] dateCopy = array.new_string()
for i = array.size(volC) - 1 to 0
array.push(volCopy, array.get(volC, i))
array.push(dateCopy, array.get(date, i))
if array.size(volBox) > 0
for i = 0 to array.size(volBox) - 1
box.delete(array.shift(volBox))
if array.size(finReq1) > 0
array.clear(finReq1)
if array.size(max) > 0
array.clear(max)
for i = 0 to math.min(array.size(volC) - 2, 500)
array.push(max, i == 0 ? 0 : array.get(volCopy, i) / array.get(volCopy, i + 1) - 1)
array.push(finReq1, str.substring(array.get(dateCopy, i),0, str.pos(array.get(dateCopy, i), "\n")))
array.push(volBox, box.new(bar_index[i + 1],
array.get(volCopy, i) > array.get(volCopy, i + 1) ? array.get(volCopy, i) : array.get(volCopy, i + 1),
bar_index[i],
array.get(volCopy, i) > array.get(volCopy, i + 1) ? array.get(volCopy, i + 1) : array.get(volCopy, i),
bgcolor = array.get(volCopy, i) > array.get(volCopy, i + 1) ?
color.new(color.green, 50) :
color.new(color.red, 50) ,
border_color = color.white ,
text = array.get(dateCopy, i) + "\nMoves On \n" +
str.tostring(volIn, format.volume) + " Volume" ,
text_color = color.white ,
text_size = txtSz
))
box.delete(finBox)
finBox := box.new(bar_index, array.get(volCopy, 0) > array.get(volCopy, 1) ? array.get(volCopy, 0) : close,
bar_index + 1,
array.get(volCopy, 0) > array.get(volCopy, 1) ? close : array.get(volCopy, 0),
bgcolor = close > array.get(volCopy, 0) ? color.new(color.green, 50) : color.new(color.red, 50),
border_color = color.white,
text = str.tostring(year, "###") + "/" + str.tostring(month, "###") + "/" + str.tostring(dayofmonth, "###") + "\n" +
str.tostring(array.get(cumVol, array.size(cumVol) - 1), format.volume) + " Volume",
text_color = color.white
)
if vShow == true
and array.size(finReq1) > 1
var linefill [] dayFill = array.new_linefill()
for n = 1 to array.size(finReq1) - 1
if array.get(finReq1, n - 1) != array.get(finReq1, n)
array.push(dayCon, line.new(box.get_left(array.get(volBox, n)) + 1,
close[n],
box.get_left(array.get(volBox, n)) + 1,
close[n] + syminfo.mintick,
extend = extend.both,
xloc = xloc.bar_index,
color = color.new(color.yellow, 50)
))
if array.size(dayCon) > 1
for x = 1 to array.size(dayCon) - 1
array.push(dayFill, linefill.new(array.get(dayCon, x), array.get(dayCon, x - 1), color.new(color.yellow, 90)))
var table stats = table.new(position.bottom_right, 10, 10, frame_color = color.white, border_color = color.white, frame_width = 1, border_width = 1)
table.cell(stats, 0, 0, text = "Volume Aggregation🛈", text_color = color.red, text_size = size.normal, bgcolor = color.new(#000000, 50)
, tooltip = "Volume Aggregation Bars Aren’t Bound to a Time-Axis; The Bars Form After a User-Defined, Cumulative Amount of Volume Is Achieved or Exceeded. Consequently, Once the Cumulative Amount of Volume Is Achieved or Exceeded - A Bar Is Produced No Matter the Price. Underlying Theory: The Chat Type Is Conducive to Identifying Price Levels Where Traders Are “Trapped”." )
table.cell(stats, 0, 1, text = "Moving On " + str.tostring(volIn, format.volume) + " Volume", text_color = color.red, text_size = size.normal,
bgcolor = color.new(#000000, 50)
)
table.cell(stats, 0, 2, text = "Largest Upside Move: " + str.tostring(array.max(max)* 100, format.percent), text_color = color.red, text_size = size.normal,
bgcolor = color.new(#000000, 50)
)
table.cell(stats, 0, 3, text = "Largest Downside Move: " + str.tostring(array.min(max)* 100, format.percent), text_color = color.red, text_size = size.normal,
bgcolor = color.new(#000000, 50)
)
if showAl == true
maxStrCop = array.new_string(array.size(finReq1))
maxCop = array.copy(max)
if array.size(max) == array.size(finReq1) and array.size(max) > 1
array.sort(maxCop, order.descending)
for i = 0 to array.size(max) - 1
finCop = array.get(finReq1, array.indexof(max, array.get(maxCop, i)) > 0 ? array.indexof(max, array.get(maxCop, i)) : 0)
array.set(maxStrCop, i, finCop)
string str = ""
string str1 = ""
if array.size(maxCop) > 0
for i = 0 to math.min(array.size(maxCop) - 1, showUp - 1)
str := str + str.tostring(array.get(maxCop, i) * 100, format.percent) + "(" + array.get(maxStrCop, i) + ")\n"
if array.size(maxCop) > showDn
for i = array.size(maxCop) - 1 to array.size(maxCop) - showDn
str1 := str1 + str.tostring(array.get(maxCop, i) * 100, format.percent) + "(" + array.get(maxStrCop, i) + ")\n"
var table upRight = table.new(position.top_right, 10, 10, frame_color = color.white, border_color = color.white, frame_width = 1, border_width = 1 )
table.cell(upRight, 0, 0, "Largest Upside Moves", text_color = color.lime, bgcolor = color.new(color.green, 75))
table.cell(upRight, 0, 1, str, text_color = color.white, bgcolor = color.new(color.green, 75), text_halign = text.align_left)
table.cell(upRight, 0, 2, "Largest Downside Moves", text_color = color.red, bgcolor = color.new(color.red, 75))
table.cell(upRight, 0, 3, str1, text_color = color.white, bgcolor = color.new(color.red, 75), text_halign = text.align_left)
if tra1 == "Custom" and warn == true
if volInt < array.percentile_linear_interpolation(volMed, 90)
table.cell(upRight, 1, 0, bgcolor = color.new(#000000, 75), text_color = color.red, text_size = size.small, text = "This Data Set Uses the OHLC Data \nFrom the Timeframe on Your Chart; \nNo Tick Data Is Used. \nIf You’re Seeing This Message: \nYour Configurations for Required Volume Are Likely Too Low. \nWhile This Script Calculates Cumulative Volume \nand Remainders Are Carried Over When the Volume Limit Is Exceeded, \nSetting the Volume Requirement Too Low May Result in Missed \nPrice Moves - Should the Cumulative Volume Threshold Be \nExceeded Twice in One Bar. \nSetting the Volume Requirement to " + str.tostring(array.percentile_linear_interpolation(volMed, 90)) + " \nor Deselcting the 'Show Warning' Option \nin the Input Settings Will Hide This Message.")
table.merge_cells(upRight, 1, 0, 1, 3)
// _______________________________________________________
//
// Gaps
// _______________________________________________________
if show == "Gaps" and loadFast
bool gDn = high < low[1] and math.abs(low[1] / high - 1) > perG
bool gUp = low > high[1] and math.abs(low / high[1] - 1) > perG
var float [] gArray = array.new_float()
var box [] gBox = array.new_box()
var color [] col = array.new_color()
var string [] dNp = array.new_string()
var float [] sli = array.new_float()
var box [] boxGpD = array.new_box()
var box [] boxGpU = array.new_box()
var int [] boxCountD = array.new_int()
var int [] boxCountU = array.new_int()
var float [] minU = array.new_float()
var float [] maxD = array.new_float()
var int [] avgU = array.new_int()
var int [] avgD = array.new_int()
if array.size(gArray) > 500
for i = 0 to array.size(gArray) - 500
array.shift(gArray)
array.shift(col)
if gUp
array.push(gArray, array.size(gArray) == 0 ? low : array.get(gArray, array.size(gArray) - 1) + low - high[1])
array.push(sli, (low / high[1] - 1) * 100)
array.push(col, color.new(color.green, 50))
array.push(dNp, str.tostring(low - high[1], format.mintick) + "\n" +
str.tostring(year, "###") + "/" +
str.tostring(month, "###") + "/" +
str.tostring(dayofmonth, "###"))
array.push(boxGpU, box.new(math.round(time),low, math.round(time) + timFin,high[1],
text = str.tostring((close / low - 1) * 100, format.percent) + " To Fill", xloc = xloc.bar_time, bgcolor = color.new(color.lime, 50),
border_color = color.lime, text_color = color.white, text_halign = text.align_right))
array.push(boxCountU, 0), array.push(minU, 1e+13), array.push(avgU, bar_index)
if gDn
array.push(gArray, array.size(gArray) == 0 ? high : array.get(gArray, array.size(gArray) - 1) + high - low[1])
array.push(sli, (high / low[1] - 1) * 100)
array.push(col, color.new(color.red, 50))
array.push(dNp, str.tostring(high - low[1], format.mintick) + "\n" +
str.tostring(year, "###") + "/" +
str.tostring(month, "###") + "/" +
str.tostring(dayofmonth, "###"))
array.push(boxGpD, box.new(math.round(time), low[1], math.round(time) + timFin, high, xloc = xloc.bar_time,
text = str.tostring((close / high - 1) * 100, format.percent) + " To Fill", bgcolor = color.new(color.red, 50),
border_color = color.white, text_color = color.white, text_halign = text.align_right))
array.push(boxCountD, 0), array.push(avgD, bar_index), array.push(maxD, 0)
var float [] finAvgU = array.new_float()
if array.size(boxGpU) > 0
for n = 0 to array.size(boxGpU) - 1
if low < box.get_bottom(array.get(boxGpU, n))
if array.get(boxCountU, n) != 1 and array.get(boxCountU, n) != 3
box.set_text(array.get(boxGpU, n), gDn ? "New Gap" : "Filled")
box.set_bgcolor(array.get(boxGpU, n), color.new(color.lime, 90))
box.set_border_color(array.get(boxGpU, n), color.new(color.lime, 90))
array.push(finAvgU, bar_index - array.get(avgU, n))
if del == false
array.set(boxCountU, n, 1)
else
array.set(boxCountU, n, 3)
else if low < box.get_top(array.get(boxGpU, n)) and low > box.get_bottom(array.get(boxGpU, n)) and array.get(boxCountU, n) == 0
array.set(boxCountU, n, 2)
if array.get(boxCountU, n) != 1 and array.get(boxCountU, n) != 3
array.set(minU, n, math.min(low, array.get(minU, n)))
box.set_right(array.get(boxGpU, n), math.round(time + timFin))
box.set_text(array.get(boxGpU, n),array.get(boxCountU, n) == 0 ?
str.tostring((box.get_bottom(array.get(boxGpU, n)) / close - 1) * 100, format.percent) + " Decrease To Fill"
: str.tostring((box.get_bottom(array.get(boxGpU, n)) / close - 1) * 100, format.percent) + " To Fill \n(Partially Filled " +
str.tostring ((( array.get(minU, n)
- box.get_top ( array.get(boxGpU, n))) * 100)
/ (box.get_bottom( array.get(boxGpU, n))
- box.get_top ( array.get(boxGpU, n))),
format.percent) + ")" )
if del == true
for i = 0 to array.size(boxGpU) - 1
if i < array.size(boxGpU)
if array.get(boxCountU, i) == 3
box.delete(array.remove(boxGpU, i))
array.remove(minU, i)
array.remove(boxCountU, i)
else
if array.size(boxGpU) > 250
for i = 0 to array.size(boxGpU) - 1
if array.get(boxCountU, i) == 1
box.delete(array.remove(boxGpU, i))
array.remove(minU, i)
array.remove(boxCountU, i)
break
if old >= 0 and array.size(boxGpU) > 0
for x = 0 to array.size(boxGpU) - 1
if array.get(boxCountU, x) != 1 and array.get(boxCountU, x) != 3
if close >= box.get_top(array.get(boxGpU, x)) * (1 + old)
box.set_bgcolor(array.get(boxGpU, x), na)
box.set_border_color(array.get(boxGpU, x), na)
box.set_right(array.get(boxGpU, x), box.get_left(array.get(boxGpU, x)))
else
box.set_bgcolor(array.get(boxGpU, x), color.new(color.lime, 50))
box.set_border_color(array.get(boxGpU, x), color.new(color.lime, 50))
var float [] finAvgD = array.new_float()
if array.size(boxGpD) > 0
for n = 0 to array.size(boxGpD) - 1
if high > box.get_top(array.get(boxGpD, n))
if array.get(boxCountD, n) != 1 and array.get(boxCountD, n) != 3
array.push(finAvgD, bar_index - array.get(avgD, n))
box.set_text(array.get(boxGpD, n), gUp ? "New Gap" : "Filled")
box.set_bgcolor(array.get(boxGpD, n), color.new(color.red, 90))
box.set_border_color(array.get(boxGpD, n), color.new(color.red, 90))
if del == false
array.set(boxCountD,n, 1)
else
array.set(boxCountD,n, 3)
else if high < box.get_top(array.get(boxGpD, n)) and high > box.get_bottom(array.get(boxGpD, n)) and array.get(boxCountD, n) == 0
array.set(boxCountD, n, 2)
if array.get(boxCountD, n) != 1 and array.get(boxCountD, n) != 3
array.set(maxD, n, math.max(high, array.get(maxD, n)))
box.set_right(array.get(boxGpD, n), math.round(time) + timFin)
box.set_text(array.get(boxGpD, n), array.get(boxCountD, n) == 0 ?
str.tostring((box.get_top(array.get(boxGpD, n)) / close - 1) * 100, format.percent) + " Increase To Fill" :
str.tostring((box.get_top(array.get(boxGpD, n)) / close - 1) * 100, format.percent) + " To Fill \n(Partially Filled " +
str.tostring(((array.get(maxD, n)
- box.get_bottom(array.get(boxGpD, n))) * 100)
/ (box.get_top(array.get(boxGpD, n))
- box.get_bottom(array.get(boxGpD, n))),
format.percent) + ")")
if del == true
for i = 0 to array.size(boxGpD) - 1
if i < array.size(boxGpD)
if array.get(boxCountD, i) == 3
box.delete(array.remove(boxGpD, i))
array.remove(maxD, i)
array.remove(boxCountD, i)
else
if array.size(boxGpD) > 250
for i = 0 to array.size(boxGpD) - 1
if array.get(boxCountD, i) == 1
box.delete(array.remove(boxGpD, i))
array.remove(maxD, i)
array.remove(boxCountD, i)
break
if old >= 0 and array.size(boxGpD) > 0
for x = 0 to array.size(boxGpD) - 1
if array.get(boxCountD, x) != 1 and array.get(boxCountD, x) != 3
if close <= box.get_bottom(array.get(boxGpD, x)) * (1 - old)
box.set_bgcolor(array.get(boxGpD, x), na)
box.set_border_color(array.get(boxGpD, x), na)
box.set_right(array.get(boxGpD, x), box.get_left(array.get(boxGpD, x)))
else
box.set_bgcolor(array.get(boxGpD, x), color.new(color.red, 50))
box.set_border_color(array.get(boxGpD, x), color.new(color.red, 50))
if barstate.islast
var int [] hold = array.new_int(1, 0)
if array.get(hold, 0) == 0
array.reverse(gArray)
array.reverse(col)
array.reverse(dNp)
array.set(hold, 0, 1)
if array.size(gArray) > 0
if vis == true
for i = 0 to math.min(500, array.size(gArray) - 2)
array.push(gBox, box.new(bar_index[i + 1],
array.get(gArray, i) > array.get(gArray, i + 1) ? array.get(gArray, i) : array.get(gArray, i + 1) ,
bar_index[i],
array.get(gArray, i) > array.get(gArray, i + 1) ? array.get(gArray, i + 1) : array.get(gArray, i),
bgcolor = array.get(col, i),
border_color = color.white,
text = array.get(dNp, i),
text_color = color.white
))
array.sort(sli, order.ascending)
var float [] dn = array.new_float()
var float [] up = array.new_float()
for x = 1 to array.size(sli) - 1
if array.get(sli, 0) < 0
if array.get(sli, array.size(sli) - 1) > 0
if array.get(sli, x - 1) < 0 and array.get(sli, x) > 0
for n = 0 to x - 1
array.push(dn, array.get(sli, n))
for n = x to array.size(sli) - 1
array.push(up, array.get(sli, n))
break
else if array.get(sli, 0) > 0
if x != array.size(sli) - 1
array.push(up, array.get(sli, x - 1))
else
if array.size(sli) > 1
array.push(up, array.get(sli, x))
array.push(up, array.get(sli, x - 1))
if array.get(sli, array.size(sli) - 1) < 0
if x != array.size(sli) - 1
array.push(dn, array.get(sli, x - 1))
else
if array.size(sli) > 1
array.push(up, array.get(sli, x))
array.push(up, array.get(sli, x - 1))
var table stats = table.new(position.bottom_right, 10, 10, border_color = color.white, frame_color= color.white, border_width = 1, frame_width = 1)
table.cell(stats, 0, 0, "# of Gaps: " + str.tostring(array.size(sli)) , text_color = color.lime, bgcolor = color.new(#000000, 75))
table.cell(stats, 0, 1, "Gaps Up: " + str.tostring(array.size(up)) , text_color = color.lime, bgcolor = color.new(#000000, 75))
table.cell(stats, 0, 2, "Gaps Down: " + str.tostring(array.size(dn)) , text_color = color.lime, bgcolor = color.new(#000000, 75))
table.cell(stats, 1, 1, "Cumulative Increase: " + str.tostring(array.sum(up), format.percent) , text_color = color.lime, bgcolor = color.new(#000000, 75))
table.cell(stats, 2, 1, "Cumulative Decrease: " + str.tostring(array.sum(dn), format.percent) , text_color = color.lime, bgcolor = color.new(#000000, 75))
table.cell(stats, 1, 2, "Avg. Increase: " + str.tostring(array.avg(up), format.percent) , text_color = color.lime, bgcolor = color.new(#000000, 75))
table.cell(stats, 2, 2, "Avg. Decrease: " + str.tostring(array.avg(dn), format.percent) , text_color = color.lime, bgcolor = color.new(#000000, 75))
strUp = ""
strDn = ""
if array.size(boxGpU) > 0 and rec > 0
upCou = 0
for n = array.size(boxGpU) - 1 to 0
if upCou == rec
break
if array.get(boxCountU, n) != 1 and array.get(boxCountU, n) != 3
strUp := strUp + str.tostring(box.get_bottom(array.get(boxGpU, n)), format.mintick) + " - " + str.tostring(box.get_top(array.get(boxGpU, n)), format.mintick) +
" (Distance: " + str.tostring((close - box.get_bottom(array.get(boxGpU, n))) * -1, format.mintick) + ")" +
"\n"
upCou += 1
if array.size(boxGpD) > 0 and rec > 0
dnCou = 0
for n = array.size(boxGpD) - 1 to 0
if dnCou == rec
break
if array.get(boxCountD, n) != 1 and array.get(boxCountD, n) != 3
strDn := strDn + str.tostring(box.get_bottom(array.get(boxGpD, n)), format.mintick) + " - " + str.tostring(box.get_top(array.get(boxGpD, n)), format.mintick) +
" (Distance: +" + str.tostring((close - box.get_top(array.get(boxGpD, n))) * -1, format.mintick) + ")" +
"\n"
dnCou += 1
var table upRight = table.new(position.top_right, 10, 10, border_color = color.white, frame_color= color.white, border_width = 1, frame_width = 1)
if rec > 0
if strUp != ""
table.cell(upRight, 0, 0, "Unfilled Up Gaps", bgcolor = color.new(#000000, 75), text_color = color.lime)
table.cell(upRight, 0, 1, strUp, bgcolor = color.new(#000000, 75), text_color = color.lime)
if strDn != ""
table.cell(upRight, 0, 2, "Unfilled Down Gaps", bgcolor = color.new(#000000, 75), text_color = color.red)
table.cell(upRight, 0, 3, strDn, bgcolor = color.new(#000000, 75), text_color = color.red)
if del == false
table.cell(stats, 1, 0, "Avg. Bars to Fill Up Gap: " + str.tostring(math.round(array.avg(finAvgU)), "#"), text_color = color.lime, bgcolor = color.new(#000000, 75))
table.cell(stats, 2, 0, "Avg. Bars to Fill Down Gap: " + str.tostring(math.round(array.avg(finAvgD)), "#") , text_color = color.lime, bgcolor = color.new(#000000, 75))
else
table.merge_cells(stats, 0, 0, 2, 0)
else
runtime.error("No Gaps Detected - Change Assets or Plot a Different Dataset")
// _______________________________________________________
//
// Quartile Volume
// _______________________________________________________
if show == "Quartile Volume" and loadFast
var line [] xy = array.new_line (2)
var linefill[] xyfill = array.new_linefill(2)
var label [] miniLab = array.new_label ()
var float [] volSub = array.new_float ()
var int [] hold = array.new_int ()
var float [] rang = array.new_float ()
var float [] sVol = array.new_float ()
var float [] pNl = array.new_float ()
var int [] bar = array.new_int ()
var bool [] binTra = array.new_bool (1, false)
var float [] fin = array.new_float ()
var table tab = na
array.push(vol, volume)
if array.size(vol) > 250
array.shift(vol)
if array.size(vol) >= 2
colCond := color.from_gradient(
volume,
array.percentile_linear_interpolation(vol, 25),
array.percentile_linear_interpolation(vol, 75),
colE, colE1
)
var float Q1 = 0.0, var float Q2 = 0.0
var float Q3 = 0.0
var float p9 = 0.0, var float Q4 = 0.0
if array.size(vol) >= 5 and array.size(hold) == 0
if array.size(xz) > 0
array.clear(xz)
array.clear(volSub)
array.clear(rang)
if array.size(sVol) > 0
array.clear(sVol)
for n = 0 to 4 + loopCount
array.push(xz, close[n])
array.push(volSub, volume[n])
array.push(rang, high[n])
array.push(rang, low[n])
for n = 4 + loopCount to 0
if not na(tvsVol)
array.push(sVol, tvsVol[n])
if array.size(vol) > 25 and array.get(binTra, 0) == false
if array.get(vol, array.size(vol) - 1) >= array.percentile_linear_interpolation(vol, 90)
array.push(pNl, close)
array.push(bar, bar_index)
array.set(binTra, 0, true)
if array.get(binTra, 0) == true
if bar_index == array.get(bar, array.size(bar) - 1) + pCalculation
ret = switch log
true => math.log(close / array.get(pNl, array.size(pNl) - 1))
false => (close / array.get(pNl, array.size(pNl) - 1) - 1)
array.push(fin, ret * 100)
array.set(binTra, 0, false)
for i = array.size(vol) - 1 to array.size(vol) - 5 - loopCount
if array.get(vol, i) >= array.percentile_linear_interpolation(vol, 90)
array.push(hold, 1)
if i == array.size(vol) - 5 - loopCount
if array.sum(hold) == 5 + loopCount
if loopCount == 0
array.push(xy, line.new(bar_index - array.size(xz) + 1, X + stDev, bar_index, Y + stDev, color = #00ffff))
array.push(xy, line.new(bar_index - array.size(xz) + 1, X - stDev, bar_index, Y - stDev, color = #00ffff))
array.push(xy, line.new(bar_index - array.size(xz) + 1, X + stDev, bar_index - array.size(xz) + 1, X - stDev, color = #00ffff))
array.push(xy, line.new(bar_index, Y + stDev, bar_index, Y - stDev, color = #00ffff))
array.push(xyfill, linefill.new(array.get(xy, array.size(xy) - 1), array.get(xy, array.size(xy) - 2), color.new(#00ffff, 75)))
array.push(miniLab, label.new(bar_index[2], math.max(X + stDev, Y + stDev) + atr, text = "Volume: " + str.tostring(array.sum(volSub), format.volume)
+ "\nσ: " + str.tostring(array.stdev(xz, false), format.mintick)
+ "\nHigh: " + str.tostring(array.max (rang), format.mintick)
+ "\nLow: " + str.tostring(array.min (rang), format.mintick)
+"\nRange: " + str.tostring(array.range(rang), format.mintick),
style = label.style_label_center,
color = color.new(#00ffff, 50),
textcolor = color.white,
size = size.small
))
if array.sum(sVol) != 0
label.set_text(array.get(miniLab, array.size(miniLab) - 1), label.get_text(array.get(miniLab, array.size(miniLab) - 1)) +
"\nShort Volume: " + str.tostring(array.sum(sVol), format.volume))
loopCount += 1
else
line.set_xy1(array.get(xy, array.size(xy) - 4), bar_index - array.size(xz) + 1, X + stDev)
line.set_xy2(array.get(xy, array.size(xy) - 4), bar_index, Y + stDev)
line.set_xy1(array.get(xy, array.size(xy) - 3), bar_index - array.size(xz) + 1, X - stDev)
line.set_xy2(array.get(xy, array.size(xy) - 3), bar_index, Y - stDev)
line.set_xy1(array.get(xy, array.size(xy) - 2), bar_index - array.size(xz) + 1, X + stDev)
line.set_xy2(array.get(xy, array.size(xy) - 2), bar_index - array.size(xz) + 1, X - stDev)
line.set_xy1(array.get(xy, array.size(xy) - 1), bar_index, Y + stDev)
line.set_xy2(array.get(xy, array.size(xy) - 1), bar_index, Y - stDev)
label.set_xy(array.get(miniLab, array.size(miniLab) - 1), math.round(math.avg(bar_index - array.size(xz) + 1, bar_index)), math.max(X + stDev, Y + stDev) + atr)
label.set_text(array.get(miniLab, array.size(miniLab) - 1), "Volume: " + str.tostring(array.sum(volSub), format.volume)
+ "\nσ: " + str.tostring(array.stdev(xz, false), format.mintick)
+ "\nHigh: " + str.tostring(array.max(rang), format.mintick)
+ "\nLow: " + str.tostring(array.min(rang), format.mintick)
+"\nRange: " + str.tostring(array.max(rang) - array.min(rang), format.mintick)
)
if array.sum(sVol) != 0
label.set_text(array.get(miniLab, array.size(miniLab) - 1), label.get_text(array.get(miniLab, array.size(miniLab) - 1)) +
"\nShort Volume: " + str.tostring(array.sum(sVol), format.volume))
loopCount += 1
if array.size(hold) > 0
array.clear(hold)
if loopCount == loopCount[5]
loopCount := 0
if array.size(vol) > 1
Q1 := array.percentile_linear_interpolation(vol, 25)
Q2 := array.median(vol)
Q3 := array.percentile_linear_interpolation(vol, 75)
p9 := array.percentile_linear_interpolation(vol, 90)
Q4 := array.max(vol)
bool v1 = volume < Q1
bool v2 = volume >= Q1 and volume < Q2
bool v3 = volume >= Q2 and volume < Q3
bool v4 = volume >= Q3 and volume < p9
var label [] quarLab = array.new_label()
array.push(quarLab, label.new(bar_index, close >= open ? high : low,
v1 ? "1" :
v2 ? "2" :
v3 ? "3" :
v4 ? "p9" :
"4" ,
color = color.new(color.white, 100),
style = close >= open ? label.style_label_down : label.style_label_up,
textcolor =
v1 ? c1 :
v2 ? c2 :
v3 ? c3 :
v4 ? c4 :
c5
))
if la == false
if array.size(quarLab) > 15
label.delete(array.shift(quarLab))
if barstate.islastconfirmedhistory
array.sort(fin, order.ascending)
var float [] dn = array.new_float()
var float [] up = array.new_float()
if array.size(fin) > 0
if array.get(fin, 0) <= 0
for i = 1 to array.size(fin) - 1
if array.get(fin, i - 1) <= 0 and array.get(fin, i) > 0
for x = 0 to i - 1
array.push(dn, array.get(fin, x))
for x = i to array.size(fin) - 1
array.push(up, array.get(fin, x))
break
else if array.get(fin, 0) > 0
for i = 0 to array.size(fin) - 1
array.push(up, array.get(fin, i) )
else if array.get(fin, array.size(fin) - 1) <= 0
for i = 0 to array.size(fin) - 1
array.push(dn, array.get(fin, i) )
if array.size(dn) > 0
for n = 0 to array.size(dn) - 1
if n < array.size(dn) - 1
if array.get(dn, n) == 0
array.remove(dn, n)
var table stats = na
tab := table.new(position.top_right, 1, 1, border_color = color.white, frame_color = color.white, border_width = 1, frame_width = 1)
stats := table.new(position.bottom_right, 50, 50, border_width = 1, frame_width = 1, border_color = color.white, frame_color = color.white)
condQuar = showIns == false
table.cell(stats, 0, 0, text = "Volume Percentiles " , bgcolor = color.new(color.white, 50), text_color = #000000)
table.cell(stats, 0, 1, text = "First Quartile: " + str.tostring(array.percentile_linear_interpolation(vol, 25), format.volume), bgcolor = color.new(c1, 50), text_color = color.white)
table.cell(stats, 0, 2, text = "Second Quartile: " + str.tostring(array.median(vol), format.volume), bgcolor = color.new(c2, 50), text_color = color.white)
table.cell(stats, 0, 3, text = "Third Quartile: " + str.tostring(array.percentile_linear_interpolation(vol, 75), format.volume), bgcolor = color.new(c3, 50), text_color = color.white)
table.cell(stats, 0, 4, text = "90 Percentile : " + str.tostring(array.percentile_linear_interpolation(vol, 90), format.volume), bgcolor = color.new(c4, 50), text_color = color.white)
table.cell(stats, 0, 5, text = "Fourth Quartile : " + str.tostring(math.round(array.max(vol)), format.volume), bgcolor = color.new(c5, 50), text_color = color.white)
table.cell(stats, condQuar ? 0 : 1, condQuar ? 6 : 0, text = "Dispersion" , bgcolor = color.new(color.white, 50), text_color = #000000)
table.cell(stats, condQuar ? 0 : 1, condQuar ? 7 : 1, text = "Q2 - Q1: " + str.tostring(Q2 - Q1, format.volume), bgcolor = color.new(#5d606b, 50), text_color = color.white, text_halign = text.align_left)
table.cell(stats, condQuar ? 0 : 1, condQuar ? 8 : 2, text = "Q3 - Q2: " + str.tostring(Q3 - Q2, format.volume), bgcolor = color.new(#434651, 50), text_color = color.white, text_halign = text.align_left)
table.cell(stats, condQuar ? 0 : 1, condQuar ? 9 : 3, text = "Q4 - Q3: " + str.tostring(Q4 - Q3, format.volume), bgcolor = color.new(#2a2e39, 50), text_color = color.white, text_halign = text.align_left)
table.cell(stats, condQuar ? 0 : 1, condQuar ? 10 : 4, text = "Quartile Deviation: " + str.tostring((Q3 - Q1) / 2, format.volume), bgcolor = color.new(#131722, 50), text_color = color.white, text_halign = text.align_left)
table.cell(stats, condQuar ? 0 : 1, condQuar ? 11 : 5, text = "Interquartile Range: " + str.tostring(Q3 - Q1, format.volume), bgcolor = color.new(#000000, 50), text_color = color.white, text_halign = text.align_left)
table.cell(stats, condQuar ? 0 : 2, condQuar ? 12 : 0, text = "If Volume Exceeds 90th Percentile \n(Flat Returns Excluded)" , bgcolor = color.new(color.white, 50), text_color = #000000)
table.cell(stats, condQuar ? 0 : 2, condQuar ? 13 : 1, text = "Avg. " + str.tostring(pCalculation, "#") + " Bar PnL: " + str.tostring(array.avg(fin), format.percent) , bgcolor = color.new(#5d606b, 50), text_color = color.white, text_halign = text.align_left)
table.cell(stats, condQuar ? 0 : 2, condQuar ? 14 : 2, text = "Avg. " + str.tostring(pCalculation, "#") + " Bar Pos. Return: " + str.tostring(array.avg(up), format.percent) , bgcolor = color.new(#434651, 50), text_color = color.white, text_halign = text.align_left)
table.cell(stats, condQuar ? 0 : 2, condQuar ? 15 : 3, text = "Avg. " + str.tostring(pCalculation, "#") + " Bar Neg. Return: " + str.tostring(array.avg(dn), format.percent) , bgcolor = color.new(#2a2e39, 50), text_color = color.white, text_halign = text.align_left)
table.cell(stats, condQuar ? 0 : 2, condQuar ? 16 : 4, text = "# of Pos. Returns: " + str.tostring(array.size(up), "#") + " (" + str.tostring(array.size(up) / array.size(fin) * 100, format.percent) + ")", bgcolor = color.new(#131722, 50), text_color = color.white, text_halign = text.align_left)
table.cell(stats, condQuar ? 0 : 2, condQuar ? 17 : 5, text = "# of Neg. Returns: " + str.tostring(array.size(dn), "#") + " (" + str.tostring(array.size(dn) / array.size(fin) * 100, format.percent) + ")", bgcolor = color.new(#000000, 50), text_color = color.white, text_halign = text.align_left)
if showIns == true
if quar == false
var table midRight = table.new(position.middle_right, 10, 10, bgcolor = na)
table.cell(midRight, 0, 0, text = "▮ = Higher Volume" , text_color = color.lime)
table.cell(midRight, 0, 1, text = "▮ = Lower Volume " , text_color = color.red)
table.cell(tab, 0, 0, text = "In Chart Settings, Hide TradingView Plotted Candlesticks ↑", text_size = size.small, bgcolor = color.new(#f06292, 50), text_color = color.white)
if barstate.islast
var label [] y = array.new_label()
var line [] y1 = array.new_line()
color c =
volume < Q1 ? color.new(c1, 75) :
volume >= Q1 and volume < Q2 ? color.new(c2, 75) :
volume >= Q2 and volume < Q3 ? color.new(c3, 75) :
volume >= Q3 and volume < p9 ? color.new(c4, 75) :
color.new(c5, 75)
color cFin = switch quar
false => colCond
true => c
if array.size(y) == 0
array.push(y, label.new(bar_index + 2, close >= open ? high : low, color = color.new(cFin, 75),
text = "This Bar Has Higher Volume Than \n" + str.tostring(array.percentrank(vol, array.size(vol) - 1), format.percent)
+ "\n Of Intervals",
style = label.style_label_left,
textcolor = color.white ,
size = size.small ,
tooltip = str.tostring(100 - array.percentrank(vol, array.size(vol) - 1), format.percent)
+ " Of Intervals Had Greater Volume Than This Bar (:"
))
array.push(y1, line.new(bar_index, label.get_y(array.get(y, array.size(y) - 1)),
bar_index + 2,
label.get_y(array.get(y, array.size(y) - 1)),
style = line.style_dashed,
color = color.new(cFin, 75)
))
else
label.set_xy ( array.get(y, array.size(y) - 1), bar_index + 2, close >= open ? high : low)
label.set_color ( array.get(y, array.size(y) - 1), color.new(cFin, 75))
line.set_xy1 ( array.get(y1,array.size(y1) - 1), bar_index, label.get_y(array.get(y, array.size(y) - 1)))
line.set_xy2 ( array.get(y1,array.size(y1) - 1), bar_index + 2, label.get_y(array.get(y, array.size(y) - 1)))
line.set_color ( array.get(y1,array.size(y1) - 1), color.new(cFin, 75))
label.set_tooltip( array.get(y, array.size(y1) - 1), str.tostring(100 - array.percentrank(vol, array.size(vol) - 1), format.percent)
+ " Of Intervals Had Greater Volume Than This Bar (:")
label.set_text ( array.get(y, array.size(y) - 1), "This Bar Has Higher Volume Than \n" + str.tostring(array.percentrank(vol, array.size(vol) - 1), format.percent)
+ "\n Of Intervals")
var line [] sten = array.new_line()
var linefill [] stenfill = array.new_linefill()
if start()
and anch == true
and s >= array.get(tim, 0)
array.push(sten, line.new(math.round(s), close, math.round(s), close + syminfo.mintick, xloc = xloc.bar_time, color = color.white, width = 2, extend = extend.both))
array.push(sten, line.new(math.round(e), close, math.round(e), close + syminfo.mintick, xloc = xloc.bar_time, color = color.white, width = 2, extend = extend.both))
array.push(stenfill, linefill.new(array.get(sten, array.size(sten) - 1), array.get(sten, array.size(sten) - 2), color.new(color.white, 95)))
if array.size(sten) > 2
line.delete(array.shift(sten))
if array.size(stenfill) > 1
linefill.delete(array.get(stenfill, array.size(stenfill) - 1))
finCol() =>
if array.size(vol) > 1
q1 = array.percentile_linear_interpolation(vol, 25)
q2 = array.median(vol)
q3 = array.percentile_linear_interpolation(vol, 75)
p9 = array.percentile_linear_interpolation(vol, 90)
q4 = array.max(vol)
if volume >= 0 and volume < q1
c1
else if volume >= q1 and volume < q2
c2
else if volume >= q2 and volume < q3
c3
else if volume >= q3 and volume < p9
c4
else if volume >= p9 and volume <= q4
c5
VWAP() =>
var float y = na
var float y1 = na
var float y2 = na
if start()[1] == false
if start() == true
y := hlc3 * volume
y1 := volume
y2 := volume * math.pow(hlc3, 2)
if start()[1] == true
y := hlc3 * volume + y[1]
y1 := volume + y1[1]
y2 := volume * math.pow(hlc3, 2) + y2[1]
float middle = y / y1
float vaR = y2 / y1 - math.pow(middle, 2)
vaR := vaR < 0 ? 0 : vaR
float stDevX = math.sqrt(vaR)
float upper = middle + stDevX * 2
float lower = middle - stDevX * 2
[middle, upper, lower]
[m,u,l] = VWAP()
Z = plot(anch == true ? m : na, title = "Anchored VWAP", color = start() ? color.orange : na)
Z1 = plot(anch == true ? u : na, title = "Upper Band", color = start() ? color.lime : na)
Z2 = plot(anch == true ? l : na, title = "Lower Band", color = start() ? color.lime : na)
fill(Z1, Z2, color = anch == true and start() ? color.new(color.lime, 80) : na)
color colr = switch show
"Quartile Volume" => colCond
=> na
color colF = switch quar
false => colr
true => finCol()
plotcandle (
open,
high,
low,
close,
color = show == "Gaps" and close >= open ? color.lime : show == "Gaps" and close < open ? color.red : colF,
wickcolor = show == "Gaps" and close >= open ? color.lime : show == "Gaps" and close < open ? color.red : colF,
bordercolor = show == "Gaps" and close >= open ? color.lime : show == "Gaps" and close < open ? color.red : colF
)
Show all 1,637 lines