Skip to content

Instantly share code, notes, and snippets.

@flare9x
Last active July 13, 2022 02:40
Show Gist options
  • Save flare9x/ad7319b66ecfe0fb541a82901c5f2526 to your computer and use it in GitHub Desktop.
Save flare9x/ad7319b66ecfe0fb541a82901c5f2526 to your computer and use it in GitHub Desktop.
rsi indicator
"""
```
Relative strength index
rsi(x::Array{T}; n::Int64=14)::Array{Float64}
Indicator weights the average gain and loss correctly not averaging over 0 values. Accounts for NaN in the calculation
using NaNMath; nm=NaNMath
```
"""
function rsi(x::AbstractArray{T}; n::Int64=14)::Array{Float64} where {T<:Real}
dims = size(x,1)
gain = zeros(dims)
loss = zeros(dims)
diffs = zeros(dims)
roll_mean_gain = zeros(dims)
roll_mean_loss = zeros(dims)
RS = zeros(dims)
RSI = zeros(dims)
for i = 2:size(x,1)
diffs[i] = x[i] - x[i-1]
if diffs[i] > 0
gain[i] = diffs[i]
loss[i] = NaN
elseif diffs[i] < 0
loss[i] = abs(diffs[i])
gain[i] = NaN
end
end
start_n = n+1
gain[Int64(start_n)] = 0
loss[Int64(start_n)] = 0
for i = Int64(start_n-1):size(x,1)
if i == start_n-1
roll_mean_gain[i] = nm.sum(gain[2:Int64(start_n-1)])./ (start_n-1.0)
roll_mean_loss[i] = nm.sum(loss[2:Int64(start_n-1)])./ (start_n-1.0)
elseif i > start_n
if isnan(gain[i])
roll_mean_gain[i] = ((roll_mean_gain[i-1] * (start_n-2.0) ) + 0) / (start_n-1.0)
else
roll_mean_gain[i] = ((roll_mean_gain[i-1] * (start_n-2.0) ) + gain[i]) / (start_n-1.0)
end
if isnan(loss[i])
roll_mean_loss[i] = ((roll_mean_loss[i-1] * (start_n-2.0) ) + 0) / (start_n-1.0)
else
roll_mean_loss[i] = ((roll_mean_loss[i-1] * (start_n-2.0) ) + loss[i]) / (start_n-1.0)
end
end
end
RS = roll_mean_gain ./ roll_mean_loss
for i = 1:size(x,1)
if roll_mean_loss[i] == 0
RSI[i] = 100.0
else
RSI[i] = 100.0 - (100.0 / (1+RS[i]) )
end
end
return RSI
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment