xmd79

LTB Zigzag Circles

May 8th, 2021
365
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.58 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. // © LonesomeTheBlue
  3.  
  4. //@version=4
  5. study("LTB Zigzag Circles", overlay = true, max_lines_count = 500)
  6. prd = input(defval = 10, title = "ZigZag Period", minval = 2, maxval = 30)
  7. showzigzag = input(defval = true, title = "Show Zigzag")
  8. showlevels = input(defval = true, title = "Show Levels")
  9. zzlinestyle_ = input(defval = "Dashed", title = "Zigzag Line Style", options = ["Solid", "Dashed", "Dotted"])
  10. upcol = input(defval = color.lime, title = "Line Colors", inline = "col")
  11. dncol = input(defval = color.red, title = "", inline = "col")
  12. uptcol = input(defval = color.black, title = "Text Colors", inline = "tcol")
  13. dntcol = input(defval = color.white, title = "", inline = "tcol")
  14.  
  15. // check highesy/lowest levels and create zigzag
  16. float ph = highestbars(high, prd) == 0 ? high : na
  17. float pl = lowestbars(low, prd) == 0 ? low : na
  18. var dir = 0
  19. dir := iff(ph and na(pl), 1, iff(pl and na(ph), -1, dir))
  20. var zigzag = array.new_float(0)
  21. // keep last point
  22. oldzigzag = array.new_float(2)
  23. if array.size(zigzag) > 1
  24. array.set(oldzigzag, 0, array.get(zigzag, 0))
  25. array.set(oldzigzag, 1, array.get(zigzag, 1))
  26.  
  27. add_to_zigzag(value, bindex)=>
  28. array.unshift(zigzag, bindex)
  29. array.unshift(zigzag, value)
  30. if array.size(zigzag) > 8
  31. array.pop(zigzag)
  32. array.pop(zigzag)
  33.  
  34. update_zigzag(value, bindex)=>
  35. if array.size(zigzag) == 0
  36. add_to_zigzag(value, bindex)
  37. else
  38. if (dir == 1 and value > array.get(zigzag, 0)) or (dir == -1 and value < array.get(zigzag, 0))
  39. array.set(zigzag, 0, value)
  40. array.set(zigzag, 1, bindex)
  41. 0.
  42.  
  43. dirchanged = dir != dir[1]
  44. if ph or pl
  45. if dirchanged
  46. add_to_zigzag(dir == 1 ? ph : pl, bar_index)
  47. else
  48. update_zigzag(dir == 1 ? ph : pl, bar_index)
  49.  
  50. // init zigzag lines
  51. var zzlines = array.new_line(0)
  52. var zzlinestyle = line.style_dashed
  53. if barstate.isfirst
  54. zzlinestyle := zzlinestyle_ == "Solid" ? line.style_solid : zzlinestyle_ == "Dashed" ? line.style_dashed : line.style_dotted
  55. array.push(zzlines, line.new(x1 = bar_index, y1 = close, x2 = bar_index -1 , y2 = close, style = zzlinestyle))
  56. array.push(zzlines, line.new(x1 = bar_index, y1 = close, x2 = bar_index -1, y2 = close, style = zzlinestyle))
  57.  
  58. // draw zigzag
  59. if showzigzag and array.size(zigzag) >= 6
  60. line.set_xy1(array.get(zzlines, 0), round(array.get(zigzag, 1)), array.get(zigzag, 0))
  61. line.set_xy2(array.get(zzlines, 0), round(array.get(zigzag, 3)), array.get(zigzag, 2))
  62. line.set_color(array.get(zzlines, 0), dir == 1 ? upcol : dncol)
  63. line.set_xy1(array.get(zzlines, 1), round(array.get(zigzag, 3)), array.get(zigzag, 2))
  64. line.set_xy2(array.get(zzlines, 1), round(array.get(zigzag, 5)), array.get(zigzag, 4))
  65. line.set_color(array.get(zzlines, 1), dir == 1 ? dncol : upcol)
  66.  
  67. // definitions
  68. width = (highest(292) - lowest(292)) / 107
  69. var up_circle_lines = array.new_line(0)
  70. var dn_circle_lines = array.new_line(0)
  71. // to get rid of consistency warning, keep close in a array
  72. var cls = array.new_float(500, na)
  73. array.unshift(cls, close)
  74. array.pop(cls)
  75.  
  76. // calculate location of y level in a point
  77. calc_pos_circle_rad(center_y_lev, center_bindex, radius, cal_bindex)=>
  78. loc_diff = abs(center_bindex - cal_bindex)
  79. rad = sqrt(pow(radius, 2) - pow(loc_diff * width, 2))
  80.  
  81. // draw uptrend circle until last candle
  82. draw_up_circle(radius)=>
  83. ind = dir == 1 ? 0 : 2
  84. nxt = dir == 1 ? 2 : 4
  85. broken = false
  86. if bar_index - 1 > array.get(zigzag, nxt + 1)
  87. last_x = round(array.get(zigzag, nxt + 1))
  88. last_y = array.get(zigzag, nxt)
  89. for x = array.get(zigzag, nxt + 1) + 1 to bar_index - 1
  90. yloc = array.get(zigzag, ind) - calc_pos_circle_rad(array.get(zigzag, ind), array.get(zigzag, ind + 1), radius, x)
  91. if na(yloc)
  92. break
  93. if not na(yloc) and array.get(cls, round(bar_index - x)) < yloc
  94. broken := true
  95. break
  96. array.push(up_circle_lines, line.new(x1 = last_x, y1 = last_y, x2 = round(x), y2 = yloc, color = upcol, width = 2))
  97. last_x := last_x + 1
  98. last_y := yloc
  99. broken
  100.  
  101. // draw downtrend circle until last candle
  102. draw_down_circle(radius)=>
  103. ind = dir == 1 ? 2 : 0
  104. nxt = dir == 1 ? 4 : 2
  105. broken = false
  106. if bar_index - 1 > array.get(zigzag, nxt + 1)
  107. last_x = round(array.get(zigzag, nxt + 1))
  108. last_y = array.get(zigzag, nxt)
  109. for x = array.get(zigzag, nxt + 1) + 1 to bar_index - 1
  110. yloc = array.get(zigzag, ind) + calc_pos_circle_rad(array.get(zigzag, ind), array.get(zigzag, ind + 1), radius, x)
  111. if na(yloc)
  112. break
  113. if not na(yloc) and array.get(cls, round(bar_index - x)) > yloc
  114. broken := true
  115. break
  116. array.push(dn_circle_lines, line.new(x1 = last_x, y1 = last_y, x2 = round(x), y2 = yloc, color = dncol, width = 2))
  117. last_x := last_x + 1
  118. last_y := yloc
  119. broken
  120.  
  121. Round_it(value)=> round(value / syminfo.mintick) * syminfo.mintick
  122.  
  123. // variables to check if any circle broken
  124. var bool uptbroken = false
  125. var bool downtbroken = false
  126. uptexist = false
  127. downtexist = false
  128.  
  129. // labels
  130. var label upt_label = na
  131. var label downt_label = na
  132.  
  133. if array.size(zigzag) >= 6
  134. // radius of circles
  135. r1 = sqrt(pow(array.get(zigzag, 0) - array.get(zigzag, 2), 2) + pow((array.get(zigzag, 1) - array.get(zigzag, 3)) * width, 2))
  136. r2 = sqrt(pow(array.get(zigzag, 2) - array.get(zigzag, 4), 2) + pow((array.get(zigzag, 3) - array.get(zigzag, 5)) * width, 2))
  137. radius_up = dir == 1 ? r1 : r2
  138. radius_down = dir == 1 ? r2 : r1
  139.  
  140. // draw uptrend circle if needed
  141. if dirchanged or width != width[1] or (dir == 1 and (array.get(zigzag, 0) != array.get(oldzigzag, 0) or array.get(zigzag, 1) != array.get(oldzigzag, 1)))
  142. uptbroken := false
  143. if array.size(up_circle_lines) > 0
  144. for x = 0 to array.size(up_circle_lines) - 1
  145. line.delete(array.pop(up_circle_lines))
  146. uptbroken := draw_up_circle(radius_up)
  147.  
  148. // draw downtrend circle if needed
  149. if dirchanged or width != width[1] or (dir == -1 and (array.get(zigzag, 0) != array.get(oldzigzag, 0) or array.get(zigzag, 1) != array.get(oldzigzag, 1)))
  150. downtbroken := false
  151. if array.size(dn_circle_lines) > 0
  152. for x = 0 to array.size(dn_circle_lines) - 1
  153. line.delete(array.pop(dn_circle_lines))
  154. downtbroken := draw_down_circle(radius_down)
  155.  
  156. // calculate/check and draw part of uptrend circle for last last
  157. if not uptbroken
  158. ind = dir == 1 ? 0 : 2
  159. yloc = array.get(zigzag, ind) - calc_pos_circle_rad(array.get(zigzag, ind), array.get(zigzag, ind + 1), radius_up, bar_index)
  160. if not na(yloc) and close >= yloc
  161. uptexist := true
  162. lasty = array.get(zigzag, ind) - calc_pos_circle_rad(array.get(zigzag, ind), array.get(zigzag, ind + 1), radius_up, bar_index - 1)
  163. array.push(up_circle_lines, line.new(x1 = bar_index - 1, y1 = lasty, x2 = bar_index, y2 = yloc, color = upcol, width = 2))
  164. if showlevels
  165. label.delete(upt_label)
  166. upt_label := label.new(x = bar_index, y = yloc, text = tostring(Round_it(yloc)), color = upcol, textcolor = uptcol, style = label.style_label_up)
  167.  
  168. if not na(yloc) and close < yloc
  169. uptbroken := true
  170.  
  171. // calculate/check and draw part of downtrend circle for last last
  172. if not downtbroken
  173. ind = dir == 1 ? 2 : 0
  174. yloc = array.get(zigzag, ind) + calc_pos_circle_rad(array.get(zigzag, ind), array.get(zigzag, ind + 1), radius_down, bar_index)
  175. if not na(yloc) and close <= yloc
  176. downtexist := true
  177. lasty = array.get(zigzag, ind) + calc_pos_circle_rad(array.get(zigzag, ind), array.get(zigzag, ind + 1), radius_down, bar_index - 1)
  178. array.push(dn_circle_lines, line.new(x1 = bar_index - 1, y1 = lasty, x2 = bar_index, y2 = yloc, color = dncol, width = 2))
  179. if showlevels
  180. label.delete(downt_label)
  181. downt_label := label.new(x = bar_index, y = yloc, text = tostring(Round_it(yloc)), color = dncol, textcolor = dntcol, style = label.style_label_down)
  182.  
  183. if not na(yloc) and close > yloc
  184. downtbroken := true
  185.  
  186. // fill the orders
  187. var long = false
  188. exitlong = false
  189. if downtexist[1] and not downtexist and uptexist
  190. long := true
  191. if long and downtexist
  192. long := false
  193. exitlong := true
  194. var short = false
  195. exitshort = false
  196. if uptexist[1] and not uptexist and downtexist
  197. short := true
  198. if short and uptexist
  199. short := false
  200. exitshort := true
  201. plotshape(long and not long[1], style = shape.triangleup, color = upcol, location = location.belowbar, size = size.small)
  202. plotshape(exitlong, style = shape.xcross, color = upcol, location = location.abovebar, size = size.small)
  203. plotshape(short and not short[1], style = shape.triangledown, color = dncol, location = location.abovebar, size = size.small)
  204. plotshape(exitshort, style = shape.xcross, color = dncol, location = location.belowbar, size = size.small)
  205.  
  206. alertcondition(long and not long[1], title='Long', message='Enter Long')
  207. alertcondition(exitlong, title='Exit Long', message='Exit Long')
  208. alertcondition(short and not short[1], title='Short', message='Enter Short')
  209. alertcondition(exitshort, title='Exit Short', message='Exit Short')
  210.  
Advertisement
Add Comment
Please, Sign In to add comment