liquidation-ranges-volumeoi-dots-kioseff-trading.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("Volume Dots", overlay = true, max_lines_count = 500, max_labels_count = 500, max_boxes_count = 500)
//
import PineCoders/Time/4 as pct
import HeWhoMustNotBeNamed/BinaryInsertionSort/1 as HeWho
//
action2 = input.bool (defval = true, title = "Show Liquidation Ranges", group = "Show Liquidation Ranges" , inline = "0")
showValues = input.bool (defval = true, title = "Show VOL/OI Values in Grid", group = "Show Liquidation Ranges", inline = "0")
action = input.string(defval = "Find As Many Vol/OI Extremities As Possible", title = "Volume/OI Dots Should: ", options = ["Find As Many Vol/OI Extremities As Possible", "Show Extremities For The Data On My Screen", "Show The Highest Vol./OI Per Bar", "Off"], group = "Volume/OI Dots Main Settings"), stringBool = "Find As Many Vol/OI Extremities As Possible"
data = input.bool (defval = false, title = "Use OI Instead Of Volume For Dots?", group = "Use OI Instead")
agg = 100 - input.float (minval = 0.01, title = "Aggressiveness", maxval = 10, defval = 0.01, group = 'If You Selected "Find As Many Vol/OI Extremities As Possible"', tooltip = "Corresponds To The Required Percent Rank For A Value To Be Distinguished. Sclaed 0.01-9.99 For Simplicity; However, Uses Percent Rank (100 Subtracted By Number In This Box) - Works Only For 'Find As Many Vol/OI Extremities As Possible'")
nake = input.bool (defval = false, title = "Naked Levels Only?", group = "Naked Levels")
actint = input.int (defval = 20, title = 'If You Selected "Show Extremities For The Data On My Screen: How Many Levels Should Be Shown?', group = "Volume/OI Dots (Screen Only)", minval = 1, maxval = 500)
ti = input.bool (defval = false, title = "Use Fixed Range", inline = "1", group = "Volume/OI Dots Misc Settings")
ti2 = input.time (defval = timestamp("04 Apr 2022 00:00 +0300"), title = "Start", inline = "1", group = "Volume/OI Dots Misc Settings")
dt = input.int (defval = 15, title = "Levels In Table Shown", minval = 0, maxval = 99, group = "Volume/OI Dots Misc Settings" , inline = "Levels")
showl = input.int (defval = 10, title = "Lines Shown", minval = 0, maxval = 500, group = "Volume/OI Dots Misc Settings", inline = "Levels")
linebool = input.bool (defval = false, title = "Only Show Lines Within a % of Price", group = "Volume/OI Dots Misc Settings", inline = "line" )
linedist = input.float (defval = 3, title = "%", minval = 0, group = "Volume/OI Dots Misc Settings", inline = "line") / 100
srcol = input.bool (defval = false, title = "Color Lines As Support/Resistance", group = "Volume/OI Dots Misc Settings"), atr = ta.atr(14)
upcol = input.color (defval = color.lime, title = "Up Color Vol ", inline = "20", group = "Volume/OI Dots Misc Settings")
dncol = input.color (defval = color.red , title = "Down Color Vol ", inline = "20", group = "Volume/OI Dots Misc Settings")
upcoloi = input.color (defval = color.blue, title = "OI Up + Price Up ", inline = "21", group = "Volume/OI Dots Misc Settings")
dncoloi = input.color (defval = color.orange , title = "OI Down + Price Down", inline = "21", group = "Volume/OI Dots Misc Settings")
upcoloi2 = input.color (defval = color.yellow, title = "OI Up + Price Down ", inline = "21", group = "Volume/OI Dots Misc Settings")
dncoloi2 = input.color (defval = color.purple , title = "OI Down + Price Up ", inline = "21", group = "Volume/OI Dots Misc Settings")
sort = input.string(defval = "Descending", title = "Sort Table Data", options = ["Occurrence", "Descending"], group = "Volume/OI Dots Misc Settings", inline = "Misc")
siz = input.string(defval = "Normal", title = "Table Size", options = ["Auto", "Tiny", "Small", "Normal", "Large", "Huge"], inline = "Misc", group = "Volume/OI Dots Misc Settings")
move = input.bool (defval = true, title = "Show OI Delta Lines", group = "Liquidation Range")
showcir = input.bool (defval = true, title = "Show Violation Circles", group = "Liquidation Range")
box2Line = input.bool (defval = false, title = "Change Liquidation Boxes to Lines", group = "Liquidation Range")
minlevl = input.string(defval = "Auto", title = "Min Liquidation Level Shown", options = ["Auto", "10", "20", "30", "40", "50"], group = "Liquidation Range")
userDefinedTime = input.bool (defval = false, title = "Fixed Range", group = "Liquidation Range")
timtest = input.time (defval = timestamp("04 Apr 2023 00:00 +0300"), title = "Start Liquidation Range"),
timtest2 = input.time (defval = timestamp("20 Apr 2023 00:00 +0300"), title = "End Liquidation Range")
method equal (string id, value) => id == value
method notEqual (string id, value) => id != value
req() =>
cont = switch str.contains(syminfo.ticker, ".P")
true => syminfo.ticker + "_OI"
=> str.endswith(syminfo.ticker, "USDT") ? syminfo.ticker + ".P_OI" : syminfo.ticker + "T.P_OI"
switch syminfo.type
"crypto" => cont
=> string(na)
r3() =>
[R1, R2, R3, R4, R5] = switch syminfo.type
"crypto" => [ close-close[1], high, low, open, close ]
=> [float(na), float(na), float(na), float(na), float(na)]
// Thank you PineCoders
float chartTfInMinutes = timeframe.in_seconds() / 60.
int ONE_MIN = 1
int ONE_SEC = ONE_MIN / 60
int ONE_HOUR = ONE_MIN * 60
int ONE_DAY = ONE_HOUR * 24
int ONE_WEEK = ONE_DAY * 7
bool marketIs24Hours = syminfo.type == "crypto" or syminfo.type == "forex"
ltfint = switch
chartTfInMinutes <= ONE_MIN * 30 => "1"
chartTfInMinutes <= ONE_HOUR => "3"
chartTfInMinutes < ONE_HOUR * 2 => "5"
chartTfInMinutes < ONE_HOUR * 4 => "15"
chartTfInMinutes < ONE_HOUR * 6 => "30"
chartTfInMinutes < ONE_HOUR * 12 => marketIs24Hours ? "60" : "30"
chartTfInMinutes < ONE_DAY => marketIs24Hours ? "120" : "30"
chartTfInMinutes < ONE_WEEK => marketIs24Hours ? "720" : "120"
// Thank you PineCoders
[oic, oih, oil, oio, trueOic ] = request.security_lower_tf(req(), ltfint, r3() )
timeframeDiff = request.security(req(), timeframe.period, close-close[1] )
[vol, clo, clo1, hi, lo, clocalc, ltf, volSign] = request.security_lower_tf(syminfo.tickerid, ltfint,
[
volume, close, close[1], high, low, close - close[1], time, close >= open ? volume : volume * -1
])
comparison(id, value, string ) =>
switch string
">" => id > value
">=" => id >= value
"==" => id == value
"<=" => id <= value
"<" => id < value
"!=" => id != value
method floatGreatEqual (float id, value) => comparison(id, value, ">=")
method floatEqual (float id, value) => comparison(id, value, "==")
method floatLessEqual (float id, value) => comparison(id, value, "<=")
method floatNotEqual (float id, value) => comparison(id, value, "!=")
method intGreatEqual (int id, value) => comparison(id, value, ">=")
method intEqual (int id, value) => comparison(id, value, "==")
method intLessEqual (int id, value) => comparison(id, value, "<=")
method intNotEqual (int id, value) => comparison(id, value, "!=")
method HeWhoSort(float [] id, value, order) =>
HeWho.binary_insertion_sort(id, value, order)
method determine (bool id, value, value2) =>
switch id
true => value
=> value2
type timeValues
float [] Difference
float [] Close
int [] Time
type dotValues
float [] Volume
float [] Close
float [] Difference
float [] OI
float [] OI2
int [] Time
label [] Circle
line [] Zone
float [] Rank
float [] perBar
float [] volSignArr
int Start
type sortedMat
float volM
float oicM
int timM
float cloM
float clcM
float toiM
color colM
string valM
var timeMat = timeValues.new(array.new_float(), array.new_float(), array.new_int())
timeMat.Difference.unshift(timeframeDiff), timeMat.Close.unshift(close), timeMat.Time.unshift(time)
var dotMat = dotValues.new(
array.new_float(), array.new_float(),
array.new_float(), array.new_float(),
array.new_float(), array.new_int (),
array.new_label(), array.new_line (),
array.new_float(), array.new_float(),
array.new_float(), 0
)
obj = switch syminfo.type.equal("crypto")
true => oic
false => vol
if action.notEqual("Off")
conditionX = switch action
"Find As Many Vol/OI Extremities As Possible" => last_bar_index - bar_index <= (4.5e6)/(timeframe.in_seconds(timeframe.period)) and not ti or
time >= ti2 and ti and vol.size().intGreatEqual(1)
"Show Extremities For The Data On My Screen" => time >= chart.left_visible_bar_time and time <= chart.right_visible_bar_time
and not ti and vol.size().intGreatEqual(1) or time >= ti2 and ti and vol.size().intGreatEqual(1)
=> last_bar_index - bar_index <= 500
if conditionX
if obj.size().intGreatEqual(1)
if action.notEqual("Show The Highest Vol./OI Per Bar")
if nake and dotMat.Volume.size().intGreatEqual(1)
for i = 0 to dotMat.Volume.size() - 1
if not na(dotMat.Close.get(i))
if dotMat.Close.get(i).floatLessEqual(high)
if dotMat.Close.get(i).floatGreatEqual(low)
dotMat.Close.set(i, na)
for i = math.min(obj.size() - 1, clo.size() - 1) to 0 // In Honor of Spunky - Rest Comfortably Sweet Princess. You'll be Loved and Cherished Forever & Always <3
dotMat.Volume .unshift(vol.get(i)) , dotMat.Close .unshift(clo.get(i))
dotMat.Difference .unshift(clocalc.get(i)) , dotMat.OI .unshift(math.abs(oic.get(i)))
dotMat.Time .unshift(ltf.get(i)) , dotMat.OI2 .unshift(oic.get(i)),
dotMat.volSignArr.unshift(volSign.get(i))
else
for i = math.min(obj.size() - 1, clo.size() - 1) to 0
cond = switch data
false => vol.get(i).floatEqual(vol.max())
=> oic.get(i).floatEqual(math.max(oic.max(), math.abs(oic.min())))
if cond
col = switch data
false => color.new(math.sign(clocalc.get(i)).floatEqual(-1).determine(color.lime , color.red), 33)
=> color.new(math.sign(oic.get(i)).floatEqual(-1).determine (
math.sign(clocalc.get(i)) .floatEqual(-1).determine (
dncoloi, dncoloi2), math.sign(clocalc.get(i)).floatEqual (
-1).determine(upcoloi2, upcoloi)), 33)
OItxt = switch syminfo.type.equal("crypto")
true => "\nOI: " + str.tostring(oic.get(i), format.mintick)
=> ""
dotMat.Circle.unshift(
label.new(
time, clo.get(i), "⬤",
tooltip = "VOL: " + (math.sign(clocalc.get(i)).floatEqual(-1).determine("-" , "")) +
str.tostring(vol.get(i), format.volume) + OItxt,
xloc = xloc.bar_time,
color = #000000,
textcolor = col,
size = size.tiny,
style = label.style_text_outline
))
dotMat.Zone.unshift(
line.new(time, clo.get(i), time, clo.get(i),
color = col,
xloc = xloc.bar_time
))
dotMat.perBar.unshift(data.determine(vol.get(i) , oic.get(i)))
if vol.size().intEqual(0)
dotMat.Start := time
var grid = matrix.new<box>(5, 20)
if barstate.islast and action.notEqual("Off")
if action.notEqual("Show The Highest Vol./OI Per Bar")
if dotMat.Circle.size().intGreatEqual(1)
for i = 0 to dotMat.Circle.size() - 1
dotMat.Circle.shift().delete()
if dotMat.Zone.size() .intGreatEqual(1)
for i = 0 to dotMat.Zone.size() - 1
dotMat.Zone.shift().delete()
if ti
line.new( ti2, high, ti2, low,
xloc = xloc.bar_time , extend = extend.both,
color = chart.fg_color, width = 2
)
var count = 1, vcopy = dotMat.Volume.copy(), ocopy = dotMat.OI.copy(), var SM = matrix.new<sortedMat>(8, 0), var tan3 = array.new_float()
switch data
false => vcopy.sort(order.descending)
=> ocopy.sort(order.descending)
for i = 0 to 249
[bool1, bool2, index] = switch data
false => [dotMat.Volume.includes(vcopy.get(i)), action.equal(stringBool).determine(
vcopy.percentrank(i).floatGreatEqual(agg) , i.intLessEqual(actint - 2)), dotMat.Volume.indexof(vcopy.get(i))]
=> [dotMat.OI.includes(ocopy.get(i)) , action.equal(stringBool).determine(
ocopy.percentrank(i).floatGreatEqual(agg) , i.intLessEqual(actint - 2)), dotMat.OI.indexof(ocopy.get(i))]
if bool1
if bool2
if dotMat.Close.indexof(dotMat.Close.get(index)).intNotEqual(-1)
append = switch data
false => vcopy.get(i)
true => ocopy.get(i)
[coloR, strinG] = if not data
switch math.sign(dotMat.Difference.get(index))
-1 => [dncol, "-"]
=> [upcol, "" ]
else
switch math.sign(dotMat.Difference.get(index))
-1 => [math.sign(dotMat.OI2.get(index)).floatEqual(-1).determine(dncoloi , upcoloi2) , "-"]
=> [math.sign(dotMat.OI2.get(index)).floatEqual(-1).determine(upcoloi , dncoloi2) , "" ]
SM.add_col(SM.columns(),
array.from(
sortedMat.new(volM = dotMat.Volume .get(index)) ,
sortedMat.new(oicM = dotMat.OI .get(index)) ,
sortedMat.new(timM = dotMat.Time .get(index)) ,
sortedMat.new(cloM = dotMat.Close .get(index)) ,
sortedMat.new(clcM = dotMat.Difference.get(index)) ,
sortedMat.new(toiM = dotMat.OI2 .get(index)) ,
sortedMat.new(colM = coloR ) ,
sortedMat.new(valM = strinG )
))
count += 1, dotMat.Rank.push(append),
tan3.push(sort.equal("Occurrence")
.determine(dotMat.Time.get(index), data
.determine(dotMat.OI.get(index) , dotMat.Volume.get(index)
)))
else
break
var uniArr = array.from("❶","❷","❸","❹","❺","❻","❼","❽","❾","❿","⓫","⓬","⓭","⓮","⓯","⓰","⓱","⓲","⓳","⓴")
colorr = array.new_color(), var tan2 = array.new_float(), var tan4 = array.new_int()
for i = 0 to SM.columns() - 1
condition = switch action
"Find As Many Vol/OI Extremities As Possible" => data.determine(ocopy.percentrank(i).floatGreatEqual(agg),
vcopy.percentrank(i).floatGreatEqual (agg))
=> i.intNotEqual(-1)
if condition
rank = dotMat.Rank.percentrank(i)
SIZE = switch rank.floatNotEqual(-1)
rank <= 10 => size.tiny
rank <= 25 => size.small
rank <= 50 => size.normal
rank <= 75 => size.large
=> size.huge
OItxt = switch syminfo.type.equal("crypto")
true => "\nOI: " + str.tostring(SM.row(5).get(i).toiM, format.mintick)
=> ""
dotMat.Circle.push(label.new(int(SM.row(2).get(i).timM), SM.row(3).get(i).cloM,
text = action.equal(stringBool) or i.intGreatEqual(uniArr.size() - 1) ? "⬤" : uniArr.get(i),
tooltip = "VOL: " + (math.sign(SM.row(4).get(i).clcM).floatEqual(-1).determine("-" , "")) +
str.tostring(SM.row(0).get(i).volM, format.volume) + OItxt,
xloc = xloc.bar_time,
color = #000000,
textcolor = color.new(SM.row(6).get(i).colM, 33),
size = action.equal(stringBool) ? SIZE : size.normal,
style = label.style_text_outline
))
colorr.push(color.new(SM.row(6).get(i).colM, 33)), tan4.push(SM.row(2).get(i).timM)
tan2.HeWhoSort(sort.equal("Occurrence").determine(SM.row(2).get(i).timM, data.determine(SM.row(1).get(i).oicM, SM.row(0).get(i).volM)), -1)
if not nake
if showl.intNotEqual(0)
countLab = 0
for i = 0 to dotMat.Circle.size() - 1
if dotMat.Circle.get(i).get_x().intGreatEqual(tan4.max(math.min(showl, tan4.size()-1)))
if linebool and dotMat.Circle.get(i).get_y().floatGreatEqual(close * (1 - linedist))
and dotMat.Circle.get(i).get_y().floatLessEqual (close * (1 + linedist))
or not linebool
finCol = switch srcol
true => dotMat.Circle.get(i).get_y().floatGreatEqual(close).determine(dncol , upcol)
=> colorr.get(i)
dotMat.Zone.push(line.new(
dotMat.Circle.get(i).get_x(), dotMat.Circle.get(i).get_y(), pct.timeFrom("close", 40, "chart"), dotMat.Circle.get(i).get_y(),
color = finCol,
xloc = xloc.bar_time
))
countLab += 1
if countLab.intEqual(showl)
break
else
if action.equal(stringBool) or action.equal("Show Extremities For The Data On My Screen")
if dotMat.Circle.size().intGreatEqual(1)
for i = 0 to dotMat.Circle.size() - 1
if linebool and dotMat.Circle.get(i).get_y().floatGreatEqual(close * (1 - linedist))
and dotMat.Circle.get(i).get_y().floatGreatEqual(close * (1 + linedist))
or not linebool
dotMat.Zone.push(line.new(
dotMat.Circle.get(i).get_x(), dotMat.Circle.get(i).get_y(),
pct.timeFrom("bar", 40, "chart"), dotMat.Circle.get(i).get_y(),
xloc = xloc.bar_time, color = color.new(SM.row(6).get(i).colM, 33)
))
sz = switch siz
"Auto" => size.auto
"Tiny" => size.tiny
"Small" => size.small
"Normal" => size.normal
"Large" => size.large
"Huge" => size.huge
if float(dt).floatGreatEqual(1)
var tab = table.new(position.top_right, 4, dt+2, frame_width = 1,
frame_color = color.white ,
border_width = 1,
border_color = color.white),
nakeCount = 0
for i = 0 to nake.determine(dotMat.Circle.size() - 1, math.min(dt - 1, SM.columns() - 1))
occCond = tan3.indexof(tan2.get(i))
if sort.equal("Occurrence")
tan3.set(occCond, 0)
if SM.row(0).get(i).volM.floatNotEqual(0)
tab.cell(0, i + 1, text = SM.row(7).get(occCond).valM + str.tostring(SM.row(0).get(occCond).volM, format.volume),
bgcolor = color.new(#000000, 50),
text_color = SM.row(6).get(occCond).colM,
text_size = sz,
text_font_family = font.family_monospace
)
tab.cell(1, i + 1, text = str.tostring(SM.row(3).get(occCond).cloM, format.mintick),
bgcolor = color.new(#000000, 50),
text_color = SM.row(6).get(occCond).colM,
text_size = sz,
text_font_family = font.family_monospace
)
if not na(oic.sum()) and syminfo.type.equal("crypto")
tab.cell(2, i + 1, text = str.tostring(SM.row(5).get(occCond).toiM, format.mintick),
bgcolor = color.new(#000000, 50),
text_color = data.determine(SM.row(6).get(occCond).colM ,
math.sign(SM.row(5).get(occCond).toiM).floatEqual(-1).determine(dncol , upcol)),
text_size = sz,
text_font_family = font.family_monospace
)
nakeCount += 1
if nakeCount.intEqual(dt)
break
tab.cell(0, 0, "Vol." , text_color = color.white, bgcolor = color.new(#000000, 50), text_size = sz, text_font_family = font.family_monospace)
tab.cell(1, 0, "Price", text_color = color.white, bgcolor = color.new(#000000, 50), text_size = sz, text_font_family = font.family_monospace)
if not na(oic.sum()) and syminfo.type.equal("crypto")
tab.cell(2, 0, "OI", text_color = color.white, bgcolor = color.new(#000000, 50), text_size = sz, text_font_family = font.family_monospace)
if dotMat.Circle.size().intEqual(0) and nake
tab.cell(0, 1, "No Naked Levels Detected", text_color = color.white, text_font_family = font.family_monospace, bgcolor = #000000)
tab.merge_cells(0, 1, 2, 1)
if action.notEqual(stringBool)
line.new(dotMat.Start, high, dotMat.Start, low,
extend = extend.both,
color = color.white,
width = 4,
xloc = xloc.bar_time
)
label.new(dotMat.Start, high * 1.01,
style = label.style_label_right,
color = #000000,
xloc = xloc.bar_time,
textcolor = color.white,
size = size.small,
text = "Earliest Start Date"
)
else
if dotMat.Circle.size().intGreatEqual(1)
for i = 0 to dotMat.Circle.size() - 1
dotMat.perBar.set(i, math.abs(dotMat.perBar.get(i)))
for i = 0 to dotMat.Circle.size() - 1
rank = dotMat.perBar.percentrank(i)
SIZE = switch rank.floatNotEqual(-1)
rank <= 10 => size.tiny
rank <= 25 => size.small
rank <= 50 => size.normal
rank <= 75 => size.large
=> size.huge
dotMat.Circle.get(i).set_size(SIZE)
if i.intLessEqual(showl - 2)
if linebool
if dotMat.Circle.get(i).get_y().floatGreatEqual(close * (1 - linedist))
and dotMat.Circle.get(i).get_y().floatLessEqual (close * (1 + linedist))
dotMat.Zone.get(i).set_x2(pct.timeFrom("bar", 40, "chart"))
else
dotMat.Zone.get(i).set_x2 (pct.timeFrom("bar", 40, "chart"))
switch srcol
true => dotMat.Zone.get(i).set_color(dotMat.Circle.get(i).get_y().
floatGreatEqual(close).determine(dncol , upcol))
=> continue
// Start
// Thank you Donovan Wall for the great range filter code!!
Cond_EMA(x, cond, n)=>
var val = array.new_float(0)
var ema_val = array.new_float(1)
if cond
val.push(x)
if val.size( )> 1
val.remove(0)
if na(ema_val.get(0))
ema_val.fill(val.get(0))
ema_val.set(0, (val.get(0) - ema_val.get(0))*(2/(n + 1)) + ema_val.get(0))
EMA = ema_val.get(0)
EMA
rng_size(x, scale, qty, n)=>
ATR = Cond_EMA(ta.tr(true), 1, n)
AC = Cond_EMA(math.abs(x - x[1]), 1, n)
rng_size = qty*AC
rng_filt(h, l, rng_, n, type, smooth, sn, av_rf, av_n)=>
rng_smooth = Cond_EMA(rng_, 1, sn)
r = smooth ? rng_smooth : rng_
var rfilt = array.new_float(2, (h + l)/2)
rfilt.set(1, rfilt.get(0))
if h - r > rfilt.get(1)
rfilt.set(0, h - r)
if l + r < rfilt.get(1)
rfilt.set(0, l + r)
rng_filt1 = rfilt.get(0)
hi_band1 = rng_filt1 + r, lo_band1 = rng_filt1 - r
rng_filt2 = Cond_EMA(rng_filt1, rng_filt1 != rng_filt1[1], av_n)
hi_band2 = Cond_EMA(hi_band1, rng_filt1 != rng_filt1[1], av_n)
lo_band2 = Cond_EMA(lo_band1, rng_filt1 != rng_filt1[1], av_n)
[rng_filt, hi_band, lo_band] = switch av_rf
true => [rng_filt2, hi_band2, lo_band2]
=> [rng_filt1, hi_band1, lo_band1]
[hi_band, lo_band, rng_filt]
[h_band, l_band, filt] = rng_filt(close, close, rng_size((close + close)/2, "Average Change", 20.618, 500), 500, "Type 1", true, 500, 0,0)
// Thank you Donovan Wall for great range filter code!!
// End
var int boxCount = 0
type liqValues
matrix <float> Average
matrix <int> Violations
matrix <float> TickVol
matrix <float> TickOI
float [] Levels
line [] boxLines
line rightUp
line rightDn
line leftUp
line leftDn
line startU
line startD
var liquidation = liqValues.new(
matrix.new<float>(5 , 0 ), matrix.new<int> (2 , 11, 0),
matrix.new<float>(21, 1000), matrix.new<float>(21, 1000 ),
array.new_float(), array.new_line()),
orientation = matrix.new<float>(2, 5)
method expCalc(array <float> id) =>
math.exp(id.avg())
method multiply(float id, string PM, float ) =>
switch PM
"+" => id * (1 + ((1./( float )) + 0.004))
"-" => id * (1 - ((1./( float )) + 0.004))
method reduced(array <float> id, float , string ) =>
switch string
"P" => id.expCalc().multiply("+", float )
"N" => id.expCalc().multiply("-", float )
method divSubtract(array<float> id, float, float2) =>
(id.reduced(float , "P") - id.reduced(float2, "N")) / 5
method double_binary_search_leftmost(array <float> id, column) =>
n = id.binary_search_leftmost (orientation.get(0, column))
n1 = id.binary_search_leftmost (orientation.get(1, column))
[n, n1]
method finSetVol(matrix <float> id, int i, int row, int start, int end) =>
for x = start to end
id.set (row, i, id.get(row, i) + liquidation.TickVol.get(i, x))
method finSetOI (matrix <float> id, int i, int row, int start, int end) =>
for x = start to end
id.set (row, i, id.get(row, i) + liquidation.TickOI.get(i, x))
method tickSet(matrix<float> id, float value, int column, int loop, int calc) =>
id.set(math.max(boxCount, 0), column, nz(nz(id.get(math.max(boxCount, 0), column)) + (value / math.max(1, (calc)))))
method netAdjust(array <float> id) =>
for i = 0 to id.size() - 1
if na(id.get(i))
id.set(i, 0)
for i = id.size() - 2 to 0
id.set(i, id.get(i) + id.get(i + 1))
if id.size().intGreatEqual(201)
for i = id.size() - 1 to 200
id.pop()
if action2 and syminfo.type.equal("crypto")
var oiclab = matrix.new<label>(2)
OIgrid = input.bool (defval = true , title = "Use OI For Grid Color (Instead of Volume) (Crypto Only)", group = "Grid Settings")
heatmap = input.bool (defval = true , title = "Show Heatmap (Grid)", group = "Grid Settings")
ext = input.bool (defval = false, title = "Extend Grid Boxes", group = "Grid Settings")
gridWidth = input.int (defval = 0, title = "Grid Width", group = "Grid Settings")
gridCol = input.color(defval = color.white, title = "Border Color", group = "Grid Settings", inline = "Grid")
gridUp = input.color(defval = color.lime, title = '"Up" Color', group = "Grid Settings", inline = "Grid")
gridDn = input.color(defval = color.red, title = '"Down" Color', group = "Grid Settings", inline = "Grid")
var float div = 0
if action.equal("Off") and not userDefinedTime
bx = box.all, la = label.all, li = line.all, lf = linefill.all
if bx.size().intGreatEqual(1)
row = grid.rows(), col = grid.columns()
grid.reshape(grid.elements_count(), 1)
for i = 0 to bx.size() - 1
if not grid.col(0).includes(bx.get(i))
bx.get(i).delete()
grid.reshape(row, col)
if la.size().intGreatEqual(1)
for i = 0 to la.size() - 1
if not oiclab.row(0).includes(la.get(i))
and not oiclab.row(1).includes(la.get(i))
la.get(i).delete()
if li.size().intGreatEqual(1)
for i = 0 to li.size() - 1
li.get(i).delete()
if lf.size().intGreatEqual(1)
for i = 0 to lf.size() - 1
lf.shift().delete()
var oicsum = matrix.new<float> (2, 0)
var int stime = 0, var int sbar = 0
if obj.size().intGreatEqual(1) and clocalc.size().intGreatEqual(1)
if sbar.intEqual(0)
sbar := bar_index, stime := time
cond = switch userDefinedTime
false => filt.floatGreatEqual(filt[1] - atr) and filt.floatLessEqual(filt[1] + atr)
=> time >= timtest and time <= timtest2
if cond
liquidation.Average.add_col(0, array.from(high, low, math.log(close), close > open ? volume : volume * -1, time))
for i = 0 to math.min(obj.size(), clocalc.size()) - 1
if syminfo.type.equal("crypto") and OIgrid
if math.sign(clocalc.get(i)).floatEqual(1)
switch math.sign(oic.get(i))
1 => oicsum.add_col(oicsum.columns(), array.from(oic.get(i), float(na)))
-1 => oicsum.add_col(oicsum.columns(), array.from(float(na), oic.get(i)))
else
switch math.sign(oic.get(i))
-1 => oicsum.add_col(oicsum.columns(), array.from(oic.get(i), float(na)))
1 => oicsum.add_col(oicsum.columns(), array.from(float(na), oic.get(i)))
else
switch math.sign(clocalc.get(i))
1 => oicsum.add_col(oicsum.columns(), array.from(vol.get(i), float(na)))
-1 => oicsum.add_col(oicsum.columns(), array.from(float(na), vol.get(i)))
if liquidation.Levels.size().intGreatEqual(1)
for i = 0 to math.min(obj.size(), clocalc.size()) - 1
highest = liquidation.Levels.binary_search_leftmost (hi.get(i))
lowest = liquidation.Levels.binary_search_leftmost (lo.get(i))
for x = lowest to highest
volx = switch math.sign(clocalc.get(i))
1 => vol.get(i)
=> vol.get(i) * -1
liquidation.TickVol.tickSet(volx , x, i, highest - lowest)
liquidation.TickOI .tickSet(obj.get(i), x, i, highest - lowest)
for i = 0 to 19
if not barstate.islast
con = div.floatGreatEqual(500)
[index, pIndex, startIndex] = switch con
true => [ time , time [1], stime]
=> [bar_index, bar_index[1], sbar]
if index >= math.round(startIndex + (div * (i + 1))) and pIndex < math.round(startIndex + (div * (i + 1)))
boxCount += 1
for z = 0 to 4
liquidation.TickVol.set(math.max(boxCount, 0), z, liquidation.TickVol.get(math.max(boxCount - 1, 0), z))
liquidation.TickOI .set(math.max(boxCount, 0), z, liquidation.TickOI .get(math.max(boxCount - 1, 0), z))
for x = 0 to 4
grid.set(x, boxCount,
box.new(
grid.get(x, boxCount - 1).get_right(),
liquidation.Average.row(2).reduced(100, "N") + (liquidation.Average.row(2).divSubtract(100, 100) * (x + 1)),
math.round(index + div),
liquidation.Average.row(2).reduced(100, "N") + (liquidation.Average.row(2).divSubtract(100, 100) * (x)),
xloc = div.floatGreatEqual(500).determine(xloc.bar_time, xloc.bar_index),
border_color = gridCol,
border_width = gridWidth,
bgcolor = color.white
))
break
if oicsum.elements_count().intGreatEqual(90001)
for i = 0 to 10000
oicsum.remove_col(i)
else
if filt < filt[1] - atr and not userDefinedTime or filt > filt[1] + atr and not userDefinedTime or userDefinedTime and time < timtest
liquidation.TickVol.fill(0, 0, liquidation.TickVol.rows(), 0, liquidation.TickVol.columns())
liquidation.TickOI .fill(0, 0, liquidation.TickOI .rows(), 0, liquidation.TickOI .columns())
liquidation.Levels.clear()
for i = 0 to grid.rows() - 1
for x = 0 to grid.columns() - 1
grid.get(i, x).delete()
if oicsum.columns().intGreatEqual(1)
for i = 0 to oicsum.columns() - 1
oicsum.remove_col()
if oiclab.columns().intGreatEqual(1)
for i = 0 to oiclab.columns() - 1
oiclab.get(0, i).delete()
oiclab.get(1, i).delete()
for i = 0 to oiclab.columns() - 1
oiclab.remove_col()
stime := time, sbar := bar_index, div := switch (last_bar_index - sbar) / 20 >= 500
false => (last_bar_index - sbar) / 20
=> (last_bar_time - stime) / 20
startIndex = div.floatGreatEqual(500).determine(time, bar_index)
for x = 0 to 4
grid.set(x, 0,
box.new(
startIndex,
liquidation.Average.row(2).reduced(100, "N") + (liquidation.Average.row(2).divSubtract(100, 100) * (x + 1)),
math.round(startIndex + div),
liquidation.Average.row(2).reduced(100, "N") + (liquidation.Average.row(2).divSubtract(100, 100) * (x)),
xloc = div.floatGreatEqual(500).determine(xloc.bar_time, xloc.bar_index),
border_color = gridCol,
border_width = gridWidth,
bgcolor = color.white
))
if liquidation.Average.columns().intGreatEqual(1)
for i = 0 to liquidation.Average.columns() - 1
liquidation.Average.remove_col()
liquidation.Average.add_col(0 , array.from(
high,
low,
math.log(close),
close > open ? volume : volume * -1,
time
))
for i = 0 to 499
liquidation.Levels.HeWhoSort(close * (1 + (i/1000)), 1)
liquidation.Levels.HeWhoSort(close * (1 - (i/1000)), 1)
boxCount := 0
if barstate.islast and not userDefinedTime or time[1] < timtest2 and time >= timtest2 and userDefinedTime
[endTime, endIndex] = switch userDefinedTime
false => [last_bar_time, last_bar_index]
true => [timtest2, bar_index ]
if userDefinedTime
x = timeMat.Time.get(timeMat.Time.indexof(timtest) + 1)
line.new(x, high, x, low, xloc = xloc.bar_time, extend = extend.both, color = color.new(color.white, 50) , width = 2)
line.new(timtest2, high, timtest2, low, xloc = xloc.bar_time, extend = extend.both, color = color.new(#000000, 50), width = 2)
posSum = oicsum.row(0).sum()
negSum = oicsum.row(1).sum()
minlvlu = 50, minlvld = 50, minlvl = 50, var corners = matrix.new<liqValues>(6, 1)
if minlevl.notEqual("Auto")
minlvlu := int(str.tonumber(minlevl))
minlvld := int(str.tonumber(minlevl))
else
for i = 50 to 20 by 10
if liquidation.Average.row(0).max().floatGreatEqual(liquidation.Average.row(2).reduced(i, "P"))
minlvlu := i + 10
if liquidation.Average.row(1).min().floatLessEqual (liquidation.Average.row(2).reduced(i, "N"))
minlvld := i - 10
minlvl := math.min(minlvlu, minlvld)
if syminfo.type.equal("crypto")
for i = 0 to liquidation.Average.columns() - 1
for x = 0 to 10
if liquidation.Average.get(0, i).floatGreatEqual(liquidation.Average.row(2).reduced(x * 10, "P"))
liquidation.Violations.set(0, x, nz(liquidation.Violations.get(0, x) + 1))
for i = 0 to liquidation.Average.columns() - 1
for x = 0 to 10
if liquidation.Average.get(1, i).floatLessEqual(liquidation.Average.row(2).reduced(x * 10, "N"))
liquidation.Violations.set(1, x, nz(liquidation.Violations.get(1, x) + 1))
if showcir
uCalc = liquidation.Average.row(2).reduced(100, "P")
lCalc = liquidation.Average.row(2).reduced(100, "N")
for i = liquidation.Average.columns() - 1 to 1
if liquidation.Average.get(0, i - 1).floatGreatEqual(uCalc)
and liquidation.Average.get(0, i) < uCalc
oiclab.add_col(oiclab.columns())
oiclab.set(0, oiclab.columns() - 1, label.new(math.round(liquidation.Average.get(4, i - 1)),
liquidation.Average.get(0, i - 1) , "⬤",
textcolor = color.new(gridUp, 50),
color = #000000,
style = label.style_text_outline,
xloc = xloc.bar_time,
size = size.tiny
))
if liquidation.Average.get(1, i - 1).floatLessEqual(lCalc)
and liquidation.Average.get(1, i).floatGreatEqual(lCalc)
oiclab.add_col(oiclab.columns())
oiclab.set(1, oiclab.columns() - 1, label.new(math.round(liquidation.Average.get(4, i - 1)),
liquidation.Average.get(1, i - 1) , "⬤",
textcolor = color.new(gridDn, 50),
color = #000000,
style = label.style_text_outline, xloc = xloc.bar_time,
size = size.tiny
))
for i = minlvl to 90 by 10
transp = array.from(45, 50, 55, 60, 65, 70, 75, 80, 85, 90)
txt = switch i.intNotEqual(90)
true => str.tostring(i, "###x")
=> box2Line ? "90x" : "90 - 100x"
switch box2Line
false =>
box.new(
stime, liquidation.Average.row(2).expCalc().multiply("-", i + 10), endTime, liquidation.Average.row(2).expCalc().multiply("-", i),
xloc = xloc.bar_time,
bgcolor = color.new( gridUp, transp.get((i - minlvl) / 10)),
text_color = color.white,
text = txt,
border_color = color.new( gridUp, transp.get((i - minlvl) / 10)),
text_halign = text.align_left,
text_size = size.auto
),
box.new(
stime, liquidation.Average.row(2).expCalc().multiply("+", i + 10), endTime, liquidation.Average.row(2).expCalc().multiply("+", i),
xloc = xloc.bar_time,
bgcolor = color.new( gridDn, transp.get((i - minlvl) / 10)),
text_color = color.white,
text = txt,
border_color = color.new( gridDn, transp.get((i - minlvl) / 10)),
text_halign = text.align_left,
text_size = size.auto
)
=>
line.new(
stime, liquidation.Average.row(2).expCalc().multiply("-", i), endTime + (time - time[3]),
liquidation.Average.row(2).expCalc().multiply("-", i),
xloc = xloc.bar_time,
color = color.new( gridUp, transp.get((i - minlvl) / 10))
),
line.new(
stime, liquidation.Average.row(2).expCalc().multiply("+", i), endTime + (time - time[3]),
liquidation.Average.row(2).expCalc().multiply("+", i),
xloc = xloc.bar_time,
color = color.new( gridDn, transp.get((i - minlvl) / 10))
)
if box2Line
label.new(bar_index + 7, liquidation.Average.row(2).expCalc().multiply("+", i),
style = label.style_label_left,
textcolor = gridDn,
color = #00000000,
text = txt
)
label.new(bar_index + 7, liquidation.Average.row(2).expCalc().multiply("-", i),
style = label.style_label_left,
textcolor = gridUp,
color = #00000000,
text = txt
)
if i.intEqual(90)
line.new(
stime, liquidation.Average.row(2).expCalc().multiply("-", i + 10), endTime + (time - time[3]),
liquidation.Average.row(2).expCalc().multiply("-", i + 10),
xloc = xloc.bar_time,
color = color.new( gridUp, transp.get((i - minlvl) / 10))
)
line.new(
stime, liquidation.Average.row(2).expCalc().multiply("+", i + 10), endTime + (time - time[3]),
liquidation.Average.row(2).expCalc().multiply("+", i + 10),
xloc = xloc.bar_time,
color = color.new( gridDn, transp.get((i - minlvl) / 10))
)
label.new(bar_index + 7, liquidation.Average.row(2).expCalc().multiply("+", i + 10),
style = label.style_label_left,
textcolor = gridDn,
text = str.tostring(i + 10, "###x"),
color = #00000000
)
label.new(bar_index + 7, liquidation.Average.row(2).expCalc().multiply("-", i + 10),
style = label.style_label_left,
textcolor = gridUp,
text = str.tostring(i + 10, "###x"),
color = #00000000
)
y1 = (liquidation.Average.row(2).divSubtract(minlvl, 100) / ((90 - minlvl) / 10) * ((i - minlvl) / 10))
colarr = array.from(11, 11, 22, 22, 33, 33, 44, 44, 55, 66, 66)
txtc = switch liquidation.Average.row(2).expCalc().multiply("+", i + 10).floatGreatEqual(liquidation.Average.row(0).max())
true => #ffffff50
=> color.new(gridDn, colarr.get((i - minlvl) / 10))
if not box2Line
label.new(endIndex + 25, liquidation.Average.row(2).reduced(minlvl, "P") - y1,
"▰",
textcolor = txtc,
size = size.tiny,
color = #000000,
style = label.style_text_outline
)
txtc2 = switch liquidation.Average.row(2).expCalc().multiply("-", i + 10).floatLessEqual(liquidation.Average.row(1).min())
true => #ffffff50
=> color.new(gridUp, colarr.get((i - minlvl) / 10))
if not box2Line
label.new(endIndex + 25, liquidation.Average.row(2).reduced(minlvl, "N") + y1,
"▰",
textcolor = txtc2 ,
size = size.tiny,
color = #000000,
style = label.style_text_outline
)
[mult, mult2, mult3] = switch minlvl
50 => [35 , 40, 30 ]
40 => [30 , 35, 25 ]
30 => [23 , 25.5, 20.5]
20 => [15 , 17, 13 ]
10 => [8 , 9 , 7 ]
liqd = math.avg(liquidation.Average.row(2).reduced(100, "N"), liquidation.Average.row(2).reduced(minlvl, "N"))
liqu = math.avg(liquidation.Average.row(2).reduced(100, "P"), liquidation.Average.row(2).reduced(minlvl, "P"))
liqd2 = liquidation.Average.row(2).reduced(mult, "N")
liqu2 = liquidation.Average.row(2).reduced(mult, "P")
sbartime = timeMat.Time.indexof(stime)
switchCond = syminfo.type.equal("crypto")
[longText, shortText, totCalc] = switch switchCond
true => [OIgrid.determine("\nNet Longs In Range", "\nBuying Vol. In Range" ),
OIgrid.determine("\nNet Shorts In Range", "\nSelling Vol. In Range"),
OIgrid.determine (posSum+negSum, posSum-negSum)]
=> ["\nBuying Vol. In Range", "\nSelling Vol. In Range", posSum-negSum]
label.new(bar_index + 15, liquidation.Average.row(2).expCalc(), str.tostring(totCalc, "###,###,###,###.00"),
color = color.white,
textcolor = color.rgb(0, 0, 0),
style = label.style_text_outline,
size = size.small
)
b = box.new(
int(
math.avg(stime, stime, endTime)),
liquidation.Average.row(2).reduced(mult2, "N"),
int(
math.avg(stime, endTime, endTime)),
liquidation.Average.row(2).reduced(mult3, "N"),
bgcolor = #00000050,
border_color = #ffffff,
text = str.tostring(posSum, "###,###,###,###,###,###.00")
+ longText ,
text_color = color.white,
text_size = size.auto,
xloc = xloc.bar_time
)
o = box.new(
int(
math.avg(stime, stime, endTime)),
liquidation.Average.row(2).reduced(mult2, "P"),
int(
math.avg(stime, endTime, endTime)),
liquidation.Average.row(2).reduced(mult3, "P"),
bgcolor = #00000050,
border_color = #ffffff,
text = str.tostring(negSum, "###,###,###,###,###,###.00") +
+ shortText ,
text_color = color.white,
text_size = size.auto,
xloc = xloc.bar_time
)
if switchCond
liquidation.boxLines.push(line.new(timeMat.Time.get(sbartime), liqd, timeMat.Time.get(sbartime + 10),
liqd,
color = gridUp,
style = line.style_dashed,
xloc = xloc.bar_time
))
corners.set(2, 0,
liqValues.new(
leftUp = line.new(timeMat.Time.get(sbartime + 10), liqd2, timeMat.Time.get(sbartime + 10),
liqd,
color = gridUp,
style = line.style_dashed,
xloc = xloc.bar_time
)))
liquidation.boxLines.push(line.new(timeMat.Time.get(sbartime + 10), liqd2, b.get_left(),liqd2,
color = gridUp,
style = line.style_dashed,
xloc = xloc.bar_time
))
corners.set(0, 0,
liqValues.new(
rightUp = line.new(endIndex + 10, liqd2, endIndex + 10, liqd,
color = gridUp,
style = line.style_dashed
)))
liquidation.boxLines.push(line.new(int(math.avg(sbar, endIndex, endIndex)), liqd2, endIndex + 10, liqd2,
color = gridUp,
style = line.style_dashed
))
liquidation.boxLines.push(line.new(endIndex, liqd, endIndex + 10,
liqd,
color = gridUp,
style = line.style_dashed
))
liquidation.boxLines.push(line.new(stime, liqu, timeMat.Time.get(sbartime + 10),
liqu,
color = gridDn,
style = line.style_dashed,
xloc = xloc.bar_time
))
corners.set(3, 0,
liqValues.new(
leftDn = line.new(timeMat.Time.get(sbartime + 10), liqu, timeMat.Time.get(sbartime + 10),
liqu2,
color = gridDn,
style = line.style_dashed,
xloc = xloc.bar_time
)))
liquidation.boxLines.push(line.new(timeMat.Time.get(sbartime + 10), liqu2, o.get_left(),liqu2,
color = gridDn,
style = line.style_dashed,
xloc = xloc.bar_time
))
corners.set(1, 0,
liqValues.new(
rightDn = line.new(endIndex + 10, liqu, endIndex + 10, liqu2,
color = gridDn,
style = line.style_dashed
)))
liquidation.boxLines.push(line.new(
int(
math.avg(sbar, endIndex, endIndex)), liqu2, endIndex + 10, liqu2,
color = gridDn,
style = line.style_dashed
))
liquidation.boxLines.push(line.new(endIndex, liqu, endIndex + 10,
liqu,
color = gridDn,
style = line.style_dashed
))
var table liqtab = table.new(
position.bottom_right, 20, 20,
bgcolor = na,
frame_color = color.white,
border_color = color.white,
frame_width = 1,
border_width = 1
)
liqtab.cell(0, 0, "Violations", text_color = color.white), liqtab.cell(0, 1, "Positive", text_color = gridDn),
liqtab.cell(2, 1, "Negative" , text_color = gridUp), liqtab.merge_cells(0, 0, 3, 0),
liqtab.merge_cells(0, 1, 1, 1)
liqtab.merge_cells(2, 1, 3, 1)
strArr = array.from("100x: ", "90x: ", "80x: ", "70x: ", "60x: ", "50x: ", "40x: ", "30x: ", "20x: ", "10x: " )
strArr2 = array.from("100x: ", "90x: ", "80x: ", "70x: ", "60x: ", "50x: ", "40x: ", "30x: ", "20x: ", "10x: " )
intMat = matrix.new<int>(0, 10)
dnRow = liquidation.Violations.row(0), dnRow.reverse()
upRow = liquidation.Violations.row(1), upRow.reverse()
for i = 0 to strArr.size() - 1
strArr .set(i, strArr.get(i) + str.tostring(dnRow.get(i)))
strArr2.set(i, strArr2.get(i) + str.tostring(upRow.get(i)))
intMat.add_row(0, array.from(0, 1, 0, 1, 0, 1, 0, 1, 0, 1))
intMat.add_row(1, array.from(2, 3, 2, 3, 2, 3, 2, 3, 2, 3))
intMat.add_row(2, array.from(2, 2, 3, 3, 4, 4, 5, 5, 6, 6))
for i = 0 to strArr.size() - 1
liqtab.cell(intMat.get(0, i), intMat.get(2, i), strArr.get (i), text_color = gridDn )
liqtab.cell(intMat.get(1, i), intMat.get(2, i), strArr2.get(i), text_color = gridUp)
if move
netLong = oicsum.row(0), netShort = oicsum.row(1)
for i = bar_index - sbar to 0
if timeMat.Close.get(i).floatGreatEqual(timeMat.Close.get(i + 1))
switch math.sign(timeMat.Difference.get(i)).floatEqual(1)
true => netLong .set(i, timeMat.Difference.get(i)),
netShort.set(i, 0)
=> netLong .set(i, 0),
netShort.set(i, timeMat.Difference.get(i))
else
switch math.sign(timeMat.Difference.get(i)).floatEqual(1)
true => netLong .set(i, 0),
netShort.set(i, timeMat.Difference.get(i))
=> netLong .set(i, timeMat.Difference.get(i)),
netShort.set(i, 0)
netLong.netAdjust(), netShort.netAdjust()
b.set_top(liquidation.Average.row(2).reduced(mult, "N"))
o.set_top(liquidation.Average.row(2).reduced(mult, "P"))
if switchCond
linefill.new(corners.get(2, 0).leftUp, corners.get(0, 0).rightUp, #00000050)
linefill.new(corners.get(3, 0).leftDn, corners.get(1, 0).rightDn, #00000050)
avgN = (math.avg(liquidation.Average.row(2).reduced(mult + 1, "N"), liquidation.Average.row(2).reduced(minlvl - 1, "N")))
avgP = (math.avg(liquidation.Average.row(2).reduced(mult + 1, "P"), liquidation.Average.row(2).reduced(minlvl - 1, "P")))
for i = 1 to math.min(bar_index - sbar, netLong.size() - 1)
netCalc = (liquidation.Average.row(2).reduced(mult + 1, "N")) + ((liquidation.Average.row(2).reduced(minlvl - 1, "N"))
- (liquidation.Average.row(2).reduced(mult + 1, "N" )))
* (netLong.get(i) - netLong.min()) / (netLong.range ())
snetCalc = (liquidation.Average.row(2).reduced(minlvl - 1, "P")) - ((liquidation.Average.row(2).reduced(minlvl - 1, "P"))
- (liquidation.Average.row(2).reduced(mult + 1, "P" )))
* (netShort.get(i) - netShort.min()) / (netShort.range ())
netCalc2 = (liquidation.Average.row(2) .reduced(mult + 1, "N")) + ((liquidation.Average.row(2) .reduced (minlvl - 1, "N"))
- (liquidation.Average.row(2).reduced(mult + 1, "N" )))
* (netLong.get(i - 1) - netLong.min()) / (netLong.range ()),
snetCalc2 = (liquidation.Average.row(2).reduced(minlvl-1, "P")) - ((liquidation.Average.row(2) .reduced(minlvl - 1, "P" ))
- (liquidation.Average.row(2).reduced(mult + 1, "P" )))
* (netShort.get(i - 1) - netShort.min()) / (netShort.range())
line.new(timeMat.Time.get(i + 1), snetCalc, timeMat.Time.get(i),
snetCalc2,
color = gridDn,
xloc = xloc.bar_time,
width = 2
)
line.new(timeMat.Time.get(i + 1), netCalc, timeMat.Time.get(i),
netCalc2,
color = gridUp,
xloc = xloc.bar_time,
width = 2
)
if not move and switchCond
if liquidation.boxLines.size().intGreatEqual(1)
for i = 0 to liquidation.boxLines.size() - 1
liquidation.boxLines.shift().delete()
for i = 0 to 3
if not na(corners.get(i, 0))
switch i % 4
0 => corners.get(0, 0).rightUp.delete()
1 => corners.get(1, 0).rightDn.delete()
2 => corners.get(2, 0).leftUp .delete()
3 => corners.get(3, 0).leftDn .delete()
if linefill.all.size().intGreatEqual(1)
for i = 0 to linefill.all.size() - 1
linefill.all.shift().delete()
if heatmap
count = 0
for i = 0 to grid.rows() - 1
for x = 0 to grid.columns() - 1
grid.get(i, x).set_bottom(liquidation.Average.row(2).reduced(100, "N") + (liquidation.Average.row(2).divSubtract(100, 100) * i))
grid.get(i, x).set_top (liquidation.Average.row(2).reduced(100, "N") + (liquidation.Average.row(2).divSubtract(100, 100) * (i + 1)))
for i = 0 to 4
orientation.set(0, i, grid.get(i, 0).get_top ())
orientation.set(1, i, grid.get(i, 0).get_bottom())
[up1, dn1] = liquidation.Levels.double_binary_search_leftmost (0), [up2, dn2] = liquidation.Levels.double_binary_search_leftmost (1),
[up3, dn3] = liquidation.Levels.double_binary_search_leftmost (2), [up4, dn4] = liquidation.Levels.double_binary_search_leftmost (3),
[up5, dn5] = liquidation.Levels.double_binary_search_leftmost (4)
var finTick = matrix.new<float>(5, 1, 0), var finTick2 = matrix.new<float>(5, 1, 0)
for i = 0 to 20
finTick .finSetVol(i, 0, dn1, up1), finTick .finSetVol(i, 1, dn2, up2)
finTick2.finSetOI (i, 0, dn1, up1), finTick2.finSetOI (i, 1, dn2, up2)
finTick .finSetVol(i, 2, dn3, up3), finTick .finSetVol(i, 3, dn4, up4)
finTick2.finSetOI (i, 2, dn3, up3), finTick2.finSetOI (i, 3, dn4, up4),
finTick .finSetVol(i, 4, dn5, up5),
finTick2.finSetOI (i, 4, dn5, up5)
finTick .add_col(finTick .columns(), finTick .col(finTick .columns() - 1))
finTick2.add_col(finTick2.columns(), finTick2.col(finTick2.columns() - 1))
for i = 0 to grid.rows() - 1
for x = 0 to grid.columns() - 1
[datax, datamin, datamax] = switch OIgrid
false => [finTick .get(i, x), finTick .min(), finTick .max()]
true and syminfo.type.notEqual("crypto") => [finTick .get(i, x), finTick .min(), finTick .max()]
=> [finTick2.get(i, x), finTick2.min(), finTick2.max()]
col = switch math.sign(datax)
0 => color.new(color.gray, 80)
1 => color.from_gradient(datax, 0, datamax, color.new(gridUp, 90), color.new(gridUp, 50))
-1 => color.from_gradient(datax, datamin, 0, color.new(gridDn, 50), color.new(gridDn, 90))
grid.get(i, x).set_bgcolor(col)
if showValues
oiTxt = switch switchCond
true => "\n\nOI: " +
(finTick2.get(i, x).floatGreatEqual(0).determine("+" , "")) + str.tostring(finTick2.get(i, x), "###,###,###.##")
=> ""
grid.get(i, x).set_text(
"VOL: " + str.tostring(finTick.get(i, x), format.volume) + oiTxt)
grid.get(i, x).set_text_color(color.white)
if ext
for i = 0 to grid.rows() - 1
for x = 1 to grid.columns() - 1
[dataCur, dataPrev] = switch OIgrid
false => [finTick .get(i, x), finTick .get(i, x - 1)]
true and syminfo.type.notEqual("crypto") => [finTick .get(i, x), finTick .get(i, x - 1)]
=> [finTick2.get(i, x), finTick2.get(i, x - 1)]
if dataCur.floatEqual(dataPrev)
grid.get(i, x).set_left(grid.get(i, x - 1).get_left())
grid.get(i, x - 1).delete()
if not switchCond
distanceTop = o.get_bottom() - o.get_top()
distanceBot = b.get_top() - b.get_bottom()
o.set_bottom(grid.get(4, 0) .get_top()) , o.set_top(o.get_bottom() + distanceTop)
b.set_top (grid.get(0, 0) .get_bottom()), b.set_bottom(b.get_top() - distanceBot)
else
for i = 0 to grid.rows() - 1
for x = 0 to grid.columns() - 1
grid.get(i, x).delete()
Show all 1,574 lines