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): 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(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