xmd79

MTF Order Block Finder

Sep 22nd, 2021
202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.14 KB | None | 0 0
  1. //@version=4
  2. study("MTF Order Block Finder", overlay = true,max_bars_back=100)
  3. tip1 = "Instituational Order Blocks (OB) often signal the beginning of a strong move. There is a high probability that OB price levels will be revisited in the future. Bullish Order block is the last down candle before a sequence of up candles. Bearish Order Block is the last up candle before a sequence of down candles."
  4. tip2 = "!Experimental!\nFind Order Blocks from different timeframes. Channel prices and positions are accurate, but arrow position is not. Lower timeframes are ignored."
  5. tip3 = "Required number of subsequent candles in the same direction to identify Order Block"
  6. tip4 = "Measured from from potential OB close to close of first candle in sequence"
  7. tip5 = "LIGHT = classic Red + Green scheme\nDARK = clean White + Blue for dark charts"
  8. tip6 = "LINE = 3 lines representing the High, Low, and Average price of the OB\nBOX = a solid bounded area where the Top and Bottom are the High and Low of the OB"
  9. tip7 = "Number of Zones to draw on chart. Higher numbers lead to \"messy\" charts"
  10. //User Inputs
  11. dummy = input(true,"Hover over ( ! ) for documentation", tooltip = tip1)
  12. colors = input("LIGHT","Color Theme", options=["LIGHT","DARK"],tooltip=tip5)
  13. style = input("BOX","Order Block drawing style",options=["LINE","BOX"],tooltip=tip6)
  14. resolution = input("","Order Block Timeframe",input.resolution,tooltip=tip2)
  15. ob_period = 1 + input(5,"Relevant Periods to identify OB",tooltip=tip3) // Required number of subsequent candles in the same direction to identify Order Block
  16. threshold = input(0.25,"Min. Percent move for valid OB", step = 0.1, tooltip=tip4) // Required minimum % move (from potential OB close to last subsequent candle to identify Order Block)
  17. bull_channels = input(2,"Max Bullish Zones to show",tooltip=tip7) // Num of channels
  18. bear_channels = input(2,"Max Bearish Zones to show",tooltip=tip7) // Num of channels
  19.  
  20. //Convert a given string resolution into seconds
  21. ResolutionToSec(res)=>
  22. mins = res == "1" ? 1 :
  23. res == "3" ? 3 :
  24. res == "5" ? 5 :
  25. res == "15" ? 15 :
  26. res == "30" ? 30 :
  27. res == "45" ? 45 :
  28. res == "60" ? 60 :
  29. res == "120" ? 120 :
  30. res == "180" ? 180 :
  31. res == "240" ? 240 :
  32. res == "1D" ? 1440 :
  33. res == "1W" ? 10080 :
  34. res == "1M" ? 43200 : 0
  35. ms = mins * 60
  36.  
  37. //Convert the current chart resolution into seconds
  38. TimeframeToSec()=>
  39. mins = 0.0
  40. if(timeframe.isdwm)
  41. mins := timeframe.isdaily ? 1440 :
  42. timeframe.isweekly ? 10080 :
  43. timeframe.ismonthly ? 43200 : mins
  44. if(timeframe.isintraday)
  45. mins := timeframe.isminutes ? 1 :
  46. timeframe.isseconds ? (1/60) : mins
  47. ms = round(mins * 60 * timeframe.multiplier)
  48.  
  49. //Given a source type, resolution, and warmup period;
  50. //Return 1) an array of prices with gaps removed
  51. // 2) a bool that is True when the given resolution has new data
  52. Rem_Gaps_Security(src,res,warm)=>
  53. max = security(syminfo.tickerid,res,bar_index,barmerge.gaps_off,barmerge.lookahead_off)
  54. gap = security(syminfo.tickerid,res,src,barmerge.gaps_on,barmerge.lookahead_off)
  55. clean = array.new_float()
  56. if (na(max) or max < warm)
  57. array.push(clean,na)
  58. [clean,false]
  59. else
  60. for i=0 to warm
  61. if(not na(gap[i]))
  62. array.push(clean,gap[i])
  63. [clean,not na(gap)]
  64.  
  65. //Initialization
  66. bullcolor = colors == "DARK"? color.white : color.green
  67. bearcolor = colors == "DARK"? color.blue : color.red
  68. OB_bull = false
  69. OB_bull_chigh = float(na)
  70. OB_bull_clow = float(na)
  71. OB_bull_avg = float(na)
  72. OB_bear = false
  73. OB_bear_chigh = float(na)
  74. OB_bear_clow = float(na)
  75. OB_bear_avg = float(na)
  76. //MTF Sync vars
  77. var sync = 0
  78. res = TimeframeToSec() > ResolutionToSec(resolution) ? "" : resolution
  79. warmup = ob_period + 1
  80. mtf_warmup = res == "" ? warmup : warmup * ResolutionToSec(res)/TimeframeToSec()
  81. //Data Curation
  82. [copen,naopen] = Rem_Gaps_Security(open,res,mtf_warmup)
  83. [chigh,nahigh] = Rem_Gaps_Security(high,res,mtf_warmup)
  84. [clow,nalow] = Rem_Gaps_Security(low,res,mtf_warmup)
  85. [cclose,naclose] = Rem_Gaps_Security(close,res,mtf_warmup)
  86. //Array with least data
  87. MinArraySize = min(array.size(copen),
  88. array.size(chigh),
  89. array.size(clow),
  90. array.size(cclose))
  91.  
  92. if(MinArraySize > warmup)
  93. //Validity of most recent candle
  94. relmove = 100*((abs(array.get(cclose,ob_period) - array.get(cclose,1)))/array.get(cclose,ob_period))>=threshold
  95. // Bullish Order Block Identification
  96. bullishOB = array.get(cclose,ob_period) < array.get(copen,ob_period) // Determine potential Bullish OB candle (red candle)
  97.  
  98. int upcandles = 0
  99. for i = 1 to ob_period-1
  100. upcandles := upcandles + (array.get(cclose,i) > array.get(copen,i)? 1 : 0) // Determine color of subsequent candles (must all be green to identify a valid Bearish OB)
  101. if(naopen and naclose)
  102. OB_bull := bullishOB and (upcandles == (ob_period-1)) and relmove // Identification logic (red OB candle & subsequent green candles)
  103. OB_bull_chigh := OB_bull? array.get(chigh,ob_period) : na // Determine OB upper limit (Open or High depending on input)
  104. OB_bull_clow := OB_bull? array.get(clow,ob_period) : na // Determine OB clower limit (Low)
  105. OB_bull_avg := (OB_bull_chigh + OB_bull_clow)/2 // Determine OB middle line
  106.  
  107. // Bearish Order Block Identification
  108. bearishOB = array.get(cclose,ob_period) > array.get(copen,ob_period) // Determine potential Bearish OB candle (green candle)
  109.  
  110. int downcandles = 0
  111. for i = 1 to ob_period-1
  112. downcandles := downcandles + (array.get(cclose,i) < array.get(copen,i)? 1 : 0) // Determine color of subsequent candles (must all be red to identify a valid Bearish OB)
  113. if(naopen and naclose)
  114. OB_bear := bearishOB and (downcandles == (ob_period-1)) and relmove // Identification logic (green OB candle & subsequent green candles)
  115. OB_bear_chigh := OB_bear? array.get(chigh,ob_period) : na // Determine OB upper limit (High)
  116. OB_bear_clow := OB_bear? array.get(clow,ob_period) : na // Determine OB clower limit (Open or Low depending on input)
  117. OB_bear_avg := (OB_bear_clow + OB_bear_chigh)/2 // Determine OB middle line
  118.  
  119. sync := time_close(res)
  120. if(style=="LINE")
  121. //Init Line Arrays
  122. var LineBullAvg = array.new_line()
  123. var LineBullHigh = array.new_line()
  124. var LineBullLow = array.new_line()
  125. var LineBearAvg = array.new_line()
  126. var LineBearHigh = array.new_line()
  127. var LineBearLow = array.new_line()
  128. //Bullish Channel Creation
  129. if(OB_bull and bull_channels>0)
  130. if array.size(LineBullAvg) == bull_channels
  131. line.delete(array.get(LineBullAvg,0))
  132. array.remove(LineBullAvg,0)
  133. line.delete(array.get(LineBullHigh,0))
  134. array.remove(LineBullHigh,0)
  135. line.delete(array.get(LineBullLow,0))
  136. array.remove(LineBullLow,0)
  137. array.push(LineBullAvg,line.new(x1 = sync, xloc=xloc.bar_time, y1 = OB_bull_avg, x2 = time[1], y2 = OB_bull_avg, extend = extend.left, color = bullcolor, style = line.style_solid, width = 1))
  138. array.push(LineBullHigh,line.new(x1 = sync, xloc=xloc.bar_time,y1 = OB_bull_chigh, x2 = time[1], y2 = OB_bull_chigh, extend = extend.left, color = color.new(bullcolor,50), style = line.style_dashed, width = 1))
  139. array.push(LineBullLow,line.new(x1 = sync, xloc=xloc.bar_time, y1 = OB_bull_clow, x2 = time[1], y2 = OB_bull_clow, extend = extend.left, color = color.new(bullcolor,50), style = line.style_dashed, width = 1))
  140. //Bearish Channel Creation
  141. if(OB_bear and bear_channels>0)
  142. if array.size(LineBearAvg) == bear_channels
  143. line.delete(array.get(LineBearAvg,0))
  144. array.remove(LineBearAvg,0)
  145. line.delete(array.get(LineBearHigh,0))
  146. array.remove(LineBearHigh,0)
  147. line.delete(array.get(LineBearLow,0))
  148. array.remove(LineBearLow,0)
  149. array.push(LineBearAvg,line.new(x1 = sync, xloc=xloc.bar_time, y1 = OB_bear_avg, x2 = time[1], y2 = OB_bear_avg, extend = extend.left, color = bearcolor, style = line.style_solid, width = 1))
  150. array.push(LineBearHigh,line.new(x1 = sync, xloc=xloc.bar_time, y1 = OB_bear_chigh, x2 = time[1], y2 = OB_bear_chigh, extend = extend.left, color = color.new(bearcolor,50), style = line.style_dashed, width = 1))
  151. array.push(LineBearLow,line.new(x1 = sync, xloc=xloc.bar_time, y1 = OB_bear_clow, x2 = time[1], y2 = OB_bear_clow, extend = extend.left, color = color.new(bearcolor,50), style = line.style_dashed, width = 1))
  152.  
  153. if(style=="BOX")
  154. //Init Line Arrays
  155. var BoxBull = array.new_box()
  156. var BoxBear = array.new_box()
  157. //Bullish Channel Creation
  158. if(OB_bull and bull_channels>0)
  159. if array.size(BoxBull) == bull_channels
  160. box.delete(array.get(BoxBull,0))
  161. array.remove(BoxBull,0)
  162. array.push(BoxBull,box.new(xloc=xloc.bar_time, left = sync, top = OB_bull_chigh, right = sync, bottom = OB_bull_clow, extend = extend.right, border_width=0, bgcolor = color.new(bullcolor,60)))
  163. //Bearish Channel Creation
  164. if(OB_bear and bear_channels>0)
  165. if array.size(BoxBear) == bear_channels
  166. box.delete(array.get(BoxBear,0))
  167. array.remove(BoxBear,0)
  168. array.push(BoxBear,box.new(xloc=xloc.bar_time, left = sync, top = OB_bear_chigh, right = sync, bottom = OB_bear_clow, extend = extend.right, border_width=0, bgcolor = color.new(bearcolor,60)))
  169.  
  170. os = res=="" ? -ob_period : -ob_period * ResolutionToSec(res)/TimeframeToSec()
  171. // Signal Plotting
  172. plotshape(OB_bull, title="Bullish OB", style = shape.triangleup, color = bullcolor, textcolor = bullcolor, size = size.tiny, location = location.belowbar, offset = os, text = "Bull") // Bullish OB Indicator
  173. bull1 = plot(OB_bull_chigh, title="Bullish OB High", style = plot.style_linebr, color = bullcolor, offset = os, linewidth = 2) // Bullish OB Upper Limit
  174. bull2 = plot(OB_bull_clow, title="Bullish OB Low", style = plot.style_linebr, color = bullcolor, offset = os, linewidth = 2) // Bullish OB Lower Limit
  175. fill(bull1, bull2, color=color.new(bullcolor,50), title = "Bullish OB fill") // Fill Bullish OB
  176. plotshape(OB_bull_avg, title="Bullish OB Average", style = shape.cross, color = bullcolor, size = size.small, location = location.absolute, offset = os) // Bullish OB Average
  177.  
  178. plotshape(OB_bear, title="Bearish OB", style = shape.triangledown, color = bearcolor, textcolor = bearcolor, size = size.tiny, location = location.abovebar, offset = os, text = "Bear") // Bearish OB Indicator
  179. bear1 = plot(OB_bear_clow, title="Bearish OB Low", style = plot.style_linebr, color = bearcolor, offset = os, linewidth = 2) // Bearish OB Lower Limit
  180. bear2 = plot(OB_bear_chigh, title="Bearish OB High", style = plot.style_linebr, color = bearcolor, offset = os, linewidth = 2) // Bearish OB Upper Limit
  181. fill(bear1, bear2, color=color.new(bearcolor,50), title = "Bearish OB fill") // Fill Bearish OB
  182. plotshape(OB_bear_avg, title="Bearish OB Average", style = shape.cross, color = bearcolor, size = size.small, location = location.absolute, offset = os) // Bullish OB Average
Advertisement
Add Comment
Please, Sign In to add comment