xmd79

Ehlers Adaptive Relative Strength Index (RSI) [Loxx]

Jun 14th, 2022
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.92 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. // © loxx
  3.  
  4. //@version=5
  5. indicator("Ehlers Adaptive Relative Strength Index (RSI) [Loxx]", overlay = false, shorttitle="EARSIA [Loxx]", timeframe="", timeframe_gaps=true, max_bars_back = 3000)
  6.  
  7. greencolor = #2DD204
  8. redcolor = #D2042D
  9.  
  10. _f_hp(_src, max_len) =>
  11. var c = 360 * math.pi / 180
  12. _alpha = (1 - math.sin(c / max_len)) / math.cos(c / max_len)
  13. _hp = 0.0
  14. _hp := 0.5 * (1 + _alpha) * (_src - nz(_src[1])) + _alpha * nz(_hp[1])
  15. _hp
  16.  
  17. _f_ess(_src, _len) =>
  18. var s = 1.414 //sqrt 2
  19. _a = math.exp(-s * math.pi / _len)
  20. _b = 2 * _a * math.cos(s * math.pi / _len)
  21. _c2 = _b
  22. _c3 = -_a * _a
  23. _c1 = 1 - _c2 - _c3
  24. _out = 0.0
  25. _out := _c1 * (_src + nz(_src[1])) / 2 + _c2 * nz(_out[1], nz(_src[1], _src)) + _c3 * nz(_out[2], nz(_src[2], nz(_src[1], _src)))
  26. [_out, _c1, _c2, _c3]
  27.  
  28. _auto_dom(src, min_len, max_len, ave_len) =>
  29. var c = 2 * math.pi
  30. var s = 1.414 //sqrt 2
  31. avglen = ave_len
  32.  
  33. [filt, _, _, _] = _f_ess(_f_hp(src, max_len), min_len)
  34. arr_size = max_len * 2
  35.  
  36. var corr = array.new_float(arr_size, initial_value=0)
  37. var cospart = array.new_float(arr_size, initial_value=0)
  38. var sinpart = array.new_float(arr_size, initial_value=0)
  39. var sqsum = array.new_float(arr_size, initial_value=0)
  40. var r1 = array.new_float(arr_size, initial_value=0)
  41. var r2 = array.new_float(arr_size, initial_value=0)
  42. var pwr = array.new_float(arr_size, initial_value=0)
  43.  
  44. for lag = 0 to max_len by 1
  45. m = avglen == 0 ? lag : avglen
  46. Sx = 0.0
  47. Sy = 0.0
  48. Sxx = 0.0
  49. Syy = 0.0
  50. Sxy = 0.0
  51. for i = 0 to m - 1 by 1
  52. x = nz(filt[i])
  53. y = nz(filt[lag + i])
  54. Sx += x
  55. Sy += y
  56. Sxx += x * x
  57. Sxy += x * y
  58. Syy += y * y
  59. Syy
  60. if (m * Sxx - Sx * Sx) * (m * Syy - Sy * Sy) > 0
  61. array.set(corr, lag, (m * Sxy - Sx * Sy) / math.sqrt((m * Sxx - Sx * Sx) * (m * Syy - Sy * Sy)))
  62.  
  63. for period = min_len to max_len by 1
  64. array.set(cospart, period, 0)
  65. array.set(sinpart, period, 0)
  66. for n = ave_len to max_len by 1
  67. array.set(cospart, period, nz(array.get(cospart, period)) + nz(array.get(corr, n)) * math.cos(c * n / period))
  68. array.set(sinpart, period, nz(array.get(sinpart, period)) + nz(array.get(corr, n)) * math.sin(c * n / period))
  69. array.set(sqsum, period, math.pow(nz(array.get(cospart, period)), 2) + math.pow(nz(array.get(sinpart, period)), 2))
  70.  
  71. for period = min_len to max_len by 1
  72. array.set(r2, period, nz(array.get(r1, period)))
  73. array.set(r1, period, 0.2 * math.pow(nz(array.get(sqsum, period)), 2) + 0.8 * nz(array.get(r2, period)))
  74.  
  75. maxpwr = 0.0
  76. maxpwr := 0.991 * maxpwr
  77.  
  78. for period = min_len to max_len by 1
  79. if nz(array.get(r1, period)) > maxpwr
  80. maxpwr := nz(array.get(r1, period))
  81.  
  82. for period = ave_len to max_len by 1
  83. if maxpwr != 0
  84. array.set(pwr, period, nz(array.get(r1, period)) / maxpwr)
  85.  
  86. spx = 0.0
  87. sp = 0.0
  88.  
  89. for period = min_len to max_len by 1
  90. if nz(array.get(pwr, period)) >= 0.5
  91. spx += period * nz(array.get(pwr, period))
  92. sp += nz(array.get(pwr, period))
  93.  
  94. dominantcycle = 0.0
  95. dominantcycle := sp != 0 ? spx / sp : dominantcycle
  96. dominantcycle := math.min(math.max(dominantcycle, min_len), max_len)
  97. dominantcycle
  98.  
  99.  
  100. auto_src = input.source(close, title='Auto Source', group = "Autocorrelation")
  101. auto_min = input.int(10, minval = 1, title='Auto Min Length', group = "Autocorrelation")
  102. auto_max = input.int(48, minval = 1, title='Auto Max Length', group = "Autocorrelation")
  103. auto_avg = input.int(3, minval = 1, title='Auto Average Length', group = "Autocorrelation")
  104.  
  105. [filt, c1, c2, c3] = _f_ess(_f_hp(auto_src, auto_max), auto_min)
  106.  
  107. masterdom = _auto_dom(auto_src, auto_min, auto_max, auto_avg)
  108.  
  109. len_out_bp_rsi = masterdom < 1 ? 1 : masterdom
  110.  
  111. cup = 0.0
  112. cdn = 0.0
  113.  
  114. for i = 0 to int(len_out_bp_rsi / 2 - 1) by 1
  115. if filt[i] > filt[i + 1]
  116. cup := cup + (filt[i] - filt[i + 1])
  117. if filt[i] < filt[i + 1]
  118. cdn := cdn + (filt[i + 1] - filt[i])
  119.  
  120. denom = cup + cdn
  121. rsiout = 0.0
  122.  
  123. if denom != 0 and denom[1] != 0
  124. rsiout := c1 * (cup / denom + cup[1] / denom[1]) / 2 + c2 * rsiout[1] + c3 * rsiout[2]
  125.  
  126. plot(rsiout, color = rsiout > rsiout[1] ? greencolor : redcolor, linewidth = 3)
  127.  
  128. plot(0.8, color=color.new(color.gray, 30), linewidth=1, style=plot.style_circles, title = "Overbought")
  129. plot(0.5, color=color.new(color.gray, 30), linewidth=1, style=plot.style_circles, title = "Middle")
  130. plot(0.2, color=color.new(color.gray, 30), linewidth=1, style=plot.style_circles, title = "Oversold")
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
Advertisement
Add Comment
Please, Sign In to add comment