def test_avg_cross(self): sma9 = indicators.SMA(self.ohlc.close, period=9) sma21 = indicators.SMA(self.ohlc.close, period=21) strategy = strategies.AvgCrossStrategy(self.ohlc.close, sma9.df.sma9, sma21.df.sma21) result = strategy.backtest(self.ohlc.close) self.assertEqual(result.start, datetime(2020, 1, 8, 1, 30, 0)) self.assertEqual(result.end, datetime(2020, 1, 18, 11, 15, 0)) self.assertEqual(result.trades, 27) self.assertTrue(math.isclose(result.netret, 9.8, rel_tol=1e-02)) self.assertTrue(math.isclose(result.sharpe, 0.0533, rel_tol=1e-03)) self.assertTrue(math.isclose(result.maxdrawdown, -3.94, rel_tol=1e-02)) self.assertEqual(result.maxdrawdownduration, 207)
def test_SMA(self): sma = pd.read_csv('tests/data/BTCUSDT_15m_SMA9.csv', index_col='time', parse_dates=True) mysma = indicators.SMA(self.ohlc.close, period=9) isclose = np.isclose(sma.sma9, mysma.df.sma9, equal_nan=True) self.assertTrue(np.all(isclose))
def drawEMA(ax, data, periods=[5, 10, 20, 30, 60, 120]): for period in periods: if data.__contains__('ema%d' % period): ema = data['ema%d' % period] elif data.__contains__('ema'): ema = data['ema'] else: close = data['close'] ema = ind.SMA(close, period) ax.plot(ema, label='ema%d' % period)
def drawSMA(ax, data, periods=[5, 10, 20, 30, 60, 120]): for period in periods: if data.__contains__('sma_%d' % period): sma = data['sma_%d' % period] elif data.__contains__('sma'): sma = data['sma'] else: close = data['close'] sma = ind.SMA(close, period) ax.plot(sma, label='sma_%d' % period, linewidth=1)
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 report_of_SMA(prices, n): '''Takes the input(a list of prices and N-day) to print the report of simple moving average and signal strategies''' a_list_of_SMAverage = indicators.SMA(prices, n) CLASS = signal_strategies.SMA_SIGNAL(prices, n, a_list_of_SMAverage) x = CLASS.simple_signal() date_close = [[], []] for b in information: date_close[0].append(b[0]) date_close[1].append(b[4]) print('\nSYMBOL: ' + s + '\nSTRATEGY: Simple Moving Average') print('\n{:10} {:6} {:9} {:5}'.format('DATE', 'CLOSE', 'INDICATOR', 'SIGNAL')) for i in range(len(date_close[0])): print('{:10} {:6} {:9} {:5}'.format(date_close[0][i], date_close[1][i], a_list_of_SMAverage[i], x[i]))
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
def main(): parser = argparse.ArgumentParser() parser.add_argument("file") parser.add_argument("--sma", type=int, nargs='+', help='Adds SMA to the price graph') parser.add_argument("--ema", type=int, nargs='+', help='Adds EMA to the price graph') parser.add_argument("--rsi", type=int, help='Adds RSI in a subplot') parser.add_argument("--macd", type=int, nargs=3, help='Adds MACD in a subplot') parser.add_argument("--bbands", type=int, nargs=2, help='Adds Bollinger Bands to the price graph') parser.add_argument("--strategy", type=int, nargs='+', help='Adds a strategy, 1 : EMA Cross') args = parser.parse_args() ohlc = pd.read_csv(args.file, index_col='time', parse_dates=True) close = ohlc['close'] # calculates the number of sublots rows = 1 if args.rsi != None: rows += 1 if args.macd != None: rows += 1 fig = make_subplots(rows=rows, cols=1, shared_xaxes=True) # plots close bar graph with averages row = 1 fig.add_trace(go.Scatter(x=ohlc.index, y=close, name="Close"), row=row, col=1) if args.ema != None: for period in args.ema: ema = indicators.EMA(close, period) fig.add_trace(go.Scatter(x=ohlc.index, y=ema.df['ema{}'.format(period)], name="EMA {}".format(period)), row=row, col=1) if args.sma != None: for period in args.sma: sma = indicators.SMA(close, period) fig.add_trace(go.Scatter(x=ohlc.index, y=sma.df['sma{}'.format(period)], name="SMA {}".format(period)), row=row, col=1) # plots Bollinger Bands if args.bbands != None: bbands = indicators.BollingerBands(close, args.bbands[0]) fig.add_trace(go.Scatter(x=ohlc.index, y=bbands.df.ma), row=row, col=1) fig.add_trace(go.Scatter(x=ohlc.index, y=bbands.df.upper), row=row, col=1) fig.add_trace(go.Scatter(x=ohlc.index, y=bbands.df.lower), row=row, col=1) row += 1 row += 1 # plots RSI if args.rsi != None: rsi = indicators.RSI(close, args.rsi) fig.add_trace(go.Scatter(x=ohlc.index, y=rsi.df.rsi, name="RSI {}".format(args.rsi)), row=row, col=1) row += 1 # plots MACD if args.macd != None: macd = indicators.MACD(close, args.macd[0], args.macd[1], args.macd[2]) fig.add_trace(go.Scatter(x=ohlc.index, y=macd.df.MACD, name="MACD {} {} {}".format(args.macd[0], args.macd[1], args.macd[2])), row=row, col=1) fig.add_trace(go.Scatter(x=ohlc.index, y=macd.df.signal, name="MACD Signal"), row=row, col=1) row += 1 # plots strategy if args.strategy != None: if args.strategy[0] == 1: fast_ema = indicators.EMA(ohlc.close, period=args.strategy[1]) slow_ema = indicators.EMA(ohlc.close, period=args.strategy[2]) strategy = strategies.AvgCrossStrategy(ohlc.close, fast_ema.data(), slow_ema.data()) fig.add_trace(go.Scatter(x=close.loc[strategy.signals['positions'] == 1.0].index, y=close.loc[strategy.signals['positions'] == 1.0], mode='markers', marker=dict(size=12, symbol='triangle-up', color='green'), name="Buy"), row=1, col=1) fig.add_trace(go.Scatter(x=close.loc[strategy.signals['positions'] == -1.0].index, y=close.loc[strategy.signals['positions'] == -1.0], mode='markers', marker=dict(size=12, symbol='triangle-down', color='red'), name="Sell"), row=1, col=1) elif args.strategy[0] == 2: macd = indicators.MACD(ohlc.close, args.strategy[1], args.strategy[2], args.strategy[3]) strategy = strategies.MACDStrategy(ohlc.close, macd) fig.add_trace(go.Scatter(x=close.loc[strategy.signals['positions'] == 1.0].index, y=close.loc[strategy.signals['positions'] == 1.0], mode='markers', marker=dict(size=12, symbol='triangle-up', color='green'), name="Buy"), row=1, col=1) fig.add_trace(go.Scatter(x=close.loc[strategy.signals['positions'] == -1.0].index, y=close.loc[strategy.signals['positions'] == -1.0], mode='markers', marker=dict(size=12, symbol='triangle-down', color='red'), name="Sell"), row=1, col=1) elif args.strategy[0] == 3: bb1 = indicators.BollingerBands(ohlc.close, 20, 1) bb2 = indicators.BollingerBands(ohlc.close, 20, 2) strategy = strategies.DBBStrategy(ohlc.close, bb1, bb2) fig.add_trace(go.Scatter(x=close.loc[strategy.signals['positions'] == 1.0].index, y=close.loc[strategy.signals['positions'] == 1.0], mode='markers', marker=dict(size=12, symbol='triangle-up', color='green'), name="Buy"), row=1, col=1) fig.add_trace(go.Scatter(x=close.loc[strategy.signals['positions'] == -1.0].index, y=close.loc[strategy.signals['positions'] == -1.0], mode='markers', marker=dict(size=12, symbol='triangle-down', color='red'), name="Sell"), row=1, col=1) elif args.strategy[0] == 4: rsi = indicators.RSI(ohlc.close, 9) macd = indicators.MACD(ohlc.close, 12, 26, 9) strategy = strategies.RSIMACDStrategy(ohlc.close, rsi, macd) fig.add_trace(go.Scatter(x=close.loc[strategy.signals['positions'] == 1.0].index, y=close.loc[strategy.signals['positions'] == 1.0], mode='markers', marker=dict(size=12, symbol='triangle-up', color='green'), name="Buy"), row=1, col=1) fig.add_trace(go.Scatter(x=close.loc[strategy.signals['positions'] == -1.0].index, y=close.loc[strategy.signals['positions'] == -1.0], mode='markers', marker=dict(size=12, symbol='triangle-down', color='red'), name="Sell"), row=1, col=1) fig.show()
stock_lib.Ping() #price_data = ReadCsv("../data/SPFB.BR-4.20_200101_200311.csv") #float_array_type = ctypes.c_double * len(price_data) #my_dll.BlackScholes_Foo(float_array_type(*price_data), len(price_data)) fig = plt.figure() #ax = plt.axes(projection='3d') price_len = 1000 # len(price_data) x = np.arange(0, price_len) ax = fig.add_subplot(2, num_columns, 1) price_data = GenerateStockPrices(len(x), 1.0) ax.plot(x, price_data) price_ema = indicators.SMA(price_data, 3) ax.plot(x, price_ema) ax = fig.add_subplot(2, num_columns, 2) stochastic_data = indicators.StochasticOscillator(price_data, 20) ax.plot(x, stochastic_data) stochastic_data_smoothed = indicators.EMA(stochastic_data, 0.5) ax.plot(x, stochastic_data_smoothed) stochastic_data_smoothed1 = indicators.SMA(stochastic_data, 3) ax.plot(x, stochastic_data_smoothed1) ax.grid() #ax = fig.add_subplot(1, num_columns, 2, projection='3d') ##ax = fig.add_subplot(111, projection='3d') # #X = np.arange(-5, 5, 0.25) #Y = np.arange(-5, 5, 0.25)
def testPolicy(symbol="JPM", sd=dt.datetime(2008, 1, 1), ed=dt.datetime(2009, 12, 31), sv=100000): orders_df = market.make_df_to_match_trading_days( colnames=['Date', 'Symbol', 'Order', 'Shares'], symbol='JPM', sd=sd, ed=ed) stock_price_library = market.get_stock_prices([symbol], sd, ed) #iterate through stock price library and short before all the drops and buy for all the gains orders_df['Symbol'] = symbol #assign to JPM orders_df['Order'] = "" #initialize with no orders orders_df['Shares'] = 0.0 #initialize with no shares orders_df['Date'] = orders_df.index state = 0 short_price = 0.0 days_in_short = 0 #load indicators bollinger_df = indicators.get_bollinger(symbol, sd=sd, ed=ed) STOK_df = indicators.stochastic_oscillator_20(symbol, sd=sd, ed=ed) SMA_df = indicators.SMA(symbol, sd=sd, ed=ed) for row in orders_df.itertuples(index=True): order_date = getattr(row, 'Date') symbol = getattr(row, 'Symbol') # print "The symbol is ", symbol order = getattr(row, 'Order') shares = getattr(row, 'Shares') bollinger_high_today = bollinger_df.loc[order_date]['bb1'] bollinger_low_today = bollinger_df.loc[order_date]['bb2'] STOK_D_today = STOK_df.loc[order_date]['%D'] stock_price_today = stock_price_library.loc[order_date][symbol] P_over_SMA_today = SMA_df.loc[order_date]['P/SMA'] total_votes = [] bb_vote = 0 bb_weight = 1 stochastic_vote = 0 stochastic_weight = 1 sma_vote = 0 sma_weight = 0.5 if stock_price_today > bollinger_high_today: bb_vote = -1 #sell! elif stock_price_today < bollinger_low_today: bb_vote = 1 #buy! if STOK_D_today < 20: stochastic_vote = 1 #buy! elif STOK_D_today > 80: stochastic_vote = -1 #get out of there! if P_over_SMA_today < 0.7: sma_vote = -1 #looks like a selling opp total_votes.append(bb_vote * bb_weight) total_votes.append(stochastic_vote * stochastic_weight) total_votes.append(sma_vote * sma_weight) average_vote = sum(total_votes) / len(total_votes) if state < 0: days_in_short += 1 if state < 0 and stock_price_today > 1.2 * short_price or days_in_short > 45: #if the price has risen 20% above our short price #or if we have been in a short position for more than 45 #get out of our position and wait for next move. orders_df.set_value(order_date, 'Order', 'BUY') orders_df.set_value(order_date, 'Shares', abs(0 - state)) state = 0 #reset days_in_short = 0 else: if average_vote < 0: #this means I want to sell if abs(-1000 - state) == 0: #legality check for sale transaction pass else: orders_df.set_value(order_date, 'Order', 'SELL') orders_df.set_value(order_date, 'Shares', abs(-1000 - state)) short_price = stock_price_today state = -1000 #short state if average_vote > 0: #this means I want to buy if abs(1000 - state) == 0: #legality check for buy transaction pass else: orders_df.set_value(order_date, 'Order', 'BUY') orders_df.set_value(order_date, 'Shares', abs(1000 - state)) state = 1000 #long state days_in_short = 0 else: pass #my best policy (based on seeing the future) return orders_df
import database_tools as dt import indicators import datetime print "standard_deviation " + str( indicators.standard_deviation("TXT", datetime.datetime.today(), 10)) print "simple_moving_average " + str( indicators.SMA("TXT", datetime.datetime.today(), 10)) print "volatility " + str( indicators.volatility("TXT", datetime.datetime.today(), 10)) print "WilliamsR " + str( indicators.willamsR("TXT", datetime.datetime.today(), 10)) print "RSI " + str(indicators.RSI("TXT", datetime.datetime.today(), 10)) print "average_true_range " + str( indicators.ATR("TXT", datetime.datetime.today(), 10)) print "EMA " + str(indicators.EMA("TXT", datetime.datetime.today(), 10)) print "bollinger_bands_customized " + str( indicators.bollinger_bands_customized("TXT", datetime.datetime.today(), 10))
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