Skip to content

Commit e5dded4

Browse files
committed
Stochastic RSI calculation
1 parent e2a86e3 commit e5dded4

File tree

3 files changed

+203
-5
lines changed

3 files changed

+203
-5
lines changed

SofienKaabar.py

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import numpy as np
2+
3+
def rsi(Data, rsi_lookback, what1, what2):
4+
5+
# From exponential to smoothed
6+
rsi_lookback = (rsi_lookback * 2) - 1
7+
8+
# Get the difference in price from previous step
9+
delta = []
10+
11+
for i in range(len(Data)):
12+
try:
13+
diff = Data[i, what1] - Data[i - 1, what1]
14+
delta = np.append(delta, diff)
15+
except IndexError:
16+
pass
17+
18+
delta = np.insert(delta, 0, 0, axis = 0)
19+
delta = delta[1:]
20+
21+
# Make the positive gains (up) and negative gains (down) Series
22+
up, down = delta.copy(), delta.copy()
23+
up[up < 0] = 0
24+
down[down > 0] = 0
25+
26+
up = np.array(up)
27+
down = np.array(down)
28+
29+
roll_up = up
30+
roll_down = down
31+
32+
roll_up = np.reshape(roll_up, (-1, 1))
33+
roll_down = np.reshape(roll_down, (-1, 1))
34+
35+
roll_up = adder(roll_up, 3)
36+
roll_down = adder(roll_down, 3)
37+
38+
roll_up = ema(roll_up, 2, rsi_lookback, what2, 1)
39+
roll_down = ema(abs(roll_down), 2, rsi_lookback, what2, 1)
40+
41+
roll_up = roll_up[rsi_lookback:, 1:2]
42+
roll_down = roll_down[rsi_lookback:, 1:2]
43+
Data = Data[rsi_lookback + 1:,]
44+
45+
# Calculate the RS & RSI
46+
RS = roll_up / roll_down
47+
RSI = (100.0 - (100.0 / (1.0 + RS)))
48+
RSI = np.array(RSI)
49+
RSI = np.reshape(RSI, (-1, 1))
50+
RSI = RSI[1:,]
51+
52+
Data = np.concatenate((Data, RSI), axis = 1)
53+
return Data
54+
55+
def ma(Data, lookback, what, where):
56+
57+
for i in range(len(Data)):
58+
try:
59+
Data[i, where] = (Data[i - lookback + 1:i + 1, what].mean())
60+
except IndexError:
61+
pass
62+
63+
return Data
64+
65+
def ema(Data, alpha, lookback, what, where):
66+
67+
# alpha is the smoothing factor
68+
# window is the lookback period
69+
# what is the column that needs to have its average calculated
70+
# where is where to put the exponential moving average
71+
72+
alpha = alpha / (lookback + 1.0)
73+
beta = 1 - alpha
74+
75+
# First value is a simple SMA
76+
Data = ma(Data, lookback, what, where)
77+
78+
# Calculating first EMA
79+
Data[lookback + 1, where] = (Data[lookback + 1, what] * alpha) + (Data[lookback, where] * beta)
80+
# Calculating the rest of EMA
81+
for i in range(lookback + 2, len(Data)):
82+
try:
83+
Data[i, where] = (Data[i, what] * alpha) + (Data[i - 1, where] * beta)
84+
85+
except IndexError:
86+
pass
87+
return Data
88+
89+
# The function to add a certain number of columns
90+
def adder(Data, times):
91+
92+
for i in range(1, times + 1):
93+
94+
z = np.zeros((len(Data), 1), dtype = float)
95+
Data = np.append(Data, z, axis = 1)
96+
return Data
97+
# The function to deleter a certain number of columns
98+
def deleter(Data, index, times):
99+
100+
for i in range(1, times + 1):
101+
102+
Data = np.delete(Data, index, axis = 1)
103+
return Data
104+
# The function to delete a certain number of rows from the beginning
105+
def jump(Data, jump):
106+
107+
Data = Data[jump:, ]
108+
109+
return Data
110+
111+
112+
def stochastic(Data, lookback, what, high, low, where):
113+
114+
for i in range(len(Data)):
115+
116+
try:
117+
Data[i, where] = (Data[i, what] - min(Data[i - lookback + 1:i + 1, low])) / (max(Data[i - lookback + 1:i + 1, high]) - min(Data[i - lookback + 1:i + 1, low]))
118+
119+
except ValueError:
120+
pass
121+
122+
Data[:, where] = Data[:, where] * 100
123+
return Data
124+
125+
# The Data variable refers to the OHLC array
126+
# The lookback variable refers to the period (5, 14, 21, etc.)
127+
# The what variable refers to the closing price
128+
# The high variable refers to the high price
129+
# The low variable refers to the low price
130+
# The where variable refers to where to put the Oscillator
131+
def stoch_rsi(Data, lookback, where):
132+
133+
# Calculating RSI of the Closing prices
134+
Data = rsi(Data, lookback, 3, 0)
135+
136+
# Adding two columns
137+
Data = adder(Data, 2)
138+
139+
for i in range(len(Data)):
140+
141+
try:
142+
Data[i, where + 1] = (Data[i, where] - min(Data[i - lookback + 1:i + 1, where])) / (max(Data[i - lookback + 1:i + 1, where]) - min(Data[i - lookback + 1:i + 1, where]))
143+
144+
except ValueError:
145+
pass
146+
147+
Data[:, where + 1] = Data[:, where + 1] * 100
148+
149+
# Signal Line using a 3-period moving average
150+
Data = ma(Data, 3, where + 1, where + 2)
151+
152+
Data = deleter(Data, where, 2)
153+
Data = jump(Data, lookback)
154+
155+
return Data

common.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/usr/bin/env python3
2+
import numpy as np
23

34
from math import nan
45

@@ -76,3 +77,45 @@ def calc_stochasticRsi_oscillator(df, n=14, m=3, smooth=3):
7677
k = 100 * (df.Close-lo) / (hi-lo)
7778
d = k.rolling(m).mean()
7879
return k, d
80+
81+
82+
# calculating RSI (gives the same values as TradingView)
83+
# https://stackoverflow.com/questions/20526414/relative-strength-index-in-python-pandas
84+
def RSI(series, period=14):
85+
delta = series.diff().dropna()
86+
ups = delta * 0
87+
downs = ups.copy()
88+
ups[delta > 0] = delta[delta > 0]
89+
downs[delta < 0] = -delta[delta < 0]
90+
ups[ups.index[period-1]] = np.mean( ups[:period] ) #first value is sum of avg gains
91+
ups = ups.drop(ups.index[:(period-1)])
92+
downs[downs.index[period-1]] = np.mean( downs[:period] ) #first value is sum of avg losses
93+
downs = downs.drop(downs.index[:(period-1)])
94+
rs = ups.ewm(com=period-1,min_periods=0,adjust=False,ignore_na=False).mean() / \
95+
downs.ewm(com=period-1,min_periods=0,adjust=False,ignore_na=False).mean()
96+
return 100 - 100 / (1 + rs)
97+
98+
99+
# calculating Stoch RSI (gives the same values as TradingView)
100+
# https://www.tradingview.com/wiki/Stochastic_RSI_(STOCH_RSI)
101+
def StochRSI(series, period=14, smoothK=3, smoothD=3):
102+
# Calculate RSI
103+
delta = series.diff().dropna()
104+
ups = delta * 0
105+
downs = ups.copy()
106+
ups[delta > 0] = delta[delta > 0]
107+
downs[delta < 0] = -delta[delta < 0]
108+
ups[ups.index[period-1]] = np.mean( ups[:period] ) #first value is sum of avg gains
109+
ups = ups.drop(ups.index[:(period-1)])
110+
downs[downs.index[period-1]] = np.mean( downs[:period] ) #first value is sum of avg losses
111+
downs = downs.drop(downs.index[:(period-1)])
112+
rs = ups.ewm(com=period-1,min_periods=0,adjust=False,ignore_na=False).mean() / \
113+
downs.ewm(com=period-1,min_periods=0,adjust=False,ignore_na=False).mean()
114+
rsi = 100 - 100 / (1 + rs)
115+
116+
# Calculate StochRSI
117+
stochrsi = (rsi - rsi.rolling(period).min()) / (rsi.rolling(period).max() - rsi.rolling(period).min())
118+
stochrsi_K = stochrsi.rolling(smoothK).mean()
119+
stochrsi_D = stochrsi_K.rolling(smoothD).mean()
120+
121+
return stochrsi, stochrsi_K, stochrsi_D

indicators/stochasticRsi.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44
sys.path.append('../finplot')
55
import finplot as fplt
66

7-
from common import calc_stochasticRsi_oscillator
7+
from common import StochRSI
88

99
class StochasticRsi():
1010

11-
def __init__(self, dataFrames, stochasticRsi_periods=14, stochasticRsi_quick=3, stochasticRsi_smooth = 3):
12-
self.stochasticRsi_df, self.stochasticRsi_quick_df = calc_stochasticRsi_oscillator(dataFrames, stochasticRsi_periods, stochasticRsi_quick, stochasticRsi_smooth)
11+
def __init__(self, dataFrames, period=14, smoothK=3, smoothD = 3):
12+
self.stochrsi, self.stochrsi_K, self.stochrsi_D = StochRSI(dataFrames, period, smoothK, smoothD)
1313
pass
1414

1515
def draw(self, ax, stochasticRsi_color = "red", stochasticRsi_quick_color="green"):
16-
self.stochasticRsi_plot = fplt.plot(self.stochasticRsi_df, ax = ax, color=stochasticRsi_color, width=1 )
17-
self.stochasticRsi_quick_plot = fplt.plot(self.stochasticRsi_quick_df, ax = ax, color=stochasticRsi_quick_color, width=1 )
16+
self.stochrsi_K_plot = fplt.plot(self.stochrsi_K, ax = ax, color=stochasticRsi_color, width=1 )
17+
self.stochrsi_D_plot = fplt.plot(self.stochrsi_D, ax = ax, color=stochasticRsi_quick_color, width=1 )
1818
pass
1919

2020
def clear(self):

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy