[text] CustomSwingAlert

Viewer

copydownloadembedprintName: CustomSwingAlert
  1. // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
  2. // © zanderdogz
  3.  
  4. //@version=5
  5. indicator("SwingCustomAlert", overlay = true)
  6.  
  7.  
  8. //RVOL Calculation: (Credits https://www.reddit.com/user/glst0rm https://www.reddit.com/user/HSeldon2020/ /u/WorkPiece /user/HurlTeaInTheSea)
  9.  
  10. smallSize = input.bool(defval=false, title="Small size")
  11. showRecentBars = input.bool(defval=true, title="Show recent bar strength?") // experimental comparison of bar heights to index
  12. days = input.int(20, minval=1, title="N Day Average")
  13.  
  14. marketTicker = input.symbol(title="Market trend ticker", defval="SPY", inline = "10")
  15.  
  16.  
  17. positionInput = input.string(title='Display position', 
  18.      options=["Upper Right", "Upper Left", "Lower Right", "Lower Left"], 
  19.      defval="Upper Right")
  20.  
  21. bgColor = input.color(title='Background color', 
  22.      defval=color.new(#03072f,0))
  23.  
  24. position = switch positionInput
  25.     "Upper Left" => position.top_left
  26.     "Upper Right" => position.top_right
  27.     "Lower Right" => position.bottom_right
  28.     "Lower Left" => position.bottom_left
  29.  
  30. positionInputBars = input.string(title='Display position of recent bar strength', 
  31.      options=["Upper Right", "Upper Left", "Lower Right", "Lower Left"], 
  32.      defval="Lower Right")
  33.  
  34. positionBars = switch positionInputBars
  35.     "Upper Left" => position.top_left
  36.     "Upper Right" => position.top_right
  37.     "Lower Right" => position.bottom_right
  38.     "Lower Left" => position.bottom_left
  39.  
  40. atrGreen = input.float(defval=.006, title="ATR green level (above)")
  41. atrRed = input.float(defval=.003, title="ATR red level (below)")
  42.  
  43. rVolGreen = input.float(defval=1.0, title="RVol green level (above)")
  44. rVolRed = input.float(defval=.6, title="ATR red level (below)")
  45.  
  46. typeSize = size.normal
  47.  
  48. if smallSize
  49.     typeSize := size.small
  50.  
  51. var newDayBars = array.new_int()
  52.  
  53. // ATR 14 and ATR % of price
  54. // ==================================
  55. atr = request.security(syminfo.tickerid, timeframe.period, ta.atr(14))
  56.  
  57. // approximately five trading days
  58. rAtrLength = switch timeframe.period
  59.     "1" => 500
  60.     "5" => 600
  61.     "15" => 160
  62.     "30" => 80
  63.     "60" => 40
  64.     "120" => 20
  65.     "240" => 10
  66.     "1D" => 5
  67.     => 500 // default (5m bars)
  68.  
  69. rAtr = ta.sma(atr,600) // relative atr over last 600 periods (roughly 5 trading days)
  70. atrPercent = atr / close
  71. rAtrPercent = atr / rAtr
  72.  
  73. atrString = "$" + str.format("{0,number}",math.round(atr, 2)) + " " 
  74.   + str.format("{0}",math.round((atr / close) * 100, 2)) + "% "   
  75.  
  76. rAtrString = str.format("{0}",math.round((rAtrPercent) * 100, 2)) + "% "   
  77.  
  78. atrColor = color.white
  79.  
  80. if (atrPercent >= atrGreen)
  81.     atrColor := color.green
  82.     
  83. else if (atrPercent >= atrRed )
  84.     atrColor := color.yellow
  85.     
  86. else if (atrPercent < atrRed )
  87.     atrColor := color.red
  88.  
  89. rAtrColor = color.white
  90.  
  91. if (rAtrPercent >= 1)
  92.     rAtrColor := color.green
  93.     
  94. else if (rAtrPercent >= .70 )
  95.     rAtrColor := color.yellow
  96.     
  97. else if (rAtrPercent < .70 )
  98.     rAtrColor := color.red
  99.  
  100. // Daily Volume
  101. // ==================================
  102. vol = request.security(syminfo.tickerid, "1D", volume, barmerge.gaps_off, barmerge.lookahead_on) // allow lookahead for current day open price (won't future leak)
  103.  
  104. // RVol and RVol to SPY
  105. // ==================================
  106. // Adapted from script by /u/HurlTeaInTheSea
  107. // https://www.reddit.com/r/RealDayTrading/comments/ue4ujq/tostv_timebased_relative_volume_rvol_a_better/
  108.  
  109. var cVol = 0.0
  110. var spyCVol = 0.0
  111.  
  112. // detect new session of day
  113. isNewDay() =>
  114.     t = time('D') // by default, time() follows symbol's session
  115.     na(t[1]) and not na(t) or t[1] < t
  116.  
  117. if isNewDay()
  118.     // reset cumulative volume
  119.     cVol := 0
  120.     spyCVol := 0
  121.     
  122.     // save new bars in circular array of length days + 1
  123.     array.push(newDayBars, bar_index)
  124.     if (array.size(newDayBars) > days + 1)
  125.         array.shift(newDayBars)
  126.  
  127. // cumulative volume
  128. cVol := cVol + volume
  129.  
  130. // cumulative spy volume
  131. spyCVol := spyCVol + request.security(marketTicker, timeframe.period, volume, barmerge.gaps_off, barmerge.lookahead_off)
  132.  
  133. // calculate relative volume
  134. relativeVolume(cVolArray) =>
  135.     aVol = 0.0
  136.     // check enough days saved in history to run (current day also saved)
  137.     len = array.size(newDayBars)
  138.     if len >= days + 1
  139.         // SMA of historical cumulative volume up to but not including current time of day
  140.         for i = 0 to len - 2
  141.             b1 = array.get(newDayBars, i)
  142.             b2 = array.get(newDayBars, i + 1)
  143.             
  144.             // use historical date but carry over current hour, minutes, seconds (this method is exact and avoids DST bugs)
  145.             t1 = time[bar_index - b1]
  146.             tLookup = timestamp(year(t1), month(t1), dayofmonth(t1), hour(time), minute(time), second(time))
  147.             
  148.             // get latest bar clamped in range [b1, b2) that is equal to or precedes given time (binary search for speed)
  149.             int lo = math.max(0, b1) - 1
  150.             int hi = math.max(0, b2)
  151.             while 1 + lo < hi
  152.                 int mi = lo + math.floor((hi - lo) / 2)
  153.                 if (tLookup < time[bar_index - mi])
  154.                     hi := mi
  155.                 else
  156.                     lo := mi
  157.             lo := lo < b1 ? hi : lo
  158.             bClosest = b1 < b2 ? lo : -1
  159.             
  160.             // add cumulative volume to SMA calculation
  161.             tClosest = time[bar_index - bClosest]
  162.             aVol := aVol + (tLookup >= tClosest ? cVolArray[bar_index - bClosest] / days : 0)
  163.     rVol = aVol > 0 ? cVolArray / aVol : 0
  164.     
  165.  
  166. rVol = relativeVolume(cVol)
  167. spyRVol = relativeVolume(spyCVol)
  168.  
  169. //Get SPY price 
  170.  
  171. SPY = request.security("SPY", timeframe.period, close)
  172.  
  173. //Alert Conditions:
  174.  
  175. SPYlimit = input(1.0)
  176. MinRVOL = input(1.25)
  177. StockPriceAlert = input(1.0)
  178.  
  179. long = SPY > SPYlimit and rVol > MinRVOL and close > StockPriceAlert
  180. short = SPY < SPYlimit and rVol > MinRVOL and close < StockPriceAlert
  181.  
  182.  
  183. //Alerts:
  184. alertcondition(long,  "LongAlert",  "Long")
  185. alertcondition(short, "ShortAlert", "Short")
  186.  
  187.  

Editor

You can edit this paste and save as new:

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

File Description
  • CustomSwingAlert
  • Paste Code
  • 21 Dec-2022
  • 6.02 Kb
You can Share it: