xmd79

Weekly Range Support & Resistance Levels

Jun 2nd, 2023
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.04 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. // © QuantVue
  3.  
  4. //@version=5
  5. indicator("Weekly Range Support & Resistance Levels", overlay = true, max_labels_count = 500, max_lines_count = 500)
  6.  
  7. //-----------------------------------------------//
  8. //runtime errors
  9. //-----------------------------------------------//
  10. if timeframe.ismonthly
  11. runtime.error('Please switch to lower timeframe')
  12. else if (timeframe.in_seconds() / 60 < timeframe.in_seconds('3') / 60) and (syminfo.type == 'stock' or syminfo.type == 'fund')
  13. runtime.error('Please switch to 3 minute chart or higher')
  14. else if timeframe.in_seconds() / 60 < timeframe.in_seconds('30') / 60 and (syminfo.type == 'crypto' or syminfo.type == 'forex')
  15. runtime.error('Please switch to 30 minute time frame or higher')
  16. else if timeframe.in_seconds() / 60 < timeframe.in_seconds('15') / 60 and syminfo.type == 'cfd'
  17. runtime.error('Please switch to 15 minute time frame or higher')
  18.  
  19. //-----------------------------------------------//
  20. //inputs
  21. //-----------------------------------------------//
  22. showTable = input.bool(true, 'Show Stats on Weekly Chart', inline = '1')
  23. yPos = input.string("Top", " ", options = ["Top", "Middle", "Bottom"], inline = '1')
  24. xPos = input.string("Right", " ", options = ["Right","Center", "Left"], inline = '1')
  25. statsBG = input.color(color.gray, 'Stats Table BG Color', inline = '2')
  26. statsText = input.color(color.white, 'Stats Table Text Color', inline = '2')
  27.  
  28. averagingPerdiod = input.int(30, 'Averaging Period', minval = 5, step = 1)
  29. multiplier = input.float(1.0, 'StDev Multiplier', minval = 1, maxval = 4, step = .25)
  30.  
  31. sLineColor = input.color(color.green, 'Support Color', inline = '3')
  32. rLineColor = input.color(color.red, 'Resistance Color', inline = '3')
  33. showFill = input.bool(true, 'Fill', inline = '3')
  34. showPrice = input.bool(true, 'Show Support / Resistance Prices', inline = '4')
  35. labelTextColor = input.color(color.rgb(255, 255, 255), ' ', inline = '4')
  36.  
  37. showWO = input.bool(true, 'Show Weekly Open Line', inline = '5')
  38. wOColor = input.color(color.orange, ' ', inline = '5')
  39. r1Style = input.string('Solid', 'R1 Line Style', ['Solid', 'Dashed', 'Dotted'], inline = '6')
  40. r2Style = input.string('Solid', 'R2 Line Style', ['Solid', 'Dashed', 'Dotted'], inline = '6')
  41. s1Style = input.string('Solid', 'S1 Line Style', ['Solid', 'Dashed', 'Dotted'], inline = '7')
  42. s2Style = input.string('Solid', 'S2 Line Style', ['Solid', 'Dashed', 'Dotted'], inline = '7')
  43. showPrevious = input.bool(false, 'Show Previous Levels')
  44.  
  45. //-----------------------------------------------//
  46. //methods
  47. //-----------------------------------------------//
  48. method switcher(string this) =>
  49. switch this
  50. 'Solid' => line.style_solid
  51. 'Dashed' => line.style_dashed
  52. 'Dotted' => line.style_dotted
  53.  
  54. //-----------------------------------------------//
  55. //variables
  56. //-----------------------------------------------//
  57. var table stats = table.new(str.lower(yPos) + '_' + str.lower(xPos), 5, 4, border_color = color.new(color.white,100), border_width = 2,
  58. frame_color = color.new(color.white,100), frame_width = 2)
  59.  
  60. var float[] upAvgArray = array.new<float>()
  61. var float[] downAvgArray = array.new<float>()
  62.  
  63. var line r1Line = na, var line r2Line = na, var line s1Line = na, var line s2Line = na, var line WO = na
  64. var label r1Label = na, var label r2Label = na, var label s1Label = na, var label s2Label = na
  65. var box rFill = na, var box sFill = na
  66. var weekCount = 0, var closeAboveR1 = 0, var closeAboveR2 = 0, var closeBelowS1 = 0, var closeBelowS2 = 0
  67. var touchR1 = 0, var touchR2 = 0, var touchS1 = 0, var touchS2 = 0
  68. var R1 = 0.0, var R2 = 0.0, var S1 = 0.0, var S2 = 0.0
  69.  
  70. [weekOpen, weekHigh, weekLow, weekClose] = request.security(syminfo.tickerid, 'W',[open,high,low,close], lookahead = barmerge.lookahead_on)
  71. avgPeriod = timeframe.period == 'W' ? 30 : timeframe.period == 'D' ? averagingPerdiod * 5 : timeframe.isminutes ?
  72. (58500 / str.tonumber(timeframe.period)) : averagingPerdiod
  73. newWeek = ta.change(time('W'))
  74. idxCount = ta.barssince(newWeek)
  75.  
  76. //-----------------------------------------------//
  77. //calculations
  78. //-----------------------------------------------//
  79. up = newWeek ? 100 * ((weekHigh - weekOpen) / weekClose) : na
  80. down = newWeek ? 100 * math.abs(((weekOpen - weekLow) / weekClose)) : na
  81. upStdev = ta.stdev(up, averagingPerdiod) * multiplier
  82. upSD = newWeek ? upStdev[1] : na
  83. downStdev = ta.stdev(down, averagingPerdiod) * multiplier
  84. downSd = newWeek ? downStdev[1] : na
  85.  
  86. if newWeek
  87. if upAvgArray.size() > averagingPerdiod
  88. upAvgArray.pop()
  89. upAvgArray.unshift(up)
  90. else
  91. upAvgArray.unshift(up)
  92. upAvg = upAvgArray.size() > 0 ? upAvgArray.avg() : na
  93.  
  94. if newWeek
  95. if downAvgArray.size() > averagingPerdiod
  96. downAvgArray.pop()
  97. downAvgArray.unshift(down)
  98. else
  99. downAvgArray.unshift(down)
  100. downAvg = downAvgArray.size() > 0 ? downAvgArray.avg() : na
  101.  
  102. R1 := newWeek ? weekOpen + (upAvg / 100) * weekOpen : R1[1]
  103. R2 := newWeek ? weekOpen + ((upAvg + upSD) / 100) * weekOpen : R2[1]
  104. S1 := newWeek ? weekOpen - (downAvg / 100) * weekOpen : S1[1]
  105. S2 := newWeek ? weekOpen - ((downAvg + downSd) / 100) * weekOpen : S2[1]
  106.  
  107. //-----------------------------------------------//
  108. //weekly stats
  109. //-----------------------------------------------//
  110. weekCount := newWeek ? weekCount + 1 : weekCount
  111. if weekClose > R1
  112. closeAboveR1 += 1
  113. if weekClose > R2
  114. closeAboveR2 += 1
  115. if weekClose < S1
  116. closeBelowS1 += 1
  117. if weekClose < S2
  118. closeBelowS2 += 1
  119. if weekHigh >= R1
  120. touchR1 += 1
  121. if weekHigh >= R2
  122. touchR2 += 1
  123. if weekLow <= S1
  124. touchS1 += 1
  125. if weekLow <= S2
  126. touchS2 += 1
  127. closeInsideAvg = weekCount - closeAboveR1 - closeBelowS1
  128. closeInsideAvgPlus = weekCount - closeAboveR2 - closeBelowS2
  129.  
  130. //-----------------------------------------------//
  131. //weekly stats table
  132. //-----------------------------------------------//
  133. if barstate.islast and showTable and timeframe.isweekly and yPos == 'Top'
  134. stats.cell(0,0, ' ')
  135. stats.cell(0, 1, 'Touch R1: ' + str.tostring(touchR1) + ' / ' + str.tostring((touchR1/weekCount), '#.#%'),
  136. text_color = statsText, bgcolor = statsBG)
  137. stats.cell(1, 1, 'Close > R1: ' + str.tostring(closeAboveR1) + ' / ' + str.tostring((closeAboveR1/weekCount), '#.#%'),
  138. text_color = statsText, bgcolor = statsBG)
  139. stats.cell(2, 1, 'Touch R2: ' + str.tostring(touchR2) + ' / ' + str.tostring((touchR2/weekCount), '#.#%'),
  140. text_color = statsText, bgcolor = statsBG)
  141. stats.cell(3, 1, 'Close > R2: ' + str.tostring(closeAboveR2) + ' / ' + str.tostring((closeAboveR2/weekCount), '#.#%'),
  142. text_color = statsText, bgcolor = statsBG)
  143. stats.cell(0, 2, 'Touch S1: ' + str.tostring(touchS1) + ' / ' + str.tostring((touchS1/weekCount), '#.#%'),
  144. text_color = statsText, bgcolor = statsBG)
  145. stats.cell(1, 2, 'Close < S1: ' + str.tostring(closeBelowS1) + ' / ' + str.tostring((closeBelowS1/weekCount), '#.#%'),
  146. text_color = statsText, bgcolor = statsBG)
  147. stats.cell(2, 2, 'Touch S2: ' + str.tostring(touchS2) + ' / ' + str.tostring((touchS2/weekCount), '#.#%'),
  148. text_color = statsText, bgcolor = statsBG)
  149. stats.cell(3, 2, 'Close < S2: ' + str.tostring(closeBelowS2) + ' / ' + str.tostring((closeBelowS2/weekCount), '#.#%'),
  150. text_color = statsText, bgcolor = statsBG)
  151. stats.cell(4, 3, 'Weeks Analyzed: ' + str.tostring(weekCount), text_color = statsText, bgcolor = statsBG)
  152. stats.cell(4, 1, 'Total Closes Inside R1/S1: ' + str.tostring(closeInsideAvg) + ' / ' + str.tostring((closeInsideAvg/weekCount), '#.#%'),
  153. text_color = statsText, bgcolor = statsBG)
  154. stats.cell(4, 2, 'Total Closes Inside R2/S2: ' + str.tostring(closeInsideAvgPlus) + ' / ' + str.tostring((closeInsideAvgPlus/weekCount), '#.#%'),
  155. text_color = statsText, bgcolor = statsBG)
  156. else if barstate.islast and showTable and timeframe.isweekly
  157. stats.cell(0, 0, 'Touch R1: ' + str.tostring(touchR1) + ' / ' + str.tostring((touchR1/weekCount), '#.#%'),
  158. text_color = statsText, bgcolor = statsBG)
  159. stats.cell(1, 0, 'Close > R1: ' + str.tostring(closeAboveR1) + ' / ' + str.tostring((closeAboveR1/weekCount), '#.#%'),
  160. text_color = statsText, bgcolor = statsBG)
  161. stats.cell(2, 0, 'Touch R2: ' + str.tostring(touchR2) + ' / ' + str.tostring((touchR2/weekCount), '#.#%'),
  162. text_color = statsText, bgcolor = statsBG)
  163. stats.cell(3, 0, 'Close > R2: ' + str.tostring(closeAboveR2) + ' / ' + str.tostring((closeAboveR2/weekCount), '#.#%'),
  164. text_color = statsText, bgcolor = statsBG)
  165. stats.cell(0, 1, 'Touch S1: ' + str.tostring(touchS1) + ' / ' + str.tostring((touchS1/weekCount), '#.#%'),
  166. text_color = statsText, bgcolor = statsBG)
  167. stats.cell(1, 1, 'Close < S1: ' + str.tostring(closeBelowS1) + ' / ' + str.tostring((closeBelowS1/weekCount), '#.#%'),
  168. text_color = statsText, bgcolor = statsBG)
  169. stats.cell(2, 1, 'Touch S2: ' + str.tostring(touchS2) + ' / ' + str.tostring((touchS2/weekCount), '#.#%'),
  170. text_color = statsText, bgcolor = statsBG)
  171. stats.cell(3, 1, 'Close < S2: ' + str.tostring(closeBelowS2) + ' / ' + str.tostring((closeBelowS2/weekCount), '#.#%'),
  172. text_color = statsText, bgcolor = statsBG)
  173. stats.cell(0, 2, 'Weeks Analyzed: ' + str.tostring(weekCount), text_color = statsText, bgcolor = statsBG)
  174. stats.cell(1, 2, 'Total Closes Inside R1/S1: ' + str.tostring(closeInsideAvg) + ' / ' + str.tostring((closeInsideAvg/weekCount), '#.#%'),
  175. text_color = statsText, bgcolor = statsBG)
  176. stats.cell(2, 2, 'Total Closes Inside R2/S2: ' + str.tostring(closeInsideAvgPlus) + ' / ' + str.tostring((closeInsideAvgPlus/weekCount), '#.#%'),
  177. text_color = statsText, bgcolor = statsBG)
  178.  
  179. //-----------------------------------------------//
  180. //support and resistance levels
  181. //-----------------------------------------------//
  182. if newWeek and (syminfo.type == 'stock' or syminfo.type == 'fund')
  183. (r1Line[1]).delete(), (r2Line[1]).delete(), (s1Line[1]).delete(), (s2Line[1]).delete()
  184. (r1Label[1]).delete(), (r2Label[1]).delete(), (s1Label[1]).delete(), (s2Label[1]).delete()
  185. (WO[1]).delete()
  186. if showWO
  187. WO := line.new(bar_index, weekOpen, timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 4 :
  188. timeframe.isminutes ? bar_index + int((390 / (str.tonumber(timeframe.period)) * 5)) : bar_index + 4, weekOpen,
  189. color = wOColor, width = 3)
  190. r1Line := line.new(bar_index, R1, timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 4 :
  191. timeframe.isminutes ? bar_index + int((390 / (str.tonumber(timeframe.period)) * 5)) : bar_index + 4, R1,
  192. color = rLineColor, width = 2, style = r1Style.switcher())
  193. r2Line := line.new(bar_index, R2, timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 4 :
  194. timeframe.isminutes ? bar_index + int((390 / (str.tonumber(timeframe.period)) * 5)) : bar_index + 4, R2,
  195. color = rLineColor, width = 2, style = r2Style.switcher())
  196. s1Line := line.new(bar_index, S1, timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 4 :
  197. timeframe.isminutes ? bar_index + int((390 / (str.tonumber(timeframe.period)) * 5)) : bar_index + 4, S1,
  198. color = sLineColor, width = 2, style = s1Style.switcher())
  199. s2Line := line.new(bar_index, S2, timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 4 :
  200. timeframe.isminutes ? bar_index + int((390 / (str.tonumber(timeframe.period)) * 5)) : bar_index + 4, S2,
  201. color = sLineColor, width = 2, style = s2Style.switcher())
  202. if showPrice
  203. r1Label := label.new(timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 4 :
  204. timeframe.isminutes ? bar_index + int((390 / (str.tonumber(timeframe.period)) * 5)) : bar_index + 4,
  205. R1, 'R1 $' + str.tostring(R1, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
  206. textcolor = labelTextColor)
  207. r2Label := label.new(timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 4 :
  208. timeframe.isminutes ? bar_index + int((390 / (str.tonumber(timeframe.period)) * 5)) : bar_index + 4,
  209. R2, 'R2 $' + str.tostring(R2, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
  210. textcolor = labelTextColor)
  211. s1Label := label.new(timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 4 :
  212. timeframe.isminutes ? bar_index + int((390 / (str.tonumber(timeframe.period)) * 5)) : bar_index + 4,
  213. S1, 'S1 $' + str.tostring(S1, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
  214. textcolor = labelTextColor)
  215. s2Label := label.new(timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 4 :
  216. timeframe.isminutes ? bar_index + int((390 / (str.tonumber(timeframe.period)) * 5)) : bar_index + 4,
  217. S2, 'S2 $' + str.tostring(S2, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
  218. textcolor = labelTextColor)
  219. if showFill
  220. (sFill[1]).delete(), (rFill[1]).delete()
  221. sFill := box.new(bar_index, S1, timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 4 :
  222. timeframe.isminutes ? bar_index + int((390 / (str.tonumber(timeframe.period)) * 5)) : bar_index + 4, S2,
  223. border_width = 0, bgcolor = color.new(sLineColor,80))
  224. rFill := box.new(bar_index, R1, timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 4 :
  225. timeframe.isminutes ? bar_index + int((390 / (str.tonumber(timeframe.period)) * 5)) : bar_index + 4, R2,
  226. border_width = 0, bgcolor = color.new(rLineColor,80))
  227. else if newWeek and (syminfo.type == 'crypto' or syminfo.type == 'forex' or syminfo.type == 'cfd')
  228. (r1Line[1]).delete(), (r2Line[1]).delete(), (s1Line[1]).delete(), (s2Line[1]).delete()
  229. (r1Label[1]).delete(), (r2Label[1]).delete(), (s1Label[1]).delete(), (s2Label[1]).delete()
  230. (WO[1]).delete()
  231. if showWO
  232. WO := line.new(bar_index, weekOpen, timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 6 :
  233. timeframe.isminutes ? bar_index + int((24 * 60 / (str.tonumber(timeframe.period)) * 7)) : bar_index + 6, weekOpen,
  234. color = wOColor, width = 3)
  235. r1Line := line.new(bar_index, R1, timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 6 :
  236. timeframe.isminutes ? bar_index + int((24 * 60 / (str.tonumber(timeframe.period)) * 7)) : bar_index + 6, R1,
  237. color = rLineColor, width = 2, style = r1Style.switcher())
  238. r2Line := line.new(bar_index, R2, timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 6 :
  239. timeframe.isminutes ? bar_index + int((24 * 60/ (str.tonumber(timeframe.period)) * 7)) : bar_index + 6, R2,
  240. color = rLineColor, width = 2, style = r2Style.switcher())
  241. s1Line := line.new(bar_index, S1, timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 6 :
  242. timeframe.isminutes ? bar_index + int((24 * 60 / (str.tonumber(timeframe.period)) * 7)) : bar_index + 6, S1,
  243. color = sLineColor, width = 2, style = s1Style.switcher())
  244. s2Line := line.new(bar_index, S2, timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 6 :
  245. timeframe.isminutes ? bar_index + int((24 * 60 / (str.tonumber(timeframe.period)) * 7)) : bar_index + 6, S2,
  246. color = sLineColor, width = 2, style = s2Style.switcher())
  247. if showPrice
  248. r1Label := label.new(timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 6 :
  249. timeframe.isminutes ? bar_index + int((24 * 60 / (str.tonumber(timeframe.period)) * 7)) : bar_index + 6,
  250. R1, 'R1 $' + str.tostring(R1, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
  251. textcolor = labelTextColor)
  252. r2Label := label.new(timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 6 :
  253. timeframe.isminutes ? bar_index + int((24 * 60 / (str.tonumber(timeframe.period)) * 7)) : bar_index + 6,
  254. R2, 'R2 $' + str.tostring(R2, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
  255. textcolor = labelTextColor)
  256. s1Label := label.new(timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 6 :
  257. timeframe.isminutes ? bar_index + int((24 * 60 / (str.tonumber(timeframe.period)) * 7)) : bar_index + 6,
  258. S1, 'S1 $' + str.tostring(S1, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
  259. textcolor = labelTextColor)
  260. s2Label := label.new(timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 6 :
  261. timeframe.isminutes ? bar_index + int((24 * 60 / (str.tonumber(timeframe.period)) * 7)) : bar_index + 6,
  262. S2, 'S2 $' + str.tostring(S2, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
  263. textcolor = labelTextColor)
  264. if showFill
  265. (sFill[1]).delete(), (rFill[1]).delete()
  266. sFill := box.new(bar_index, S1, timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 6 :
  267. timeframe.isminutes ? bar_index + int((24 * 60 / (str.tonumber(timeframe.period)) * 7)) : bar_index + 6, S2,
  268. border_width = 0, bgcolor = color.new(sLineColor,80))
  269. rFill := box.new(bar_index, R1, timeframe.isweekly ? bar_index + 2 : timeframe.isdaily ? bar_index + 6 :
  270. timeframe.isminutes ? bar_index + int((24 * 60 / (str.tonumber(timeframe.period)) * 7)) : bar_index + 6, R2,
  271. border_width = 0, bgcolor = color.new(rLineColor,80))
  272. if showPrevious and showFill
  273. sFill.set_left(bar_index), rFill.set_left(bar_index)
  274.  
  275. //-----------------------------------------------//
  276. //show historical levels
  277. //-----------------------------------------------//
  278. fillColor = color.new(color.white,100)
  279. r1Plot = plot(showPrevious ? R1 : na, color = color.red)
  280. r2Plot = plot(showPrevious ? R2 : na, color = color.maroon)
  281. s1Plot = plot(showPrevious ? S1 : na, color = color.green)
  282. s2Plot = plot(showPrevious ? S2 : na, color = color.lime)
  283. fill(r1Plot, r2Plot, color = showFill ? color.new(rLineColor, 80) : fillColor)
  284. fill(s1Plot, s2Plot, color = showFill ? color.new(sLineColor, 80) : fillColor)
  285.  
  286. //-----------------------------------------------//
  287. //alert conditions
  288. //-----------------------------------------------//
  289. crossR1 = ta.crossover(close,R1)
  290. crossR2 = ta.crossover(close,R2)
  291. crossS1 = ta.crossunder(close,S1)
  292. crossS2 = ta.crossunder(close,S2)
  293.  
  294. alertcondition(crossR1, 'Cross Above R1', 'Price crossing above R1')
  295. alertcondition(crossR2, 'Cross Above R2', 'Price crossing above R2')
  296. alertcondition(crossS1, 'Cross Below S1', 'Price crossing below S1')
  297. alertcondition(crossS2, 'Cross Below S2', 'Price crossing below S2')
Advertisement
Add Comment
Please, Sign In to add comment