def plot(data): fig, ax = plt.subplots() ax2 = ax.twinx() data = data.iloc[-24 * 500:-24 * 250] close = data['close'] x = data.index upper, lower, sma = indicators.bollinger(close, window=30, std_mul=2.0) sell, buy = indicators.bollinger_signals(close, upper, lower) print('simulating') balance, returns, live_returns = sim.trade(data, sell, buy) print('plotting') # indicator chart ax.fill_between(x, upper, lower, color='darkslategray') ax.plot(x, close, color='springgreen', lw=1) ax.plot(x, sma, color='turquoise', lw=1) ax2.yaxis.set_major_formatter(FormatStrFormatter('%g')) # ax2.plot(x, balance, color='gold', lw=1) for y in live_returns: ax2.plot(x, y, color='gold', alpha=0.1, lw=1) # signals ax.scatter(x[buy], close[buy], color='green', marker=10) ax.scatter(x[sell], close[sell], color='crimson', marker=11) # plt.ylim((min(0.0, np.min(balance)), np.max(balance))) fig.autofmt_xdate() plt.show()
def testPolicy(self, symbol, sd, ed, sv): lookback = 18 period = 10 symbols = [] symbols.append(symbol) price = get_data(symbols, pd.date_range(sd, ed)) sma = smacalc(price, lookback) bbp = bollinger(price, lookback, sma) sma = smaoverprice(sma, price) rsi = Rsi(lookback, price) mom = momentum_calc(price, period) orders = price.copy() orders.ix[:, :] = np.nan spy_mom = mom.copy() spy_mom.values[:, :] = spy_mom.ix[:, ['SPY']] sma_cross = pd.DataFrame(0, index=sma.index, columns=sma.columns) sma_cross[sma >= 1] = 1 sma_cross[1:] = sma_cross.diff() sma_cross.ix[0] = 0 orders[(sma < 0.95) & (bbp < 0) & (mom < 0) & (spy_mom > 0)] = 1000 orders[(sma > 1.05) & (bbp > 1) & (mom > 0) & (spy_mom < 0)] = -1000 orders[sma_cross != 0] = 0 orders.ffill(inplace=True) orders.fillna(0, inplace=True) orders[1:] = orders.diff() orders.ix[0] = 0 del orders['SPY'] symbols = list(orders.columns) orders = orders.loc[(orders != 0).any(axis=1)] order_list = [] for day in orders.index: for sym in symbols: if orders.ix[day, sym] > 0: order_list.append([day.date(), sym, 'BUY', 1000]) elif orders.ix[day, sym] < 0: order_list.append([day.date(), sym, 'SELL', 1000]) df_orders = pd.DataFrame(data=order_list, columns=['Date', 'Symbol', 'Order', 'Shares']) return df_orders
def testPolicy(self, symbol = "ML4T-220", \ sd=dt.datetime(2010,1,1), \ ed=dt.datetime(2011,12,31), \ sv = 10000): # example usage of the old backward compatible util function syms=[symbol] dates = pd.date_range(sd, ed) prices_all = ut.get_data(syms, dates) # automatically adds SPY prices = prices_all[syms] # only portfolio symbols prices_SPY = prices_all['SPY'] lookback = 14 period = 5 # calculate the indicators sma = smacalc(prices, lookback) bbp = bollinger(prices, lookback, sma) sma = smaoverprice(sma, prices) mom = momentum_calc(prices, period) position = 1 state = int(str(position) + str(discretize(self.mom, float(mom.iloc[lookback]))) + str(discretize(self.sma, float(sma.iloc[lookback]))) + str(discretize(self.bbp, float(bbp.iloc[lookback])))) df_trades = pd.DataFrame(data=np.zeros((prices.shape[0], 2)), columns = [symbol, 'Cash'], index = prices.index) for day in range(lookback+1, prices.shape[0]): action = self.q.querysetstate(state) if position != action: if 1000 * (action - position) > 0: df_trades[symbol][prices.index[day]] += abs(1000 * (action - position)) df_trades['Cash'][prices.index[day]] -= abs(1000 * (action - position)) * prices[symbol][day] + abs(1000 * (action - position)) * prices[symbol][day] * self.impact else: df_trades[symbol][prices.index[day]] -= abs(1000 * (action - position)) df_trades['Cash'][prices.index[day]] += abs(1000 * (action - position)) * prices[symbol][day] + abs(1000 * (action - position)) * prices[symbol][day] * self.impact position = action state = int(str(action) + str(discretize(self.mom, float(mom.iloc[day]))) + str(discretize(self.sma, float(sma.iloc[day]))) + str(discretize(self.bbp, float(bbp.iloc[day])))) if self.verbose: print type(df_trades) # it better be a DataFrame! if self.verbose: print df_trades self.trades = df_trades # if self.verbose: print prices_all return df_trades[symbol].to_frame()
def calculateIndicators(self, b=20, r=14, m=[12, 26, 9]): self.bb, self.s, self.l, self.h = bollinger(self.value, b) self.macd, self.signal, self.hist = macd(self.value, m[0], m[1], m[2]) self.rsi = rsi(self.open, self.close, r) self.bbn = bollingernormalized(self.value, self.bb, self.s)
def addEvidence(self, symbol = "IBM", \ sd=dt.datetime(2008,1,1), \ ed=dt.datetime(2009,1,1), \ sv = 10000): # add your code to do learning here # example usage of the old backward compatible util function syms = [symbol] dates = pd.date_range(sd, ed) prices_all = ut.get_data(syms, dates) # automatically adds SPY prices = prices_all[syms] # only portfolio symbols prices_SPY = prices_all['SPY'] # only SPY, for comparison later #if self.verbose: print prices #print prices # example use with new colname volume_all = ut.get_data(syms, dates, colname="Volume") # automatically adds SPY volume = volume_all[syms] # only portfolio symbols volume_SPY = volume_all['SPY'] # only SPY, for comparison later if self.verbose: print volume #print volume S = sma(prices, 20) upper, lower, bb, r_m, r_std = bollinger(prices) M = momentum(prices) SMA = pd.DataFrame({'SMA': S}) bb_val = pd.DataFrame({'Bollinger': bb}) Upper = pd.DataFrame({'Upper': upper}) Lower = pd.DataFrame({'Lower': lower}) Momentum = pd.DataFrame({'Momentum': M}) R_M = pd.DataFrame({'Rolling Mean': r_m}) R_STD = pd.DataFrame({"Rolling STD": r_std}) ind = pd.concat((SMA, bb_val, Upper, Lower, R_M, R_STD, Momentum), axis=1) ind.fillna(0, inplace=True) ind = ind[:-self.Days] x_train = ind.values ''' for i in range(0,len(prices)-self.Days): if i<20: x_train[i][0] = 0 x_train[i][1] = 0 x_train[i][2] = 0 x_train[i][3] = prices.iloc[i] x_train[i][4] = prices.iloc[i + self.Days] else: x_train[i][0] = SMA.iloc[i] x_train[i][1] = bb_val.iloc[i] x_train[i][2] = Momentum.iloc[i] x_train[i][3]=prices.iloc[i] x_train[i][4]=prices.iloc[i+self.Days] ''' #print x_train y_temp = [] for i in range(0, len(prices) - self.Days): if prices.ix[i + self.Days, symbol] / prices.ix[i, symbol] > 1.008 + self.impact: y_temp.append(1) elif prices.ix[i + self.Days, symbol] / prices.ix[ i, symbol] < 0.992 - self.impact: y_temp.append(-1) else: y_temp.append(0) y_train = np.array(y_temp) self.learner.addEvidence(x_train, y_train)
def testPolicy(self, symbol = "IBM", \ sd=dt.datetime(2009,1,1), \ ed=dt.datetime(2010,1,1), \ sv = 10000): # here we build a fake set of trades # your code should return the same sort of data dates = pd.date_range(sd, ed) prices_all = ut.get_data([symbol], dates) # automatically adds SPY prices = prices_all[[ symbol, ]] # only portfolio symbols trades_SPY = prices_all['SPY'] # only SPY, for comparison later #print prices S = sma(prices, 20) upper, lower, bb, r_m, r_std = bollinger(prices) M = momentum(prices) SMA = pd.DataFrame({'SMA': S}) bb_val = pd.DataFrame({'Bollinger': bb}) Upper = pd.DataFrame({'Upper': upper}) Lower = pd.DataFrame({'Lower': lower}) Momentum = pd.DataFrame({'Momentum': M}) R_M = pd.DataFrame({'Rolling Mean': r_m}) R_STD = pd.DataFrame({"Rolling STD": r_std}) ind = pd.concat((SMA, bb_val, Upper, Lower, R_M, R_STD, Momentum), axis=1) ind.fillna(0, inplace=True) ind = ind[:-self.Days] x_test = ind.values ''' x_test = np.zeros(shape=(len(prices) - self.Days, 3)) for i in range(0, len(prices) - self.Days): if i<20: x_test[i][0] = 0 x_test[i][1] = 0 x_test[i][2] = 0 else: x_test[i][0] = SMA.iloc[i] x_test[i][1] = bb_val.iloc[i] x_test[i][2] = Momentum.iloc[i] ''' #print x_test y_ans = self.learner.query(x_test) #print(y_ans) trades = pd.DataFrame(0, columns=prices.columns, index=prices.index) shares = 0 for i in range(0, len(prices) - self.Days): if y_ans[i] == 1: trades[symbol].iloc[i] = 1000 - shares shares = 1000 elif y_ans[i] == -1: trades[symbol].iloc[i] = -shares - 1000 shares = -1000 #print trades ''' trades.values[:,:] = 0 # set them all to nothing trades.values[0,:] = 1000 # add a BUY at the start trades.values[40,:] = -1000 # add a SELL trades.values[41,:] = 1000 # add a BUY trades.values[60,:] = -2000 # go short from long trades.values[61,:] = 2000 # go long from short trades.values[-1,:] = -1000 #exit on the last day if self.verbose: print type(trades) # it better be a DataFrame! if self.verbose: print trades if self.verbose: print prices_all ''' return trades
def addEvidence(self, symbol = "ML4T-220", \ sd=dt.datetime(2008,1,1), \ ed=dt.datetime(2009,12,31), \ sv = 100000): # example usage of the old backward compatible util function syms=[symbol] dates = pd.date_range(sd, ed) prices_all = ut.get_data(syms, dates) # automatically adds SPY prices = prices_all[syms] # only portfolio symbols prices_SPY = prices_all['SPY'] # only SPY, for comparison later it = 0 max_iter = 50 min_iter = 25 convergence = False lookback = 14 period = 5 cr_prev = None # calculate the indicators sma = smacalc(prices, lookback) bbp = bollinger(prices, lookback, sma) sma = smaoverprice(sma, prices) mom = momentum_calc(prices, period) # create the discrtizer lists self.bbp = create_discretize(bbp.iloc[lookback:], syms = syms) self.sma = create_discretize(sma.iloc[lookback:], syms = syms) self.mom = create_discretize(mom.iloc[lookback:], syms = syms) self.q = ql.QLearner(num_states=10**4, num_actions = 3, alpha = 0.2, gamma = 0.9, rar = 0.5, radr = 0.99, dyna = 0, verbose = False) # position can be {0: 'short', 1: 'nothing', 2:'long'} while it < max_iter and not convergence or it < min_iter: df_trades = pd.DataFrame(data=np.zeros((prices.shape[0], 2)), columns = [symbol, 'Cash'], index = prices.index) position = 1 action = 1 state = int(str(position) + str(discretize(self.mom, float(mom.iloc[lookback]))) + str(discretize(self.sma, float(sma.iloc[lookback]))) + str(discretize(self.bbp, float(bbp.iloc[lookback])))) self.q.querysetstate(state) for day in range(lookback+1, prices.shape[0]): if action == 0 and action != position: r = -(prices.iloc[day]/prices.iloc[day-1] - 1) - penalty elif action == 0: r = -(prices.iloc[day]/prices.iloc[day-1] - 1) elif action == 1: r = 0 elif action == 2 and action != position: r = (prices.iloc[day]/prices.iloc[day-1] - 1) - penalty else: r = (prices.iloc[day]/prices.iloc[day-1] - 1) position = action action = self.q.query(state, r) if position != action: if 1000 * (action - position) > 0: df_trades[symbol][prices.index[day]] += abs(1000 * (action - position)) df_trades['Cash'][prices.index[day]] -= abs(1000 * (action - position)) * prices[symbol][day] + abs(1000 * (action - position)) * prices[symbol][day] * self.impact else: df_trades[symbol][prices.index[day]] -= abs(1000 * (action - position)) df_trades['Cash'][prices.index[day]] += abs(1000 * (action - position)) * prices[symbol][day] + abs(1000 * (action - position)) * prices[symbol][day] * self.impact penalty = self.impact * prices.iloc[day] else: penalty = 0 state = int(str(action) + str(discretize(self.mom, float(mom.iloc[day]))) + str(discretize(self.sma, float(sma.iloc[day]))) + str(discretize(self.bbp, float(bbp.iloc[day])))) opt = compute_portvals(df_trades, sd, ed, start_val = sv, commission = 0.0, impact = self.impact) cr = float((opt.iloc[-1] - opt.iloc[0])/ opt.iloc[0]) if self.verbose: print str(it) + ': cr = ' + str(cr) if cr == cr_prev: convergence = True else: cr_prev = cr it += 1 return df_trades