def trial(toPerform, curr): global pair global chart global prevPair global now global mcl global trained_mcl global chartData now += 1 num = "_".join(map(str, ("-".join(map(str, a)) for a in toPerform))) strategyDetails = {} for z in toPerform: if z[0] == "currency": pair = tradeCurrencies[z[1] - 1] strategyDetails[z[0]] = z[1] print("{} | {}/{} | {}".format(str(num), now, total, str(datetime.datetime.now())[:10])) if strat in ["4"]: if ('lookback-mc' in strategyDetails or 'advance' in strategyDetails or 'learnProgTotal' in strategyDetails) or mcl == "": mcl = MachineStrat(strat, strategyDetails) if not mcl.trained: learnProgTotal = 1400 if not 'learnProgTotal' in strategyDetails else strategyDetails[ 'learnProgTotal'] chart = BotChart(functions, pair) chart.getHistorical(period, startTime - period * (learnProgTotal + 30), endTime) totalChartData = chart.getPoints() trainingSet = totalChartData["weightedAverage"][:learnProgTotal] chartData = totalChartData[learnProgTotal:] trained_mcl = mcl.train(trainingSet) else: if pair != prevPair: chart = BotChart(functions, pair) chart.getHistorical(period, startTime, endTime) chartData = chart.getPoints() prevPair = pair strategy = BotStrategy(period, functions, totalBalance, num, strategyDetails, strat, trained_mcl) for index, candlestick in chartData.iterrows(): strategy.tick(candlestick) strategy.closeAllTrades() totalAssets, totalFees, totalTime, marketProf = strategy.calculateCurrentPosition( ) totalProfit = strategy.balance global trialResults timeEf = totalTime / (int(strategy.currentDateOrig) - int(strategy.startDate)) trialResults.append([ num, toPerform.copy(), totalProfit, (marketProf) * totalBalance, totalTime, timeEf ])
def main(argv): global period global pair global startTime global endTime global totalBalance global liveTrading global environment global chart global strat global cont global trained_mcl output.log("------------STARTING BACKTESTER------------") # Handle all the incoming arguments try: opts, args = getopt.getopt(argv, "hp:c:s:e:b:v:u:l:", ["period=", "currency="]) except getopt.GetoptError: try: opts, args = getopt.getopt(argv, "r") except: print( 'backtest.py -p <period length> -c <currency pair> -s <start time> -e <end time> -u <strategy> -b <balance> -v <environment> -l <live>' ) sys.exit(2) for opt, arg in opts: if opt == '-h': print( 'backtest.py -p <period length> -c <currency pair> -s <start time> -e <end time> -u <strategy> -b <balance> -v <environment> -l <live>' ) sys.exit() elif opt in ("-p", "--period"): if (int(arg) in [30, 300, 900, 1800, 7200, 14400, 86400]): period = int(arg) else: print( 'Poloniex requires periods in 300 (5mins),900 (15),1800 (30),7200 (2hr),14400(4hr), or 86400(24hr) second increments' ) sys.exit(2) elif opt in ("-s"): startTime = DateHelper.ut( datetime.datetime.strptime(arg, '%d/%m/%Y')) if "/" in arg else arg elif opt in ("-r"): cont = True elif opt in ("-v"): environment = arg elif opt in ("-e"): endTime = DateHelper.ut(datetime.datetime.strptime( arg, '%d/%m/%Y')) if "/" in arg else arg elif opt in ("-b"): totalBalance = int(arg) elif opt in ("-l"): liveTrading = True if int(arg) == 1 else False elif opt in ("-c"): if arg in currencies: pair = arg else: print("incorrect pair") sys.exit() elif opt in ("-u"): if len( list( set([str(i + 1) for i in range(numberOfStrats)]) & set(str(arg).split(',')))) > 0: strat = arg else: print("Bad strat params") sys.exit() # Instanstiate GUI for results createIndex = CreateIndex(environment) if not liveTrading and cont == False: #============================================================================== # [factor, lower limit, higher limit, step] is the format #============================================================================== # trialDetails = [['trailingstop',0,0.3,0.15],['maFactor',1,1.05,0.025],['lowMA',15,17,1],['highMA',35,55,10]] # trialDetails= [['stoplossDayCount', 0*86400/period, 30*86400/period, 5*86400/period],['stoploss', 0, 0.25, 0.05]] trialDetails = [['howSimReq', 0.87, 0.87, 0.01], ['lookback-mc', 9, 9, 1]] # trialDetails = [['highRSI',60,80,2],['lowRSI',20,40,2],['stoploss',0,0.4,0.04],['rsiperiod',10,20,2]] # trialDetails = [['upfactor',1,1.1,0.02],['downfactor',1,1.1,0.02],['lookback',28,40,1]] global total total = 1 for i in trialDetails: add = ((i[2] - i[1]) / i[3]) if isclose(add, round(add)): # fix this total *= (add + 1) else: print("bad params") sys.exit(2) performTrial(trialDetails, len(trialDetails), np.zeros(len(trialDetails))) output.logTrials(trialDetails, trialResults) # N dimensional views botgrapher.heatmap(trialResults) # 2 dimensional views if len(trialDetails) == 2: botgrapher.graph(trialResults) createIndex.CreatePages() else: trades = [] if cont == False: strategyDetails = {'howSimReq': 0.9, "lookback-mc": 7} param_to_store = strategyDetails param_to_store['strategy'] = strat param_to_store['pair'] = pair param_to_store['period'] = period functions.mysql_conn.storeAllParameters(param_to_store) else: strategyDetails = functions.mysql_conn.getAllParameters() stats = functions.mysql_conn.getStatistics() totalBalance = stats['balance'] trades = functions.mysql_conn.getAllOpenTrades() strat = strategyDetails['strategy'] pair = strategyDetails['pair'] period = int(strategyDetails['period']) del strategyDetails['strategy'] del strategyDetails['pair'] del strategyDetails['period'] if 'running_time' in stats: strategyDetails['running_time'] = stats['running_time'] print(strategyDetails) chart = BotChart(functions, pair) if (strat == "4"): print("Pretraining STARTED") learnProgTotal = 1400 if not 'learnProgTotal' in strategyDetails else strategyDetails[ 'learnProgTotal'] if (endTime == ""): endTime = DateHelper.ut(datetime.datetime.now()) if (startTime == ""): startTime = endTime - period * (learnProgTotal + 100) print("training from ~{} to {}".format(DateHelper.dt(startTime), DateHelper.dt(endTime))) chart.getHistorical(period, startTime, endTime) trainingSet = chart.getPoints() mcl = MachineStrat(strat, strategyDetails) trained_mcl = mcl.train( trainingSet["weightedAverage"][:learnProgTotal + 30]) lookback = 7 if not 'lookback-mc' in strategyDetails else int( strategyDetails['lookback-mc']) print("Pretraining finished") strategy = BotStrategy(period, functions, totalBalance, 0, strategyDetails, strat, trained_mcl, trades) if strat == "4": for index, candlestick in trainingSet[-lookback - 1:].iterrows(): strategy.tick(candlestick, True) while True: date = datetime.datetime.now() while ((date.hour % 4 == 0 and date.minute > 30) or (date.hour % 4 == 1 and date.minute < 25)) == False: date = datetime.datetime.now() print('checking for appropriate start time', date) time.sleep(60 * 5) start = time.time() currTick = dict(chart.getNext()) currTick['date'] = str(DateHelper.ut(datetime.datetime.now())) strategy.tick(currTick) createIndex.CreatePages() print('{}: Sleeping ...'.format(currTick['date'])) end = time.time() if int(period) - (end - start) > 0: time.sleep(int(period) - (end - start)) else: print("Calculation took too long. Continuing to next tick...")