class BotStrategy(object): def __init__(self): #connect; read and write to db self.TradeDatabase = TradeDatabase() self.TradeDatabase.connect() #amount to trade (capital): self.amountInUSD = 300 #prices information self.prices = [] self.currentPrice = "" #graph and indicators self.output = BotLog() self.indicators = BotIndicators() #self.graphdataPoints = [] self.dataDate = "" self.SMA = "" self.CResistance = 0.0 self.EMA9 = [] self.MACD = [] #trade details self.tradePlaced = [] self.typeOfTrade = [] self.cumulatedProfits = 0.0 #wins and loses self.numofwins = 0 self.numofloses = 0 def tick(self): #only call API once try: self.APIlist = FinexAPI.ticker() except: try: time.sleep(10) self.APIlist = FinexAPI.ticker() except: try: time.sleep(10) self.APIlist = FinexAPI.ticker() except: pass #date self.dataDate = datetime.datetime.fromtimestamp( int(float( self.APIlist["timestamp"]))).strftime('%Y-%m-%d %H:%M:%S') #prices self.currentPrice = float(self.APIlist["last_price"]) #insert into SQL db self.TradeDatabase.insertStatement01(self.dataDate, self.currentPrice) #load datelist, prices from db self.datelist, self.prices = self.TradeDatabase.readtolist01() #indicators self.SMA = self.indicators.movingAverage(self.prices, 200) self.CResistance = self.indicators.trendline(self.prices) self.RSI = self.indicators.RSI(self.prices) #macd indicators & insert into DB if len(self.prices) > 26: #get macd indicators emaslow, emafast, self.MACD = self.indicators.MACD(self.prices) self.EMA9 = self.indicators.EMA(self.MACD, 9) #Insert all to DB (no need for macd and ema9 - they are self generated and contained lists) self.TradeDatabase.insertStatement02(self.dataDate, self.CResistance, self.SMA, self.RSI) #graph #archaic : self.graphdataPoints.append({'date':self.dataDate, 'price': self.currentPrice, 'trend': self.CResistance, 'SMA': self.SMA, 'RSI':self.RSI, 'short': np.nan, 'long':np.nan,'closedLong':np.nan,'closedShort':np.nan}) #graph with pdDataFrame obj self.graphdataPoints = self.TradeDatabase.frameit() #if/else indicators self.tradePlaced, self.typeOfTrade, self.cryptoAmount = self.TradeDatabase.readtolist02( ) self.tradePlaced = [i for i in self.tradePlaced if i * 0 == 0] #only get the numbers self.typeOfTrade = [i for i in self.typeOfTrade if i != None] #only get the strings self.cryptoAmount = [i for i in self.cryptoAmount if i * 0 == 0] #only get the numbers #print timestamp and price to cmd line for logging purposes self.output.log(self.dataDate + "\tPrice: " + str(self.currentPrice) + "\tMoving Average: " + str(self.SMA)) #print numofwins, numofloses and cumulated profits to cmd line self.cumulatedProfits, self.numofwins, self.numofloses = self.TradeDatabase.cumwinloss( ) self.output.log( "No. of Wins: {}, No. of Loses: {}, Cumulated Profits: {}".format( self.numofwins, self.numofloses, self.cumulatedProfits)) #decide when to buy and when to sell - MACD strat + 200 period SMA - maybe can implement stops (?) GOLDEN GRAIL!!! def evaluatePositions(self): try: if len(self.tradePlaced) == 0 or self.tradePlaced[-1] == 0: #if market is bullish - only take buy signals if self.currentPrice > self.SMA: #MACD indicator - when EMA9 crosses higher than the MACD curve - buy if (len(self.MACD) > 1) and ( self.EMA9[-2] < self.MACD[-2]) and (self.EMA9[-1] > self.MACD[-1]): self.buyposition() #elif market is bearish - only take sell signals elif self.currentPrice < self.SMA: #MACD indicator - when EMA9 crosses lower than the MACD curve - sell if (len(self.MACD) > 1) and ( self.EMA9[-2] > self.MACD[-2]) and (self.EMA9[-1] < self.MACD[-1]): self.sellposition() elif self.typeOfTrade[-1] == "long": #MACD indicator - when EMA9 crosses lower than the MACD curve - sell if ((self.EMA9[-2] > self.MACD[-2]) and (self.EMA9[-1] < self.MACD[-1]) and (self.cryptoAmount[-1] * self.currentPrice > 0.95 * self.amountInUSD)): self.closeLong() #if bullish trend ends and you are stuck, immediately sell to recoup loss elif self.currentPrice < self.SMA: self.closeLong() elif self.typeOfTrade[-1] == "short": #MACD indicator - when EMA9 crosses higher than the MACD curve - buy if ((self.EMA9[-2] < self.MACD[-2]) and (self.EMA9[-1] > self.MACD[-1]) and (0.996 * self.amountInUSD) > 0.95 * (self.currentPrice * self.cryptoAmount[-1])): self.closeShort() #if bearish trend ends and you are stuck, immediately buy to recoup loss elif self.currentPrice > self.SMA: self.closeShort() except TypeError: pass #buy and sell positions def buyposition(self): amountincryptos = 0.996 * float(self.amountInUSD) / self.currentPrice self.output.log("BUY {} Cryptos at {}USD".format( amountincryptos, self.amountInUSD)) self.TradeDatabase.insertStatement03(self.dataDate, amountincryptos, self.currentPrice, 1, "long") def sellposition(self): amountincryptos = float(self.amountInUSD) / self.currentPrice self.output.log("SELL {} Cryptos at {}USD".format( amountincryptos, self.amountInUSD)) self.TradeDatabase.insertStatement04(self.dataDate, amountincryptos, self.currentPrice, 1, "short") def closeLong(self): netProfit = self.cryptoAmount[-1] * self.currentPrice - self.amountInUSD self.TradeDatabase.insertStatement05(self.dataDate, netProfit) self.cumulatedProfits, self.numofwins, self.numofloses = self.TradeDatabase.cumwinloss( ) self.TradeDatabase.insertStatement06(self.dataDate, self.currentPrice, 0) if netProfit >= 0: self.output.log( "Closed LONG ORDER at {}".format(self.currentPrice) + self.output.color("\tNet Profit: {}".format(netProfit), 'green') + "\tCumulated Profits: {}".format(self.cumulatedProfits)) self.output.log( "No. of Wins: {}, No. of Loses: {}, Win Rate: {}".format( self.numofwins, self.numofloses, round(self.numofwins / (self.numofwins + self.numofloses), 2))) else: self.output.log( "Closed LONG ORDER at {}".format(self.currentPrice) + self.output.color("\tNet Profit: {}".format(netProfit), 'red') + "\tCumulated Profits: {}".format(self.cumulatedProfits)) self.output.log( "No. of Wins: {}, No. of Loses: {}, Win Rate: {}".format( self.numofwins, self.numofloses, round(self.numofwins / (self.numofwins + self.numofloses), 2))) def closeShort(self): netProfit = (0.996 * self.amountInUSD) - (self.currentPrice * self.cryptoAmount[-1]) self.TradeDatabase.insertStatement05(self.dataDate, netProfit) self.cumulatedProfits, self.numofwins, self.numofloses = self.TradeDatabase.cumwinloss( ) self.TradeDatabase.insertStatement07(self.dataDate, self.currentPrice, 0) if netProfit >= 0: self.output.log( "Closed SHORT ORDER at {}".format(self.currentPrice) + self.output.color("\tNet Profit: {}".format(netProfit), 'green') + "\tCumulated Profits: {}".format(self.cumulatedProfits)) self.output.log( "No. of Wins: {}, No. of Loses: {}, Win Rate: {}".format( self.numofwins, self.numofloses, round(self.numofwins / (self.numofwins + self.numofloses), 2))) else: self.output.log( "Closed SHORT ORDER at {}".format(self.currentPrice) + self.output.color("\tNet Profit: {}".format(netProfit), 'red') + "\tCumulated Profits: {}".format(self.cumulatedProfits)) self.output.log( "No. of Wins: {}, No. of Loses: {}, Win Rate: {}".format( self.numofwins, self.numofloses, round(self.numofwins / (self.numofwins + self.numofloses), 2)))
class BotStrategy(): def __init__(self, pair): if (not config.CONFIG["VERBOSE"]): print("Calculating indicators") self.pair = pair self.output = BotLog() self.path = config.CONFIG['PATH'] self.prices = [] self.closes = [] self.trades = [] self.movingAVG = [] self.momentum = [] self.RSI = [] self.currentPrice = "" self.currentClose = "" self.numSimulTrades = 1 self.indicators = BotIndicators() self.graph_data = { "date": [], "movingAverage": [], "momentum": [], "RSI": [] } def tick(self, candlestick): self.currentPrice = float(candlestick.priceAverage) self.currentClose = float(candlestick.close) self.movingAVG = self.indicators.movingAverage(self.prices, 15) self.momentum = self.indicators.momentum(self.closes, 15) self.RSI = self.indicators.RSI(self.prices, 15) self.MACD = self.indicators.MACD(self.prices) self.prices.append(self.currentPrice) self.closes.append(self.currentClose) self.output.log("Price: " + str(candlestick.priceAverage) + "\tMoving Average: " + str(self.movingAVG)) self.evaluatePositions(candlestick) self.updateOpenTrades() self.showPositions() def evaluatePositions(self, candlestick): openTrades = [] for trade in self.trades: if (trade.status == "OPEN"): openTrades.append(trade) # Make sure NoneType is handled if (self.movingAVG is None): self.movingAVG = 0 if (len(openTrades) < self.numSimulTrades): if (self.currentPrice < self.movingAVG): self.trades.append(BotTrade(self.currentPrice, stopLoss=.0001)) for trade in openTrades: if (self.currentPrice > self.movingAVG): trade.close(self.currentPrice) self.graph_data['date'].append(candlestick.date.astype(int)) self.graph_data['movingAverage'].append(self.movingAVG) self.graph_data['momentum'].append(self.momentum) self.graph_data['RSI'].append(self.RSI) df = pd.DataFrame(self.graph_data) df.to_csv( util.os.path.join( self.path, 'data/' + self.pair.replace('/', '-') + "/" + 'indicators.csv')) def updateOpenTrades(self): for trade in self.trades: if (trade.status == "OPEN"): trade.tick(self.currentPrice) def showPositions(self): for trade in self.trades: trade.showTrade()
class BotStrategy(object): def __init__(self): self.output = BotLog() self.prices = [] self.closes = [] # Needed for Momentum Indicator self.trades = [] self.currentPrice = "" self.currentClose = "" self.numSimulTrades = 10 self.indicators = BotIndicators() self.totalProfit = 0.0 self.minRSI = 30 self.maxRSI = 70 self.minMomentum = 103 self.maxMomentum = 97 def tick(self,candlestick): self.currentPrice = float(candlestick.priceAverage) self.prices.append(self.currentPrice) #self.currentClose = float(candlestick['close']) #self.closes.append(self.currentClose) #self.output.log("Price: "+str(candlestick.priceAverage)+"\tMoving Average: "+str(self.indicators.movingAverage(self.prices,15))) self.evaluatePositions() self.updateOpenTrades() self.showPositions() #self.output.log("Total Profit: "+str(self.totalProfit)) return self.totalProfit def evaluatePositions(self): openTrades = [] for trade in self.trades: if (trade.status == "OPEN"): openTrades.append(trade) if (len(openTrades) < self.numSimulTrades): if (self.currentPrice < self.indicators.movingAverage(self.prices,15)): self.trades.append(BotTrade(self.currentPrice,stopLoss=.0001)) elif(self.indicators.RSI(self.prices,15) <= self.minRSI): self.trades.append(BotTrade(self.currentPrice,stopLoss=.0001)) elif(self.indicators.momentum(self.prices,15) >= self.minMomentum): self.trades.append(BotTrade(self.currentPrice,stopLoss=.0001)) for trade in openTrades: if (self.currentPrice > self.indicators.movingAverage(self.prices,15)): trade.close(self.currentPrice) elif(self.indicators.RSI(self.prices,15) >= self.maxRSI): trade.close(self.currentPrice) elif(self.indicators.momentum(self.prices,15) <= self.maxMomentum): trade.close(self.currentPrice) def updateOpenTrades(self): for trade in self.trades: if (trade.status == "OPEN"): trade.tick(self.currentPrice) def showPositions(self): for trade in self.trades: trade.showTrade() if(vars(trade)["tradeProfit"]): self.totalProfit = float(vars(trade)["tradeProfit"]) + self.totalProfit
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): def __init__(self): self.output = BotLog() self.prices = [] self.opens = [] self.closes = [] #for Momentum self.trades = [] self.MACD_History = [] # MACD History self.MACD_Signal_History = [] # MACD Signal History self.currentPrice = None self.numSimulTrades = 1 self.takeProfit = 0.0001 self.stopLoss = 1 self.indicators = BotIndicators() self.trendPeriod = 3 # ETH : 3 # DASH : 3 self.minVolume = 1.2 # ETH : 1.2 # DASH : 1 def tick(self, candlestick): self.currentPrice = float(candlestick['weightedAverage']) self.currentVolume = float(candlestick['volume']) self.open = float(candlestick['open']) self.close = float(candlestick['close']) self.high = float(candlestick['high']) self.low = float(candlestick['low']) self.date = float(candlestick['date']) self.prices.append(self.currentPrice) self.closes.append(self.close) # for Momentum self.output.log("Price: " + str(candlestick['weightedAverage']) + "\tMoving Average: " + str(self.indicators.movingAverage(self.prices, 15)) + "\tMomentum: " + str(self.indicators.momentum(self.closes)) + "\tRSI: " + str(self.indicators.RSI(self.prices))) self.evaluatePositions() self.updateOpenTrades() self.showPositions() def evaluatePositions(self): MacdCurrent = None MacdPrevious = None SignalCurrent = None SignalPrevious = None openTrades = [] for trade in self.trades: if (trade.status == "OPEN"): openTrades.append(trade) if (len(openTrades) < self.numSimulTrades): #if (self.currentPrice < self.indicators.movingAverage(self.prices,15)): #if (float(ticker['BTC_ZEC']['percentChange']) < 0): #print("Momentum: " + str(self.indicators.momentum(self.closes))) #print("Pivot: " + str(self.indicators.Pivot('BTC_ZEC', 300,self.date))) # dont need to calculate this every tick #print("RSI : " + str(self.indicators.RSI(self.prices))) #slow, fast, signal = self.indicators.MACD(self.closes) #print(slow) #print(fast) #print(signal) if ( len(self.closes) > 26 + 2 ): # Need to have enought prices in order to calculate the slowEMA SlowEMA = (self.indicators.EMA(self.closes, 26)) FastEMA = (self.indicators.EMA(self.closes, 12)) self.MACD_History.append( self.indicators.iMACD(SlowEMA, FastEMA)) MacdCurrent = self.MACD_History[ -1] # this is the most recent MACD in the list if (len(self.MACD_History) > 2): MacdPrevious = ( self.MACD_History[-2] ) # This is the second most recent MACD in the List if (len(self.MACD_History) > 9 + 2): SignalCurrent = self.indicators.EMA(self.MACD_History, 9) self.MACD_Signal_History.append(SignalCurrent) if (len(self.MACD_Signal_History) > 2): SignalPrevious = self.MACD_Signal_History[-2] #print("MACD: ") #print(MacdCurrent) #print(MacdPrevious) #print(SignalCurrent) #print(SignalPrevious) if (len(self.closes) > 100): if (MacdCurrent and MacdPrevious and SignalCurrent and SignalPrevious): if (MacdCurrent < 0 and MacdCurrent > SignalCurrent and MacdPrevious < SignalPrevious and self.indicators.RSI(self.prices, 14) < 50): self.trades.append( BotTrade(self.currentPrice, stopLoss=self.stopLoss)) #if (self.indicators.trend(self.prices,self.trendPeriod) == 1 and self.currentVolume > self.minVolume): #self.trades.append(BotTrade(self.currentPrice,stopLoss=self.stopLoss)) #if (self.indicators.RSI(self.prices,14) < 30 and self.currentVolume > self.minVolume): # self.trades.append(BotTrade(self.currentPrice,stopLoss=self.stopLoss)) #print bcolors.WARNING + "Warning: No active frommets remain. Continue?" + bcolors.ENDC for trade in openTrades: currentProfit = float(self.currentPrice) - float(trade.entryPrice) if currentProfit > 0: print("entry: " + str(trade.entryPrice)) print(bcolors.OKGREEN + str(currentProfit) + bcolors.ENDC) else: print("entry: " + str(trade.entryPrice)) print(bcolors.WARNING + str(currentProfit) + bcolors.ENDC) #if (MacdCurrent and MacdPrevious and SignalCurrent and SignalPrevious): # if (MacdCurrent > 0 and MacdCurrent < SignalCurrent and MacdPrevious > SignalPrevious): if (self.currentPrice >= (float(trade.entryPrice) + self.takeProfit) or self.date > 1499309550 - 300): trade.close(self.currentPrice) #if (self.currentPrice > self.indicators.movingAverage(self.prices,15)): #if (self.indicators.trend(self.prices,self.trendPeriod) == 0 and self.currentVolume > self.minVolume): #if (self.indicators.RSI(self.prices,14) > 70 and self.currentVolume > self.minVolume): # trade.close(self.currentPrice) def updateOpenTrades(self): for trade in self.trades: if (trade.status == "OPEN"): trade.tick(self.currentPrice) def showPositions(self): for trade in self.trades: trade.showTrade()
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
class BotStrategy(object): def __init__(self, period, functions, balance, trial, details, strat, trained_model="", defTrades=[]): self.output = BotLog() self.prices = [] self.period = period self.startPrice = 0 self.closes = [] # Needed for Momentum Indicator self.trades = defTrades self.currentPrice = 0 self.startDate = "" self.currentDate = "" self.currentClose = "" self.functions = functions self.balance = balance self.origBalance = balance self.account = BotAccount(self.functions) self.account.createBalancePage() self.startingPositions = self.account.getBalance() self.indicators = BotIndicators() self.trained_model = trained_model self.dirty = True self.fee = 0.0025 self.strat = strat self.lookback = 7 if not 'lookback' in details else int( details['lookback']) self.trial = trial self.openTrades = [] self.balanceRecord = [] self.highMA = 47 if not 'highMA' in details else details['highMA'] self.lowMA = 28 if not 'lowMA' in details else details['lowMA'] self.mamultfactor = 1 if not 'maFactor' in details else details[ 'maFactor'] self.numSimulTrades = 1 if not 'simTrades' in details else details[ 'simTrades'] self.stoploss = 0 if not 'stoploss' in details else float( details['stoploss']) self.advance = 13 if not 'advance' in details else int( details['advance']) self.lowrsi = 30 if not 'lowrsi' in details else details['lowrsi'] self.highrsi = 70 if not 'highrsi' in details else details['highrsi'] self.rsiperiod = 14 if not 'rsiperiod' in details else details[ 'rsiperiod'] self.learnProgTotal = 1400 if not 'learnProgTotal' in details else int( details['learnProgTotal']) self.upfactor = 1.1 if not 'upfactor' in details else details[ 'upfactor'] self.downfactor = 1.3 if not 'downfactor' in details else details[ 'downfactor'] self.trailingstop = 0.1 if not 'trailingstop' in details else details[ 'trailingstop'] self.prev_run_time = 0 if not 'running_time' in details else int( details['running_time']) self.stoploss_day_count = 0 self.stoploss_day_count_set = 0 if not 'stoplossDayCount' in details else details[ 'stoplossDayCount'] # initiate any trades left over from last time for trade in self.trades: trade.stopLoss = trade.entryPrice * (1 - self.stoploss) if '4' in self.strat: trade.expiry = self.advance trade.log = self.trial def tick(self, candlestick, training=False): if not self.trial == 0 or training: # HISTORIC VALUES self.currentPrice = float(candlestick['weightedAverage']) else: # LIVE VALUES self.currentPrice = float(candlestick['last']) self.prices.append(self.currentPrice) # self.prices = self.prices[-self.learnProgTotal - 10:] #self.currentClose = float(candlestick['close']) #self.closes.append(self.currentClose) self.currentDateOrig = int(candlestick['date']) self.currentDate = datetime.datetime.fromtimestamp( int(candlestick['date'])).strftime('%Y-%m-%d %H:%M:%S') if self.startPrice == 0 and not training: self.startPrice = self.currentPrice self.startDate = self.currentDateOrig #self.indicators.doDataPoints(self.currentPrice, self.currentDateOrig, self.strat) if (self.stoploss_day_count != 0): self.stoploss_day_count -= 1 #lastMax = 0 if len(self.indicators.localMax) == 0 else self.indicators.localMax[-1] #lastMin = 0 if len(self.indicators.localMin) == 0 else self.indicators.localMin[-1] # LOGGING # self.output.log("Date: "+self.currentDate+"\tPrice: "+str(self.currentPrice)+"\tLowMA: "+str(self.indicators.movingAverage(self.prices,self.lowMA))+ \ # "\tHighMA: "+str(self.indicators.movingAverage(self.prices,self.lowMA))+"\tRSI: "+str(self.indicators.RSI (self.prices))+"\tTrend :"+str(self.indicators.trend)+"\tLast Max "+ \ # str(lastMax) + "\tLast Min: "+str(lastMin) + "\tRes: "+str(self.indicators.currentResistance)+"\tSup: "+str(self.indicators.currentSupport)) self.evaluatePositions(training) if not training: self.updateOpenTrades() if self.dirty and self.trial == 0: # self.showAllTrades() self.dirty = False totalAssets, totalFees, totalTime, _ = self.calculateCurrentPosition( ) stats = { "balance": self.balance, "assets": totalAssets, "running_time": self.prev_run_time + int(self.currentDateOrig) - int(self.startDate) } self.functions.mysql_conn.storeStatistics(stats) def evaluatePositions(self, training): changeCheckTrades = self.trades.copy() changeCheckBal = self.balance self.getOpenTrades() if '1' in self.strat: self.MACrossover() if '2' in self.strat: self.BuyLowSellHigh() if '3' in self.strat: self.BuyUpShortCrash() if '4' in self.strat: self.LearnPatterns(training) if changeCheckTrades != self.trades or self.balance != changeCheckBal: self.dirty = True assets, _, _, marketProf = self.calculateCurrentPosition() self.balanceRecord.append([ self.currentDateOrig, self.balance + assets, self.origBalance * marketProf ]) # print(self.balance) def getOpenTrades(self): self.openTrades = [] for trade in self.trades: if (trade.status == "OPEN"): self.openTrades.append(trade) def handleStopLosses(self, trade): if (self.stoploss != 0): if ((self.currentPrice < trade.stopLoss and trade.volume < 0) or (self.currentPrice > trade.stoploss and trade.volume >= 0)): self.trades[trade.id].close(self.currentDateOrig, self.currentPrice, "Stoploss") self.balance += trade.volume * self.currentPrice self.stoploss_day_count = self.stoploss_day_count_set def handleTrailingStop(self, trade): if (self.trailingstop != 0): if (trade.maxSeen < self.currentPrice): trade.maxSeen = self.currentPrice if (self.currentPrice < trade.maxSeen * (1 - self.trailingstop)): trade.close(self.currentDate, self.currentPrice, "Trailing") self.balance += trade.volume * self.currentPrice def updateOpenTrades(self): for trade in self.trades: if (trade.status == "OPEN"): trade.tick(self.currentPrice) def showAllTrades(self): self.output.logTrades(self.trades, self.origBalance, self.trial) #self.indicators.graphIndicators(self.trades, self.balanceRecord) def closeAllTrades(self): for trade in self.trades: if (trade.status == "OPEN"): if (trade.volume >= 0): self.closeLong(trade.id) else: self.closeShort(trade.id) self.showAllTrades() def calculateCurrentPosition(self): totalAssets = 0 totalFees = 0 totalTime = 0 for trade in self.trades: if trade.status == "OPEN": totalAssets += self.currentPrice * trade.volume totalFees += trade.fee totalTime += (int(self.currentDateOrig) - int(trade.dateOpened) if trade.dateClosed == "" else int(trade.dateClosed) - int(trade.dateOpened)) marketProf = (self.currentPrice - self.startPrice) / self.startPrice return totalAssets, totalFees, totalTime, marketProf #============================================================================== # Strategies #============================================================================== # Strat 1 def MACrossover(self): fifteenDayMA = self.indicators.movingAverage(self.prices, self.lowMA) fiftyDayMA = self.indicators.movingAverage(self.prices, self.highMA) if (fifteenDayMA > fiftyDayMA * self.mamultfactor): amountToBuy = (self.balance - 10) / (self.currentPrice * (1 + self.fee)) fee = amountToBuy * self.currentPrice * self.fee if (len(self.openTrades) < self.numSimulTrades and self.balance >= fee + amountToBuy * self.currentPrice + 10): stoplossn = self.currentPrice * (1 - self.stoploss) self.balance -= (amountToBuy * self.currentPrice + fee) self.trades.append( BotTrade(self.functions, self.currentDate, amountToBuy, self.currentPrice, len(self.trades), stopLoss=stoplossn, fee=fee)) for trade in self.openTrades: if (fifteenDayMA < fiftyDayMA / self.mamultfactor): self.balance += trade.volume * self.currentPrice self.trades[trade.id].close(self.currentDate, self.currentPrice, "MA Crossover") else: # self.handleStopLosses(trade) self.handleTrailingStop(trade) # Strat 2 def BuyLowSellHigh(self): rsi = self.indicators.RSI(self.prices, self.rsiperiod) if (rsi < self.lowrsi): amountToBuy = (self.balance - 10) / (self.currentPrice * (1 + self.fee)) fee = amountToBuy * self.currentPrice * self.fee if (len(self.openTrades) < self.numSimulTrades and self.balance >= fee + amountToBuy * self.currentPrice + 10): stoplossn = self.currentPrice * (1 - self.stoploss) self.balance -= (amountToBuy * self.currentPrice + fee) self.trades.append( BotTrade(self.functions, self.currentDate, amountToBuy, self.currentPrice, len(self.trades), stopLoss=stoplossn, fee=fee)) for trade in self.openTrades: if (rsi > self.highrsi): self.balance += trade.volume * self.currentPrice self.trades[trade.id].close(self.currentDate, self.currentPrice, "Overbought RSI") else: self.handleStopLosses(trade) # Strat 3 def BuyUpShortCrash(self): # SIm trades can only be 1 if len(self.prices) > self.lookback: if (self.currentPrice > self.prices[-self.lookback] * self.upfactor): amountToBuy = (self.balance - 10) / (self.currentPrice * (1 + self.fee)) fee = amountToBuy * self.currentPrice * self.fee if (self.balance >= fee + amountToBuy * self.currentPrice + 10): stoplossn = self.currentPrice * (1 - self.stoploss) self.balance -= (amountToBuy * self.currentPrice + fee) self.trades.append( BotTrade(self.functions, self.currentDate, amountToBuy, self.currentPrice, len(self.trades), stopLoss=stoplossn, fee=fee)) for trade in self.openTrades: if (self.currentPrice < self.prices[-self.lookback] * self.downfactor): self.balance += trade.volume * self.currentPrice self.trades[trade.id].close(self.currentDate, self.currentPrice, "In crash") else: self.handleStopLosses(trade) # Strat 4 def LearnPatterns(self, training): toBuy, predictions = self.trained_model.calc(self.prices) if not training: for trade in self.openTrades: # if trade.expiry != 0: # if trade.age >= trade.expiry: # self.balance += trade.volume * self.currentPrice # self.trades[trade.id].close(self.currentDate, self.currentPrice, "Expired") # else: self.trades[trade.id].age += 1 self.handleStopLosses(trade) self.getOpenTrades() if (self.stoploss_day_count == 0 or self.stoploss_day_count_set == 0): if toBuy == "Buy": if len(self.openTrades) > 0: if self.trades[-1].volume < 0: self.closeShort(-1) else: amountToBuy = (self.balance - 10) / (self.currentPrice * (1 + self.fee)) self.openLong(amountToBuy) elif toBuy == "Sell": if len(self.openTrades) > 0: if self.trades[-1].volume >= 0: self.closeLong(-1) else: amountToSell = (self.balance - 10) / (self.currentPrice * (1 + self.fee)) self.openShort(amountToSell) if self.trial == 0: self.functions.mysql_conn.storePredictions( self.currentDateOrig, self.period, predictions) def openLong(self, amt): fee = amt * self.currentPrice * self.fee if (self.balance >= fee + amt * self.currentPrice ) and (fee + amt * self.currentPrice) > self.origBalance * 0.02: stoplossn = self.currentPrice * (1 - self.stoploss) self.balance -= (amt * self.currentPrice + fee) self.trades.append((BotTrade(self.functions, self.currentDateOrig, amt, self.currentPrice, len(self.trades), stopLoss=stoplossn, fee=fee, expiry=self.advance, log=self.trial))) def closeLong(self, tradeId): if self.trades[tradeId].status != "CLOSED": self.balance += self.trades[tradeId].volume * self.currentPrice self.trades[tradeId].close(self.currentDateOrig, self.currentPrice, "Sell indicator") def openShort(self, amt): fee = amt * self.currentPrice * self.fee if (self.balance >= fee + amt * self.currentPrice + 10) and ( fee + amt * self.currentPrice + 10) > self.origBalance * 0.02: stoplossn = self.currentPrice * (1 + self.stoploss) self.balance += (amt * self.currentPrice - fee) self.trades.append((BotTrade(self.functions, self.currentDateOrig, -1 * amt, self.currentPrice, len(self.trades), stopLoss=stoplossn, fee=fee, expiry=self.advance, log=self.trial))) def closeShort(self, tradeId): if self.trades[tradeId].status != "CLOSED": self.balance += self.trades[tradeId].volume * self.currentPrice self.trades[tradeId].close(self.currentDateOrig, self.currentPrice, "Buy indicator")