class BotChart(object): #------------------------------------------------------------ ------# #---------Part 1.1: Fetch the data from market---------------------# #------------------------------------------------------------------# #---Output: self.data=[Botcandlstck1 ,Botcandlestick2, ..3, ..4]---# #------------------------------------------------------------------# #------------------------------------------------------------------# def __init__(self, exchange, pair, period, startTime, endTime, backtest=True): self.botHTML = BotHTML() self.vars = botVariables() self.api_key = self.vars.api_key_poloniex self.api_secret = self.vars.api_secret_poloniex self.avPeriod = self.vars.movingAvPeriod self.indicators = BotIndicators() self.pair = pair self.period = period self.startTime = startTime self.endTime = endTime self.data = [] self.prices = [] self.poloData = [] self.trades = [] if (exchange == "poloniex"): print('Ecxhange with Poloniex') self.conn = poloniex.Poloniex(self.api_key, self.api_secret) if backtest: print("Checking the data from " + datetime.datetime.fromtimestamp(int(startTime)).strftime( '%Y-%m-%d %H:%M:%S') + " to " + datetime.datetime.fromtimestamp(int(endTime)).strftime( '%Y-%m-%d %H:%M:%S')) self.poloData = self.conn.returnChartData( self.pair, self.period, self.startTime, self.endTime) #A:poloData is an list (checked with the funtion type(), where each item of the list contains 6 values of the period for datum in self.poloData: #datum is a dict = {key1:value1, key2:value2, ... } if (datum['open'] and datum['close'] and datum['high'] and datum['low']): #putting all this data to the BotCandlestick object self.data.append( BotCandlestick(self.period, datum['open'], datum['close'], datum['high'], datum['low'], datum['weightedAverage'], datum['date'])) if (exchange == "binance"): # Remember to install binance python script with --> pip install python-binance print('Ecxhange with Binance') if backtest: # create the Binance client, no need for api key client = Client("", "") klines = client.get_historical_klines( self.vars.pairBinance, getattr(client, self.vars.periodBinance), self.vars.startTimeBinance, self.vars.endTimeBinance) for kline in klines: self.data.append( BotCandlestick( self.period, kline[1], kline[4], kline[2], kline[3], str((float(kline[1]) + float(kline[2]) + float(kline[4]) + float(kline[3])) / 4), int(((kline[0]) + (kline[6])) / 2000))) #because in miliseconds """ Get Historical Klines from Binance [ [ 1499040000000, // 0.Open time 1517803200000 "0.01634790", // 1.Open "0.80000000", // 2.High "0.01575800", // 3.Low "0.01577100", // 4.Close "148976.11427815", // 5.Volume 1499644799999, // 6.Close time "2434.19055334", // 7.Quote asset volume 308, // 8.Number of trades "1756.87402397", // 9.Taker buy base asset volume "28.46694368", // 10.Taker buy quote asset volume "17928899.62484339" // Ignore. ] ] """ # d = self.data[0].__dict__ # print (d) #------------------------------------------------------------------# #---------END--Part 1.1: initialisating the bot strategy-----------# #------------------------------------------------------------------# #--------------------------------------------------------------# #---------Part 1.3: Evaluating each candlestic from the chart--# #--------------------------------------------------------------# #--------------------USING THE STRATEGY TICK-------------------# #--------------------------------------------------------------# def getPoints(self): return self.data def getCurrentPrice(self): currentValues = self.conn.api_query("returnTicker") lastPairPrice = {} lastPairPrice = currentValues[self.pair]["last"] return lastPairPrice def getLastPrices(self, date, dataCandlestick, period): lastPrices = [] #https://stackoverflow.com/a/3940144/5176549 for candlestick in reversed(dataCandlestick): lastPrices.append(candlestick['weightedAverage']) if date == (candlestick['date']): break return lastPrices[-period:] def createChart(self): historicalData = self.data dataPoints = [] priceData = [] label = 'null' output = open("output.html", 'w') output.truncate() #Understanding googlechart: https://developers.google.com/chart/interactive/docs/basic_load_libs output.write(self.botHTML.begin) while True: #step 0: iterating over data points if (self.startTime and historicalData): nextDataPoint = historicalData.pop( 0) #https://stackoverflow.com/a/4426727/5176549 lastPairPrice = nextDataPoint.priceAverage priceData.append(float(lastPairPrice)) movingAverage = self.indicators.movingAverage( priceData, self.vars.movingAvPeriod, lastPairPrice) movingAverage2 = self.indicators.movingAverage( priceData, self.vars.movingAvPeriod2, lastPairPrice) label = nextDataPoint.label dataDate = datetime.datetime.fromtimestamp( int(nextDataPoint.date)).strftime('%Y-%m-%d %H:%M:%S') #adding the trades on the label #step 2: once the iteration is finished, adding all the info in the chart elif (self.startTime and not historicalData): print("Finished") for point in dataPoints: output.write("[" + self.stringToDate(point['date']) + "," + point['price'] + "," + point['label'] + "," + point['desc'] + "," + point['movAv1'] + "," + point['movAv2']) output.write("],\n") output.write(self.botHTML.end) break #step 1: addind the last point on the list else: currentValues = conn.api_query("returnTicker") lastPairPrice = currentValues[pair]["last"] dataDate = datetime.datetime.now() #Main step: appending values to local dataPoints dataPoints.append({ 'date': dataDate, 'price': str(lastPairPrice), 'movAv1': str(movingAverage), 'movAv2': str(movingAverage2), 'label': label, 'desc': 'null' }) def stringToDate(self, date): #date is the follwing format: date='2017-12-27 11:50:00' return "new Date(" + date[0:4] + ", " + date[5:7] + ", " + date[ 8:10] + ", " + date[11:13] + ", " + date[14:16] + ")" def creatChartRSI(self): #Double Chart zoom: https://stackoverflow.com/a/42238747/5176549 or https://jsfiddle.net/pzamu7kt/ #Understanding googlechart: https://developers.google.com/chart/interactive/docs/basic_load_libs historicalData = self.data dataPoints = [] priceData = [] movingAverage = 0 label = 'null' output = open("outputrsi.html", 'w') output.truncate() #Understanding googlechart: https://developers.google.com/chart/interactive/docs/basic_load_libs output.write(self.botHTML.javascript) while True: #step 0: iterating over data points if (self.startTime and historicalData): nextDataPoint = historicalData.pop(0) #https://stackoverflow.com/a/4426727/5176549 lastPairPrice = nextDataPoint.priceAverage priceData.append(float(lastPairPrice)) BollUp = self.indicators.BollUp(priceData, self.vars.BollPeriod, lastPairPrice) BollDown = self.indicators.BollDown(priceData, self.vars.BollPeriod, lastPairPrice) rsiData = self.indicators.RSI(priceData) label = nextDataPoint.label dataDate = datetime.datetime.fromtimestamp( int(nextDataPoint.date)).strftime('%Y-%m-%d %H:%M:%S') #adding the trades on the label #step 2: once the iteration is finished, adding all the info in the chart elif (self.startTime and not historicalData): output.write(self.botHTML.chart11) for point in dataPoints: output.write("[" + self.stringToDate(point['date']) + "," + point['price'] + "," + point['label'] + "," + point['desc'] + "," + point['BollUp'] + "," + point['BollDown']) output.write("],\n") output.write(self.botHTML.chart12) output.write(self.botHTML.chart21) for point in dataPoints: output.write("[" + self.stringToDate(point['date']) + "," + point['rsi']) output.write("],\n") output.write(self.botHTML.chart22) output.write(self.botHTML.endjavascript) break #step 1: addind the last point on the list else: currentValues = conn.api_query("returnTicker") lastPairPrice = currentValues[pair]["last"] dataDate = datetime.datetime.now() #Main step: appending values to local dataPoints dataPoints.append({ 'date': dataDate, 'price': str(lastPairPrice), 'BollUp': str(BollUp), 'BollDown': str(BollDown), 'rsi': str(rsiData), 'label': label, 'desc': 'null' })
class BotStrategy(object): #--------------------------------------------------------------# #---------Part 1.2: initialisating the bot strategy------------# #--------------------------------------------------------------# def __init__(self): self.vars = botVariables() self.investement = self.vars.initialInvestment self.makeFee = self.vars.makeFee self.takeFee = self.vars.takeFee self.output = BotLog() self.prices = [] self.closes = [] # Needed for Momentum Indicator self.trades = [] self.numOfTrades = 0 self.currentPrice = "" self.currentTime = "" self.currentClose = "" self.numSimulTrades = 1 self.indicators = BotIndicators() self.absMargin = 0 self.relMargin = 0 #these are the values of the indicators qat each endTime self.SMA1 = 0 self.SMA2 = 0 self.EMA1 = 0 self.EMA2 = 0 self.RSI = 0 self.BollUp = 0 self.BollDown = 0 #--------------------------------------------------------------# #---END:--Part 1.2: initialisating the bot strategy------------# #--------------------------------------------------------------# #--------------------------------------------------------------# #---------Part 1.3: Evaluating each candlestic from the chart--# #--------------------------------------------------------------# #--------------------USING THE STRATEGY TICK-------------------# #--------------------------------------------------------------# def tick( self, candlestick ): #where a candlestick is a an item of the list BotChart.getPoints self.currentPrice = float(candlestick.priceAverage) self.currentTime = candlestick.date self.prices.append(self.currentPrice) #self.currentClose = float(candlestick['close']) #self.closes.append(self.currentClose) #self.output.log(datetime.datetime.fromtimestamp(self.currentTime).strftime('%Y-%m-%d %H:%M:%S')+" - Price: "+str(candlestick.priceAverage)+"\tMoving Average: "+str(self.indicators.movingAverage(self.prices,self.vars.movingAvPeriod,self.currentPrice))) self.evaluatePositions(candlestick) self.updateOpenTrades(candlestick) self.showPositions() def evaluatePositions(self, candlestic): openTrades = [] self.SMA1 = self.indicators.movingAverage(self.prices, self.vars.movingAvPeriod, self.currentPrice) self.SMA2 = self.indicators.movingAverage(self.prices, self.vars.movingAvPeriod2, self.currentPrice) self.EMA1 = self.indicators.EMA(self.prices, self.vars.movingAvPeriod, self.currentPrice) self.EMA2 = self.indicators.EMA(self.prices, self.vars.movingAvPeriod2, self.currentPrice) self.RSI = self.indicators.RSI(self.prices) self.BollUp = self.indicators.BollUp(self.prices, self.vars.BollPeriod, self.currentPrice) self.BollDown = self.indicators.BollDown(self.prices, self.vars.BollPeriod, self.currentPrice) for trade in self.trades: if (trade.status == "OPEN"): openTrades.append(trade) if (len(openTrades) < self.numSimulTrades): #--------------------------------------------------------------# #------Part 1.3.A: Adding a trade if the conditions are met----# #--------------------------------------------------------------# if self.strategy1(True): #self.output.log("Trade Opened. Currentprice: "+str(self.currentPrice)+", MovAverage: "+str(self.indicators.movingAverage(self.prices,self.vars.movingAvPeriod,self.currentPrice))) candlestic.label = "'Buy'" self.trades.append( BotTrade(self.currentTime, self.currentPrice)) self.numOfTrades += 1 for trade in openTrades: if self.strategy1(False): #self.output.log("Trade Closed. Currentprice: "+str(self.currentPrice)+", MovAverage: "+str(self.indicators.movingAverage(self.prices,self.vars.movingAvPeriod,self.currentPrice))) candlestic.label = "'Sell'" trade.close(self.currentPrice, self.currentTime) def updateOpenTrades(self, candlestic): status = "" for trade in self.trades: if (trade.status == "OPEN"): status += trade.update( self.currentPrice, self.currentTime) #returns if state is open or close if status == "CLOSED": candlestic.label = "'StopLoss'" def showPositions(self): for trade in self.trades: trade.showTrade() def showMargin(self): tradeStatus = "Stat" for trade in self.trades: if (trade.status == "CLOSED"): tradeStatus = datetime.datetime.fromtimestamp( trade.exitTime).strftime('%Y-%m-%d %H:%M:%S') + " " + str( trade.status) + " Entry: " + str( round(trade.entryPrice, 2)) + " Exit: " + str( round(trade.exitPrice, 2)) self.makeInvesment( trade) #considering the trade as an indicator tradeStatus = tradeStatus + " Profit: " if (trade.exitPrice > trade.entryPrice): tradeStatus = tradeStatus + "\033[92m" else: tradeStatus = tradeStatus + "\033[91m" tradeStatus = tradeStatus + str( round(trade.exitPrice - trade.entryPrice, 2)) + "\033[0m" + " Inves: " if (self.investement > botVariables().initialInvestment): tradeStatus = tradeStatus + "\033[92m" else: tradeStatus = tradeStatus + "\033[91m" tradeStatus = tradeStatus + str(round(self.investement, 2)) + "\033[0m" self.output.log(tradeStatus) # self.output.log(tradeStatus) def makeInvesment(self, trade): self.investement = ( (1 - self.makeFee) * self.investement / trade.entryPrice) * ( (1 - self.takeFee) * trade.exitPrice) def showTrades(self): return self.trades def strategy1(self, buyTrueSellFalse): if buyTrueSellFalse: return self.SMA2 < self.SMA1 # and self.RSI>70 else: return self.SMA2 > self.SMA1 # and self.RSI<30 def strategy2(self, buyTrueSellFalse): if buyTrueSellFalse: return self.currentPrice < self.BollDown and self.RSI < 40 else: return self.currentPrice > self.BollUp and self.RSI > 55