def runstrat(): #Create an instance of cerebro cerebro = bt.Cerebro(exactbars=-1) #exactbars True reduces memory usage significantly, but change to '-1' for partial memory savings (keeping indicators in memory) or 'false' to turn off completely if having trouble accessing bars beyond max indicator paramaters. cerebro.broker.set_coc(False) #allows you to buy/sell close price of previous bar, vs. default behavior of open on next bar. cerebro.broker.set_coo(False) #default is False, meaning assuming day bars,orders are put in at end of previous day (end of previous bar) and order execution happens at open of today's bar (at open of current bar). Cheat on open puts order in same day before bar opens, and executes at open price. Such a use case fails when the opening price gaps (up or down, depending on whether buy or sell is in effect) and the cash is not enough for an all-in operation. This forces the broker to reject the operation. cerebro.broker.set_shortcash(True) #False means decrease cash available when you short, True means increase it #Add our strategy cerebro.addstrategy(Strategy) #Create/Instantiate objects to access parameters from UserInput Class #Can NOT create object referencing Strategy class as per backtrader modelp = UserInputs.model_params() if modelp.get('live_status'): ibdatalist = UserInputs.datalist('ib') #Ensure stock lists have no duplicates - duplicates will BREAK program if len(ibdatalist) != len(set(ibdatalist)): print("*****You have duplicates in stock list - FIX LIST*****") else: datalist = UserInputs.datalist('hist') if len(datalist) != len(set(datalist)): print("*****You have duplicates in stock list - FIX LIST*****") #GET THE DATA session_start = modelp.get('sessionstart') session_end = modelp.get('sessionend') if not modelp.get('live_status'): #******BACTESTING ONLY - MYSQL DATABASE********* #mysql configuration items for connection host = '127.0.0.1' user = '******' password = '******' database = 'Stock_Prices' table = '5_min_prices' #Determine data range to run start_date = modelp.get('start_date') end_date = modelp.get('end_date') for i,j in enumerate(datalist): #Get data from mysql and add data to Cerebro data = mysql.MySQLData(dbHost = host, dbUser = user, dbPWD = password, dbName = database, table = table, symbol = j, fromdate = start_date, todate= end_date, sessionstart = session_start, sessionend = session_end, compression = modelp.get('timeframe0'), ) data_BaseTimeframe = cerebro.adddata(data=data, name="{}0".format(j), ) if modelp.get('timeframe1on'): #Apply resamplings data_Timeframe1 = cerebro.resampledata(data, name="{}1".format(j), timeframe=bt.TimeFrame.Minutes, compression = modelp.get('timeframe1'), ) if modelp.get('timeframe2on'): data_Timeframe2 = cerebro.resampledata(data, name="{}2".format(j), timeframe=bt.TimeFrame.Minutes, compression = modelp.get('timeframe2'), ) # Set our desired cash start cerebro.broker.setcash(modelp.get('start_cash')) # Set the commission cerebro.broker.setcommission(commission=0.00003, margin= None, mult=1.0, commtype=None, percabs=True, stocklike=True, leverage=1) """ #Set the slippage cerebro.broker.set_slippage_perc(0.001, slip_open=True, slip_limit=True, slip_match=True, slip_out=False) """ elif modelp.get('live_status'): #***** LIVE TRADING PARAMETERS******* store = bt.stores.IBStore(host='127.0.0.1', port=7497, clientId = 100) """ for i,j in enumerate(ibdatalist): #Data for live IB trading data = store.getdata(dataname=j, sectype='STK', exchange='SMART', currency='USD', timeframe=bt.TimeFrame.Minutes, tz = pytz.timezone('US/Central'), sessionstart = session_start, sessionend = session_end, useRTH = True, rtbar=True, ) cerebro.resampledata(data, name="{}0".format(j),timeframe=bt.TimeFrame.Minutes, compression=modelp.get('timeframe0')) #Apply resamplings if modelp.get('timeframe1on'): data_Timeframe1 = cerebro.resampledata(data,name="{}1".format(j), timeframe=bt.TimeFrame.Minutes, compression = modelp.get('timeframe1')) if modelp.get('timeframe2on'): data_Timeframe2 = cerebro.resampledata(data,name="{}2".format(j), timeframe=bt.TimeFrame.Minutes, compression = modelp.get('timeframe2')) """ forexdatalist = ['EUR.USD','GBP.USD'] #MAKE SURE NO COMMAS AFTER LAST TICKER for i,j in enumerate(forexdatalist): #Data for live IB trading forexdata = store.getdata(dataname=j, sectype='CASH', exchange='IDEALPRO', timeframe=bt.TimeFrame.Minutes, tz = pytz.timezone('US/Central'), sessionstart = session_start, sessionend = session_end, ) cerebro.resampledata(forexdata, name="{}0".format(j),timeframe=bt.TimeFrame.Minutes, compression=modelp.get('timeframe0')) #Apply resamplings if modelp.get('timeframe1on'): data_Timeframe1 = cerebro.resampledata(forexdata,name="{}1".format(j), timeframe=bt.TimeFrame.Minutes, compression = modelp.get('timeframe1')) if modelp.get('timeframe2on'): data_Timeframe2 = cerebro.resampledata(forexdata,name="{}2".format(j), timeframe=bt.TimeFrame.Minutes, compression = modelp.get('timeframe2')) """ #ADD MARKET BREADTH DATA LIKE TICK indexdatalist = ['TICK-NYSE'] #MAKE SURE NO COMMAS AFTER LAST TICKER for i,j in enumerate(indexdatalist): tickdata = store.getdata(dataname=j, sectype='IND', exchange='NYSE', currency='USD', timeframe=bt.TimeFrame.Minutes, what = 'TRADES', sessionstart = session_start, sessionend = session_end, ) cerebro.resampledata(tickdata, name="{}0".format(j), timeframe=bt.TimeFrame.Minutes, compression=modelp.get('timeframe0')) #Apply resamplings if modelp.get('timeframe1on'): tickdata_Timeframe1 = cerebro.resampledata(tickdata,name="{}1".format(j), timeframe=bt.TimeFrame.Minutes, compression = modelp.get('timeframe1')) if modelp.get('timeframe2on'): tickdata_Timeframe2 = cerebro.resampledata(tickdata,name="{}2".format(j), timeframe=bt.TimeFrame.Minutes, compression = modelp.get('timeframe2')) """ cerebro.broker = store.getbroker() #*****Critical line of code to access broker so you can trade***** # Add SQN to qualify the trades (rating to analyze quality of trading system: 2.5-3 good, above 3 excellent. SquareRoot(NumberTrades) * Average(TradesProfit) / StdDev(TradesProfit). Need at least 30 trades to be reliable cerebro.addanalyzer(bt.analyzers.SQN) #Add Sharpe Ratio - configured for daily returns cerebro.addanalyzer(bt.analyzers.SharpeRatio) #Adding my own custom analyzer - when creating analyzer, make sure to include file in _init_.py within backtrader.analyzer folder so it runs cerebro.addanalyzer(bt.analyzers.AcctStats) #Adding analyzer for drawdown cerebro.addanalyzer(bt.analyzers.DrawDown) # Add TradeAnalyzer to output trade statistics - THESE ARE THE TRADE NOTIFICATIONS THAT ARE PRINTED WHEN PROGRAM IS RUN #cerebro.addanalyzer(bt.analyzers.Transactions) #Adds just buy/sell observer to chart (assuming stdstats is set to false) cerebro.addobservermulti(bt.observers.BuySell,) #Adds custom observers cerebro.addobserver(bt.observers.AcctValue) #reports trade statistics in command prompt at end of program run #cerebro.addobserver(bt.observers.OrderObserver) #reports trades in command prompt when program is run #Generate output report in csv format if UserInputs.model_params().get('writer')=='on': current_time = datetime.now().strftime("%Y-%m-%d_%H.%M.%S.csv") csv_file = 'C:/Program Files (x86)/Python36-32/Lib/site-packages/backtrader/out/' csv_file += 'Strategy' csv_file += current_time cerebro.addwriter(bt.WriterFile, csv = True, out=csv_file) print("Writer CSV Report On") #RUN EVERYTHING results = cerebro.run(stdstats=False, #enables some additional chart information like profit/loss, buy/sell, etc, but tends to clutter chart runonce=True, ) if not modelp.get('live_status'): #Print analyzers for alyzer in results[0].analyzers: alyzer.print() #Calculate Program end time end_time = datetime.now().time() print('Program end at {}'.format(end_time)) #PLOT TRADING RESULTS - **Ensure trading session ends at 2:55 (if it ends at 3, some tickers only go up to 2:55, creating data length mismatches between tickers that doesn't allow plotting) plot_end = modelp.get('end_date')-timedelta(hours=8, minutes=0, seconds=.01) #Hack to prevent errors with plotting, specifically x and y shape different error #Chart 5 minute timeframes only, 1 by 1 for i in range (0,len(results[0].datas),3): for j, d in enumerate(results[0].datas): d.plotinfo.plot = i ==j cerebro.plot(end = plot_end, barup='olive', bardown='lightpink',volup = 'lightgreen',voldown='crimson')
def runstrat(): #Create an instance of cerebro cerebro = bt.Cerebro(exactbars=-1) #exactbars True reduces memory usage significantly, but change to '-1' for partial memory savings (keeping indicators in memory) or 'false' to turn off completely if having trouble accessing bars beyond max indicator paramaters. cerebro.broker.set_coc(False) #cheat on close allows you to buy the close price of the current bar in which order was made. cheat on open allows you to simulate a market order on the open price of the next bar cerebro.broker.set_coo(False) #cheat on close allows you to buy the close price of the current bar in which order was made. cheat on open allows you to simulate a market order on the open price of the next bar #Add our strategy cerebro.addstrategy(Strategy) #Create/Instantiate objects to access parameters from UserInput Class #Can NOT create object referencing Strategy class as per backtrader modelp = UserInputs.model_params() indp = UserInputs.ind_params() datalist = UserInputs.datalist('hist') ibdatalist = UserInputs.datalist('ib') #Ensure stock lists have no duplicates - duplicates will BREAK program if len(datalist) != len(set(datalist)) or len(ibdatalist) != len(set(ibdatalist)): print("*****You have duplicates in stock list - FIX LIST*****") #GET THE DATA session_start = modelp.get('sessionstart') session_end = modelp.get('sessionend') start_date = modelp.get('start_date') end_date = modelp.get('end_date') sqlstart_date = "{} {}".format(start_date,session_start) sqlend_date = "{} {}".format(end_date,session_end) if modelp.get('live_status'): #***** LIVE TRADING PARAMETERS******* store = bt.stores.IBStore(host='127.0.0.1', port=7497, clientId = 100) #get number of tickers ticker_count = len(ibdatalist) indicator_dict = UserInputs.ind_params() max_ind = max(indicator_dict.values()) #Data set for live trading IB for i,j in enumerate(ibdatalist): #Data for live IB trading data = store.getdata(dataname=j, timeframe=bt.TimeFrame.Minutes, tz = pytz.timezone('US/Central'), #historical = True, backfill_start = True, #true enables maximum allowable backfill in single request useRTH = True, rtbar=True, fromdate = UserInputs.ib_backfill_start(UserInputs.max_ind()),#from date determined by today - max period paramater sessionstart = session_start, sessionend = session_end, notifyall=True, qcheck=2.0, debug=True) cerebro.resampledata(data, name="{}0".format(j),timeframe=bt.TimeFrame.Minutes, compression=modelp.get('base_timeframe')) #Apply resamplings if modelp.get('timeframe1on'): data_Timeframe1 = cerebro.resampledata(data,name="{}1".format(j), timeframe=bt.TimeFrame.Minutes, compression = modelp.get('timeframe1')) if modelp.get('timeframe2on'): data_Timeframe2 = cerebro.resampledata(data,name="{}2".format(j), timeframe=bt.TimeFrame.Minutes, compression = modelp.get('timeframe2')) cerebro.broker = store.getbroker() elif not modelp.get('live_status'): #******BACTESTING ONLY - MYSQL DATABASE********* #get number of tickers ticker_count = len(datalist) #mysql configuration items for connection host = '127.0.0.1' user = '******' password = '******' database = 'Stock_Prices' table = '5_min_prices' #Determine data range to run start_date = modelp.get('start_date') end_date = modelp.get('end_date') for i,j in enumerate(datalist): #Get data from mysql and add data to Cerebro data = mysql.MySQLData(dbHost = host, dbUser = user, dbPWD = password, dbName = database, table = table, symbol = j, fromdate = start_date, todate= end_date, timeframe=bt.TimeFrame.Minutes, compression = modelp.get('base_timeframe'), sessionstart=session_start, sessionend=session_end, ) data_BaseTimeframe = cerebro.adddata(data=data, name="{}0".format(j), ) data_BaseTimeframe.csv=True #Report this data to csv file (true) or not (false) data_BaseTimeframe.plotinfo.plot = True if modelp.get('timeframe1on'): #Apply resamplings data_Timeframe1 = cerebro.resampledata(data, name="{}1".format(j), timeframe=bt.TimeFrame.Minutes, compression = modelp.get('timeframe1'), ) data_Timeframe1.csv=False #Report this data to csv file (true) or not (false) data_Timeframe1.plotinfo.plot = True #data_Timeframe1.plotinfo.plotmaster = data_BaseTimeframe if modelp.get('timeframe2on'): data_Timeframe2 = cerebro.resampledata(data, name="{}2".format(j), timeframe=bt.TimeFrame.Minutes, compression = modelp.get('timeframe2'), ) data_Timeframe2.csv=False #Report this data to csv file (true) or not (false) data_Timeframe2.plotinfo.plot = True #data_Timeframe2.plotinfo.plotmaster = data_BaseTimeframe # Set our desired cash start cerebro.broker.setcash(modelp.get('start_cash')) # Set the commission cerebro.broker.setcommission(commission=0.00003, margin= None, mult=1.0, commtype=None, percabs=True, stocklike=True, leverage=1) """ #Set the slippage cerebro.broker.set_slippage_perc(0.001, slip_open=True, slip_limit=True, slip_match=True, slip_out=False) """ # Add SQN to qualify the trades (rating to analyze quality of trading system: 2.5-3 good, above 3 excellent. SquareRoot(NumberTrades) * Average(TradesProfit) / StdDev(TradesProfit). Need at least 30 trades to be reliable cerebro.addanalyzer(bt.analyzers.SQN) #Adding my own custom analyzer - when creating analyzer, make sure to include file in _init_.py within backtrader.analyzer folder so it runs cerebro.addanalyzer(bt.analyzers.AcctStats) #Adding analyzer for drawdown cerebro.addanalyzer(bt.analyzers.DrawDown) # Add TradeAnalyzer to output trade statistics cerebro.addanalyzer(bt.analyzers.Transactions) #Adds just buy/sell observer to chart (assuming stdstats is set to false) cerebro.addobservermulti(bt.observers.BuySell) #Adds custom observers cerebro.addobserver(bt.observers.AcctValue) #reports trade statistics in command prompt at end of program run cerebro.addobserver(bt.observers.OrderObserver) #reports trades in command prompt when program is run #Generate output report in csv format if UserInputs.model_params().get('writer')=='on': current_time = datetime.now().strftime("%Y-%m-%d_%H.%M.%S.csv") csv_file = 'C:/Program Files (x86)/Python36-32/Lib/site-packages/backtrader/out/' csv_file += 'Strategy' csv_file += current_time cerebro.addwriter(bt.WriterFile, csv = True, out=csv_file) print("Writer CSV Report On") #RUN EVERYTHING results = cerebro.run(stdstats=False, #enables some additional chart information like profit/loss, buy/sell, etc, but tends to clutter chart runonce=False, ) strats = results[0] if not modelp.get('live_status'): #Print analyzers for alyzer in strats.analyzers: alyzer.print() #Calculate Program end time end_time = datetime.now().time() print('Program end at {}'.format(end_time)) #Chart all timeframes, one by one for i in range (len(strats.datas)): for j, d in enumerate(strats.datas): d.plotinfo.plot = i ==j cerebro.plot(volume = True, style='candlestick',barup='olive', bardown='lightpink',volup = 'lightgreen',voldown='crimson') #Only chart 5 minute graphs, one by one """