def add_indicators(self): #self.add_ema(9) #self.add_ema(21) #self.strategy = strategies.CustomStrategy(self.df['close'], self.df['ema9'], self.df['ema21']) #return self.strategy self.rsi = indicators.RSI(self.df['close'], 9) self.macd = indicators.MACD(self.df['close'], 12, 26, 9)
def test_MACD(self): macd = indicators.MACD(self.ohlc.close, 12, 26, 9) strategy = strategies.MACDStrategy(self.ohlc, macd) 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, 41) self.assertTrue(math.isclose(result.netret, 22.39, rel_tol=1e-02)) self.assertTrue(math.isclose(result.sharpe, 0.1409, rel_tol=1e-03)) self.assertTrue(math.isclose(result.maxdrawdown, -2.97, rel_tol=1e-02)) self.assertEqual(result.maxdrawdownduration, 156)
def test_RSI_MACD(self): rsi = indicators.RSI(self.ohlc.close, period=9) macd = indicators.MACD(self.ohlc.close, 12, 26, 9) strategy = strategies.RSIMACDStrategy(self.ohlc, rsi, macd) 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, 41) self.assertTrue(math.isclose(result.netret, 26.06, rel_tol=1e-02)) self.assertTrue(math.isclose(result.sharpe, 0.1297, rel_tol=1e-03)) self.assertTrue(math.isclose(result.maxdrawdown, -2.85, rel_tol=1e-02)) self.assertEqual(result.maxdrawdownduration, 82)
def drawMACD(ax, data, periods=[12, 26, 9]): close = data['close'] if data.__contains__('dif') & data.__contains__('dea') & data.__contains__('hist'): macd = data['dif'] macd_signal = data['dea'] macd_histogram = data['hist'] else: macd, macd_signal, macd_histogram = ind.MACD(close, fast_period=periods[0], slow_period=periods[1], signal_period=periods[2]) ax.plot(macd, label='macd%d' % periods[0]) ax.plot(macd_signal, label='macd_singal%d' % periods[1]) ax.bar(close.index, macd_histogram.clip(lower=0), facecolor='r') ax.bar(close.index, macd_histogram.clip(upper=0), facecolor='g') drawHline(ax, [0]) # ax.set_ylabel('MACD') ax.set_yticks([])
def test_MACD(self): macd = pd.read_csv('tests/data/BTCUSDT_15m_MACD_12_26_9.csv', index_col='time', parse_dates=True) mymacd = indicators.MACD(self.ohlc.close, short_period=12, long_period=26, period=9) # consider first 250 values as warmup ismacdclose = np.isclose(macd.macd.iloc[250:], mymacd.df.MACD.iloc[250:], equal_nan=True) ismacdsignalclose = np.isclose(macd.macdsignal.iloc[250:], mymacd.df.signal.iloc[250:], equal_nan=True) self.assertTrue(np.all(ismacdclose)) self.assertTrue(np.all(ismacdsignalclose))
def _indicators(self): """ This will calculate our technical indicators based on the parameters in our ti dict ... this can be ran in one bang OR iteratively. It goes directly to the indicator structs. Not pretty, but what the f**k. """ # TODO: update this if we ever want to add multiple OHLC frames for time_str in self.ohlc: for indicator in self.ti: if indicator == "RSI": self.ti[indicator]["data"] = ind.RSI( self.ohlc[time_str], self.ti[indicator]["n"]) elif indicator == "ROC": self.ti[indicator]["data"] = ind.ROC( self.ohlc[time_str], self.ti[indicator]["n"]) elif indicator == "AMA": self.ti[indicator]["data"] = ind.AMA( self.ohlc[time_str].close, self.ti[indicator]["n"], self.ti[indicator]["fn"], self.ti[indicator]["sn"]) elif indicator == "CCI": self.ti[indicator]["data"] = ind.CCI( self.ohlc[time_str], self.ti[indicator]["n"]) elif indicator == "FRAMA": self.ti[indicator]["data"] = ind.FRAMA( self.ohlc[time_str], self.ti[indicator]["n"]) elif indicator == "RVI2": self.ti[indicator]["data"] = ind.RVI2( self.ohlc[time_str], self.ti[indicator]["n"], self.ti[indicator]["s"]) elif indicator == "MACD": self.ti[indicator]["data"] = ind.MACD( self.ohlc[time_str], self.ti[indicator]["f"], self.ti[indicator]["s"], self.ti[indicator]["m"]) elif indicator == "ADX": self.ti[indicator]["data"] = ind.ADX( self.ohlc[time_str], self.ti[indicator]["n"]) elif indicator == "ELI": self.ti[indicator]["data"] = ind.ELI( self.ohlc[time_str], self.ti[indicator]["n"]) elif indicator == "TMI": self.ti[indicator]["data"] = ind.TMI( self.ohlc[time_str], self.ti[indicator]["nb"], self.ti[indicator]["nf"])
def indicator_values(self, df_prices): """Function is used to generate X inputs based on indicator performance Accepts a prices df from util.get_data, returns a df of indicator performance""" # window = self.indicator_window # simple moving average and bollinger bands sma, upper, lower = ind.simple_ma(df_prices, window=19, bollinger=True, threshold=1.45102) # BB percentage perc_upper = df_prices.iloc[:, 0] / upper.iloc[:, 0] perc_upper = pd.DataFrame(perc_upper.rename('upper_BB%')) perc_lower = lower.iloc[:, 0] / df_prices.iloc[:, 0] perc_lower = pd.DataFrame(perc_lower.rename('lower_BB%')) # moving average convergence divergence macd, macd_s = ind.MACD(df_prices, ema1_days=12, ema2_days=24) # below checks percentage crossover md = macd_s['macd_signal'] / macd['macd'] md.rename('macd_sigal/macd') # stoichastic oscillator K, D = ind.stoc_osc(df_prices, k_window=12) # below is to check for percentage of crossover for the stoich osc k = D.iloc[:, 0] / K.iloc[:, 0] k.replace([np.inf, -np.inf, np.nan], 0, inplace=True) k.rename('D/K', inplace=True) df_ind = pd.concat([perc_upper, perc_lower, md, D, k], axis=1) self.window = df_ind.isnull().any(1).nonzero()[0].max( ) + 1 # highest index is mainteined to prevent training during this period if self.verbose: self.ind = df_ind return (df_ind.iloc[self.window:, :])
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()
tp_style='hlc3') BB20.batch_fit(candles) # RSI: print('Fitting RSI...') RSI = ind.RSI(window_length=14, time_frame=time_frame) RSI.batch_fit(candles) # Stochastic RSI: print('Fitting Stochastic RSI...') SRSI = ind.StochasticRSI(stoch_length=14, time_frame=time_frame) SRSI.batch_fit(candles) # MACD: print('Fitting MACD...') MACD = ind.MACD(12, 26, 9, time_frame, 'close') MACD.batch_fit(candles) """ Making plots using Plotly """ print('\nPlotting...') fig = make_subplots( rows=5, cols=1, shared_xaxes=True, specs=[[{ "rowspan": 2 }], [None], [{}], [{}], [{}]], ) # Bollinger Bands on the background: BB20.plot(fig) # Then Candlesticks:
def main(): parser = argparse.ArgumentParser() parser.add_argument("file") args = parser.parse_args() df = pd.read_csv(args.file, index_col='time', parse_dates=True) #close = df.loc['20191225':,['close']].astype('float64') close = df print("Buy And Hold Strategy :") strat1 = strategies.BuyAndHoldStrategy(close, 0.001) res = strat1.backtest(close['close']) print(res) print(flush=True) add_ema(close, 12) add_ema(close, 26) macd = indicators.MACD(close['close'], 12, 26, 9) rsi = indicators.RSI(close['close'], 9) bb1 = indicators.BollingerBands(close['close'], 20, 1) bb2 = indicators.BollingerBands(close['close'], 20, 2) print("MACD Strategy :") strat3 = strategies.MACDStrategy(close, macd, 0.001) res = strat3.backtest(close['close']) print(res) print(flush=True) print("RSI Strategy :") strat4 = strategies.RSIStrategy(close, rsi, 0.001) res = strat4.backtest(close['close']) print(res) print(flush=True) print("Double Bollinger Bands Strategy :") strat5 = strategies.DBBStrategy(close['close'], bb1, bb2) res = strat5.backtest(close['close']) print(res) print(flush=True) print("Custom RSI + MACD Strategy :") strat2 = strategies.RSIMACDStrategy(close, rsi, macd, 0.001) res = strat2.backtest(close['close']) print(res) fig, (ax1, ax2, ax3, ax4) = plt.subplots(4, sharex=True) fig.suptitle(args.file) ax1.plot(close['close']) ax1.plot(close['ema12'], label='EMA12') ax1.plot(close['ema26'], label='EMA26') ax1.plot(close['close'].loc[strat2.signals['positions'] == 1.0].index, close['close'].loc[strat2.signals['positions'] == 1.0], '^', markersize=10, color='g') ax1.plot(close['close'].loc[strat2.signals['positions'] == -1.0].index, close['close'].loc[strat2.signals['positions'] == -1.0], 'v', markersize=10, color='r') ax1.legend() macd, macd_signal = macd.data() ax2.plot(macd, label='MACD 12 26 9') ax2.plot(macd_signal) #ax3.plot(strat1.signals['equity']) ax3.plot(rsi.data(), label='RSI 9') ax4.plot(strat2.signals['equity']) plt.show()