if __name__ == '__main__': cerebro = bt.Cerebro(maxcpus=1) data = bt.feeds.YahooFinanceCSVData( dataname="datas/orcl-1995-2014.txt", fromdate=datetime.datetime(2000, 1, 1), todate=datetime.datetime(2001, 2, 28), ) cerebro.adddata(data) cerebro.addanalyzer(bt.analyzers.TradeAnalyzer) cerebro.optstrategy(MyStrategy, buydate=range(40, 180, 30)) optres = cerebro.run(optreturn=False) def benchmark(optresults): a = [x.analyzers.tradeanalyzer.get_analysis() for x in optresults] return sum([x.pnl.gross.total if 'pnl' in x else 0 for x in a]) result = [ OrderedOptResult.BenchmarkedResult(benchmark(x), x) for x in optres ] ordered_result = sorted(result, key=lambda x: x.benchmark, reverse=True) ordered_result = OrderedOptResult("Profit & Losss", ordered_result) b = Bokeh(style='bar', plot_mode="single", scheme=Tradimo()) b.plot_result(ordered_result)
if pos == self.p.buydate: self.buy(self.datas[0], size=None) if pos == self.p.buydate + self.p.holdtime: self.sell(self.datas[0], size=None) if __name__ == '__main__': cerebro = bt.Cerebro(maxcpus=1) data = bt.feeds.YahooFinanceCSVData( dataname="datas/orcl-1995-2014.txt", fromdate=datetime.datetime(2000, 1, 1), todate=datetime.datetime(2001, 2, 28), ) cerebro.adddata(data) cerebro.addanalyzer(bt.analyzers.TradeAnalyzer) cerebro.optstrategy(MyStrategy, buydate=range(40, 180, 30)) result = cerebro.run(optreturn=False) def get_pnl_gross(strats): a = strats[0].analyzers.tradeanalyzer.get_analysis() return a.pnl.gross.total if 'pnl' in a else 0 columns = dict(pnl=get_pnl_gross) b = Bokeh(style='bar', plot_mode="single", scheme=Tradimo()) b.plot_result(result, columns)
sma1 = bt.indicators.SMA(period=11, subplot=True) bt.indicators.SMA(period=17, plotmaster=sma1) bt.indicators.RSI() def next(self): pos = len(self.data) if pos == self.p.buydate: self.buy(self.datas[0], size=None) if pos == self.p.buydate + self.p.holdtime: self.sell(self.datas[0], size=None) if __name__ == '__main__': cerebro = bt.Cerebro(maxcpus=1) data = bt.feeds.YahooFinanceCSVData( dataname="datas/orcl-1995-2014.txt", fromdate=datetime.datetime(2000, 1, 1), todate=datetime.datetime(2001, 2, 28), ) cerebro.adddata(data) cerebro.addanalyzer(bt.analyzers.TradeAnalyzer) cerebro.optstrategy(MyStrategy, buydate=range(40, 180, 30)) result = cerebro.run(optreturn=False) b = Bokeh(style='bar', plot_mode="single", scheme=Tradimo()) b.plot_result(result)
def perform_backtest(symbol_par, n_fast_par, n_slow_par, long_macd_threshold_par, long_per_threshold_par, long_close_threshold_par, short_macd_threshold_par, short_per_threshold_par, short_close_threshold_par, initial_cash=10000, comission=0.1, df=None): ''' Parameter: __________ symbol_par (string): The symbol to use n_fast_par (int): Fast EMA line used during MACD calculation n_slow_par (int): Slower EMA line used during MACD calculation long_macd_threshold_par (int): The threshold of normalized macd, above which we might open a long position long_per_threshold_par (int): The value of percentage change over the last 2 hours above which we might open a long position #Might make this a parameter too long_close_threshold_par (int): Threshold of normalized macd, below which we will close the opened long position short_macd_threshold_par (int): The threshold of normalized macd, below which we might open a short position short_per_threshold_par (int): The value of percentage change over the last 2 hours below which we might open a short position short_close_threshold_par (int): Threshold of normalized macd, above which we will close the opened short position initial_cash (int) (optional): The cash to start from. Initiall 10k comission (int) (option): int fraction value. Defaults to 0.1%. This is much higher than normal. Staying on the safe side. df (Dataframe) (option): Uses df as features dataframe if specified. Otherwise reads the coin folder ''' global n_fast global n_slow global long_macd_threshold global long_per_threshold global long_close_threshold global short_macd_threshold global short_per_threshold global short_close_threshold global symbol n_fast = n_fast_par n_slow = n_slow_par long_macd_threshold = long_macd_threshold_par long_per_threshold = long_per_threshold_par long_close_threshold = long_close_threshold_par short_macd_threshold = short_macd_threshold_par short_per_threshold = short_per_threshold_par short_close_threshold = short_close_threshold_par symbol = symbol_par json_info = {} json_info['n_fast'] = n_fast json_info['n_slow'] = n_slow json_info['long_macd_threshold'] = long_macd_threshold_par json_info['long_per_threshold'] = long_per_threshold_par json_info['long_close_threshold'] = long_close_threshold_par json_info['short_macd_threshold'] = short_macd_threshold_par json_info['short_per_threshold'] = short_per_threshold_par json_info['short_close_threshold'] = short_close_threshold_par json_info['initial_cash'] = initial_cash json_info['comission'] = comission with open(get_root_dir() + "/data/parameters.json", 'w') as f: json.dump(json_info, f) features_file = get_root_dir() + "/data/features/{}.csv".format(symbol) if df is None: df = pd.read_csv(features_file) df['macd'] = ta.trend.macd(df['sentistrength_total'], n_fast=n_fast, n_slow=n_slow, fillna=True) df['macd'] = df['macd'].fillna(0) df['Time'] = pd.to_datetime(df['Time']) json_data = {} json_data['mean'] = df['macd'].mean() json_data['std'] = df['macd'].std() df['macd'] = (df['macd'] - json_data['mean']) / json_data['std'] df = df.dropna(subset=['Time']) curr_dir = get_root_dir() + "/data/backtest/{}".format(symbol) if not os.path.exists(curr_dir): os.makedirs(curr_dir) fig = create_plot(df, 'macd', 'SentiStength') plotly_json = fig.to_json() html = fig.to_html() with open(curr_dir + '/plotly.html', 'w') as file: file.write(html) with open(curr_dir + '/plotly.json', 'w') as file: file.write(plotly_json) df = df[['Time', 'Open', 'High', 'Low', 'Close', 'Volume', 'macd']] df.to_csv(os.path.join(curr_dir, "data.csv"), index=None) data = PandasData_Custom(dataname=df) cerebro = bt.Cerebro(cheat_on_open=True, maxcpus=None) cerebro.adddata(data) cerebro.addstrategy(tradeStrategy) cerebro.addanalyzer(bt.analyzers.SharpeRatio_A) cerebro.addanalyzer(bt.analyzers.Calmar) cerebro.addanalyzer(bt.analyzers.DrawDown) cerebro.addanalyzer(bt.analyzers.Returns) cerebro.addanalyzer(bt.analyzers.TradeAnalyzer) cerebro.broker.setcash(initial_cash) cerebro.broker.setcommission(comission / 100) run = cerebro.run() analysis = run[0].analyzers.getbyname('tradeanalyzer').get_analysis() trade_analyzer = {} trade_analyzer['total'] = analysis['total']['total'] trade_analyzer['open'] = analysis['total']['open'] trade_analyzer['closed'] = analysis['total']['closed'] with open(curr_dir + "/stats.json", 'w') as f: json.dump(trade_analyzer, f) portfolioValue, trades, operations = run[0].get_logs() # fig = cerebro.plot() # figure = fig[0][0] # figure.savefig(curr_dir + "/backtest.png") output_file(curr_dir + "/backtest.html") b = Bokeh(style='bar', plot_mode="tabs", scheme=Tradimo()) b.plot_result(run) df = df.set_index('Time') df = df.resample('1D').apply(resampler) df = df.reset_index() df = df[['Time', 'Open']].merge(portfolioValue, left_on='Time', right_on='Date').drop('Time', axis=1) df['hodl'] = (initial_cash / df['Open'].iloc[0]) * df['Open'] df = df.drop('Open', axis=1) df.to_csv(curr_dir + '/portfolio.csv', index=None) trades.to_csv(curr_dir + '/trades.csv', index=None) operations.to_csv(curr_dir + '/operations.csv', index=None) with open(os.path.join(curr_dir, "data.json"), 'w') as fp: json.dump(json_data, fp)