def test_github_issue37_plotaspectratio(): cerebro = bt.Cerebro() data = bt.feeds.YahooFinanceCSVData( dataname=getdatadir("orcl-1995-2014.txt"), fromdate=datetime.datetime(2000, 1, 1), todate=datetime.datetime(2001, 2, 28), reverse=False, ) cerebro.adddata(data) cerebro.broker.setcash(10000) cerebro.coc = True cerebro.broker.setcommission(commission=0.00075) cerebro.addstrategy(BokehTest) cerebro.run() plotconfig = { 'id:rsi': dict(plotaspectratio=10, ), } b = Bokeh(style='bar', plot_mode='single', scheme=Tradimo(), plotconfig=plotconfig, output_mode='memory') output = cerebro.plot(b) assert output[0][0].figures[1].bfigure.aspect_ratio == 10
def run_back_testing(cls, stock_id): """ Run the back testing, return the analysis data. :param stock_id(string) :return(dict): analysis data. """ # get the data data = cls.get_data(stock_id) cerebro = bt.Cerebro() data = bt.feeds.PandasData(dataname=data) cerebro.adddata(data, name=stock_id) cerebro.addstrategy(Basic5MA) cerebro.addanalyzer(bt.analyzers.TimeReturn, _name='al_return', timeframe=bt.analyzers.TimeFrame.NoTimeFrame) cerebro.addanalyzer(bad.TimeDrawDown, _name='al_max_drawdown') cerebro.broker.set_cash(bsu.Utils.DEFAULT_CASH) cerebro.addsizer(bt.sizers.FixedSize, stake=100) cerebro.broker.setcommission(commission=0.005) cerebro.run() if conf.DEBUG: list = [stock_id, '.html'] b = Bokeh(style='bar', plot_mode='single', scheme=Tradimo(), filename=''.join(list), output_mode='show') cerebro.plot(b)
def test_github_issue30(): cerebro = bt.Cerebro() cerebro.addstrategy(MyStrategy) data = bt.feeds.YahooFinanceCSVData( dataname=getdatadir("orcl-1995-2014.txt"), fromdate=datetime.datetime(2000, 1, 1), todate=datetime.datetime(2001, 2, 28), reverse=False, ) cerebro.adddata(data) cerebro.addanalyzer(bt.analyzers.SharpeRatio) cerebro.run() b = backtrader_plotting.Bokeh(filename='chart.html', style='bar', scheme=Tradimo(), output_mode='memory') figs = cerebro.plot(b) assert isinstance(figs[0][0], backtrader_plotting.bokeh.bokeh.FigurePage) assert len(figs[0][0].figures) == 4 assert len(figs[0][0].analyzers) == 1
def save_plot(**kwargs): # Instantiate Cerebro cerebro = bt.Cerebro() # Add data original timestamp cerebro.adddata(_data) # Upsampling in case of need just uncomment the next line cerebro.replaydata(_data, timeframe=tframes[_replay_period]) # Add strateg cerebro.addstrategy(_strategy, **kwargs) # Set our desired cash start cerebro.broker.setcash(_cash) # Set the commission cerebro.broker.setcommission(commission=_commission) cerebro.run() # Plot the result b = Bokeh(style='bar', scheme=Tradimo(), output_mode='save', filename='./best_iteration.html') cerebro.plot(b)
def runstart(): cerebro = bt.Cerebro() #画图 b = Bokeh(style='bar', plot_mode='single', scheme=Tradimo()) #数据加工清洗: #for d in fk.get_cyb: for code in stockpool: codename=code df = pro.daily(ts_code=code,start_date=20180101) #数据-加工 df['trade_date']=pd.to_datetime(df['trade_date']) df=df.rename(columns={'vol':'volume'}) df.set_index('trade_date', inplace=True) # 设置索引覆盖原来的数据 df = df.sort_index(ascending=True) #从小到大 df['openinterest']=0 df=df[['open','high','low','close','volume','openinterest']] data = bt.feeds.PandasData(dataname=df) cerebro.adddata(data,name=code) cerebro.addstrategy(MyStrategy) cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='SP') #夏普 cerebro.addanalyzer(bt.analyzers.AnnualReturn, _name='AR')#每年化收益率 cerebro.addanalyzer(bt.analyzers.DrawDown, _name='DD')#回撤 cerebro.addanalyzer(bt.analyzers.Returns, _name='RE') #收益率 #回测-资金规则(总资产和手续费) cerebro.broker.setcash(100000.0) cerebro.broker.setcommission(0.0003) #回测-启动 print('初始金额: %.2f' % cerebro.broker.getvalue()) back = cerebro.run() #总份额,年化,回撤,夏普 ratio_list=[[ x.analyzers.SP.get_analysis()['sharperatio'],#夏普比率 x.analyzers.RE.get_analysis()['rtot']*100, #总复合收益率 x.analyzers.DD.get_analysis()['max']['drawdown'], #最大回撤 x.analyzers.DD.get_analysis()['max']['len']]#最大回撤周期 for x in back] #夏普 ratio_df = pd.DataFrame(ratio_list,columns=['夏普','年化%','最大回撤','最大回撤周期']) print(ratio_df) print('历年收益率:%s' %back[0].analyzers.AR.get_analysis())#每年年化收益率 print('标准收益率:%s' %back[0].analyzers.RE.get_analysis()['rnorm100']) # 年化标准化回报以100%展示 cerebro.plot(b) # cerebro.plot(style='candle') print('最终收益: %.2f' % cerebro.broker.getvalue())
def run_back_testing(cls, stock_id): """ Run the back testing, return the analysis data. :param stock_id(string) :return(dict): analysis data. """ # get the data data = cls.get_data(stock_id) length = len(data) # get the params best_params = cls.get_params(stock_id) cerebro = bt.Cerebro() data = bt.feeds.PandasData(dataname=data) cerebro.adddata(data, name=stock_id) ma_periods = best_params.ma_periods cerebro.addstrategy(cls, ma_periods=dict(ma_period_s=ma_periods.get('ma_period_s'), ma_period_l=ma_periods.get('ma_period_l'), stock_id=ma_periods.get('stock_id'))) cerebro.addanalyzer(bt.analyzers.TimeReturn, _name='al_return', timeframe=bt.analyzers.TimeFrame.NoTimeFrame) cerebro.addanalyzer(bad.TimeDrawDown, _name='al_max_drawdown') cerebro.broker.set_cash(bsu.Utils.DEFAULT_CASH) logger.debug( 'Starting back testing, stock is %s, params is ma_period_s: %d, ma_period_l: %d...' % ( ma_periods.get('stock_id'), ma_periods.get('ma_period_s'), ma_periods.get('ma_period_l') )) strats = cerebro.run() strat = strats[0] for k, v in strat.analyzers.al_return.get_analysis().items(): total_return_rate = v al_result = dict( stock_id=ma_periods.get('stock_id'), trading_days=length, total_return_rate=total_return_rate, max_drawdown=strat.analyzers.al_max_drawdown.get_analysis().get('maxdrawdown'), max_drawdown_period=strat.analyzers.al_max_drawdown.get_analysis().get('maxdrawdownperiod'), drawdown_points=strat.analyzers.al_max_drawdown.get_analysis().get('drawdownpoints') ) if conf.DEBUG: list = [ma_periods.get('stock_id'), '.html'] b = Bokeh(style='bar', plot_mode='single', scheme=Tradimo(), filename=''.join(list), output_mode='show') cerebro.plot(b) return al_result
def test_github_issue36(): cerebro = bt.Cerebro() cerebro.addstrategy(MyStrategy) filedir = os.path.dirname(os.path.abspath(__file__)) df = pd.read_csv(os.path.join(filedir, "datas/NQ.csv"), index_col=0) df.index = pd.DatetimeIndex(df.index) data = bt.feeds.PandasData(dataname=df, name='NQ', timeframe=bt.TimeFrame.Minutes) cerebro.adddata(data) cerebro.resampledata(data, name='NQ_5min', timeframe=bt.TimeFrame.Minutes, compression=5) cerebro.addanalyzer(bt.analyzers.SharpeRatio) cerebro.run() b = Bokeh(filename='chart.html', style='bar', plot_mode="single", scheme=Tradimo(), output_mode='memory') cerebro.plot(b)
def trade_run(): cerebro = bt.Cerebro() data = DBDataFeed( # 本地postgresql数据库 db_uri=ConfigUtils.get_mysql('engine'), dataname="sh.600004", fromdate=datetime.date(2010, 1, 1), ) cerebro.adddata(data) cerebro.addstrategy(SMACross) cerebro.addsizer(bt.sizers.AllInSizerInt) cerebro.broker.set_cash(100000) cerebro.addanalyzer(bt.analyzers.AnnualReturn, _name="annual_returns") cerebro.addanalyzer(bt.analyzers.DrawDown, _name="draw_down") cerebro.addanalyzer(bt.analyzers.Transactions, _name="transactions") results = cerebro.run() # 打印Analyzer结果到日志 for result in results: annual_returns = result.analyzers.annual_returns.get_analysis() log.info("annual returns:") for year, ret in annual_returns.items(): log.info("\t {} {}%, ".format(year, round(ret * 100, 2))) draw_down = result.analyzers.draw_down.get_analysis() log.info( "drawdown={drawdown}%, moneydown={moneydown}, drawdown len={len}, " "max.drawdown={max.drawdown}, max.moneydown={max.moneydown}, " "max.len={max.len}".format(**draw_down)) transactions = result.analyzers.transactions.get_analysis() log.info("transactions") # 运行结果绘图 # cerebro.plot() b = Bokeh(style="bar", tabs="multi", scheme=Tradimo()) cerebro.plot(b)
def _run_cerebro(stratcls): cerebro = bt.Cerebro() cerebro.addstrategy(stratcls) datas = [ 'nvda-1999-2014.txt', 'orcl-1995-2014.txt', ] for dname in datas: data = bt.feeds.YahooFinanceCSVData( dataname=getdatadir(dname), fromdate=datetime.datetime(2000, 1, 1), todate=datetime.datetime(2001, 2, 28), reverse=False, ) cerebro.adddata(data) cerebro.addanalyzer(bt.analyzers.SharpeRatio) cerebro.run() b = backtrader_plotting.Bokeh(style='bar', scheme=Tradimo(), output_mode='memory') return cerebro.plot(b)
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)
cerebro.addstrategy(TestStrategy) # Create a data feed data = bt.feeds.YahooFinanceData(dataname='MSFT', fromdate=datetime.datetime(2019, 1, 1), todate=datetime.datetime(2019, 12, 31)) # Add the Data Feed to Cerebro cerebro.adddata(data) # Set our desired cash start cerebro.broker.setcash(1000.0) # Add a FixedSize sizer according to the stake cerebro.addsizer(bt.sizers.FixedSize, stake=10) # Set the commission cerebro.broker.setcommission(commission=0.0) # Print out the starting conditions #print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) # Run over everything cerebro.run() # Print out the final result #print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue()) # Plot the result b = Bokeh(style='bar', tabs='multi', scheme=Tradimo()) cerebro.plot(b)
bt.indicators.Ichimoku() def next(self): pos = len(self.data) if pos == 45 or pos == 145: self.buy(self.datas[0], size=None) if pos == 116 or pos == 215: self.sell(self.datas[0], size=None) if __name__ == '__main__': cerebro = bt.Cerebro() cerebro.addstrategy(MyStrategy) data = bt.feeds.YahooFinanceCSVData( dataname="datas/orcl-1995-2014.txt", fromdate=datetime.datetime(2000, 1, 1), todate=datetime.datetime(2001, 2, 28), reverse=False, swapcloses=True, ) cerebro.adddata(data) cerebro.addanalyzer(bt.analyzers.SharpeRatio) cerebro.run() b = Bokeh(style='bar', scheme=Tradimo()) cerebro.plot(b)
def perform_backtest(params, df, strategy, PandasData_Custom, bokeh=False): curr_result = {} curr_result = params data = PandasData_Custom(dataname=df) cerebro = bt.Cerebro() cerebro.adddata(data) cerebro.addstrategy(strategy, parameters=params) cerebro.addanalyzer(bt.analyzers.SharpeRatio, riskfreerate=0.0, annualize=True, timeframe=bt.TimeFrame.Days) cerebro.addanalyzer(bt.analyzers.Calmar) cerebro.addanalyzer(bt.analyzers.DrawDown) cerebro.addanalyzer(bt.analyzers.Returns) cerebro.addanalyzer(bt.analyzers.TradeAnalyzer) initial_cash = 1000 cerebro.broker = bt.brokers.BackBroker( cash=initial_cash, slip_perc=0.01 / 100, commission=CommInfoFractional(commission=(0.075 * params['mult']) / 100, mult=params['mult']), slip_open=True, slip_out=True) # 0.5% run = cerebro.run() all_logs = run[0].get_logs() portfolio = all_logs[0] trades = all_logs[1] operations = all_logs[2] trades_analysis = trades.merge(operations, on='Date', how='left') trades_analysis = trades_analysis.fillna(method='bfill') trades_analysis['Date'] = pd.to_datetime(trades_analysis['Date']) trades_analysis['Date'] = trades_analysis['Date'] - timedelta(minutes=10) analysis = run[0].analyzers.getbyname('tradeanalyzer').get_analysis() try: curr_result['Total Trades'] = analysis['total']['total'] except: curr_result['Total Trades'] = 0 try: curr_result['Total Profit'] = analysis['won']['total'] curr_result['Avg Profit'] = analysis['won']['pnl']['average'] except: curr_result['Total Profit'] = 0 curr_result['Avg Profit'] = 0 try: curr_result['Total Loss'] = analysis['lost']['total'] curr_result['Average Loss'] = analysis['lost']['pnl']['average'] except: curr_result['Total Loss'] = 0 curr_result['Average Loss'] = 0 try: curr_result['Total Long'] = analysis['long']['total'] curr_result['Average Long'] = analysis['long']['pnl']['average'] except: curr_result['Total Long'] = 0 curr_result['Average Long'] = 0 try: curr_result['Total Short'] = analysis['short']['total'] curr_result['Average Short'] = analysis['short']['pnl']['average'] except: curr_result['Total Short'] = 0 curr_result['Average Short'] = 0 curr_result['Return (%)'] = round( ((portfolio['Value'].iloc[-1] - portfolio['Value'].iloc[0]) / portfolio['Value'].iloc[0]) * 100, 2) curr_result['sharpe'] = run[0].analyzers.getbyname( 'sharperatio').get_analysis()['sharperatio'] portfolio['Date'] = pd.to_datetime(portfolio['Date']) portfolio = portfolio.set_index('Date') daily_portfolio = portfolio.resample('1D').agg( {'Value': lambda x: x.iloc[-1]}) if bokeh == True: b = Bokeh(style='bar', plot_mode='single', scheme=Tradimo()) fig = cerebro.plot(b) s_fig = fig[0][0] bokeh_html = file_html(s_fig.model, CDN, "Backtest Plot") if not os.path.isdir("bokeh/"): os.makedirs("bokeh/") fname = secrets.token_hex(3) + ".html" with open('bokeh/{}'.format(fname), 'w') as file: file.write(bokeh_html) return fname return curr_result
def bt_run(strat_p_list,df): # Create a cerebro entity try: cerebro = bt.Cerebro(tradehistory=True) cerebro.addanalyzer(bt.analyzers.cmtrans.cmTrans) # cerebro.addwriter(bt.WriterFile, out = 'test.csv', csv=True, rounding=5) data_table_id = strat_p_list[0] scrip_code = strat_p_list[1] strategy = strat_p_list[2] trade_size = strat_p_list[3] start_cash = strat_p_list[4] ex,m_t,t_f = su.parameters_from_data_table_id(data_table_id) # Get Class from strategy Name module = importlib.import_module('spe.strategies.'+strategy) class_name = strategy strategy = getattr(module, class_name) # Add a strategy cerebro.addstrategy(strategy,trade_size=trade_size) # Minimum datalength min_data = strategy.candle_lb() # Add the Data Feed to Cerebro # Returns Cerebro riteith datafeed attached cerebro_w_data = dh.data_feed(scrip_code,ex,m_t,t_f,cerebro,min_data) if cerebro_w_data is None: print('No Data Available') return [] # Set our desired cash start cerebro_w_data.broker.setcash(start_cash) # Set the commission - 0.1% ... divide by 100 to remove the % cerebro_w_data.broker.setcommission(commission=0.000) # cerebro_w_data.addanalyzer(bt.analyzers.TradeAnalyzer, _name="stats") # cerebro_w_data.addanalyzer(bt.analyzers.PositionsValue, _name="an_return") cerebro_w_data.addanalyzer(bt.analyzers.Returns) # cerebro_w_data.addanalyzer(bt.analyzers.PyFolio) # Print out the starting conditions # print('Starting Portfolio Value: %.2f' % cerebro_w_data.broker.getvalue()) # Run over everything strategy = cerebro_w_data.run() b = Bokeh(style='bar', plot_mode='single', scheme=Tradimo()) # cerebro_w_data.plot(b) Strat = strategy[0] # Print out the final result # print('Final Portfolio Value: %.2f' % cerebro_w_data.broker.getvalue()) # Strat.analyzers.stats.print() # Strat.analyzers.an_return.print() # print(f"Norm. Annual Return: {Strat.analyzers.returns.get_analysis()['rnorm100']:.2f}%") # pyfolizer = Strat.analyzers.getbyname('pyfolio') # returns, positions, transactions, gross_lev = pyfolizer.get_pf_items() # pf.create_returns_tear_sheet(returns) df = backtest_out(Strat,df) return Strat,df except Exception as e: # err.error_log(str(e),bt_run.__name__,'bt_run') logging.exception(str(e))
import backtrader from strategies.strategies import TestStrategy import pandas as pd from backtrader_plotting import Bokeh from backtrader_plotting.schemes import Tradimo #pip3 install backtrader_plotting #import matplotlib.pyplot as plt plotconfig = { 'id:ind#0': dict(subplot=True, ), } b = Bokeh(style='bar', plot_mode='single', scheme=Tradimo(), plotconfig=plotconfig) def create_stock_sp500_ratio_csv(stockName): datapath = (rf'Data\{stockName}.csv') dataframeStock = pd.read_csv(datapath) datapath = (rf'Data\SPY.csv') dataframeSPY = pd.read_csv(datapath) #crate copy df = dataframeSPY.copy() for i in range(df.shape[0]): # gives number of row count # df['Date'].iloc[i]-=dataframeStock['Date'].iloc[i] df['Open'].iloc[i] -= dataframeStock['Open'].iloc[i] df['High'].iloc[i] -= -dataframeStock['High'].iloc[i] df['Low'].iloc[i] -= dataframeStock['Low'].iloc[i] df['Close'].iloc[i] -= dataframeStock['Close'].iloc[i] df['Volume'].iloc[i] -= dataframeStock['Volume'].iloc[i]
print('最大回撤DW:', results[0].analyzers.DrawDown.get_analysis()) # 选取一只股票进行回测 cerebro2 = bt.Cerebro() baseline = '000300.SH' feed = bt.feeds.PandasData(dataname=get_data(baseline)) cerebro2.adddata(feed, name=baseline) cerebro2.broker.get_notification() # 回测设置 cerebro2.broker.setcash(startcash) # 设置佣金为千分之一 cerebro2.broker.setcommission(commission=0.001) # 添加策略 cerebro2.addstrategy(BaseStrategy, printlog=True) results2 = cerebro2.run() # 获取回测结束后的总资金 portvalue2 = cerebro2.broker.getvalue() pnl2 = portvalue2 - startcash # 打印结果 print(f'沪深300 总资金: {round(portvalue2, 2)}') print(f'沪深300 净收益: {round(pnl2, 2)}') print('沪深300Final Portfolio Value: %.2f' % cerebro2.broker.getvalue()) # 绘制图像 b = Bokeh(style='bar', plot_mode='multi', scheme=Tradimo()) # cerebro.plot(b) # cerebro.plot() plot_result(results, results2, s)
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)