xmd79

Short/Medium/Long-term Highs&lows

Apr 7th, 2023
394
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.63 KB | None | 0 0
  1. // Using pivots, counters and arrays to determine 'long-term' highs & lows (those nested between Intermediate term highs&lows, which themselves are nested between short term highs&lows)
  2. // Applying 'Spikeyness' filter to filter out weak Pivot highs/lows (default toggled ON)
  3. // Added Alerts; added display table.
  4. // Added optional Lines (self-terminating when hit by price)
  5. // 27th March 2023
  6. // © twingall
  7.  
  8. //@version=5
  9. indicator("Short/Medium/Long-term Highs&lows", shorttitle= "ST/MT/LT H&L", overlay = true, max_labels_count = 500, max_bars_back = 5000, max_lines_count = 500)
  10.  
  11. //user inputs
  12. lb1 =input.int(15, 'pivots: lookback/forward', tooltip = "larger number for more significant pivot highs / pivot lows")
  13. useSpikeyCond = input.bool(true, "Apply 'Spikeyness' filter", inline ='2')
  14. atrMult =input.float(1.3, '|| Spikeyness index', minval = 0, step =0.1, inline ='2', tooltip = "For catching only the 'spiky' pivot highs/pivot lows\n\nIncreasing this number will filter out smooth/unimpressive pivot high&lows\n\nRepresents local ATR multiple for distance from local Moving average a high or low must be\n\nSetting of 1.5 seems optimal on 15m chart with pivot lookback/lookforward = 15")
  15.  
  16. showSTHs = input.bool(true, "short-term", inline='1', group = 'pivot highs')
  17. txtColSTH = input.color(color.teal, "", inline ='1', group = 'pivot highs')
  18. inputTextStyleSTH = input.string("Ʌ (single)", "Style:", inline='1', group = 'pivot highs', options = ["Ʌ (single)", "text horizontal", "text vertical" ])
  19. sizeSTH = input.string(size.normal,"Size", options = [size.auto, size.tiny, size.small, size.normal, size.large, size.huge], group = 'pivot highs', inline='1')
  20. showSTHlines = input.bool(false, "lines", group = 'pivot highs', inline='1')
  21. showMTHs = input.bool(true, "med-term", inline='2', group = 'pivot highs')
  22. txtColMTH = input.color(color.blue, "", inline ='2', group = 'pivot highs')
  23. inputTextStyleMTH = input.string("text horizontal", "Style:", inline='2', group = 'pivot highs', options = ["Ʌ (double)" ,"text horizontal", "text vertical"])
  24. sizeMTH = input.string(size.normal,"Size", options = [size.auto, size.tiny, size.small, size.normal, size.large, size.huge], group = 'pivot highs', inline='2')
  25. showMTHlines = input.bool(false, "lines", group = 'pivot highs', inline='2')
  26. showLTHs = input.bool(true, "long-term", inline='3', group = 'pivot highs')
  27. txtColLTH = input.color(color.green, "", inline ='3', group = 'pivot highs')
  28. inputTextStyleLTH = input.string("text horizontal", "Style:", inline='3', group = 'pivot highs', options = ["Ʌ (triple)","text horizontal", "text vertical" ])
  29. sizeLTH = input.string(size.large,"Size:", options = [size.auto, size.tiny, size.small, size.normal, size.large, size.huge], group = 'pivot highs', inline='3')
  30. showLTHlines = input.bool(false, "lines", group = 'pivot highs', inline='3')
  31.  
  32. showSTLs = input.bool(true, "short-term", inline='1', group = 'pivot lows')
  33. txtColSTL = input.color(color.orange, "", inline ='1', group = 'pivot lows')
  34. inputTextStyleSTL = input.string("V (single)", "Style:", inline='1', group = 'pivot lows', options = ["V (single)", "text horizontal", "text vertical" ])
  35. sizeSTL = input.string(size.normal,"Size", options = [size.auto, size.tiny, size.small, size.normal, size.large, size.huge], group = 'pivot lows', inline='1')
  36. showSTLlines = input.bool(false, "lines", group = 'pivot lows', inline='1')
  37. showMTLs = input.bool(true, "med-term", inline='2', group = 'pivot lows')
  38. txtColMTL = input.color(color.fuchsia, "", inline ='2', group = 'pivot lows')
  39. inputTextStyleMTL = input.string("text horizontal", "Style:", inline='2', group = 'pivot lows', options = ["V (double)" ,"text horizontal", "text vertical"])
  40. sizeMTL = input.string(size.normal,"Size", options = [size.auto, size.tiny, size.small, size.normal, size.large, size.huge], group = 'pivot lows', inline='2')
  41. showMTLlines = input.bool(false, "lines", group = 'pivot lows', inline='2')
  42. showLTLs = input.bool(true, "long-term", inline='3', group = 'pivot lows')
  43. txtColLTL = input.color(color.red, "", inline ='3', group = 'pivot lows')
  44. inputTextStyleLTL = input.string("text horizontal", "Style:", inline='3', group = 'pivot lows', options = ["V (triple)","text horizontal", "text vertical" ])
  45. sizeLTL = input.string(size.large,"Size", options = [size.auto, size.tiny, size.small, size.normal, size.large, size.huge], group = 'pivot lows', inline='3')
  46. showLTLlines = input.bool(false, "lines", group = 'pivot lows', inline='3')
  47.  
  48. showTable = input.bool(true, "Table", group = "Other Settings", inline ='1' )
  49. tabPos = input.string(position.top_right, "|| Position:", group = "Other Settings", inline ='1', options = [ position.top_left, position.top_center, position.top_right, position.middle_left, position.middle_center, position.middle_right, position.bottom_left, position.bottom_center, position.bottom_right])
  50. tabCol = input.color(color.new(color.blue, 60), "|| Bg Color:", group = "Other Settings", inline ='1')
  51. txtCol = input.color(color.black, "|| txt Color:", group = "Other Settings", inline ='1')
  52. unit_1 = input.float(0.25, "Label spacer above/below (ATR multiples)",minval = 0, step = 0.25, group = "Other Settings", inline ='2', tooltip = "spacer above/below for pivot labels, based on multiples of long-term average true range")
  53. lineStyle = input.string(line.style_dotted, "LINES: | line style", options =[line.style_solid, line.style_dotted, line.style_dashed], group = "Other Settings", inline ='3')
  54. lineWidth = input.int (1, "line width:", minval =1, maxval =5,group = "Other Settings", inline ='3')
  55.  
  56. atrSpacer = ta.atr(300)
  57. colorNone=color.new(color.white, 100)
  58.  
  59. string textStyleSTH = switch inputTextStyleSTH
  60. "Ʌ (single)" => "ʌ"
  61. "text horizontal" => "STH\nʌ"
  62. "text vertical" => "S\nT\nH\n."
  63. string textStyleMTH = switch inputTextStyleMTH
  64. "Ʌ (double)" => "ʌ\nʌ"
  65. "text horizontal" => "MTH\nʌ"
  66. "text vertical" => "M\nT\nH\n."
  67. string textStyleLTH = switch inputTextStyleLTH
  68. "Ʌ (triple)" => "ʌ\nʌ\nʌ"
  69. "text horizontal" => "LTH\nʌ"
  70. "text vertical" => "L\nT\nH\n."
  71. string textStyleSTL = switch inputTextStyleSTL
  72. "V (single)" => "v"
  73. "text horizontal" => "v\nSTL"
  74. "text vertical" => ".\nS\nT\nL"
  75. string textStyleMTL = switch inputTextStyleMTL
  76. "V (double)" => "v\nv"
  77. "text horizontal" => "v\nMTL"
  78. "text vertical" => ".\nM\nT\nL"
  79. string textStyleLTL = switch inputTextStyleLTL
  80. "V (triple)" => "v\nv\nv"
  81. "text horizontal" => "v\nLTL"
  82. "text vertical" => ".\nL\nT\nL"
  83.  
  84. pivHigh = ta.pivothigh(high, lb1, lb1)
  85. pivLow = ta.pivotlow(low, lb1, lb1)
  86. isPivHigh = na(pivHigh)? false:true
  87. isPivLow = na(pivLow)? false:true
  88.  
  89. var float PH = na
  90. var float PL = na
  91. var array<float> PHarr = array.new<float>(0)
  92. var array<float> PLarr = array.new<float>(0)
  93.  
  94. var label countLabH = na
  95. var label countLabL = na
  96. var array<label> countLabHArr = array.new<label>(0)
  97. var array<label> countLabLArr = array.new<label>(0)
  98. var int PHbarInd =0
  99. var int PLbarInd =0
  100. var array<int>PHbarIndArr=array.new<int>(0)
  101. var array<int>PLbarIndArr=array.new<int>(0)
  102. var int MTHbarInd =0
  103. var int MTLbarInd =0
  104. var array<int>MTHbarIndArr=array.new<int>(0)
  105. var array<int>MTLbarIndArr=array.new<int>(0)
  106. var float MTH = na
  107. var float MTL = na
  108. var array<float> MTHarr = array.new<float>(0)
  109. var array<float> MTLarr = array.new<float>(0)
  110. var label MTHlab = na
  111. var label MTLlab = na
  112. var array<label> MTHlabArr = array.new<label>(0)
  113. var array<label> MTLlabArr = array.new<label>(0)
  114. var array<float> LTHarr = array.new<float>(0)
  115. var array<float> LTLarr = array.new<float>(0)
  116.  
  117. ///~~~~~~ line arrays declared
  118. var line STHline = na, var array<line> STHlineArr = array.new<line>(0)
  119. var line STLline = na, var array<line> STLlineArr = array.new<line>(0)
  120. var line MTHline = na, var array<line> MTHlineArr = array.new<line>(0)
  121. var line MTLline = na, var array<line> MTLlineArr = array.new<line>(0)
  122. var line LTHline = na, var array<line> LTHlineArr = array.new<line>(0)
  123. var line LTLline = na, var array<line> LTLlineArr = array.new<line>(0)
  124. ///~~~~~
  125.  
  126. /////##### PIVOT HIGHS #####
  127.  
  128. //spikey condition
  129. atr = ta.atr(2*lb1)
  130. maH = ta.sma(high, 2*lb1)
  131. bool spikeyH = useSpikeyCond? pivHigh > maH+atrMult*atr:true
  132. //
  133. if isPivHigh
  134. if spikeyH
  135. PH:= pivHigh
  136. array.push(PHarr,PH)
  137. array.push(PHbarIndArr,bar_index-lb1)
  138. countLabH:=label.new(bar_index-lb1, high[lb1]+unit_1*atrSpacer, textStyleSTH, style=label.style_label_down, textcolor =showSTHs?txtColSTH:colorNone, size = sizeSTH, color = colorNone)
  139. array.push(countLabHArr,countLabH)
  140. if showSTHlines
  141. STHline:= line.new(bar_index-lb1,high[lb1], bar_index, high[lb1], color =txtColSTH, style = lineStyle, width =lineWidth)
  142. array.push(STHlineArr, STHline)
  143. PHbarIndArrSize = array.size(PHbarIndArr)
  144. PHarrSize = array.size(PHarr)
  145.  
  146. _lastSTH = array.size(PHarr)>1?array.get(PHarr, PHarrSize-1):na
  147. _lastBarIndSTH = array.size(PHbarIndArr)>1?array.get(PHbarIndArr, PHbarIndArrSize-1):na
  148. _2ndLastSTH = array.size(PHarr)>2?array.get(PHarr, PHarrSize-2):na
  149. _2ndLastBarIndSTH = array.size(PHbarIndArr)>2?array.get(PHbarIndArr, PHbarIndArrSize-2):na
  150. _3rdLastSTH= array.size(PHarr)>3?array.get(PHarr, PHarrSize-3):na
  151. _3rdLastBarIndSTH= array.size(PHbarIndArr)>3?array.get(PHbarIndArr, PHbarIndArrSize-3):na
  152.  
  153. MTH_index = array.indexof(PHbarIndArr, _2ndLastBarIndSTH)
  154. if (_lastSTH<_2ndLastSTH and _2ndLastSTH>_3rdLastSTH) and not (_lastSTH<_2ndLastSTH and _2ndLastSTH>_3rdLastSTH)[1]
  155. MTHlab:=label.new(_2ndLastBarIndSTH, _2ndLastSTH+unit_1*atrSpacer, textStyleMTH, style=label.style_label_down, textcolor =showMTHs?txtColMTH:colorNone, size = sizeMTH, color = colorNone)
  156. array.push(MTHarr,_2ndLastSTH)
  157. array.push(MTHbarIndArr,_2ndLastBarIndSTH)
  158. array.push(MTHlabArr, MTHlab)
  159. label.set_text(array.get(countLabHArr, MTH_index),"")
  160. if showMTHlines
  161. MTHline:= line.new(_2ndLastBarIndSTH,_2ndLastSTH, bar_index, _2ndLastSTH, color =txtColMTH, style = lineStyle, width =lineWidth)
  162. array.push(MTHlineArr, MTHline)
  163.  
  164. MTHbarIndArrSize = array.size(MTHbarIndArr)
  165. MTHsizeOfArr = array.size(MTHarr)
  166. MTHlabArrSize = array.size(MTHlabArr)
  167.  
  168. _lastMTH = array.size(MTHarr)>1?array.get(MTHarr, MTHsizeOfArr-1):na
  169. _lastBarIndMTH = array.size(MTHbarIndArr)>1?array.get(MTHbarIndArr, MTHbarIndArrSize-1):na
  170. _2ndLastMTH = array.size(MTHarr)>2?array.get(MTHarr, MTHsizeOfArr-2):na
  171. _2ndLastBarIndMTH = array.size(MTHbarIndArr)>2?array.get(MTHbarIndArr, MTHbarIndArrSize-2):na
  172. _3rdLastMTH= array.size(MTHarr)>3?array.get(MTHarr, MTHsizeOfArr-3):na
  173. _3rdLastBarIndMTH= array.size(MTHbarIndArr)>3?array.get(MTHbarIndArr, MTHbarIndArrSize-3):na
  174.  
  175. LTH_index1 = array.indexof(PHbarIndArr, _2ndLastBarIndMTH)
  176. LTH_index2 = array.indexof(MTHbarIndArr, _2ndLastBarIndMTH)
  177. if (_lastMTH<_2ndLastMTH and _2ndLastMTH>_3rdLastMTH) and not (_lastMTH<_2ndLastMTH and _2ndLastMTH>_3rdLastMTH)[1]
  178. label.new(_2ndLastBarIndMTH, _2ndLastMTH+unit_1*atrSpacer, textStyleLTH, style=label.style_label_down, textcolor =showLTHs?txtColLTH:colorNone, size = sizeLTH, color = colorNone)
  179. label.set_text(array.get(MTHlabArr, LTH_index2),"")
  180. label.set_text(array.get(countLabHArr, LTH_index1),"")
  181. array.push(LTHarr,_2ndLastMTH)
  182. if showLTHlines
  183. LTHline:= line.new(_2ndLastBarIndMTH,_2ndLastMTH, bar_index, _2ndLastMTH, color = txtColLTH, style = lineStyle, width =lineWidth )
  184. array.push(LTHlineArr, LTHline)
  185.  
  186. /////##### PIVOT LOWS #####
  187.  
  188. //spikey condition
  189. maL = ta.sma(low, 2*lb1)
  190. bool spikeyL = useSpikeyCond? pivLow < maL-atrMult*atr:true
  191. //
  192. if isPivLow
  193. if spikeyL
  194. PL:= pivLow
  195. array.push(PLarr,PL)
  196. array.push(PLbarIndArr,bar_index-lb1)
  197. countLabL:=label.new(bar_index-lb1, low[lb1]-unit_1*atrSpacer, textStyleSTL, style=label.style_label_up, textcolor =showSTLs?txtColSTL:colorNone, size = sizeSTL, color = colorNone)
  198. array.push(countLabLArr,countLabL)
  199. if showSTLlines
  200. STLline:= line.new(bar_index-lb1,low[lb1], bar_index, low[lb1], color =txtColSTL, style = lineStyle, width =lineWidth)
  201. array.push(STLlineArr, STLline)
  202. PLbarIndArrSize = array.size(PLbarIndArr)
  203. PLarrSize = array.size(PLarr)
  204.  
  205. _lastSTL = array.size(PLarr)>1?array.get(PLarr, PLarrSize-1):na
  206. _lastBarIndSTL = array.size(PLbarIndArr)>1?array.get(PLbarIndArr, PLbarIndArrSize-1):na
  207. _2ndLastSTL = array.size(PLarr)>2?array.get(PLarr, PLarrSize-2):na
  208. _2ndLastBarIndSTL = array.size(PLbarIndArr)>2?array.get(PLbarIndArr, PLbarIndArrSize-2):na
  209. _3rdLastSTL= array.size(PLarr)>3?array.get(PLarr, PLarrSize-3):na
  210. _3rdLastBarIndSTL= array.size(PLbarIndArr)>3?array.get(PLbarIndArr, PLbarIndArrSize-3):na
  211.  
  212. MTL_index = array.indexof(PLbarIndArr, _2ndLastBarIndSTL)
  213. if (_lastSTL>_2ndLastSTL and _2ndLastSTL<_3rdLastSTL) and not (_lastSTL>_2ndLastSTL and _2ndLastSTL<_3rdLastSTL)[1] //// MTLs
  214. MTLlab:=label.new(_2ndLastBarIndSTL, _2ndLastSTL-unit_1*atrSpacer, textStyleMTL, style=label.style_label_up, textcolor =showMTLs?txtColMTL:colorNone, size = sizeMTL, color = colorNone)
  215. array.push(MTLarr,_2ndLastSTL)
  216. array.push(MTLbarIndArr,_2ndLastBarIndSTL)
  217. array.push(MTLlabArr, MTLlab)
  218. label.set_text(array.get(countLabLArr, MTL_index),"")
  219. if showMTLlines
  220. MTLline:= line.new(_2ndLastBarIndSTL,_2ndLastSTL, bar_index, _2ndLastSTL, color =txtColMTL, style = lineStyle, width =lineWidth)
  221. array.push(MTLlineArr, MTLline)
  222.  
  223. MTLbarIndArrSize = array.size(MTLbarIndArr)
  224. MTLsizeOfArr = array.size(MTLarr)
  225. MTLlabArrSize = array.size(MTLlabArr)
  226.  
  227. _lastMTL = array.size(MTLarr)>1?array.get(MTLarr, MTLsizeOfArr-1):na
  228. _lastBarIndMTL = array.size(MTLbarIndArr)>1?array.get(MTLbarIndArr, MTLbarIndArrSize-1):na
  229. _2ndLastMTL = array.size(MTLarr)>2?array.get(MTLarr, MTLsizeOfArr-2):na
  230. _2ndLastBarIndMTL = array.size(MTLbarIndArr)>2?array.get(MTLbarIndArr, MTLbarIndArrSize-2):na
  231. _3rdLastMTL= array.size(MTLarr)>3?array.get(MTLarr, MTLsizeOfArr-3):na
  232. _3rdLastBarIndMTL= array.size(MTLbarIndArr)>3?array.get(MTLbarIndArr, MTLbarIndArrSize-3):na
  233.  
  234. LTL_index1 = array.indexof(PLbarIndArr, _2ndLastBarIndMTL)
  235. LTL_index2 = array.indexof(MTLbarIndArr, _2ndLastBarIndMTL)
  236. if (_lastMTL>_2ndLastMTL and _2ndLastMTL<_3rdLastMTL) and not (_lastMTL>_2ndLastMTL and _2ndLastMTL<_3rdLastMTL)[1] //// LTLs
  237. label.new(_2ndLastBarIndMTL, _2ndLastMTL-unit_1*atrSpacer, textStyleLTL, style=label.style_label_up, textcolor =showLTLs?txtColLTL:colorNone, size = sizeLTL, color = colorNone)
  238. label.set_text(array.get(MTLlabArr, LTL_index2),"")
  239. label.set_text(array.get(countLabLArr, LTL_index1),"")
  240. array.push(LTLarr,_2ndLastMTL)
  241. if showLTLlines
  242. LTLline:= line.new(_2ndLastBarIndMTL,_2ndLastMTL, bar_index, _2ndLastMTL, color =txtColLTL, style = lineStyle, width =lineWidth)
  243. array.push(LTLlineArr, LTLline)
  244.  
  245. // ~~ Alerts ~~
  246. lastLTH = array.size(LTHarr)>0?array.last(LTHarr):na
  247. lastLTL = array.size(LTLarr)>0?array.last(LTLarr):na
  248. lastMTH = array.size(MTHarr)>0?array.last(MTHarr):na
  249. lastMTL = array.size(MTLarr)>0?array.last(MTLarr):na
  250. lastSTH = array.size(PHarr)>0? array.last(PHarr):na
  251. lastSTL = array.size(PLarr)>0? array.last(PLarr):na
  252. alertcondition(ta.crossover(close, lastLTH), "LTH, cross above", "price has crossed above last LTH")
  253. alertcondition(ta.crossunder(close, lastLTL), "LTL, cross below", "price has crossed below last LTL")
  254. alertcondition(ta.crossover(close, lastMTH), "MTH, cross above", "price has crossed above last MTH")
  255. alertcondition(ta.crossunder(close, lastMTL), "MTL, cross below", "price has crossed below last MTL")
  256. alertcondition(ta.crossover(close, lastSTH), "STH, cross above", "price has crossed above last STH")
  257. alertcondition(ta.crossunder(close, lastSTL), "STL, cross below", "price has crossed below last STL")
  258.  
  259. /// ~ Display Table ~
  260. var Table = table.new(tabPos, columns = 3, rows =3, bgcolor = tabCol, border_width = 1)
  261. if barstate.islast and showTable
  262. table.cell(Table, 0, 0, "Long-Term", text_color = txtCol)
  263. table.cell(Table, 0, 1, "last LTH = "+str.tostring(lastLTH, format.mintick),bgcolor = color.new(color.orange,70), text_color = txtCol)
  264. table.cell(Table, 0, 2, "last LTL = " +str.tostring(lastLTL, format.mintick),bgcolor = color.new(color.orange,70), text_color = txtCol)
  265. table.cell(Table, 1, 0, "Med-Term", text_color = txtCol)
  266. table.cell(Table, 1, 1, "last MTH = " +str.tostring(lastMTH, format.mintick),bgcolor = color.new(color.yellow,60), text_color = txtCol)
  267. table.cell(Table, 1, 2, "last MTL = " +str.tostring(lastMTL, format.mintick),bgcolor = color.new(color.yellow,60), text_color = txtCol)
  268. table.cell(Table, 2, 0, "Short-Term", text_color = txtCol)
  269. table.cell(Table, 2, 1, "last STH = "+str.tostring(lastSTH, format.mintick),bgcolor = color.new(color.gray,70), text_color = txtCol)
  270. table.cell(Table, 2, 2, "last STL = " +str.tostring(lastSTL, format.mintick),bgcolor = color.new(color.gray,70), text_color = txtCol)
  271.  
  272. ///### Adding self-terminating lines
  273. // ~~ credit to @Bjorgum for this Function ~~
  274. extendAndRemove( array<line> lineArray, simple bool isBull, int maxSize) =>
  275. if lineArray.size() > 0
  276. for i = lineArray.size() -1 to 0
  277. line ln = lineArray.get(i)
  278. ln.set_x2(bar_index)
  279. float price = ln.get_price(bar_index)
  280. int m = isBull ? 1 : -1
  281. float hiLo = isBull ? high : low
  282. if hiLo * m > price * m
  283. lineArray.remove(i)
  284. if lineArray.size() > maxSize
  285. line.delete(lineArray.shift())
  286.  
  287. extendAndRemove(STHlineArr,true, 66)
  288. extendAndRemove(STLlineArr,false, 66)
  289. extendAndRemove(MTHlineArr,true, 44)
  290. extendAndRemove(MTLlineArr,false, 44)
  291. extendAndRemove(LTHlineArr,true, 22)
  292. extendAndRemove(LTLlineArr,false, 22)
Advertisement
Add Comment
Please, Sign In to add comment