def testPolicy(self, symbol="JPM", sd=dt.datetime(2008, 1, 1), ed=dt.datetime(2009, 12, 31), sv=100000): self.sv = sv #Read in the stock price if type(symbol) is str: symbols = list() symbols.append(symbol) else: symbols = symbol prices_df = get_data(symbols, pd.date_range(sd, ed), addSPY=True, colname='Adj Close') #prices_df['cash'] = 1.0 #prices_df = prices_df.drop(['SPY'], axis = 1) prices_df = prices_df.fillna(method='ffill') prices_df = prices_df.fillna(method='bfill') lookback_days = 30 #date_range = prices_df.index[(lookback_days-1):] #Create an empty dataframe df_trades df_trades = pd.DataFrame(data=0, index=prices_df.index, columns=symbols) #print df_trades.head(20) sma, p_sma = p_sma_ratio(prices_df, lookback=lookback_days) K, D = stochastic_K_D(prices_df, lookback=lookback_days) BB, upperband, lowerband = bband(prices_df, lookback=lookback_days) for i in range(1, df_trades.shape[0] - (lookback_days - 1)): #The long entry if BB[symbol][i - 1] <= -1.01 and p_sma[symbol][i] > p_sma[symbol][ i - 1] and D[symbol][i - 1] < 20: if self.netHolding == -1000: df_trades.iloc[i + lookback_days - 1] = 2000 elif self.netHolding == 0: df_trades.iloc[i + lookback_days - 1] = 1000 #The short entry elif BB[symbol][i - 1] >= 1.01 and p_sma[symbol][i] < p_sma[symbol][ i - 1] and D[symbol][i - 1] > 80: # if self.netHolding == 1000: df_trades.iloc[i + lookback_days - 1] = -2000 elif self.netHolding == 0: df_trades.iloc[i + lookback_days - 1] = -1000 #The exit position elif (BB[symbol][i - 1] >= 0.95 and BB[symbol][i - 1] < 1.0) or ( BB[symbol][i - 1] > -1.0 and BB[symbol][i - 1] <= -0.95): df_trades.iloc[i + lookback_days - 1] = -self.netHolding self.netHolding += df_trades.iloc[i + lookback_days - 1].values return df_trades
def __init__(self, sym='SPY', sd=dt.datetime(2008,1, 1), \ ed=dt.datetime(2009,12,31),sv=100000,verbose=False): self.sym = sym self.verbose = verbose self.shares = 0 self.position = 0 self.sv = sv self.cash = sv self.pp = 0 #period n = 28 chart = False #take in, normalize data df = ut.get_data([sym], pd.date_range(sd - dt.timedelta(100), ed))[sym] normed = df / df.ix[0] #get features sma = ind.SMA(normed, n) smap = ind.standardize(normed / sma) bbp = ind.standardize(ind.bband(normed, n, chart)[0]) stdev = ind.standardize(normed.rolling(window=n, min_periods=n).std()) mom = ind.standardize(ind.momentum(normed, n, chart)) momvol = ind.standardize(mom / stdev) #daily returns & combined features rets = pd.DataFrame(df) daily_rets = rets[sym].copy() daily_rets[1:] = (rets[sym].ix[1:] / rets[sym].ix[:-1].values) - 1 daily_rets.ix[0] = 0 #print df #df = pd.DataFrame(df).assign(normed = normed).assign(smap=smap).\ # assign(stdev=stdev).assign(bbp=bbp).assign(mom=mom)[sd:] df = pd.DataFrame(df).assign(normed = normed).assign(smap=smap).\ assign(bbp=bbp).assign(mom=mom)[sd:] #print df daily_rets.ix[0] = 0 df = df.assign(dr=daily_rets) #print df self.df = df self.market = df.iterrows() self.curr = self.market.next() self.action = self.Action() #self.features = ['smap', 'stdev', 'bbp', 'mom'] self.features = ['smap', 'bbp', 'mom']
def testPolicy(symbol = "AAPL", sd=dt.datetime(2010,1,1), \ ed = dt.datetime(2011,12,31), sv=100000): chart = False n = 14 #symbol = [symbol] prices = get_data(symbol, pd.date_range(sd, ed)) #print prices #ffill and drop SPY prices.fillna(method='ffill', inplace=True) prices.fillna(method='bfill', inplace=True) prices = prices[symbol] #Generate indicators sma = ind.SMA(prices, n) smap = ind.standardize(prices / sma) bbp = ind.standardize(ind.bband(prices, n, chart)[0]) stdev = ind.standardize(prices.rolling(window=n, min_periods=n).std()) mom = ind.standardize(ind.momentum(prices, n, chart)) momvol = ind.standardize(mom / stdev) orders = prices.copy() orders.ix[:, :] = np.nan smap_cross = pd.DataFrame(0, index=smap.index, columns=smap.columns) smap_cross[smap >= 1] = 1 smap_cross[1:] = smap_cross.diff() smap_cross.ix[0] = 0 orders[(smap < 0.95) & (bbp < 0) & (stdev < 0.1) & (mom < 0)] = 1000 orders[(smap > 1.05) & (bbp > 1) & (stdev > 0.3) & (mom > 0)] = -1000 orders[(smap_cross != 0)] = 0 orders.ffill(inplace=True) orders.fillna(0, inplace=True) orders[1:] = orders.diff() #orders.ix[0] = 1000 #orders.ix[-1] = -1000 #orders = orders.loc[(orders!=0).any(axis=1)] #orders.ix[0] = 0 #orders.ix[-1] = orders.ix[-2]*-1 #print orders return orders
# split to Bid/Ask dfdict = func.splitbidask(dfprices) #----------------------------------------------------------------------------- # indicators testing #----------------------------------------------------------------------------- dfbid = dfdict['bid'] dfbid.head() dfbid.dtypes df1 = ind.trix( dfbid, [10,15]) df1 = ind.sma( dfbid, window = [3,5,9]) df1 = ind.sma( dfbid, 'volume', [5]) df1 = ind.bband( dfbid, 21) df1.head(30) df1 = ( dfbid.pipe( ind.bband, 21) .pipe( ind.sma, [3,5,9]) .pipe( ind.trix, [7,11]) #----------------------------------------------------------------------------- # optimization for indicators
def addEvidence(self, symbol = "IBM", \ sd=dt.datetime(2008,1,1), \ ed=dt.datetime(2009,1,1), \ sv = 100000): # add your code to do learning here self.sv = sv #Read in the stock price if type(symbol) is str: symbols = list() symbols.append(symbol) else: symbols = symbol prices_df = ut.get_data(symbols, pd.date_range(sd, ed), addSPY=True, colname='Adj Close') #prices_df['cash'] = 1.0 #prices_df = prices_df.drop(['SPY'], axis = 1) prices_df = prices_df.fillna(method='ffill') prices_df = prices_df.fillna(method='bfill') prices_df = prices_df.drop(['SPY'], axis=1) lookback_days = 15 #Create an empty dataframe df_trades df_trades = pd.DataFrame(data=0, index=prices_df.index, columns=symbols) #print df_trades.head(20) sma, p_sma = p_sma_ratio(prices_df, lookback=lookback_days) K, D = stochastic_K_D(prices_df, lookback=lookback_days) BB, upperband, lowerband = bband(prices_df, lookback=lookback_days) #discretize the indicators p_sma_bins = pd.to_numeric( pd.cut(p_sma[symbol], 10, labels=range(0, 10))) K_bins = pd.to_numeric(pd.cut(K[symbol], 8, labels=range(0, 8))) BB_bins = pd.to_numeric(pd.cut(BB[symbol], 10, labels=range(0, 10))) states = 100 * K_bins + 10 * p_sma_bins + BB_bins #print type(states[0]) #Instantiate a Q-learner converge = False count = 0 #portvals_prev = [sv, sv, sv, sv, sv, sv, sv, sv, sv, sv] portvals_prev = [sv, sv, sv, sv, sv] #df_tmp = df_trades while (not converge and count < 500): action = self.learner.querysetstate(states[0]) if (action == 0): #long self.netHolding = 1000 elif (action == 1): #Nothing self.netHolding = 0 else: #short self.netHolding = -1000 #print df_trades.loc['2008-01-02':'2008-01-31'] # print states.index # print states.shape[0] # print prices_df.loc[states.index[0]] for i in range(1, states.shape[0]): day = states.index[i] day_before = states.index[i - 1] if (action == 0): impact_sign = 1 elif (action == 1): impact_sign = 0 else: impact_sign = -1 #r = (prices_df[symbol].loc[day] - prices_df[symbol].loc[day_before] * \ # (1+impact_sign * self.impact)) * self.netHolding / self.sv r = self.netHolding * (prices_df[symbol].loc[day] / prices_df[symbol].loc[day_before] - 1 - self.impact * impact_sign) # if self.netHolding != 0: # r = prices_df[symbol].loc[day]/prices_df[symbol].loc[day_before] - 1 - self.impact # else: # r = 0 #r = ((prices_df[symbol].loc[day] - prices_df[symbol].loc[day_before]) * self.netHolding \ # - impact_sign * self.impact * df_trades.loc[day_before] * prices_df[symbol].loc[day_before])/self.sv action = self.learner.query(states[day], r) if (action == 0): #long if self.netHolding == -1000: df_trades.loc[day] = 2000 elif self.netHolding == 0: df_trades.loc[day] = 1000 elif (action == 2): #Short if self.netHolding == 1000: df_trades.loc[day] = -2000 elif self.netHolding == 0: df_trades.loc[day] = -1000 self.netHolding += df_trades.loc[day].values # print prices_df.loc[day] # print df_trades.loc[day] # print self.netHolding # print "" portvals, cr, stdev, mean = compute_portvals(df_trades, start_val=sv, commission=0, impact=self.impact) #diff_portvals = abs(portvals[-1]- portvals_prev) diff_portvals = abs(portvals[-1] - np.mean(portvals_prev)) #print portvals_prev if (count >= 10 and diff_portvals < 50.0): converge = True else: count += 1 portvals_prev.pop(0) portvals_prev.append(portvals[-1]) print count
def testPolicy(self, symbol = "JPM", \ sd=dt.datetime(2009,1,1), \ ed=dt.datetime(2010,1,1), \ sv = 10000): #Read in the stock price if type(symbol) is str: symbols = list() symbols.append(symbol) else: symbols = symbol prices_df = ut.get_data(symbols, pd.date_range(sd, ed), addSPY=True, colname='Adj Close') #prices_df['cash'] = 1.0 #prices_df = prices_df.drop(['SPY'], axis = 1) prices_df = prices_df.fillna(method='ffill') prices_df = prices_df.fillna(method='bfill') prices_df = prices_df.drop(['SPY'], axis=1) lookback_days = 15 #Create an empty dataframe df_trades df_trades = pd.DataFrame(data=0, index=prices_df.index, columns=symbols) #print df_trades.head(20) sma, p_sma = p_sma_ratio(prices_df, lookback=lookback_days) K, D = stochastic_K_D(prices_df, lookback=lookback_days) BB, upperband, lowerband = bband(prices_df, lookback=lookback_days) #discretize the indicators p_sma_bins = pd.to_numeric( pd.cut(p_sma[symbol], 10, labels=range(0, 10))) K_bins = pd.to_numeric(pd.cut(K[symbol], 8, labels=range(0, 8))) BB_bins = pd.to_numeric(pd.cut(BB[symbol], 10, labels=range(0, 10))) states = 100 * K_bins + 10 * p_sma_bins + BB_bins netHolding = 0 for i in range(1, states.shape[0]): day = states.index[i] #day_before = states.index[i-1] #r = (prices_df[symbol].loc[day] - prices_df[symbol].loc[day_before])* netHolding / sv action = self.learner.querysetstate(states[day]) if (action == 0): #long if netHolding == -1000: df_trades.loc[day] = 2000 elif netHolding == 0: df_trades.loc[day] = 1000 elif (action == 2): #Short if netHolding == 1000: df_trades.loc[day] = -2000 elif netHolding == 0: df_trades.loc[day] = -1000 netHolding += df_trades.loc[day].values #portvals, cr, stdev, mean = compute_portvals(df_trades, start_val = sv, commission=0, impact=self.impact) # print states[day] # 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 # trades = prices_all[[symbol,]] # only portfolio symbols # trades_SPY = prices_all['SPY'] # only SPY, for comparison later # 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 df_trades
def __init__(self, sym='SPY', sd=dt.datetime(2008,1, 1), \ ed=dt.datetime(2009,12,31),sv=100000,verbose=False, experiment=False, impact=0.0): self.sym = sym self.verbose = verbose self.shares = 0 self.position = 2 self.sv = sv self.cash = sv self.pp = 0 self.impact = impact self.experiment = experiment #n = 3 #period chart = False #take in, normalize data df = ut.get_data([sym], pd.date_range(sd - dt.timedelta(100), ed))[sym] #print df #print sd, ed normed = df / df.ix[0] #print normed #daily returns & combined features rets = pd.DataFrame(df) daily_rets = rets[sym].copy() daily_rets[1:] = (rets[sym].ix[1:] / rets[sym].ix[:-1].values) - 1 daily_rets.ix[0] = 0 #Simple moving average sma5 = normed.rolling(5).mean() sma15 = normed.rolling(15).mean() sma20 = normed.rolling(20).mean() sma25 = normed.rolling(25).mean() sma30 = normed.rolling(30).mean() sma40 = normed.rolling(40).mean() #print sma5 # Volatility vol5 = normed.rolling(5).std() vol10 = normed.rolling(10).std() vol20 = normed.rolling(20).std() vol30 = normed.rolling(30).std() # Bollinger bands sma_bb = normed.rolling(5).mean() sma_bb_std = normed.rolling(5).std() bb = (normed - (sma_bb - 2 * sma_bb_std)) / ((sma_bb + 2 * sma_bb_std) - (sma_bb - 2 * sma_bb_std)) # Moving average convergence/divergence #ema12 = pd.ewma(np.asarray(normed), span=12) #ema26 = pd.ewma(np.asarray(normed), span=26) #macd = ema12 - ema26 # Momentum momentum2 = normed / normed.shift(2) - 1 momentum5 = normed / normed.shift(5) - 1 momentum10 = normed / normed.shift(10) - 1 # Combine into new dataframe df = pd.DataFrame(df).assign(sma5=normed / sma5 - 1).assign(\ bb=bb).assign(momentum2=momentum2).assign(normed=normed).\ assign(vol10=vol10).assign(vol20=vol20).assign(vol30=vol30).assign(vol10=vol10)\ .assign(vol5=vol5).assign(\ momentum5=momentum5).assign(momentum10=momentum10)[sd:] df = df.assign(dr=daily_rets) #print df # Determine optimal features for states corr_df = df.corr().abs() corr = corr_df['dr'][:] corr.ix[0] = 0 corr['normed'] = 0 icorr = np.asarray(corr) scorr = icorr.argsort( )[-4:][::-1] # select top 3 features and daily returns scorr = scorr[1:] # remove daily returns from possible features optimal_ftrs = [] for i in scorr: optimal_ftrs.append(corr_df.columns[i]) if experiment: #print "Experiment 1 ACTIVATED" n = 14 sma = ind.SMA(normed, n) smap = ind.standardize(normed / sma) bbp = ind.standardize(ind.bband(normed, n, chart)[0]) stdev = ind.standardize( normed.rolling(window=n, min_periods=n).std()) mom = ind.standardize(ind.momentum(normed, n, chart)) momvol = ind.standardize(mom / stdev) df = pd.DataFrame(df).assign(normed=normed).assign( smap=smap).assign(stdev=stdev).assign(bbp=bbp).assign( mom=mom)[sd:] optimal_ftrs = ['smap', 'stdev', 'bbp', 'mom'] #df = pd.DataFrame(df).assign(normed = normed).assign(smap=smap).assign(bbp=bbp).assign(mom=mom)[sd:] #df = pd.DataFrame(df).assign(normed = normed)[sd:] self.df = df self.market = df.iterrows() self.curr = self.market.next() self.action = self.Action() self.features = optimal_ftrs