forked from Skinok/backtrader-pyqt-ui
-
Notifications
You must be signed in to change notification settings - Fork 0
/
common.py
121 lines (107 loc) · 3.89 KB
/
common.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/env python3
import numpy as np
from math import nan
def calc_parabolic_sar(df, af=0.2, steps=10):
up = True
sars = [nan] * len(df)
sar = ep_lo = df.Low.iloc[0]
ep = ep_hi = df.High.iloc[0]
aaf = af
aaf_step = aaf / steps
af = 0
for i,(hi,lo) in enumerate(zip(df.High, df.Low)):
# parabolic sar formula:
sar = sar + af * (ep - sar)
# handle new extreme points
if hi > ep_hi:
ep_hi = hi
if up:
ep = ep_hi
af = min(aaf, af+aaf_step)
elif lo < ep_lo:
ep_lo = lo
if not up:
ep = ep_lo
af = min(aaf, af+aaf_step)
# handle switch
if up:
if lo < sar:
up = not up
sar = ep_hi
ep = ep_lo = lo
af = 0
else:
if hi > sar:
up = not up
sar = ep_lo
ep = ep_hi = hi
af = 0
sars[i] = sar
df['sar'] = sars
return df['sar']
def calc_rsi(df, n=14):
diff = df.Close.diff().values
gains = diff
losses = -diff
gains[~(gains>0)] = 0.0
losses[~(losses>0)] = 1e-10 # we don't want divide by zero/NaN
m = (n-1) / n
ni = 1 / n
g = gains[n] = gains[:n].mean()
l = losses[n] = losses[:n].mean()
gains[:n] = losses[:n] = nan
for i,v in enumerate(gains[n:],n):
g = gains[i] = ni*v + m*g
for i,v in enumerate(losses[n:],n):
l = losses[i] = ni*v + m*l
rs = gains / losses
rsi = 100 - (100/(1+rs))
return rsi
def calc_stochastic_oscillator(df, n=14, m=3, smooth=3):
lo = df.Low.rolling(n).min()
hi = df.High.rolling(n).max()
k = 100 * (df.Close-lo) / (hi-lo)
d = k.rolling(m).mean()
return k, d
def calc_stochasticRsi_oscillator(df, n=14, m=3, smooth=3):
lo = df.Low.rolling(n).min()
hi = df.High.rolling(n).max()
k = 100 * (df.Close-lo) / (hi-lo)
d = k.rolling(m).mean()
return k, d
# calculating RSI (gives the same values as TradingView)
# https://stackoverflow.com/questions/20526414/relative-strength-index-in-python-pandas
def RSI(series, period=14):
delta = series.diff().dropna()
ups = delta * 0
downs = ups.copy()
ups[delta > 0] = delta[delta > 0]
downs[delta < 0] = -delta[delta < 0]
ups[ups.index[period-1]] = np.mean( ups[:period] ) #first value is sum of avg gains
ups = ups.drop(ups.index[:(period-1)])
downs[downs.index[period-1]] = np.mean( downs[:period] ) #first value is sum of avg losses
downs = downs.drop(downs.index[:(period-1)])
rs = ups.ewm(com=period-1,min_periods=0,adjust=False,ignore_na=False).mean() / \
downs.ewm(com=period-1,min_periods=0,adjust=False,ignore_na=False).mean()
return 100 - 100 / (1 + rs)
# calculating Stoch RSI (gives the same values as TradingView)
# https://www.tradingview.com/wiki/Stochastic_RSI_(STOCH_RSI)
def StochRSI(series, period=14, smoothK=3, smoothD=3):
# Calculate RSI
delta = series.diff().dropna()
ups = delta * 0
downs = ups.copy()
ups[delta > 0] = delta[delta > 0]
downs[delta < 0] = -delta[delta < 0]
ups[ups.index[period-1]] = np.mean( ups[:period] ) #first value is sum of avg gains
ups = ups.drop(ups.index[:(period-1)])
downs[downs.index[period-1]] = np.mean( downs[:period] ) #first value is sum of avg losses
downs = downs.drop(downs.index[:(period-1)])
rs = ups.ewm(com=period-1,min_periods=0,adjust=False,ignore_na=False).mean() / \
downs.ewm(com=period-1,min_periods=0,adjust=False,ignore_na=False).mean()
rsi = 100 - 100 / (1 + rs)
# Calculate StochRSI
stochrsi = (rsi - rsi.rolling(period).min()) / (rsi.rolling(period).max() - rsi.rolling(period).min())
stochrsi_K = stochrsi.rolling(smoothK).mean()
stochrsi_D = stochrsi_K.rolling(smoothD).mean()
return stochrsi, stochrsi_K, stochrsi_D