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')
Ejemplo n.º 2
0
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
		"""