xmd79

Multiple Divergences (UDTs - objects)

Jan 10th, 2023
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.54 KB | None | 0 0
  1. fi(ki)=>'ra' // ©fikira - This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
  2. //@version=5
  3.  
  4. indicator('Multiple Divergences (UDTs - objects)' , max_lines_count=500, max_labels_count=500, overlay=true) // max_bars_back=2000,
  5.  
  6. // ––––––––––––––––––––––––––––––––––––––––––––––––––––––[ input's ]––––––––––––––––––––––––––––––––––––––––––––––––––––––
  7.  
  8. int left = input.int ( 3, 'left' , minval= 1, maxval= 100)
  9. int right = input.int ( 1, 'right' , minval= 1, maxval= 100)
  10.  
  11. int mx = input.int ( 750, 'max values', minval=100, maxval=2000)
  12.  
  13. bool trsi = input.bool ( true, '' , inline='1', group='Oscillators (+ length)')
  14. int l_rsi = input.int ( 14, 'RSI' , minval= 1, maxval= 100, inline='1', group='Oscillators (+ length)')
  15. color bl1 = input.color (color.lime , '' , inline='1', group='Oscillators (+ length)')
  16. color br1 = input.color (#FF0000 , '' , inline='1', group='Oscillators (+ length)')
  17.  
  18. bool tCci = input.bool ( true, '' , inline='2', group='Oscillators (+ length)')
  19. int l_cci = input.int ( 14, 'CCI' , minval= 1, maxval= 100, inline='2', group='Oscillators (+ length)')
  20. color bl2 = input.color (color.olive , '' , inline='2', group='Oscillators (+ length)')
  21. color br2 = input.color (color.red , '' , inline='2', group='Oscillators (+ length)')
  22.  
  23. bool tMfi = input.bool ( true, '' , inline='3', group='Oscillators (+ length)')
  24. int l_mfi = input.int ( 14, 'MFI' , minval= 1, maxval= 100, inline='3', group='Oscillators (+ length)')
  25. color bl3 = input.color (color.yellow, '' , inline='3', group='Oscillators (+ length)')
  26. color br3 = input.color (color.orange, '' , inline='3', group='Oscillators (+ length)')
  27.  
  28.  
  29. // ––––––––––––––––––––––––––––––––––––––––––––––––––––––[ UDT's ]––––––––––––––––––––––––––––––––––––––––––––––––––––––
  30.  
  31. // @type An object of highs and lows
  32. // @field b bar_index - right
  33. // @field h high[right]
  34. // @field l low [right]
  35. // @field isPh is Pivot High
  36. // @field isPl is Pivot Low
  37. type HLs
  38. int b = na
  39. float h = na
  40. float l = na
  41. bool isPh = false
  42. bool isPl = false
  43.  
  44. // @type An object of oscillator values
  45. // @field b bar_index - right
  46. // @field o oscillator[right]
  47. // @field isPh is Pivot High
  48. // @field isPl is Pivot Low
  49. type Osc
  50. int b = na
  51. float o = na
  52. bool isPh = false
  53. bool isPl = false
  54.  
  55.  
  56. // ––––––––––––––––––––––––––––––––––––––––––––––––––––––[ array's ]––––––––––––––––––––––––––––––––––––––––––––––––––––––
  57.  
  58. var HLs[] aHLs = array.new <HLs>()
  59. var Osc[] aRSI = array.new <Osc>()
  60. var Osc[] aCCI = array.new <Osc>()
  61. var Osc[] aMFI = array.new <Osc>()
  62. var line[] aLn = array.new <line>()
  63.  
  64. // ––––––––––––––––––––––––––––––––––––––––––––––––––––––[ data ]––––––––––––––––––––––––––––––––––––––––––––––––––––––
  65.  
  66. int sz = array.size ( aHLs )
  67. int ls = array.size ( aLn )
  68.  
  69. float hi = nz(high [right])
  70. float lo = nz(low [right])
  71. int bx = nz(bar_index - right )
  72.  
  73. // ––––––––––––––––––––––––––––––––––––––––––––––––––––––[ functions ]––––––––––––––––––––––––––––––––––––––––––––––––––––––
  74.  
  75. // @function Fills Oscillator array
  76. aOsc(series bool osc_ph, series bool osc_pl, series float osc, Osc[] aOsc) =>
  77. max_bars_back(osc, 2000)
  78. os = nz(osc [right])
  79. switch
  80. osc_ph => get = Osc.new(bx, os, true , false), array.unshift(aOsc, get)
  81. osc_pl => get = Osc.new(bx, os, false, true ), array.unshift(aOsc, get)
  82. => get = Osc.new(bx, os, false, false), array.unshift(aOsc, get)
  83.  
  84.  
  85. // @function Checks for Regular Divergence (high/low)
  86. Reg_Div_Piv(series HLs getZ, series string BlBr) => // - - - - - // getZ = current Pivot point
  87. max_bars_back(time, 2000) // prevents "Pine cannot determine the referencing length of a series. Try using max_bars_back ..." error
  88. bull = BlBr == 'bl' // - - - - - - - - - - - - - // bullish/bearish divergence
  89. check = false // checks for a non-pierced DIV line
  90. int x1 = na, float y1 = na, int x2 = na, float y2 = na //
  91. if sz > right // - - - - - - - - - - - - - // if enough data in array
  92. //-{ //
  93. for i = 0 to sz - right //
  94. getA = array.get(aHLs, i) // - - - - - // getA = point in history
  95. if (bull ? getA.isPl : getA.isPh) // if getA is a Pivot point
  96. _x1 = getA.b, _y1 = (bull ? getA.l : getA.h) // collect data
  97. _x2 = getZ.b, _y2 = (bull ? getZ.l : getZ.h) //
  98. if (bull ? _y2 < _y1 : _y2 > _y1) // - - - - - // if condition for DIV is true
  99. testline = line.new(_x1, _y1, _x2, _y2) // create testline
  100. bix = bar_index - _x1 //
  101. //-{ //
  102. for j = right to bix // - - - - - // check if high/low pierces testline in between
  103. getY = array.get(aHLs, j) //
  104. if (bull ? getY.l < line.get_price(testline, getY.b) : //
  105. getY.h > line.get_price(testline, getY.b) ) //
  106. break // - - - - - - - - - - // if pierced -> break, check remains false
  107. if j == bix // if at end of loop
  108. check := true // - - - - - // else -> collect data for output
  109. x1 := getA.b, y1 := (bull ? getA.l : getA.h) //
  110. x2 := getZ.b, y2 := (bull ? getZ.l : getZ.h) //
  111. // }- //
  112. line.delete(testline) // - - - - - // deleted testline
  113. // }- //
  114. [check, x1, y1, x2, y2]// - - - - - - - - - - - - - // output
  115.  
  116.  
  117. // @function Checks for Regular Divergence (oscillator)
  118. Reg_Div_Osc(Osc[] aOsc, series int pv_x1, series int pv_x2, series string BlBr) => // aOsc = array of oscillator values
  119. max_bars_back(time, 2000) // prevents "Pine cannot determine the referencing length of a series. Try using max_bars_back ..." error
  120. bull = BlBr == 'bl' // - - - - - - - - - - - - - // bullish/bearish divergence
  121. check = false // checks for a non-pierced DIV line
  122. int x1 = na, float y1 = na, int x2 = na, float y2 = na //
  123. if sz > right and array.size(aOsc) > 0 // - - - - - // if enough data in array
  124. getZ = array.get (aOsc , 0) // get current oscillator data
  125. //-{ //
  126. for i = 0 to sz - right //
  127. getA = array.get(aOsc , i) // - - - - - // getA = point in history
  128. _x1 = getA.b, _y1 = getA.o, _x2 = getZ.b, _y2 = getZ.o //
  129. isPiv = (bull ? getA.isPl : getA.isPh) // if getA is a Pivot point
  130. if isPiv and math.abs(pv_x1 - _x1) < 3 and math.abs(pv_x2 - _x2) < 3 // if Piv high/low is not too far from Piv Oscillator
  131. if (bull ? _y2 > _y1 : _y2 < _y1) // - - - - - // if condition for DIV is true
  132. testline = line.new(_x1, _y1, _x2, _y2) // create testline
  133. bix = bar_index - _x1 //
  134. //-{ //
  135. for j = right to bix // - - - - - // check if oscillator pierces testline in between
  136. getY = array.get(aOsc, j) //
  137. if (bull ? getY.o < line.get_price(testline, getY.b) : //
  138. getY.o > line.get_price(testline, getY.b) ) //
  139. break // - - - - - - - - - - // if pierced -> break, check remains false
  140. if j == bix // if at end of loop
  141. check := true // - - - - - // else -> collect data for output
  142. x1 := getA.b, y1 := getA.o //
  143. x2 := getZ.b, y2 := getZ.o //
  144. // }- //
  145. line.delete(testline) // - - - - - // deleted testline
  146. // }- //
  147. [check, x1, y1, x2, y2]// - - - - - - - - - - - - - // output
  148.  
  149.  
  150. // @function Draws a line when divergence is spotted
  151. draw(series string BlBr, series bool toggle, Osc[] aOsc, series int x1, series float y1, series int x2, series float y2, series color col) =>
  152. int check = 0
  153. bool bull = BlBr == 'bl'
  154. if toggle
  155. [ch_osc, x1_o, y1_o, x2_o, y2_o] = Reg_Div_Osc(aOsc, x1, x2, bull ? 'bl' : 'br')
  156. if ch_osc
  157. check := 1
  158. array.unshift(aLn, line.new(x1, y1, x2, y2, color=col, width=1))
  159. check
  160.  
  161.  
  162. // @function Cleans array when full
  163. pop(arr) =>
  164. if array.size(arr) > mx
  165. array.pop(arr)
  166.  
  167.  
  168. // @function Lines are dotted when unconfirmed DIV, solid if confirmed
  169. setLine(series int n) =>
  170. line ln = ls > n ? array.get(aLn, n) : na
  171. line.set_style(ln, bar_index - line.get_x2(ln) <= right ? line.style_dotted : line.style_solid )
  172.  
  173.  
  174. // ––––––––––––––––––––––––––––––––––––––––––––––––––––––[ Action ]––––––––––––––––––––––––––––––––––––––––––––––––––––––
  175.  
  176. // calculate values -{
  177. float rsi = ta.rsi (close , l_rsi)
  178. float cci = ta.cci (close , l_cci)
  179. float mfi = ta.mfi (close , l_mfi)
  180.  
  181. ph = ta.pivothigh( left, right)
  182. pl = ta.pivotlow ( left, right)
  183. rsi_ph = ta.pivothigh(rsi , left, right)
  184. rsi_pl = ta.pivotlow (rsi , left, right)
  185. cci_ph = ta.pivothigh(cci , left, right)
  186. cci_pl = ta.pivotlow (cci , left, right)
  187. mfi_ph = ta.pivothigh(mfi , left, right)
  188. mfi_pl = ta.pivotlow (mfi , left, right)
  189. // }
  190.  
  191. // add object (Osc.new) to array -{
  192. if trsi
  193. aOsc(rsi_ph, rsi_pl, rsi, aRSI)
  194.  
  195. if tCci
  196. aOsc(cci_ph, cci_pl, cci, aCCI)
  197.  
  198. if tMfi
  199. aOsc(mfi_ph, mfi_pl, mfi, aMFI)
  200. // }
  201.  
  202. // add object (HLs.new) to array -{
  203. switch
  204. //
  205. ph =>
  206. getZ = HLs.new(bx, hi, lo, true , false), array.unshift(aHLs, getZ)
  207. [check, x1, y1, x2, y2] = Reg_Div_Piv(getZ, 'br')
  208. if check
  209. check1 = draw('br', trsi, aRSI, x1, y1, x2, y2, br1)
  210. check2 = draw('br', tCci, aCCI, x1, y1, x2, y2, br2)
  211. check3 = draw('br', tMfi, aMFI, x1, y1, x2, y2, br3)
  212. total = check1 + check2 + check3
  213. if total > 0
  214. label.new(
  215. bx, hi, style=label.style_label_down, text=str.tostring(total),
  216. color=color.new(#FF0000, 90), textcolor=#FF0000
  217. )
  218. //
  219. pl =>
  220. getZ = HLs.new(bx, hi, lo, false, true ), array.unshift(aHLs, getZ)
  221. [check, x1, y1, x2, y2] = Reg_Div_Piv(getZ, 'bl')
  222. if check
  223. check1 = draw('bl', trsi, aRSI, x1, y1, x2, y2, bl1)
  224. check2 = draw('bl', tCci, aCCI, x1, y1, x2, y2, bl2)
  225. check3 = draw('bl', tMfi, aMFI, x1, y1, x2, y2, bl3)
  226. total = check1 + check2 + check3
  227. if total > 0
  228. label.new(
  229. bx, lo, style=label.style_label_up , text=str.tostring(total),
  230. color=color.new(#00FF00, 90), textcolor=#00FF00
  231. )
  232. //
  233. => array.unshift(aHLs, HLs.new(bx, hi, lo, false, false))
  234. // }
  235.  
  236. // ––––––––––––––––––––––––––––––––––––––––––––––––––––––[ ––––––––– ]––––––––––––––––––––––––––––––––––––––––––––––––––––––
  237.  
  238. // clean array's
  239. pop(aHLs), pop(aRSI), pop(aCCI), pop(aMFI)
  240.  
  241. // clean line array
  242. if ls > 500
  243. line.delete(array.pop(aLn))
  244.  
  245. // set line style
  246. setLine(0), setLine(1), setLine(2)
  247.  
  248. // ––––––––––––––––––––––––––––––––––––––––––––––––––––––[ ––––––––– ]––––––––––––––––––––––––––––––––––––––––––––––––––––––
  249.  
  250.  
  251.  
Advertisement
Add Comment
Please, Sign In to add comment