class BotStrategy(object): def __init__(self, name, mode, pair, numTrades, startUSD, startUnit, tradeAmount, stopLoss, targetPrice, backtest, output): self.output = output self.name = name self.mode = mode self.pair = pair self.numTrades = numTrades self.startUSD = startUSD self.startUnit = startUnit self.tradeAmount = tradeAmount self.stopLoss = stopLoss self.targetPrice = targetPrice self.backtest = backtest self.prices = [] self.closes = [] self.trades = [] self.upperBBand = [] self.lowerBBand = [] self.midBBand = [] self.MACDDiff = [] self.MACDSignal = [] self.rsi = [] self.date = "" self.action = [] self.dataPoints = [] self.balancePoints = [] self.MACDPoints = [] self.rsiPoints = [] self.currentPrice = "" self.currentClose = "" self.holdingsUSD = startUSD self.holdingsUnits = startUnit self.balance = startUSD self.balanceNoTrade = startUSD self.profit = 0 self.fees = 0 self.indicators = BotIndicators() self.priceAverage = 0 def tick(self,candlestick): self.action = [] self.description = [] self.currentPrice = float(candlestick.priceAverage) self.prices.append(self.currentPrice) self.updateBalance(0, self.currentPrice) #self.currentClose = float(candlestick['close']) #self.closes.append(self.currentClose) currentUpperBBand, currentLowerBBand, currentMidBBand = self.indicators.bbands(self.prices[-30:]) self.upperBBand.append(currentUpperBBand) self.lowerBBand.append(currentLowerBBand) currentMACDSlow, currentMACDFast, currentMACDDiff, currentMACDSignal = self.indicators.MACD(self.prices[-30:]) self.MACDDiff.append(currentMACDDiff) self.MACDSignal.append(currentMACDSignal) # self.rsi.append(self.indicators.RSI(self.prices[-30:])) if self.backtest in ["backtest", "paper", "live"]: self.evaluatePositions() if self.backtest in ["backtest", "warm"]: tickdate = candlestick.date self.date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(tickdate)) else: tickdate = int(time.time()) self.date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(tickdate)) self.dataPoints.append({'date': str(tickdate * 1000), 'price': str(self.currentPrice), 'upperbb': str(currentUpperBBand), 'lowerbb': str(currentLowerBBand), 'action': 'null', 'description': 'null'}) self.balancePoints.append({'date': str(tickdate * 1000), 'balance': str(self.balance), 'balanceNoTrade': str(self.balanceNoTrade)}) self.MACDPoints.append({'date': str(tickdate * 1000), 'MACDDiff': str(self.MACDDiff[-1]), 'MACDSignal': str(self.MACDSignal[-1])}) # self.rsiPoints.append({'date': str(tickdate * 1000), 'RSI': str(self.rsi[-1]), 'RSIHIGH': str(70), 'RSILOW': str(30)}) if len(self.action) > 0: self.dataPoints[-1]['action'] = "'*'" self.dataPoints[-1]['description'] = "'" + ', '.join(self.action) + "'" def evaluatePositions(self): openTrades = [] for trade in self.trades: if (trade.status == "OPEN"): openTrades.append(trade) if len(openTrades) < self.numTrades and self.holdingsUSD > self.tradeAmount: if self.mode in ["MACD", "ALL"] and self.MACDDiff[-1] < self.MACDSignal[-1] and self.MACDDiff[-2] > self.MACDSignal[-2]: self.trades.append(BotTrade(self.date, "MACD", self.pair, self.currentPrice, self.tradeAmount, self.stopLoss, self.targetPrice, self.backtest, self.output)) self.updateBalance(self.tradeAmount / self.currentPrice, self.currentPrice) self.action.append('Open MACD=, Amount=' + str(self.tradeAmount) + ', Price=' + str(self.currentPrice)) elif self.mode in ["MACD2", "ALL"] and self.MACDDiff[-1] < 500 and ((self.MACDDiff[-1] > 0 and self.MACDDiff[-2] < 0) or (self.MACDDiff[-1] < self.MACDSignal[-1] and self.MACDDiff[-2] > self.MACDSignal[-2])): self.trades.append(BotTrade(self.date, "MACD2", self.pair, self.currentPrice, self.tradeAmount, self.stopLoss, self.targetPrice, self.backtest, self.output)) self.updateBalance(self.tradeAmount / self.currentPrice, self.currentPrice) self.action.append('Open MACD2=, Amount=' + str(self.tradeAmount) + ', Price=' + str(self.currentPrice)) elif self.mode in ["MACD3", "ALL"] and self.MACDDiff[-1] > 0 and self.MACDDiff[-2] < 0: self.trades.append(BotTrade(self.date, "MACD3", self.pair, self.currentPrice, self.tradeAmount, self.stopLoss, self.targetPrice, self.backtest, self.output)) self.updateBalance(self.tradeAmount / self.currentPrice, self.currentPrice) self.action.append('Open MACD3=, Amount=' + str(self.tradeAmount) + ', Price=' + str(self.currentPrice)) elif self.mode in ["BBAND", "ALL"] and self.prices[-1] > self.lowerBBand[-1] and self.prices[-2] < self.lowerBBand[-2]: self.trades.append(BotTrade(self.date, "BBAND", self.pair, self.currentPrice, self.tradeAmount, self.stopLoss, self.targetPrice, self.backtest, self.output)) self.updateBalance(self.tradeAmount / self.currentPrice, self.currentPrice) self.action.append('Open BBAND, Amount='+ str(self.tradeAmount) + ', Price=' + str(self.currentPrice)) elif self.mode in ["RSI"] and self.rsi[-1] < 30 and self.rsi[-2] > 30: self.trades.append(BotTrade(self.date, "RSI", self.pair, self.currentPrice, self.tradeAmount, self.stopLoss, self.targetPrice, self.backtest, self.output)) self.updateBalance(self.tradeAmount / self.currentPrice, self.currentPrice) self.action.append('Open RSI, Amount='+ str(self.tradeAmount) + ', Price=' + str(self.currentPrice)) elif len(self.prices) > 12: if self.mode in ["DROP", "ALL"] and self.prices[-1] < self.prices[-6] *.95 and self.prices[-1] > self.prices[-2]: self.trades.append(BotTrade(self.date, "DROP", self.pair, self.currentPrice, self.tradeAmount, self.stopLoss, self.targetPrice, self.backtest, self.output)) self.updateBalance(self.tradeAmount / self.currentPrice, self.currentPrice) self.action.append('Open DROP, Amount='+ str(self.tradeAmount) + ', Price=' + str(self.currentPrice)) for trade in openTrades: if (self.currentPrice < trade.stopLoss): trade.close(self.date, self.currentPrice, "STOPLOSS") self.updateBalance(-trade.quantity, self.currentPrice) self.action.append('Close STOPLOSS=' + str(self.currentPrice)) elif trade.type in ["MACD"] and ((self.MACDDiff[-2] > 0 and self.MACDDiff[-1] < 0) or (self.MACDDiff[-1] > self.MACDSignal[-1] and self.MACDDiff[-2] < self.MACDSignal[-2])) and self.currentPrice > trade.targetPrice: trade.close(self.date, self.currentPrice, "MACD") self.updateBalance(-trade.quantity, self.currentPrice) self.action.append('CLOSE MACD=' + str(self.currentPrice)) elif trade.type in ["MACD2"] and self.MACDDiff[-1] > self.MACDSignal[-1] and self.MACDDiff[-2] < self.MACDSignal[-2] and self.currentPrice > trade.targetPrice: trade.close(self.date, self.currentPrice, "MACD2") self.updateBalance(-trade.quantity, self.currentPrice) self.action.append('CLOSE MACD2=' + str(self.currentPrice)) elif trade.type in ["MACD3"] and self.MACDDiff[-2] > 0 and self.MACDDiff[-1] < 0 and self.currentPrice > trade.targetPrice: trade.close(self.date, self.currentPrice, "MACD3") self.updateBalance(-trade.quantity, self.currentPrice) self.action.append('CLOSE MACD3=' + str(self.currentPrice)) elif trade.type in ["BBAND"] and self.prices[-1] < self.upperBBand[-1] and self.prices[-2] > self.upperBBand[-2] and self.currentPrice > trade.targetPrice: trade.close(self.date, self.currentPrice, "BBAND") self.updateBalance(-trade.quantity, self.currentPrice) self.action.append('CLOSE BBAND=' + str(self.currentPrice)) elif trade.type in ["RSI"] and self.rsi[-1] > 65 and self.rsi[-2] < 65 and self.currentPrice > trade.targetPrice: trade.close(self.date, self.currentPrice, "RSI") self.updateBalance(-trade.quantity, self.currentPrice) self.action.append('CLOSE RSI=' + str(self.currentPrice)) """elif trade.type in ["DROP"] and self.currentPrice > trade.targetPrice: trade.close(self.date, self.currentPrice, "DROP") self.updateBalance(-trade.quantity, self.currentPrice) self.action.append('CLOSE DROP=' + str(self.currentPrice))""" self.tradeAmount = int((self.holdingsUSD - 1) / self.numTrades) #self.output.log(str(self.tradeAmount)) def showPositions(self): for trade in self.trades: trade.showTrade() def showProfit(self): self.profit = 0 self.fees = 0 for trade in self.trades: self.fees = self.fees + trade.fees if (trade.status == "CLOSED"): self.profit = self.profit + trade.profit tradesOpened = sum(1 for i in self.trades if i.status == "OPEN") tradesClosed = sum(1 for i in self.trades if i.status == "CLOSED") tradesProfitableNumber = sum(1 for i in self.trades if i.profit > 0 and i.status == "CLOSED") tradesProfitableAmount = sum(i.profit for i in self.trades if i.profit > 0 and i.status == "CLOSED") tradesLossesNumber = sum(1 for i in self.trades if i.profit < 0 and i.status == "CLOSED") tradesLossesAmount = sum(i.profit for i in self.trades if i.profit < 0 and i.status == "CLOSED") self.output.log("\nSummary for " + self.name + ", Target / StopLoss " + str(self.targetPrice) + " / " + str(self.stopLoss) + ", with " + self.mode + " Start with: " + str(self.startUnit) + " unit(s) and " + str(self.startUSD) + " USD") self.output.log("Hold: End valuation: " + str(self.balanceNoTrade) + " Units: " + str(self.startUnit) + " USD: " + str(self.startUSD) + " Price: " + str(self.currentPrice)) self.output.log("Trade: End valuation: " + str(self.balance) + " Units: " + str(self.holdingsUnits) + " USD: " + str(self.holdingsUSD) + ". Price: " + str(self.currentPrice) + "\n") if tradesClosed > 0: self.output.log("Profit inc Fees: " + str(self.profit) + ", Fees: " + str(self.fees) + ", " + str(len(self.trades)) + " Trades with " + str(tradesOpened) + " still open\n") #self.output.log("Trades > 0: Number: " + str(tradesProfitableNumber) + ", Total: " + str(tradesProfitableAmount)) #self.output.log("Trades < 0: Number: " + str(tradesLossesNumber) + ", Total: " + str(tradesLossesAmount)) def updateBalance(self, quantity, price): self.holdingsUSD = self.holdingsUSD - (quantity * price) self.holdingsUnits = self.holdingsUnits + quantity self.balance = self.holdingsUSD + (self.holdingsUnits * price) self.balanceNoTrade = self.startUSD + (self.startUnit * price) def drawGraph(self): self.output.drawGraph(self.dataPoints, self.balancePoints, self.MACDPoints, self.name, self.mode)
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 MACDStrategy(BotStrategy): """ New MACD strategy """ _NAME = 'MACD Strategy' # Entry strategy flags. Keep at least one set to true or the trade will never enter MACD_CROSSOVER = True # Exit strategy flags. Keep at least one set to true or the trade will never exit TAKE_PROFIT = True take_profit = 0.007 # Exit when realized profit of trade is above this percentage. e.g. 0.005 == 0.5% def __init__(self, pair, period): BotStrategy.__init__(self, pair, period) self.highs = [] self.lows = [] self.closes = [] self.current_price = "" self.pair = pair self.stop_loss_percent = 2.5 self.indicators = BotIndicators() self.macd_fast = 12 self.macd_slow = 26 self.macd_signal = 9 self.macd_period = self.macd_signal + self.macd_slow # Number of data points needed to use MACD indicator self.hist_period = max(self.macd_fast, self.macd_slow, self.macd_signal, self.macd_period) self.max_hist = 0 # Used to keep track of the maximum value of the MACD histogram used on this trade. # Prime the bot with past data. self.past_typical_prices, self.past_opens, self.past_closes, self.past_highs, self.past_lows = self.get_past_prices( self.period, self.hist_period) if self.past_typical_prices and self.past_closes and self.past_highs and self.past_lows and self.past_opens: self.prices = self.past_typical_prices self.closes = self.past_closes self.highs = self.past_highs self.lows = self.past_lows def tick(self, candlestick): self.current_price = float(candlestick.typical_price) self.prices.append(self.current_price) # Highs self.currentHigh = float(candlestick.high) self.highs.append(self.currentHigh) # Lows self.currentLow = float(candlestick.low) self.lows.append(self.currentLow) # Closes self.currentClose = float(candlestick.close) self.closes.append(self.currentClose) if len(self.prices) > self.hist_period: # Price action self.output.log("\n{color}Typical Price: {price}".format( color=Cyan, price=str(candlestick.typical_price))) # MACD m, s, h = self.indicators.MACD(self.prices, self.macd_slow, self.macd_fast, self.macd_signal) self.output.log( "Last/Current indicator values:\tMACD {}\tSignal: {}\t Hist: {}" .format(str(m[-2:]), str(s[-2:]), str(h[-2:]))) statsd.histogram('macd.macd', m[-1], tags=[ 'macd.macd_line', 'bot_name:{}.bot_id:{}'.format( BOT_NAME, BOT_ID) ]) statsd.histogram('macd.signal', s[-1], tags=[ 'macd.signal_line', 'bot_name:{}.bot_id:{}'.format( BOT_NAME, BOT_ID) ]) statsd.histogram('macd.histogram', h[-1], tags=[ 'macd.histogram', 'bot_name:{}.bot_id:{}'.format( BOT_NAME, BOT_ID) ]) self.output.log(White) self.evaluate_positions() self.update_open_trades() self.show_positions() def evaluate_positions(self): openTrades = [] for trade in self.trades: if trade.status == "OPEN": openTrades.append(trade) # Instantiate indicator. _, _, hist = self.indicators.MACD(self.prices, self.macd_slow, self.macd_fast, self.macd_signal) # Only open a trade when the number of open trades is not more than the configured max allowed. # And there is enough data for indicator if len(openTrades) < self.num_simultaneous_trades and len( self.prices) > self.hist_period: ######################### # Entry Strategy ######################### # Buy/Long if self.MACD_CROSSOVER: if hist[-2] < 0.0 < hist[-1]: self.output.log("{} buy signal. MACD crossover".format( self._NAME)) self.trades.append( BotTrade(pair=self.pair, current_price=self.current_price, trade_type="BUY", order_type='market', stop_loss_percent=self.stop_loss_percent)) # NOTE: LEVERAGE REQUIRED FOR SELLING ON KRAKEN ############### # Exit Strategy ############### for trade in openTrades: # Buy/Long if self.TAKE_PROFIT: # Exit on % profit. if self.current_price >= ( trade.entry_price * (1.0 + self.take_profit) ) and trade.trade_type.upper() == "BUY": self.output.log("{} Closed on {}% gain".format( self._NAME, self.take_profit * 100)) trade.close(self.current_price) continue
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)))