xmd79

Order Blocks

Nov 12th, 2021
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.01 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. // © pmk07
  3. //
  4. // Acknowledgements/Reference:
  5. //
  6. // @rumpypumpydumpy - Higher Order Pivots
  7. // https://www.tradingview.com/v/x2LlRvBe/
  8. //
  9. // @MarkMiddleton2020 - Order Blocks
  10. // https://www.tradingview.com/v/GecN34Qq/
  11. //
  12. //@version=5
  13.  
  14. indicator(title='Order Blocks', overlay=true)
  15.  
  16. bool pv2_sv = input.bool (true, title='Plot 2nd order pivots')
  17. bool msb_sv = input.bool (true, title='Plot MSB lines')
  18. bool box_sv = input.bool (true, title='Plot Orderblocks')
  19. bool m_sv = input.bool (true, title='Plot Breakerblocks')
  20. bool range_sv = input.bool (true, title='Plot Range')
  21. bool range_eq_sv = input.bool (true, title='Plot Range 0.5 Line')
  22. bool range_q_sv = input.bool (true, title='Plot Range 0.25 and 0.75 Lines')
  23. bool log_sv = input.bool (true, title='Use Log Scale')
  24. bool msb_a_sv = input.bool (true, title='Alert MSB')
  25. bool ob_a_sv = input.bool (true, title='Alert Orderblock test')
  26. bool bb_a_sv = input.bool (true, title='Alert Breakerblock test')
  27. bool r_a_sv = input.bool (true, title='Alert New Range')
  28. bool rt_a_sv = input.bool (true, title='Alert Range test')
  29. color u_s = input.color (color.rgb(192, 192, 192, 80), title='Untested Supply Color')
  30. color t_s = input.color (color.rgb(255, 0, 0, 80), title='Tested Supply Color')
  31. color u_d = input.color (color.rgb(192, 192, 192, 80), title='Untested Demand Color')
  32. color t_d = input.color (color.rgb(0, 255, 0, 80), title='Tested Demand Color')
  33. color u_b = input.color (color.rgb(192, 192, 192, 80), title='Untested Breaker Color')
  34. color t_b = input.color (color.new(color.blue, 80), title='Tested Breaker Color')
  35.  
  36. var float[] pvh1_price = array.new_float (30, na) // high
  37. var int[] pvh1_time = array.new_int (30, na)
  38. var float[] pvl1_price = array.new_float (30, na) // low
  39. var int[] pvl1_time = array.new_int (30, na)
  40. var float[] pvh2_price = array.new_float (10, na) // higher high
  41. var int[] pvh2_time = array.new_int (10, na)
  42. var float[] pvl2_price = array.new_float (10, na) // lower low
  43. var int[] pvl2_time = array.new_int (10, na)
  44. var float htcmrll_price = na // high that created most recent ll
  45. var int htcmrll_time = na
  46. var float ltcmrhh_price = na // low that created most recent hh
  47. var int ltcmrhh_time = na
  48. var box[] long_boxes = array.new_box() // orderblocks
  49. var box[] short_boxes = array.new_box()
  50. var box[] m_long_boxes = array.new_box() // breakerblocks
  51. var box[] m_short_boxes = array.new_box()
  52. var line[] bull_bos_lines = array.new_line() // MSB lines
  53. var line[] bear_bos_lines = array.new_line()
  54. var line[] range_h_lines = array.new_line() // Range lines
  55. var line[] range_25_lines = array.new_line()
  56. var line[] range_m_lines = array.new_line()
  57. var line[] range_75_lines = array.new_line()
  58. var line[] range_l_lines = array.new_line()
  59. var label[] la_ph2 = array.new_label() // 2nd order pivots
  60. var label[] la_pl2 = array.new_label()
  61. var float temp_pv_0 = na
  62. var float temp_pv_1 = na
  63. var float temp_pv_2 = na
  64. var int temp_time = na
  65. var float last_range_h = na
  66. var float last_range_l = na
  67. var line range_m = na
  68. var line range_25 = na
  69. var line range_75 = na
  70. var float box_top = na
  71. var float box_bottom = na
  72. var int h_a_time = 0
  73. var int l_a_time = 0
  74. var int mh_a_time = 0
  75. var int ml_a_time = 0
  76. var int rh_a_time = 0
  77. var int rl_a_time = 0
  78. bool pvh = high < high[1] and high[1] > high[2]
  79. bool pvl = low > low[1] and low[1] < low[2]
  80. int pv1_time = bar_index[1]
  81. float pv1_high = high[1]
  82. float pv1_low = low[1]
  83. bool new_ph_2nd = false
  84. bool new_pl_2nd = false
  85. string alert = na
  86.  
  87. if barstate.isconfirmed
  88. if pvh
  89. array.pop(pvh1_price)
  90. array.pop(pvh1_time)
  91. array.unshift(pvh1_price, pv1_high)
  92. array.unshift(pvh1_time, pv1_time)
  93. if array.size(pvh1_price) > 2
  94. temp_pv_0 := array.get(pvh1_price, 0)
  95. temp_pv_1 := array.get(pvh1_price, 1)
  96. temp_pv_2 := array.get(pvh1_price, 2)
  97. if temp_pv_0 < temp_pv_1 and temp_pv_1 > temp_pv_2
  98. array.pop(pvh2_price)
  99. array.pop(pvh2_time)
  100. array.unshift(pvh2_price, temp_pv_1)
  101. array.unshift(pvh2_time, array.get(pvh1_time, 1))
  102. new_ph_2nd := true
  103. if temp_pv_1 > array.get(pvh2_price, 1)
  104. for i = 0 to array.size(pvl2_time) - 1 by 1
  105. temp_ltcmrhh_time = array.get(pvl2_time, i)
  106. if temp_ltcmrhh_time < array.get(pvh2_time, 0)
  107. ltcmrhh_price := array.get(pvl2_price, i)
  108. ltcmrhh_time := temp_ltcmrhh_time
  109. break
  110. if temp_pv_0 < ltcmrhh_price
  111. if msb_sv
  112. array.push(bear_bos_lines, line.new(x1=ltcmrhh_time, y1=ltcmrhh_price, x2=bar_index, y2=ltcmrhh_price, color=color.green, width=2))
  113. box_top := array.get(pvh2_price, 0)
  114. box_bottom := math.max(low[bar_index - array.get(pvh2_time, 0)], low[bar_index - array.get(pvh2_time, 0) + 1])
  115. array.push(short_boxes, box.new(left=array.get(pvh2_time, 0), top=box_top, right=bar_index, bottom=box_bottom, bgcolor= box_sv ? u_s : na , border_color=na, extend=extend.right))
  116. if msb_a_sv
  117. alert := alert + 'Bearish MSB @ ' + str.tostring(ltcmrhh_price) + '\n' + 'New Supply Zone : '+ str.tostring(box_top) + ' - ' + str.tostring(box_bottom) + '\n'
  118. ltcmrhh_price := na
  119. if pvl
  120. array.pop(pvl1_price)
  121. array.pop(pvl1_time)
  122. array.unshift(pvl1_price, pv1_low)
  123. array.unshift(pvl1_time, pv1_time)
  124. if array.size(pvl1_price) > 2
  125. temp_pv_0 := array.get(pvl1_price, 0)
  126. temp_pv_1 := array.get(pvl1_price, 1)
  127. temp_pv_2 := array.get(pvl1_price, 2)
  128. if temp_pv_0 > temp_pv_1 and temp_pv_1 < temp_pv_2
  129. array.pop(pvl2_price)
  130. array.pop(pvl2_time)
  131. array.unshift(pvl2_price, temp_pv_1)
  132. array.unshift(pvl2_time, array.get(pvl1_time, 1))
  133. new_pl_2nd := true
  134. if temp_pv_1 < array.get(pvl2_price, 1)
  135. for i = 0 to array.size(pvh2_time) - 1 by 1
  136. temp_htcmrll_time = array.get(pvh2_time, i)
  137. if temp_htcmrll_time < array.get(pvl2_time, 0)
  138. htcmrll_price := array.get(pvh2_price, i)
  139. htcmrll_time := temp_htcmrll_time
  140. break
  141. if temp_pv_0 > htcmrll_price
  142. if msb_sv
  143. array.push(bull_bos_lines, line.new(x1=htcmrll_time, y1=htcmrll_price, x2=bar_index, y2=htcmrll_price, color=color.red, width=2))
  144. box_top := math.min(high[bar_index - array.get(pvl2_time, 0)], high[bar_index - array.get(pvl2_time, 0) + 1])
  145. box_bottom := array.get(pvl2_price, 0)
  146. array.push(long_boxes, box.new(left=array.get(pvl2_time, 0), top=box_top, right=bar_index, bottom=box_bottom, bgcolor= box_sv ? u_d : na, border_color=na, extend=extend.right))
  147. if msb_a_sv
  148. alert := alert + 'Bullish MSB @ ' + str.tostring(htcmrll_price) + '\n' + 'New Demand Zone : '+ str.tostring(box_bottom) + ' - ' + str.tostring(box_top) + '\n'
  149. htcmrll_price := na
  150. if array.size(short_boxes) > 0
  151. for i = array.size(short_boxes) - 1 to 0 by 1
  152. tbox = array.get(short_boxes, i)
  153. top = box.get_top(tbox)
  154. bottom = box.get_bottom(tbox)
  155. ago = box.get_left(tbox)
  156. if array.get(pvh1_price, 0) > bottom
  157. if box_sv
  158. box.set_bgcolor(tbox, t_s)
  159. if ob_a_sv and close < bottom
  160. if array.get(pvh1_time, 0) != h_a_time
  161. h_a_time := array.get(pvh1_time, 0)
  162. alert := alert + 'Supply Zone Test @ ' + str.tostring(array.get(pvh1_price, 0)) + ' (age = ' + str.tostring(bar_index-ago) + ' bars) \n'
  163. if array.get(pvl1_price, 0) > top
  164. if m_sv
  165. box.set_bgcolor(tbox, u_b)
  166. array.push(m_long_boxes, tbox)
  167. else
  168. box.delete(tbox)
  169. array.remove(short_boxes, i)
  170. if msb_sv
  171. line.delete(array.get(bear_bos_lines, i))
  172. array.remove(bear_bos_lines, i)
  173. if array.size(long_boxes) > 0
  174. for i = array.size(long_boxes) - 1 to 0 by 1
  175. lbox = array.get(long_boxes, i)
  176. top = box.get_top(lbox)
  177. bottom = box.get_bottom(lbox)
  178. ago = box.get_left(lbox)
  179. if array.get(pvl1_price, 0) < top
  180. if box_sv
  181. box.set_bgcolor(lbox, t_d)
  182. if ob_a_sv and close > top
  183. if array.get(pvl1_time, 0) != l_a_time
  184. l_a_time := array.get(pvl1_time, 0)
  185. alert := alert + 'Demand Zone Test @ ' + str.tostring(array.get(pvl1_price, 0)) + ' (age = ' + str.tostring(bar_index-ago) + ' bars) \n'
  186. if array.get(pvh1_price, 0) < bottom
  187. if m_sv
  188. box.set_bgcolor(lbox, u_b)
  189. array.push(m_short_boxes, lbox)
  190. else
  191. box.delete(lbox)
  192. array.remove(long_boxes, i)
  193. if msb_sv
  194. line.delete(array.get(bull_bos_lines, i))
  195. array.remove(bull_bos_lines, i)
  196. if array.size(m_short_boxes) > 0
  197. for i = array.size(m_short_boxes) - 1 to 0 by 1
  198. tbox = array.get(m_short_boxes, i)
  199. top = box.get_top(tbox)
  200. bottom = box.get_bottom(tbox)
  201. ago = box.get_left(tbox)
  202. if array.get(pvh1_price, 0) > bottom
  203. box.set_bgcolor(tbox, t_b)
  204. if bb_a_sv and close < bottom
  205. if array.get(pvh1_time, 0) != mh_a_time
  206. mh_a_time := array.get(pvh1_time, 0)
  207. alert := alert + 'Breakerblock Test Up @ ' + str.tostring(array.get(pvh1_price, 0)) + ' (age = ' + str.tostring(bar_index-ago) + ' bars) \n'
  208. if array.get(pvl1_price, 0) > top
  209. box.delete(tbox)
  210. array.remove(m_short_boxes, i)
  211. if array.size(m_long_boxes) > 0
  212. for i = array.size(m_long_boxes) - 1 to 0 by 1
  213. lbox = array.get(m_long_boxes, i)
  214. top = box.get_top(lbox)
  215. bottom = box.get_bottom(lbox)
  216. ago = box.get_left(lbox)
  217. if array.get(pvl1_price, 0) < top
  218. box.set_bgcolor(lbox, t_b)
  219. if bb_a_sv and close > top
  220. if array.get(pvl1_time, 0) != ml_a_time
  221. ml_a_time := array.get(pvl1_time, 0)
  222. alert := alert + 'Breakerblock Test Down @ ' + str.tostring(array.get(pvl1_price, 0)) + ' (age = ' + str.tostring(bar_index-ago) + ' bars) \n'
  223. if array.get(pvh1_price, 0) < bottom
  224. box.delete(lbox)
  225. array.remove(m_long_boxes, i)
  226. if range_sv and (new_ph_2nd or new_pl_2nd) and (array.get(pvh2_price, 0) < array.get(pvh2_price, 1) and array.get(pvl2_price, 0) > array.get(pvl2_price, 1) and array.get(pvh2_price, 0) > array.get(pvl2_price, 1) and array.get(pvl2_price, 0) < array.get(pvh2_price, 1)) and (array.get(pvl2_price, 1) > nz(last_range_h) or na(last_range_l)? true : (array.get(pvh2_price, 1) < last_range_l))
  227. temp_time := math.min(array.get(pvh2_time, 1), array.get(pvl2_time, 1))
  228. last_range_h := array.get(pvh2_price, 1)
  229. last_range_l := array.get(pvl2_price, 1)
  230. temp_pv_0 := log_sv ? math.exp((math.log(last_range_h) + math.log(last_range_l))/2) : (last_range_h + last_range_l)/2
  231. temp_pv_1 := log_sv ? math.exp((math.log(last_range_h) + math.log(temp_pv_0))/2) : (last_range_h + temp_pv_0)/2
  232. temp_pv_2 := log_sv ? math.exp((math.log(last_range_l) + math.log(temp_pv_0))/2) : (last_range_l + temp_pv_0)/2
  233. array.push(range_h_lines, line.new(x1=temp_time, y1=last_range_h, x2=bar_index, y2=last_range_h, color=color.gray, width=1, extend=extend.right))
  234. array.push(range_l_lines, line.new(x1=temp_time, y1=last_range_l, x2=bar_index, y2=last_range_l, color=color.gray, width=1, extend=extend.right))
  235. if range_eq_sv
  236. array.push(range_m_lines, line.new(x1=temp_time, y1=temp_pv_0, x2=bar_index, y2=temp_pv_0, color=color.gray, width=1, extend=extend.right))
  237. if range_q_sv
  238. array.push(range_25_lines, line.new(x1=temp_time, y1=temp_pv_1, x2=bar_index, y2=temp_pv_1, style=line.style_dashed, color=color.gray, width=1, extend=extend.right))
  239. array.push(range_75_lines, line.new(x1=temp_time, y1=temp_pv_2, x2=bar_index, y2=temp_pv_2, style=line.style_dashed, color=color.gray, width=1, extend=extend.right))
  240. if r_a_sv
  241. alert := alert + 'New Range : ' + str.tostring(last_range_h) + ' - ' + str.tostring(last_range_l) + '. Mean = ' + str.tostring(temp_pv_0) + '\n'
  242. if array.size(range_h_lines) > 0
  243. for i = array.size(range_h_lines) - 1 to 0 by 1
  244. range_h = array.get(range_h_lines, i)
  245. top = line.get_y1(range_h)
  246. range_l = array.get(range_l_lines, i)
  247. bottom = line.get_y1(range_l)
  248. temp_time := line.get_x1(range_h)
  249. if array.get(pvh1_price, 0) > top
  250. if rt_a_sv and close < top
  251. if array.get(pvh1_time, 0) != rh_a_time
  252. rh_a_time := array.get(pvh1_time, 0)
  253. alert := alert + 'Range High Test @ ' + str.tostring(array.get(pvh1_price, 0)) + ' \n'
  254. if array.get(pvl1_price, 0) < bottom
  255. if rt_a_sv and close > bottom
  256. if array.get(pvl1_time, 0) != rl_a_time
  257. rl_a_time := array.get(pvl1_time, 0)
  258. alert := alert + 'Range Low Test @ ' + str.tostring(array.get(pvl1_price, 0)) + ' \n'
  259. if range_eq_sv
  260. range_m := array.get(range_m_lines, i)
  261. if range_q_sv
  262. range_25 := array.get(range_25_lines, i)
  263. range_75 := array.get(range_75_lines, i)
  264. if array.get(pvh1_price, 0) < bottom or array.get(pvl1_price, 0) > top
  265. line.delete(range_h)
  266. array.remove(range_h_lines, i)
  267. line.delete(range_l)
  268. array.remove(range_l_lines, i)
  269. if range_eq_sv
  270. line.delete(range_m)
  271. array.remove(range_m_lines, i)
  272. if range_q_sv
  273. line.delete(range_25)
  274. array.remove(range_25_lines, i)
  275. line.delete(range_75)
  276. array.remove(range_75_lines, i)
  277. last_range_h := na
  278. last_range_l := na
  279. if pv2_sv
  280. if new_ph_2nd
  281. array.push(la_ph2, label.new(x = array.get(pvh2_time, 0), y = array.get(pvh2_price, 0), xloc = xloc.bar_index, style = label.style_label_down, color = #770000FF, size = size.tiny))
  282. if new_pl_2nd
  283. array.push(la_pl2, label.new(x = array.get(pvl2_time, 0), y = array.get(pvl2_price, 0), xloc = xloc.bar_index, style = label.style_label_up, color = #007700FF, size = size.tiny))
  284.  
  285. alert := not na(alert) ? (alert + 'Current price = ' + str.tostring(close) + '\n') : na
  286. exec = not na(alert) ? true : false
  287. if exec==true
  288. alert(alert, alert.freq_once_per_bar_close)
Advertisement
Add Comment
Please, Sign In to add comment