-
Notifications
You must be signed in to change notification settings - Fork 43
/
compute.py
188 lines (144 loc) · 5.83 KB
/
compute.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
import pandas as pd
import datetime
import numpy as np
#https://github.com/nlsdfnbch/pandas-technical-indicators/blob/master/technical_indicators.py
def daily_returns(df):
# how to read/interpret this ?
print df.head()
# (tomorrow price/today price) - 1
daily_return = (df / df.shift(1)) - 1
print daily_return.head()
daily_return.ix[0, :] = 0
return daily_return
def normalize(df, column='Adj Close'):
# take column, normalize from earliest available date.
print 'pending normalize'
# moving average.
def running_average(df, windowsize):
return df.rolling(windowsize).mean()
def exponential_moving_average(df, windowsize=60):
# df['ewma'] = pd.ewma(df["avg"], span=60, freq="D")
pd.ewma(df["Adj Close"], span=windowsize, freq="D")
def rolling_std_mean(values, window):
"""Return rolling mean of given values, using specified window size."""
# take df, column name option, default value for window too.
# return pd.rolling_std(values, window=window, center=False).mean()
return pd.rolling_mean(values, window=window)
def rolling_std(values, window):
"""Return rolling standard deviation of given values, using specified window size."""
return pd.rolling_std(values, window=window)
def bollinger_bands(rm, rstd):
"""Return upper and lower Bollinger Bands."""
# TODO: Compute upper_band and lower_band
upper_band = rm + rstd * 2 # pd.rolling_std(values, window=window)
lower_band = rm - rstd * 2 # pd.rolling_std(values, window=window)
return upper_band, lower_band
def RSI(series, period):
# print series.size
delta = series.diff().dropna()
# print 'size after drop is '
# print delta.size
u = delta * 0
d = u.copy()
u[delta > 0] = delta[delta > 0]
d[delta < 0] = -delta[delta < 0]
u[u.index[period-1]] = np.mean( u[:period] ) #first value is sum of avg gains
u = u.drop(u.index[:(period-1)])
d[d.index[period-1]] = np.mean( d[:period] ) #first value is sum of avg losses
d = d.drop(d.index[:(period-1)])
rs = pd.stats.moments.ewma(u, com=period-1, adjust=False) / \
pd.stats.moments.ewma(d, com=period-1, adjust=False)
df = pd.DataFrame(100 - 100 / (1 + rs))
# slice first period dates, create series with 50 as value, per date. then concat.
prefixed_values = pd.Series(50, index=series.index.values[0:period])
return pd.concat([prefixed_values, df.ix[:, 0]])
def MACD(df, fast_ma=26, slow_ma=12, signal_period=9):
df['30 mavg'] = pd.rolling_mean(df['Close'], 30)
df['26 ema'] = pd.ewma(df['Close'], span=fast_ma)
df['12 ema'] = pd.ewma(df['Close'], span=slow_ma)
df['MACD'] = (df['12 ema'] - df['26 ema'])
df['Signal'] = pd.ewma(df['MACD'], span=signal_period)
df['Crossover'] = df['MACD'] - df['Signal']
return df
# to be tested...
def stochastic_oscillator_k(df, k_window=14, d_window=3):
# Create the "L14" column in the DataFrame
df['Low_K'] = df['Low'].rolling(window=k_window).min()
# Create the "H14" column in the DataFrame
df['High_K'] = df['High'].rolling(window=k_window).max()
# Create the "%K" column in the DataFrame
df['%K'] = 100 * ((df['Close'] - df['Low_K']) / (df['High_K'] - df['Low_K']))
# Create the "%D" column in the DataFrame
df['%D'] = df['%K'].rolling(window=d_window).mean()
def ROC(df, n):
M = df.diff(n - 1)
N = df.shift(n - 1)
ROC = pd.Series(((M / N) * 100), name = 'ROC_' + str(n))
return ROC
def vortex_indicator(df, n):
"""Calculate the Vortex Indicator for given data.
Vortex Indicator described here:
http://www.vortexindicator.com/VFX_VORTEX.PDF
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
i = 0
TR = [0]
while i < df.index[-1]:
Range = max(df.get_value(i + 1, 'High'), df.get_value(i, 'Close')) - min(df.get_value(i + 1, 'Low'),
df.get_value(i, 'Close'))
TR.append(Range)
i = i + 1
i = 0
VM = [0]
while i < df.index[-1]:
Range = abs(df.get_value(i + 1, 'High') - df.get_value(i, 'Low')) - abs(
df.get_value(i + 1, 'Low') - df.get_value(i, 'High'))
VM.append(Range)
i = i + 1
VI = pd.Series(pd.rolling_sum(pd.Series(VM), n) / pd.rolling_sum(pd.Series(TR), n), name='Vortex_' + str(n))
df = df.join(VI)
return df
def money_flow_index(df, n):
"""Calculate Money Flow Index and Ratio for given data.
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
PP = (df['High'] + df['Low'] + df['Close']) / 3
i = 0
PosMF = [0]
while i < df.index[-1]:
if PP[i + 1] > PP[i]:
PosMF.append(PP[i + 1] * df.get_value(i + 1, 'Volume'))
else:
PosMF.append(0)
i = i + 1
PosMF = pd.Series(PosMF)
TotMF = PP * df['Volume']
MFR = pd.Series(PosMF / TotMF)
MFI = pd.Series(pd.rolling_mean(MFR, n), name='MFI_' + str(n))
df = df.join(MFI)
return df
def CCI(df):
print 'pending'
def Williams_percent_r(df):
print 'pending'
# ---------------------------------------------
def accumulated_close(df):
# requires a column Stance, and Adj close
pointer = df.iloc[0] #first date as index.
booked_profit = 0.00
for index, row in df.iterrows():
if row['Stance'] > 0:
df.loc[index, 'Accumulated Close'] = df.loc[index, 'Adj Close'] + booked_profit
pointer = index
# print 'Buy and hold'
elif row['Stance'] < 0:
df.loc[index, 'Accumulated Close'] = df.loc[pointer, 'Accumulated Close']
booked_profit = df.loc[pointer, 'Accumulated Close'] - df.loc[index, 'Adj Close']
# print 'Sell and hold'
else:
df.loc[index, 'Accumulated Close'] = df.loc[index, 'Adj Close']
# print 'Waiting...'