xmd79

Range Analysis - By Leviathan

Mar 14th, 2023
328
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 37.33 KB | None | 0 0
  1. // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
  2. // © LeviathanCapital
  3.  
  4. //@version=5
  5. indicator("Range Analysis - By Leviathan", shorttitle='Range Analysis - By Leviathan', overlay=true, max_boxes_count=500, max_bars_back = 500)
  6.  
  7. timeGroup = 'Time Interval'
  8. vpGroup = 'Volume Profile / Open Interest Profile / Heatmap'
  9. rangeGroup = 'Range Levels'
  10. nstip = 'Node Size inputs controls the scaling of volume profile nodes in relation to the range size. Example: The value of 1 will proportionally extend the nodes to right max of the range, whereas the value of 0.5 will extend the nodes to the middle of the range.'
  11. rstip = 'Increasing the resolution input will improve the volume profile but will also limit the script from generating profiles on longer ranges. Play around and find the higest resolution value that works on your selected range.'
  12. vapcttip = 'Value Area is the area where the most volume occurred. The input is usually 70% or 68%, but you can adjust it to any percentage you want.'
  13. svtip = 'Useful for assets that have very large spikes in volume over large bars. It uses ema of volume instead of just volume and helps create better profiles when needed.'
  14. dirtip = 'Specify the direction of your range (eg. from low to high = UP and high to low = DOWN). This is only significant for level labels and fibbonacci levels'
  15. ndtytip = 'Type 1 means that one node consists of both UP and DOWN data. Type 2 means that UP node will be on the right side of y axis and DOWN node will be on the left side of y axis.'
  16. prfdirtip = 'Choose whether the nodes of the profile are facing left or right.'
  17. prfpostip = 'Choose whether the profile is positioned on the left side of the range or on the right side of the range.'
  18. volndtip = 'Up/Down shows the proportion of UP data and DOWN data in a node. Total shows the net value of UP data + DOWN data. Delta shows the net difference between UP Data and DOWN data.'
  19. dtatyptip = 'Choose the data source used for generating the profile and the heatmaps'
  20.  
  21. // Range levels inputs
  22. dir = input.string('UP', 'Direction', options = ['UP', 'DOWN'], group = rangeGroup, tooltip = dirtip)
  23. showHL = input.bool(true, '', inline='rm', group = rangeGroup)
  24. rangemax = input.string('Range Max: Close', '', options = ['Range Max: Wick', 'Range Max: Close', 'Range Max: HLC3', 'Range Max:OHLC4'], inline='rm', group = rangeGroup)
  25. rangemaxStyle = input.string('────', '', options=['────', '--------', '┈┈┈┈'], inline='rm', group = rangeGroup)
  26. hlCol = input.color(color.silver, '', inline='rm', group = rangeGroup)
  27. lvl05 = input.bool(true, 'Half      ', inline='2', group = rangeGroup)
  28. lvl05Col = input.color(color.rgb(178, 181, 190, 20), '', inline='2', group = rangeGroup)
  29. lvl05Style = input.string('────', '', options=['────', '--------', '┈┈┈┈'], inline='2', group = rangeGroup)
  30. quarters = input.bool(true, 'Quarters    ', inline='4', group = rangeGroup)
  31. quartersCol = input.color(color.rgb(178, 181, 190, 70), '', inline='4', group = rangeGroup)
  32. quartersStyle = input.string('────', '', options=['────', '--------', '┈┈┈┈'], inline='4', group = rangeGroup)
  33. eighths = input.bool(false, 'Eighths       ', inline='8', group = rangeGroup)
  34. eighthsCol = input.color(color.rgb(178, 181, 190, 80), '', inline='8', group = rangeGroup)
  35. eighthsStyle = input.string('────', '', options=['────', '--------', '┈┈┈┈'], inline='8', group = rangeGroup)
  36. fib = input.bool(false, 'Fibonacci  ', inline='F', group = rangeGroup)
  37. fibCol = input.color(color.rgb(178, 181, 190, 80), '', inline='F', group = rangeGroup)
  38. fibStyle = input.string('────', '', options=['────', '--------', '┈┈┈┈'], inline='F', group = rangeGroup)
  39. showvwap = input.bool(false, 'VWAP    ', group = rangeGroup, inline='vwap')
  40. vwapCol = input.color(color.silver, '', group = rangeGroup, inline='vwap')
  41. vwapStyle = input.string('•••••••••', '', options=['•••••••••', '────'], inline='vwap', group = rangeGroup)
  42. outer = input.bool(false, 'Outer     ', inline='out', group = rangeGroup)
  43. outerCol = input.color(color.rgb(178, 181, 190, 80), '', group = rangeGroup, inline='out')
  44. outerStyle = input.string('────', '', options=['────', '--------', '┈┈┈┈'], inline='out', group = rangeGroup)
  45. extendb = input.bool(false, 'Extend (+Bars)', group = rangeGroup, inline='ex')
  46. extnmb = input.int(50, '', group = rangeGroup, inline='ex')
  47. extend = input.bool(false, 'Extend Right', group = rangeGroup, inline='opt')
  48. labels = input.bool(true, 'Show Labels', group = rangeGroup, inline='opt')
  49. dirline = input.bool(false, 'Diagonal Line', group = rangeGroup, inline='dd')
  50. stats = input.bool(false, 'Stats (Soon)', group = rangeGroup, inline='dd')
  51.  
  52. // Volume Profile inputs
  53. voltype = input.string('Volume', 'Data Type:         ', options=['Volume', 'Open Interest'], group=vpGroup, inline='vp1', tooltip = dtatyptip)
  54. res = input.int(30, 'Resolution', minval=5, tooltip=rstip, group=vpGroup)
  55. showProf = input.bool(false, 'Volume/OI Profile    ', group=vpGroup, inline = 'vpm')
  56. bullCol = input.color(color.rgb(76, 175, 79, 50), '', group=vpGroup, inline='vpm')
  57. bearCol = input.color(color.rgb(255, 82, 82, 50), '', group=vpGroup, inline='vpm')
  58. volhm = input.bool(false, 'Vertical Heatmap    ', group = vpGroup, inline = 'vhm')
  59. hvolhm = input.bool(false, 'Horizontal Heatmap ', group = vpGroup, inline = 'hhm')
  60. vhmcol1 = input.color(color.rgb(33, 149, 243, 100), '', group=vpGroup, inline='vhm')
  61. vhmcol2 = input.color(color.rgb(20, 94, 255, 63), '', group=vpGroup, inline='vhm')
  62. hhmcol1 = input.color(color.rgb(33, 149, 243, 100), '', group=vpGroup, inline='hhm')
  63. hhmcol2 = input.color(color.rgb(20, 94, 255, 63), '', group=vpGroup, inline='hhm')
  64. volnodes = input.string('Up/Down', 'Node Type', options = ['Up/Down', 'Total', 'Delta'], group=vpGroup, tooltip = volndtip)
  65. profilepos = input.string('Left', 'Profile Position', options=['Left', 'Right'], group=vpGroup, tooltip = prfpostip)
  66. profiledir = input.string('Right', 'Profile Direction', options=['Left', 'Right'], group=vpGroup, tooltip = prfdirtip)
  67. profiletype = input.string('Type 1', 'Profile Type', options=['Type 1', 'Type 2'], group=vpGroup, tooltip = ndtytip)
  68. nodesize = input.float(30, 'Node Size (%)', minval=1, maxval = 600, step = 5, group=vpGroup, tooltip = nstip)
  69. VApct = input.float(70.0, 'Value Area (%)', minval=1, maxval = 100, step=1, group=vpGroup, tooltip = vapcttip)
  70. volval = input.bool(false, 'Profile Node Values', group=vpGroup, inline = 'vl')
  71. hmval = input.bool(false, 'Heatmap Node Values', group=vpGroup, inline='vl')
  72. showPoc = input.bool(false, 'POC      ', group=vpGroup, inline='poc')
  73. pocCol = input.color(color.maroon, '', inline='poc', group=vpGroup)
  74. pocStyle = input.string('────', '', options=['────', '--------', '┈┈┈┈'], inline='poc', group = vpGroup)
  75. showVAH = input.bool(false, 'VAH      ', group=vpGroup, inline='vah')
  76. vahCol = input.color(color.rgb(255, 153, 0, 36), '', inline='vah', group=vpGroup)
  77. vahStyle = input.string('────', '', options=['────', '--------', '┈┈┈┈'], inline='vah', group = vpGroup)
  78. showVAL = input.bool(false, 'VAL       ', group=vpGroup, inline='val')
  79. valCol = input.color(color.rgb(255, 153, 0, 36), '', inline='val', group=vpGroup)
  80. valStyle = input.string('────', '', options=['────', '--------', '┈┈┈┈'], inline='val', group = vpGroup)
  81. showVAbox = input.bool(false, 'VA        ', group=vpGroup, inline='vb')
  82. VAboxCol = input.color(color.rgb(2, 68, 122, 85), '', group=vpGroup, inline='vb')
  83. netcol1 = input.color(color.blue, 'Total Volume', group=vpGroup, inline='ttv')
  84. netcol2 = input.color(color.red, '', group=vpGroup, inline='ttv')
  85. smoothVol = input.bool(false, 'Smooth Volume Data', tooltip=svtip, group=vpGroup)
  86. ndsize = input.string('Auto', 'Node Text Style     ', options = ['Tiny', 'Small', 'Normal', 'Large', 'Auto'], group= 'Additional Settings', inline = 'nds')
  87. ndpos = input.string('Center', '', options = ['Left', 'Right', 'Center'], group= 'Additional Settings', inline = 'nds')
  88. lblsize = input.string('Small', 'Label Text Style     ', options = ['Tiny', 'Small', 'Normal', 'Large', 'Auto'], group= 'Additional Settings', inline = 'lbls')
  89. lblpos = input.string('Right', '', options=['Right', 'Left'], group= 'Additional Settings', inline = 'lbls')
  90. hmsize = input.string('Auto', 'Heatmap Text Style ', options = ['Tiny', 'Small', 'Normal', 'Large', 'Auto'], group= 'Additional Settings', inline = 'hms')
  91. hmpos = input.string('Left', '', options = ['Left', 'Right', 'Center'], group= 'Additional Settings', inline = 'hms')
  92. profbuff = input.int(10, 'Profile Node Buffer',minval = 3,maxval = 12, group= 'Additional Settings')
  93. hmbuff = input.int(1, 'Profile Node Buffer', minval = 1,maxval = 10, group= 'Additional Settings')
  94. showRB = input.bool(false, 'Range Box', inline='rb', group= 'Additional Settings')
  95. rangebCol = input.color(color.rgb(178, 181, 190, 98), '', inline='rb', group= 'Additional Settings')
  96.  
  97. startTime = input.time(defval=0, title='Start Time', confirm=true, group=timeGroup)
  98. endTime = input.time(defval=0, title='End Time', confirm=true, group=timeGroup)
  99.  
  100. //
  101. bool inZone = time >= startTime and time <= endTime
  102. bool newSession = inZone and not inZone[1]
  103. bool endSession = not inZone and inZone[1]
  104.  
  105. var int barsInSession = 0
  106. var int zoneStartIndex = 0
  107. var int zoneEndIndex = 0
  108. var int zoneStart = 0
  109. barsInSession := inZone ? barsInSession + 1 : barsInSession
  110.  
  111. if newSession
  112. zoneStartIndex := bar_index
  113. if endSession
  114. zoneEndIndex := bar_index
  115. int lookback = bar_index - zoneStart
  116. var activeZone = false
  117.  
  118. //
  119. highest = rangemax=='Range Max: Wick' ? high : rangemax=='Range Max: Close' ? close : rangemax=='Range Max: HLC3' ? hlc3 : ohlc4
  120. lowest = rangemax=='Range Max: Wick' ? low : rangemax=='Range Max: Close' ? close : rangemax=='Range Max: HLC3' ? hlc3 : ohlc4
  121. profHigh = ta.highest(highest, barsInSession+1)[1]
  122. profLow = ta.lowest(lowest, barsInSession+1)[1]
  123. resolution = res
  124.  
  125. //
  126. var vpGreen = array.new_float(resolution, 0)
  127. var vpRed = array.new_float(resolution, 0)
  128. var zoneBounds = array.new_float(resolution, 0)
  129.  
  130. //
  131. var float[] ltfOpen = array.new_float(0)
  132. var float[] ltfClose = array.new_float(0)
  133. var float[] ltfHigh = array.new_float(0)
  134. var float[] ltfLow = array.new_float(0)
  135. var float[] ltfVolume = array.new_float(0)
  136.  
  137. //
  138. string userSymbol = syminfo.prefix + ":" + syminfo.ticker
  139. string openInterestTicker = str.format("{0}_OI", userSymbol)
  140. string timeframe = syminfo.type == "futures" and timeframe.isintraday ? "1D" : timeframe.period
  141. deltaOi = request.security(openInterestTicker, timeframe, close-close[1], ignore_invalid_symbol = true)
  142. oi = request.security(openInterestTicker, timeframe.period, close, ignore_invalid_symbol = true)
  143. pldeltaoi = deltaOi
  144.  
  145. //
  146. vol() =>
  147. out = smoothVol ? ta.ema(volume, 5) : volume
  148. if voltype == 'Open Interest'
  149. out := deltaOi
  150. out
  151.  
  152. //
  153. float dO = open
  154. float dC = close
  155. float dH = high
  156. float dL = low
  157. float dV = vol()
  158.  
  159. //
  160. switchLineStyle(x) =>
  161. switch x
  162. '────' => line.style_solid
  163. '--------' => line.style_dashed
  164. '┈┈┈┈' => line.style_dotted
  165.  
  166. switchPos(x) =>
  167. switch x
  168. 'Left' => text.align_left
  169. 'Right' => text.align_right
  170. 'Center' => text.align_center
  171.  
  172. switchPlotStyle(x) =>
  173. switch x
  174. '•••••••••' => plot.style_circles
  175. '────' => plot.style_linebr
  176.  
  177. switchsize(x) =>
  178. switch x
  179. 'Tiny' => size.tiny
  180. 'Small' => size.small
  181. 'Normal' => size.normal
  182. 'Large' => size.large
  183. 'Auto' => size.auto
  184.  
  185. //
  186. resetProfile(enable) =>
  187. if enable
  188. array.fill(vpGreen, 0)
  189. array.fill(vpRed, 0)
  190. array.clear(ltfOpen)
  191. array.clear(ltfHigh)
  192. array.clear(ltfLow)
  193. array.clear(ltfClose)
  194. array.clear(ltfVolume)
  195.  
  196.  
  197. tr = ta.atr(1)
  198. atr = ta.atr(14)
  199.  
  200. get_vol(y11, y12, y21, y22, height, vol) =>
  201. nz(math.max(math.min(math.max(y11, y12), math.max(y21, y22)) - math.max(math.min(y11, y12), math.min(y21, y22)), 0) * vol / height)
  202.  
  203. profileAdd(o, h, l, c, v, g, w) =>
  204. for i = 0 to array.size(vpGreen) - 1
  205. zoneTop = array.get(zoneBounds, i)
  206. zoneBot = zoneTop - g
  207.  
  208. body_top = math.max(c, o)
  209. body_bot = math.min(c, o)
  210. itsgreen = c >= o
  211.  
  212. topwick = h - body_top
  213. bottomwick = body_bot - l
  214. body = body_top - body_bot
  215. bodyvol = body * v / (2 * topwick + 2 * bottomwick + body)
  216. topwickvol = 2 * topwick * v / (2 * topwick + 2 * bottomwick + body)
  217. bottomwickvol = 2 * bottomwick * v / (2 * topwick + 2 * bottomwick + body)
  218.  
  219. if voltype == 'Volume'
  220. array.set(vpGreen, i, array.get(vpGreen, i) + (itsgreen ? get_vol(zoneBot, zoneTop, body_bot, body_top, body, bodyvol) : 0) + get_vol(zoneBot, zoneTop, body_top, h, topwick, topwickvol) / 2 + get_vol(zoneBot, zoneTop, body_bot, l, bottomwick, bottomwickvol) / 2)
  221. array.set(vpRed, i, array.get(vpRed, i) + (itsgreen ? 0 : get_vol(zoneBot, zoneTop, body_bot, body_top, body, bodyvol)) + get_vol(zoneBot, zoneTop, body_top, h, topwick, topwickvol) / 2 + get_vol(zoneBot, zoneTop, body_bot, l, bottomwick, bottomwickvol) / 2)
  222. else if voltype == 'Open Interest'
  223. if v > 0
  224. array.set(vpGreen, i, array.get(vpGreen, i) + get_vol(zoneBot, zoneTop, body_bot, body_top, body, v))// + get_vol(zoneBot, zoneTop, body_top, h, topwick, topwickvol) / 2 + get_vol(zoneBot, zoneTop, body_bot, l, bottomwick, bottomwickvol) / 2)
  225. if v < 0
  226. array.set(vpRed, i, array.get(vpRed, i) + get_vol(zoneBot, zoneTop, body_bot, body_top, body, -v))// + get_vol(zoneBot, zoneTop, body_top, h, topwick, topwickvol) / 2 + get_vol(zoneBot, zoneTop, body_bot, l, bottomwick, bottomwickvol) / 2)
  227. calcSession(update) =>
  228. array.fill(vpGreen, 0)
  229. array.fill(vpRed, 0)
  230. if bar_index > lookback and update and (showPoc or showProf or showVAbox or showVAH or showVAL or hvolhm)
  231. gap = (profHigh - profLow) / resolution
  232.  
  233. for i = 0 to resolution - 1
  234. array.set(zoneBounds, i, profHigh - gap * i)
  235.  
  236. if array.size(ltfOpen) > 0
  237. for j = 0 to array.size(ltfOpen) - 1
  238. profileAdd(array.get(ltfOpen, j), array.get(ltfHigh, j), array.get(ltfLow, j), array.get(ltfClose, j), array.get(ltfVolume, j), gap, 1)
  239.  
  240. pocLevel() =>
  241. float maxVol = 0
  242. int levelInd = 0
  243. for i = 0 to array.size(vpRed) - 1
  244. if array.get(vpRed, i) + array.get(vpGreen, i) > maxVol
  245. maxVol := array.get(vpRed, i) + array.get(vpGreen, i)
  246. levelInd := i
  247.  
  248. float outLevel = na
  249. if levelInd != array.size(vpRed) - 1
  250. outLevel := array.get(zoneBounds, levelInd) - (array.get(zoneBounds, levelInd) - array.get(zoneBounds, levelInd+1)) / 2
  251. outLevel
  252.  
  253. valueLevels(poc) =>
  254. float gap = (profHigh - profLow) / resolution
  255. float volSum = array.sum(vpRed) + array.sum(vpGreen)
  256. float volCnt = 0
  257.  
  258. float vah = profHigh
  259. float val = profLow
  260.  
  261. int pocInd = 0
  262. for i = 0 to array.size(zoneBounds)-2
  263. if array.get(zoneBounds, i) >= poc and array.get(zoneBounds, i + 1) < poc
  264. pocInd := i
  265.  
  266. volCnt += (array.get(vpRed, pocInd) + array.get(vpGreen, pocInd))
  267. for i = 1 to array.size(vpRed)
  268. if pocInd + i >= 0 and pocInd + i < array.size(vpRed)
  269. volCnt += (array.get(vpRed, pocInd + i) + array.get(vpGreen, pocInd + i))
  270. if volCnt >= volSum * (VApct/100)
  271. break
  272. else
  273. val := array.get(zoneBounds, pocInd + i) - gap
  274. if pocInd - i >= 0 and pocInd - i < array.size(vpRed)
  275. volCnt += (array.get(vpRed, pocInd - i) + array.get(vpGreen, pocInd - i))
  276. if volCnt >= volSum * (VApct/100)
  277. break
  278. else
  279. vah := array.get(zoneBounds, pocInd - i)
  280.  
  281. [val, vah]
  282.  
  283. //
  284. half = (profHigh+profLow) / 2
  285. l75 = (half + profHigh) / 2
  286. l25 = (half + profLow) / 2
  287. l125 = (profLow+l25) / 2
  288. l375 = (half + l25) / 2
  289. l625 = (half + l75) / 2
  290. l875 = (l75 + profHigh) / 2
  291.  
  292. f618 = dir=='UP' ? (profHigh - ((profHigh-profLow) * 0.618)) : (profLow + ((profHigh-profLow) * 0.618))
  293. f236 = dir=='UP' ? (profHigh - ((profHigh-profLow) * 0.236)) : (profLow + ((profHigh-profLow) * 0.236))
  294. f382 = dir=='UP' ? (profHigh - ((profHigh-profLow) * 0.382)) : (profLow + ((profHigh-profLow) * 0.382))
  295. f786 = dir=='UP' ? (profHigh - ((profHigh-profLow) * 0.786)) : (profLow + ((profHigh-profLow) * 0.786))
  296. f161 = dir=='UP' ? (profHigh - ((profHigh-profLow) * 1.618)) : (profLow + ((profHigh-profLow) * 1.618))
  297. f261 = dir=='UP' ? (profHigh - ((profHigh-profLow) * 2.618)) : (profLow + ((profHigh-profLow) * 2.618))
  298.  
  299. //
  300. f_newLine(condition,x, y, c, w, s) =>
  301. condition ? line.new(x, y, extendb ? bar_index+extnmb : bar_index, y, color=c, width=w, style=switchLineStyle(s), extend = extend ? extend.right : extend.none) : na
  302. f_newLabel(condition, x, y, txt, txtcl) =>
  303. condition ? label.new(extend ? x : (lblpos=='Right' ? (extendb ? bar_index+extnmb+1 : bar_index+1) : x), y, text=txt, color=color.rgb(255, 255, 255, 100), textcolor = txtcl, style = extend or lblpos=='Left' ? label.style_label_right : label.style_label_left, size=switchsize(lblsize)) : na
  304. f_newNode(condition, x, top, right, bott, col, txt) =>
  305. condition ? box.new(x, top, right, bott, bgcolor=col, border_width=0, text= volval ? txt : na,xloc=xloc.bar_index, text_size = switchsize(ndsize), text_color = chart.fg_color, text_halign = switchPos(ndpos)) : na
  306. f_newHeatmap(condition, x, top, right, bott, col, txt) =>
  307. condition ? box.new(x, top, right, bott, bgcolor=col, border_width=0, text= hmval ? txt : na,xloc=xloc.bar_index, text_size = switchsize(hmsize), text_color = chart.fg_color, text_halign = switchPos(hmpos)) : na
  308.  
  309. drawNewZone(update) =>
  310. var box [] profileBoxesArray = array.new_box(0)
  311. var line [] levelsLinesArray = array.new_line(0)
  312. var box [] boxes = array.new_box(0)
  313. var line [] RangeLinesArray = array.new_line(0)
  314. var label[] levelLabels = array.new_label(0)
  315.  
  316. float leftMax = zoneStartIndex
  317. float rightMax = (((barstate.islast and inZone) ? bar_index : zoneEndIndex) - zoneStartIndex) * (nodesize/100) + zoneStartIndex
  318.  
  319. if update and array.sum(vpGreen) + array.sum(vpRed) > 0
  320. gap = (profHigh - profLow) / resolution
  321. gap2 = (profHigh - profLow) / 10
  322. float rightMaxVol = array.max(vpGreen)+array.max(vpRed)
  323. float buffer = gap / profbuff
  324. float buffer2 = gap / hmbuff
  325. if showProf or hvolhm
  326. size = array.size(profileBoxesArray)
  327. if size > 0
  328. for j = 0 to size - 1
  329. box.delete(array.get(profileBoxesArray, size - 1 - j))
  330. array.remove(profileBoxesArray, size - 1 - j)
  331.  
  332. for i = 0 to array.size(vpRed) - 1
  333. vpct = array.percentrank(vpGreen, i)/100
  334. netcol = color.from_gradient(vpct, 0, 1, netcol1, netcol2)
  335. hmcol = color.from_gradient(vpct, 0, 1, hhmcol1, hhmcol2)
  336. gleft = profilepos=='Left' ? leftMax : bar_index[0]
  337. greenEnd = int(leftMax + (rightMax - leftMax) * (array.get(vpGreen, i) / rightMaxVol))
  338. greenEndD = int(gleft - (rightMax - leftMax) * (array.get(vpGreen, i) / rightMaxVol))
  339. greenEnd2 = int(bar_index[0] + (rightMax - leftMax) * (array.get(vpGreen, i) / rightMaxVol))
  340. redEnd = int(greenEnd + (rightMax - leftMax) * (array.get(vpRed, i) / rightMaxVol))
  341. redEndD = int(greenEndD - (rightMax - leftMax) * (array.get(vpRed, i) / rightMaxVol))
  342. redEnd2 = int(greenEnd2 + (rightMax - leftMax) * (array.get(vpRed, i) / rightMaxVol))
  343. redEnd3 = int(int(leftMax) - (rightMax - leftMax) * (array.get(vpRed, i) / rightMaxVol))
  344. redEnd4 = int(bar_index[0] - (rightMax - leftMax) * (array.get(vpRed, i) / rightMaxVol))
  345. total = int(leftMax + ((rightMax - leftMax) * (array.get(vpGreen, i) / rightMaxVol)) + (rightMax - leftMax) * (array.get(vpRed, i) / rightMaxVol))
  346. totalD = int(gleft - ((rightMax - leftMax) * (array.get(vpGreen, i) / rightMaxVol)) - (rightMax - leftMax) * (array.get(vpRed, i) / rightMaxVol))
  347. total2 = int(bar_index[0] + ((rightMax - leftMax) * (array.get(vpGreen, i) / rightMaxVol)) + (rightMax - leftMax) * (array.get(vpRed, i) / rightMaxVol))
  348. delta = array.get(vpGreen, i)-array.get(vpRed, i)
  349. deltap = (int(gleft + (rightMax - leftMax) * (math.abs(array.get(vpGreen, i)-array.get(vpRed, i)) / rightMaxVol)))
  350. deltap2 = (int(gleft - (rightMax - leftMax) * (math.abs(array.get(vpGreen, i)-array.get(vpRed, i)) / rightMaxVol)))
  351. totvol = str.tostring(array.get(vpGreen, i) + (voltype=='Volume' ? array.get(vpRed, i) : 0), format.volume)
  352. hmvoloi = str.tostring(array.get(vpGreen, i) - array.get(vpRed, i) , format.volume)
  353. gvol = str.tostring(array.get(vpGreen, i), format.volume)
  354. rvol = str.tostring(array.get(vpRed, i), format.volume)
  355. dvol = str.tostring(delta, format.volume)
  356. if profilepos=='Left' and showProf
  357. array.push(profileBoxesArray, f_newNode(volnodes=='Up/Down', int(leftMax), array.get(zoneBounds, i) - buffer, profiledir=='Right' ? greenEnd : greenEndD, array.get(zoneBounds, i) - gap + buffer, bullCol, gvol))
  358. array.push(profileBoxesArray, f_newNode(volnodes=='Up/Down' and profiletype=='Type 1', profiledir=='Right' ? greenEnd : greenEndD, array.get(zoneBounds, i) - buffer, profiledir=='Right' ? redEnd : redEndD, array.get(zoneBounds, i) - gap + buffer, bearCol, rvol))
  359. array.push(profileBoxesArray, f_newNode(volnodes=='Up/Down' and profiletype=='Type 2', int(leftMax), array.get(zoneBounds, i) - buffer, redEnd3, array.get(zoneBounds, i) - gap + buffer, bearCol, rvol))
  360. array.push(profileBoxesArray, f_newNode(volnodes=='Total', int(leftMax), array.get(zoneBounds, i) - buffer, profiledir=='Right' ? total : totalD, array.get(zoneBounds, i) - gap + buffer, netcol, totvol))
  361. array.push(profileBoxesArray, f_newNode(volnodes=='Delta' and profiletype=='Type 1', int(leftMax), array.get(zoneBounds, i) - buffer, deltap, array.get(zoneBounds, i) - gap + buffer, delta>0 ? bullCol : bearCol, dvol))
  362. array.push(profileBoxesArray, f_newNode(volnodes=='Delta' and profiletype=='Type 2', int(leftMax), array.get(zoneBounds, i) - buffer, delta>0 ? deltap : deltap2, array.get(zoneBounds, i) - gap + buffer, delta>0 ? bullCol : bearCol, dvol))
  363.  
  364.  
  365. if profilepos=='Right' and showProf
  366. array.push(profileBoxesArray, f_newNode(volnodes=='Up/Down', bar_index[0], array.get(zoneBounds, i) - buffer, profiledir=='Right' ? greenEnd2 : greenEndD, array.get(zoneBounds, i) - gap + buffer, bullCol, gvol))
  367. array.push(profileBoxesArray, f_newNode(volnodes=='Up/Down' and profiletype=='Type 1', profiledir=='Right' ? greenEnd2 : greenEndD , array.get(zoneBounds, i) - buffer, profiledir=='Right' ? redEnd2 : redEndD, array.get(zoneBounds, i) - gap + buffer, bearCol, rvol))
  368. array.push(profileBoxesArray, f_newNode(volnodes=='Up/Down' and profiletype=='Type 2', bar_index[0], array.get(zoneBounds, i) - buffer, redEnd4, array.get(zoneBounds, i) - gap + buffer, bearCol, rvol))
  369. array.push(profileBoxesArray, f_newNode(volnodes=='Total', bar_index[0], array.get(zoneBounds, i) - buffer, profiledir=='Right' ? total2 : totalD, array.get(zoneBounds, i) - gap + buffer, netcol, totvol))
  370. array.push(profileBoxesArray, f_newNode(volnodes=='Delta' and profiletype=='Type 1', int(gleft), array.get(zoneBounds, i) - buffer, deltap, array.get(zoneBounds, i) - gap + buffer, delta>0 ? bullCol : bearCol, dvol))
  371. array.push(profileBoxesArray, f_newNode(volnodes=='Delta' and profiletype=='Type 2', int(gleft), array.get(zoneBounds, i) - buffer, delta>0 ? deltap : deltap2, array.get(zoneBounds, i) - gap + buffer, delta>0 ? bullCol : bearCol, dvol))
  372. if hvolhm
  373. array.push(profileBoxesArray, f_newHeatmap(true, int(leftMax), array.get(zoneBounds, i) - buffer2, bar_index, array.get(zoneBounds, i) - gap + buffer2, hmcol, voltype=='Volume' ? totvol : hmvoloi))
  374.  
  375.  
  376. if showHL
  377. line.new(int(leftMax), profHigh, extendb ? bar_index+extnmb : bar_index, profHigh, color=hlCol, width=1, style=line.style_solid, extend = extend ? extend.right : extend.none)
  378. line.new(int(leftMax), profLow, extendb ? bar_index+extnmb : bar_index, profLow, color=hlCol, width=1, style=line.style_solid, extend = extend ? extend.right : extend.none)
  379. if lvl05 or quarters or eighths
  380. f_newLine(true,int(leftMax), half, lvl05Col, 1, lvl05Style)
  381. if quarters or eighths
  382. f_newLine(true,int(leftMax), l75, quartersCol, 1, quartersStyle)
  383. f_newLine(true,int(leftMax), l25, quartersCol, 1, quartersStyle)
  384. if eighths
  385. f_newLine(true,int(leftMax), l125, eighthsCol, 1, eighthsStyle)
  386. f_newLine(true,int(leftMax), l375, eighthsCol, 1, eighthsStyle)
  387. f_newLine(true,int(leftMax), l625, eighthsCol, 1, eighthsStyle)
  388. f_newLine(true,int(leftMax), l875, eighthsCol, 1, eighthsStyle)
  389. if outer
  390. f_newLine(quarters or eighths,int(leftMax), profLow - (l25-profLow), outerCol, 1, outerStyle)
  391. f_newLine(quarters or eighths,int(leftMax), profLow - (half-profLow), outerCol, 1, outerStyle)
  392. f_newLine(quarters or eighths,int(leftMax), profHigh + (l25-profLow), outerCol, 1, outerStyle)
  393. f_newLine(quarters or eighths,int(leftMax), profHigh + (half-profLow), outerCol, 1, outerStyle)
  394. f_newLine(eighths,int(leftMax), profHigh + (l125-profLow), outerCol, 1, outerStyle)
  395. f_newLine(eighths,int(leftMax), profHigh + (l375-profLow), outerCol, 1, outerStyle)
  396. f_newLine(eighths,int(leftMax), profLow - (l125-profLow), outerCol, 1, outerStyle)
  397. f_newLine(eighths,int(leftMax), profLow - (l375-profLow), outerCol, 1, outerStyle)
  398. f_newLine(fib,int(leftMax), f161, fibCol, 1, fibStyle)
  399. f_newLine(fib,int(leftMax), f261, fibCol, 1, fibStyle)
  400. if fib
  401. f_newLine(true,int(leftMax), f618, fibCol, 1, fibStyle)
  402. f_newLine(true,int(leftMax), f236, fibCol, 1, fibStyle)
  403. f_newLine(true,int(leftMax), f382, fibCol, 1, fibStyle)
  404. f_newLine(true,int(leftMax), f786, fibCol, 1, fibStyle)
  405. if dirline
  406. line.new(int(leftMax), dir=='UP' ? profLow : profHigh, bar_index, dir=='UP' ? profHigh : profLow, color=fibCol, width = 1, style=switchLineStyle(fibStyle), extend = extend ? extend.right : extend.none)
  407. if labels
  408. f_newLabel(lvl05, int(leftMax), half, '0.5', hlCol)
  409. f_newLabel(fib, int(leftMax), f618, '0.618', fibCol)
  410. f_newLabel(fib, int(leftMax), f236, '0.236', fibCol)
  411. f_newLabel(fib, int(leftMax), f382, '0.382', fibCol)
  412. f_newLabel(fib, int(leftMax), f786, '0.786', fibCol)
  413. f_newLabel(showHL, int(leftMax), profHigh, dir=='UP' ? '0' : '1', hlCol)
  414. f_newLabel(showHL, int(leftMax), profLow, dir=='UP' ? '1' : '0', hlCol)
  415. f_newLabel(quarters, int(leftMax), l75, dir=='UP' ? '0.25' : '0.75', hlCol)
  416. f_newLabel(quarters, int(leftMax), l25, dir=='UP' ? '0.75' : '0.25', hlCol)
  417.  
  418. poc = pocLevel()
  419. [val, vah] = valueLevels(poc)
  420. if showPoc or showVAbox or showVAL or showVAH
  421. size = array.size(levelsLinesArray)
  422. if size > 0
  423. for j = 0 to size - 1
  424. line.delete(array.get(levelsLinesArray, size - 1 - j))
  425. array.remove(levelsLinesArray, size - 1 - j)
  426. if showPoc
  427. array.push(levelsLinesArray, line.new(int(leftMax), poc, extendb ? bar_index+extnmb : bar_index, poc, color=pocCol, width=1, xloc=xloc.bar_index, extend = extend ? extend.right : extend.none, style = switchLineStyle(pocStyle)))
  428. if showVAH
  429. array.push(levelsLinesArray, line.new(int(leftMax), vah, extendb ? bar_index+extnmb : bar_index, vah, color=vahCol, width=1, xloc=xloc.bar_index, extend = extend ? extend.right : extend.none, style = switchLineStyle(vahStyle)))
  430. if showVAL
  431. array.push(levelsLinesArray, line.new(int(leftMax), val, extendb ? bar_index+extnmb : bar_index, val, color=valCol, width=1, xloc=xloc.bar_index, extend = extend ? extend.right : extend.none, style = switchLineStyle(valStyle)))
  432. if showVAbox
  433. array.push(boxes, box.new(int(leftMax), vah, extendb ? bar_index+extnmb : bar_index, val, bgcolor=VAboxCol,border_color = na, xloc=xloc.bar_index, extend = extend ? extend.right : extend.none))
  434.  
  435. if update and (showHL or dirline or lvl05 or quarters or eighths or outer or fib or labels)
  436. size = array.size(RangeLinesArray)
  437. if size > 0
  438. for j = 0 to size - 1
  439. line.delete(array.get(RangeLinesArray, size - 1 - j))
  440. label.delete(array.get(levelLabels, size - 1 - j))
  441. array.remove(RangeLinesArray, size - 1 - j)
  442. array.remove(RangeLinesArray, size - 1 - j)
  443. array.push(RangeLinesArray, showHL ? line.new(int(leftMax), profHigh, extendb ? bar_index+extnmb : bar_index, profHigh, color=hlCol, width=1, style=line.style_solid, extend = extend ? extend.right : extend.none) : na)
  444. array.push(RangeLinesArray, showHL ? line.new(int(leftMax), profLow, extendb ? bar_index+extnmb : bar_index, profLow, color=hlCol, width=1, style=line.style_solid, extend = extend ? extend.right : extend.none) : na)
  445. array.push(RangeLinesArray, dirline ? line.new(int(leftMax), dir=='UP' ? profLow : profHigh, bar_index, dir=='UP' ? profHigh : profLow, color=fibCol, width = 1, style=switchLineStyle(fibStyle), extend = extend ? extend.right : extend.none) : na)
  446. array.push(RangeLinesArray, lvl05 or quarters or eighths ? f_newLine(true,int(leftMax), half, lvl05Col, 1, lvl05Style) : na)
  447. array.push(RangeLinesArray, quarters or eighths ? f_newLine(true,int(leftMax), l75, quartersCol, 1, quartersStyle) : na)
  448. array.push(RangeLinesArray, quarters or eighths ? f_newLine(true,int(leftMax), l25, quartersCol, 1, quartersStyle) : na)
  449. array.push(RangeLinesArray, eighths ? f_newLine(true,int(leftMax), l125, eighthsCol, 1, eighthsStyle) : na)
  450. array.push(RangeLinesArray, eighths ? f_newLine(true,int(leftMax), l375, eighthsCol, 1, eighthsStyle) : na)
  451. array.push(RangeLinesArray, eighths ? f_newLine(true,int(leftMax), l625, eighthsCol, 1, eighthsStyle) : na)
  452. array.push(RangeLinesArray, eighths ? f_newLine(true,int(leftMax), l875, eighthsCol, 1, eighthsStyle) : na)
  453. array.push(RangeLinesArray, outer and (quarters or eighths) ? f_newLine(true,int(leftMax), profLow - (l25-profLow), outerCol, 1, outerStyle) : na)
  454. array.push(RangeLinesArray, outer and (quarters or eighths) ? f_newLine(true,int(leftMax), profLow - (half-profLow), outerCol, 1, outerStyle) : na)
  455. array.push(RangeLinesArray, outer and (quarters or eighths) ? f_newLine(true,int(leftMax), profHigh + (l25-profLow), outerCol, 1, outerStyle) : na)
  456. array.push(RangeLinesArray, outer and eighths ? f_newLine(true,int(leftMax), profLow - (l375-profLow), outerCol, 1, outerStyle) : na)
  457. array.push(RangeLinesArray, outer and eighths ? f_newLine(true,int(leftMax), profLow - (l125-profLow), outerCol, 1, outerStyle) : na)
  458. array.push(RangeLinesArray, outer and (quarters or eighths) ? f_newLine(true,int(leftMax), profHigh + (half-profLow), outerCol, 1, outerStyle) : na)
  459. array.push(RangeLinesArray, outer and eighths ? f_newLine(true,int(leftMax), profHigh + (l125-profLow), outerCol, 1, outerStyle) : na)
  460. array.push(RangeLinesArray, outer and eighths ? f_newLine(true,int(leftMax), profHigh + (l375-profLow), outerCol, 1, outerStyle) : na)
  461. array.push(RangeLinesArray, outer and fib ? f_newLine(true,int(leftMax), f161, fibCol, 1, fibStyle) : na)
  462. array.push(RangeLinesArray, outer and fib ? f_newLine(true,int(leftMax), f261, fibCol, 1, fibStyle) : na)
  463. array.push(RangeLinesArray, fib ? f_newLine(true,int(leftMax), f618, fibCol, 1, fibStyle) : na)
  464. array.push(RangeLinesArray, fib ? f_newLine(true,int(leftMax), f236, fibCol, 1, fibStyle) : na)
  465. array.push(RangeLinesArray, fib ? f_newLine(true,int(leftMax), f382, fibCol, 1, fibStyle) : na)
  466. array.push(RangeLinesArray, fib ? f_newLine(true,int(leftMax), f786, fibCol, 1, fibStyle) : na)
  467. array.push(levelLabels, labels and fib ? f_newLabel(true,int(leftMax), f618, '0.618', hlCol) : na)
  468. array.push(levelLabels, labels and fib ? f_newLabel(true,int(leftMax), f236, '0.236', hlCol) : na)
  469. array.push(levelLabels, labels and fib ? f_newLabel(true,int(leftMax), f382, '0.382', hlCol) : na)
  470. array.push(levelLabels, labels and fib ? f_newLabel(true,int(leftMax), f786, '0.786', hlCol) : na)
  471. array.push(levelLabels, labels and lvl05 ? f_newLabel(true,int(leftMax), half, '0.5', hlCol) : na)
  472. array.push(levelLabels, labels and showHL ? f_newLabel(true,int(leftMax), profHigh, dir=='UP' ? '0' : '1', hlCol) : na)
  473. array.push(levelLabels, labels and showHL ? f_newLabel(true,int(leftMax), profLow, dir=='UP' ? '1' : '0', hlCol) : na)
  474. array.push(levelLabels, labels and quarters ? f_newLabel(true,int(leftMax), l25, dir=='UP' ? '0.75' : '0.25', hlCol) : na)
  475. array.push(levelLabels, labels and quarters ? f_newLabel(true,int(leftMax), l75, dir=='UP' ? '0.25' : '0.75', hlCol) : na)
  476. array.push(boxes, showRB ? box.new(zoneStartIndex, profHigh, bar_index, profLow, border_color=na, bgcolor = rangebCol) : na)
  477.  
  478. //
  479. combArray(arr1, arr2) =>
  480. out = array.copy(arr1)
  481. if array.size(arr2) > 0
  482. for i = 0 to array.size(arr2) - 1
  483. array.push(out, array.get(arr2, i))
  484. out
  485.  
  486. //
  487. updateIntra(o, h, l, c, v) =>
  488. array.push(ltfOpen, o)
  489. array.push(ltfHigh, h)
  490. array.push(ltfLow, l)
  491. array.push(ltfClose, c)
  492. array.push(ltfVolume, v)
  493.  
  494. //
  495. calcSession(endSession or (barstate.islast and inZone))
  496. drawNewZone(endSession or (barstate.islast and inZone))
  497. resetProfile(newSession)
  498.  
  499. //
  500. if inZone
  501. updateIntra(dO, dH, dL, dC, dV)
  502. if endSession
  503. activeZone := false
  504. if newSession
  505. zoneStart := bar_index
  506. activeZone := true
  507.  
  508. //
  509. startCalculationDate = startTime
  510. vwap_calc() =>
  511. var srcVolArray = array.new_float(na)
  512. var volArray = array.new_float(na)
  513. if startCalculationDate <= time
  514. array.push(srcVolArray, hlc3*volume)
  515. array.push(volArray, volume)
  516. else
  517. array.clear(srcVolArray), array.clear(volArray)
  518. array.sum(srcVolArray)/array.sum(volArray)
  519. anchoredVwap = vwap_calc()
  520.  
  521. plot((extend ? true : inZone) and showvwap ? anchoredVwap : na, "VWAP", linewidth=1, color=vwapCol, style = switchPlotStyle(vwapStyle), editable=false)
  522.  
  523. //
  524. vhmsrc = voltype=='Volume' ? volume : deltaOi
  525. hvol = ta.highest(vhmsrc, 50)
  526. lvol = ta.lowest(vhmsrc, 50)
  527. color1 = color.from_gradient(vhmsrc, 0, hvol, vhmcol1, vhmcol2)
  528. ph = plot((extend ? true : inZone) and volhm ? profHigh : na, color= color.rgb(54, 58, 69, 100), style=plot.style_linebr)
  529. pl = plot((extend ? true : inZone) and volhm ? profLow : na, color= color.rgb(54, 58, 69, 100), style=plot.style_linebr)
  530. fill(ph, pl, color1)
  531.  
  532.  
  533.  
  534.  
Advertisement
Add Comment
Please, Sign In to add comment