xmd79

MomentumSignals

Nov 14th, 2021
182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.38 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. // © Electrified (electrifiedtrading)
  3.  
  4. // @version=5
  5. // @description Contains utilities varying algorithms for detecting key changes in momentum. Note: Momentum is not velocity and should be used in conjunction with other indicators. A change in momentum does not mean a reversal of velocity or trend.
  6. library('MomentumSignals')
  7. import Electrified/MovingAverages/3 as MA
  8. import Electrified/Momentum/2
  9.  
  10. quantize(float value, simple int up = 1, simple int dn = -1) =>
  11. na(value) ? na : value > 0 ? up : value < 0 ? dn : 0
  12.  
  13. signalOnly(
  14. series float s) =>
  15. quantize(ta.change(s))
  16.  
  17. // Changes in direction at the key.
  18. reverseSignalOnly(
  19. series float s,
  20. simple int len = 2) =>
  21. c = ta.change(s, len)
  22. if c > 0 and s < 0
  23. +1
  24. else if c < 0 and s > 0
  25. -1
  26. else
  27. 0
  28.  
  29. // Simplified super-trend algo
  30. trend(series float h, series float d, int len, float m = 1) =>
  31. var lo = h
  32. var hi = h
  33. var direction = 0
  34.  
  35. if na(lo)
  36. lo := h
  37. if na(hi)
  38. hi := h
  39.  
  40. std = ta.stdev(d, len)
  41.  
  42. if h > hi
  43. direction := +1
  44. hi := h
  45. lo := h - std * m
  46. else if h < lo
  47. direction := -1
  48. lo := h
  49. hi := h + std * m
  50.  
  51. [direction, std]
  52. ////
  53.  
  54. ///////////////////////////////////////////////////
  55. // @function Compares two series for changes in momentum to derive signal values.
  56. // @param primary The primary series (typically a moving average) to look for changes in momentum.
  57. // @param secondary The secondary series (typically derived moving average of the primary) to use as a comparison value.
  58. // @param len The number of bars to measure the change in momentum.
  59. export simple(
  60. series float primary,
  61. series float secondary) =>
  62. p = signalOnly(primary)
  63. s = signalOnly(secondary)
  64. h = primary - secondary // similar to the histogram in MACD.
  65. d = ta.change(h)
  66. x = quantize(d)
  67.  
  68. p + s + x
  69. ///////////////////////////////////////////////////
  70.  
  71. ///////////////////////////////////////////////////
  72. // @function Compares two series for changes in momentum to derive signal values. Uses statistics to filter out changes in momentum.
  73. // @param primary The primary series (typically a moving average) to look for changes in momentum.
  74. // @param secondary The secondary series (typically derived moving average of the primary) to use as a comparison value.
  75. // @param len The number of bars to measure the change in momentum.
  76. // @param stdlen The number of bars to measure the change in momentum for filtering.
  77. // @param stdMultiple The multiple of the change in momentum to use before reversiing.
  78. export filtered(
  79. series float primary,
  80. series float secondary,
  81. simple int stdlen = 200,
  82. simple float stdMultiple = 3.5) =>
  83. p = signalOnly(primary)
  84. s = signalOnly(secondary)
  85. h = primary - secondary // similar to the histogram in MACD.
  86. d = ta.change(h)
  87. [t, std] = trend(h, d, stdlen, stdMultiple)
  88. x = t > 0 and d < 0 or t < 0 and d > 0 ? 0 : quantize(d)
  89.  
  90. p + s + x
  91. ///////////////////////////////////////////////////
  92.  
  93. ///////////////////////////////////////////////////
  94. // @function Compares two series for changes in momentum to derive signal values. Uses statistics to filter out changes in momentum. Does not signal when likely overbought or oversold.
  95. // @param primary The primary series (typically a moving average) to look for changes in momentum.
  96. // @param secondary The secondary series (typically derived moving average of the primary) to use as a comparison value.
  97. // @param stdlen The number of bars to measure the change in momentum for filtering.
  98. // @param stdMultiple The multiple of the change in momentum to use before reversiing.
  99. export special(
  100. series float primary,
  101. series float secondary,
  102. simple int stdlen = 200,
  103. simple float stdMultiple = 3.5) =>
  104. p = signalOnly(primary)
  105. s = signalOnly(secondary)
  106. h = primary - secondary // similar to the histogram in MACD.
  107. d = ta.change(h)
  108. [t, std] = trend(h, d, stdlen, stdMultiple)
  109. sm = std * stdMultiple / 2
  110. x = t > 0 and d < 0 or t < 0 and d > 0 ? 0 : quantize(d)
  111. r = p + s + x
  112. // When the signal level has exceeded the histogram, signals become more risky.
  113. r := primary > secondary and secondary > h or primary < secondary and secondary < h ? x : r
  114. // Filter out noise.
  115. r > 0 and primary > 0 and primary < secondary or r < 0 and primary < 0 and primary > secondary ? 0 : r
  116. ///////////////////////////////////////////////////
  117.  
  118. ///////////////////////////////////////////////////
  119. // @function Returns a signal value representing the stage of where the RSI is in its cycle.
  120. // @param smoothK The length to average the stochastic.
  121. // @param smoothD The length to smooth out K and produce D.
  122. // @param rsiLen The length of the RSI.
  123. // @param stochLen The length of stochastic.
  124. // @param src The series to measure from. Default is 'close'.
  125. // @param kmode The type of moving average to generate. Values allowed are: SMA, EMA, WMA, VWMA and VAWMA.
  126. // @param upper The upper band of the range.
  127. // @param lower The lower band of the range.
  128. // @returns [K, D]
  129. export stochRSI(
  130. simple int smoothK,
  131. simple int smoothD,
  132. simple int rsiLen,
  133. simple int stochLen,
  134. series float src = close,
  135. simple string kmode = "SMA",
  136. simple float upper = 80,
  137. simple float lower = 20) =>
  138. [k, d] = Momentum.stochRSI(smoothK, smoothD, rsiLen, stochLen, src, kmode)
  139.  
  140. // Where are we?
  141. var stage = 0
  142. if k < lower
  143. stage := -2
  144. else if k > upper
  145. stage := +2
  146. else if k < 50
  147. stage := -1
  148. else if k > 50
  149. stage := +1
  150.  
  151. stage_c = ta.change(stage)
  152. k_c = quantize(ta.change(k))
  153.  
  154. // Does k not align with the direction?
  155. if k_c != quantize(k - d)
  156. 0
  157. else
  158. if stage_c > 0 and stage == -1
  159. k_c + 1
  160. else if stage_c < 0 and stage == +1
  161. k_c - 1
  162. else if d < lower
  163. k_c < 0 ? 0 : k_c
  164. else if d > upper
  165. k_c > 0 ? 0 : k_c
  166. else
  167. k_c
  168. ///////////////////////////////////////////////////
  169.  
  170.  
  171.  
  172.  
  173. // Example:
  174. SMA = 'SMA', EMA = 'EMA', WMA = 'WMA', VWMA = 'VWMA', VAWMA = 'VAWMA'
  175. [m, s, h] = Momentum.macd(
  176. input.int(24, "MACD Length", minval=1),
  177. input.int(52, "Signal Length", minval=1),
  178. input.int(12, "Signal Smoothing", minval=1),
  179. input.source(hlc3, "Source"),
  180. input.string(WMA, "MACD MA Type", options=[SMA,EMA,WMA,VWMA,VAWMA]),
  181. input.string(WMA, "Signal MA Type", options=[SMA,EMA,WMA,VWMA,VAWMA]))
  182.  
  183. stdLen = input.int(200, "StdDev Length", minval=1, tooltip="Length of standard deviation measurement of historgram change")
  184. stdM = input.float(3.5, "StdDev Multiple", minval=0, step=0.5, tooltip="The number of standard deviations before momentum may have reversed")
  185.  
  186. plot(m, "MACD", color.blue)
  187. plot(s, "Signal", color.yellow)
  188. plot(h, "Histogram", color.gray, style=plot.style_columns)
  189.  
  190. signal = special(m, s, stdLen, stdM)
  191. //plot(signal, "Signal", color.orange)
  192. color signalColor = switch signal
  193. +3 => color.new(color.green, 40)
  194. +2 => color.new(color.green, 60)
  195. +1 => color.new(color.green, 80)
  196. -1 => color.new(color.red, 80)
  197. -2 => color.new(color.red, 60)
  198. -3 => color.new(color.red, 40)
  199. => na
  200.  
  201. bgcolor(signalColor)
Advertisement
Add Comment
Please, Sign In to add comment