class StrategyLib(object): def __init__(self): self.indicators = BotIndicators() def MACrossover(self, lowMA, highMA): fifteenDayMA = self.indicators.movingAverage(self.prices,self.lowMA) fiftyDayMA = self.indicators.movingAverage(self.prices,self.highMA) # print(fifteenDayMA, fiftyDayMA) if (len(self.openTrades) < self.numSimulTrades): if (fifteenDayMA > fiftyDayMA * self.mamultfactor ): amountToBuy = self.balance * 0.2 / self.currentPrice fee = amountToBuy * self.currentPrice * self.fee stoploss = self.currentPrice * 0.1 self.currentId += 1 self.balance -= (amountToBuy * self.currentPrice + fee) self.trades.append(BotTrade(self.functions, self.currentDate, amountToBuy, self.currentPrice,self.currentId,stopLoss=stoploss, fee=fee)) for trade in self.openTrades: if (fifteenDayMA < fiftyDayMA / self.mamultfactor): self.balance += trade.volume * self.currentPrice trade.close(self.currentDate, self.currentPrice, "MA Crossover") elif (trade.stopLoss): if (trade.entryPrice - self.currentPrice > trade.stopLoss): trade.close(self.currentDate, self.currentPrice, "Stoploss") self.balance += trade.volume * self.currentPrice
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 = 1 self.indicators = BotIndicators() def tick(self, candlestick): print candlestick.priceAverage 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() 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)) for trade in openTrades: if (self.currentPrice > self.indicators.movingAverage( self.prices, 15)): 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, period, log, api, checker, stopLoss=0, startBalance=100): self.highs = {} self.lows = {} self.closes = {} self.dates = [] self.volumes = {} self.MFIs = {} self.MACD = {} self.MovingAverage = {} self.output = log self.api = api self.fee = {} self.fee['BTC'] = self.api.getFee('ETHBTC') self.fee['BNB'] = self.api.getFee('BNBBTC') self.fee['USDT'] = self.api.getFee('BTCUSDT') self.pairs = checker.pairs self.coins = checker.coins self.indicators = BotIndicators(period, self.pairs) # unused, but find application self.stopLoss = stopLoss # self.balance = {i: 0 for i in checker.coins} # disable (it has to be in the tick method below) # setting start values for USDT # self.balance['USDT'] = startBalance self.oldValue = 0 self.ovrValue = 0 self.MFIs = {} self.MovingAverage = {} self.MFI = None self.period = period self.counter = 0 def tick(self, history, timestamp, initialize_live): # are all dictionaries, with timestamp as 1st level key and pair becomes 2nd level key (nested dictionary) self.highs[timestamp] = {} self.lows[timestamp] = {} self.closes[timestamp] = {} self.dates.append(timestamp) self.volumes[timestamp] = {} self.MFIs[timestamp] = {} self.MovingAverage[timestamp] = {} self.MACD[timestamp] = {} for pair in self.pairs: self.highs[timestamp][pair] = history[timestamp][pair]['high'] self.lows[timestamp][pair] = history[timestamp][pair]['low'] self.closes[timestamp][pair] = history[timestamp][pair]['close'] self.volumes[timestamp][pair] = history[timestamp][pair]['volume'] self.MovingAverage[timestamp][ pair] = self.indicators.movingAverage(closes=self.closes, dates=self.dates, pair=pair, length=5) self.MFI = self.indicators.moneyFlowIndex(period=self.period, dates=self.dates, highs=self.highs, lows=self.lows, closes=self.closes, volumes=self.volumes, pair=pair) self.MFIs[timestamp][pair] = self.MFI self.MACD[timestamp][pair] = self.indicators.MACD_Histogram( period=self.period, dates=self.dates, closes=self.closes, pair=pair) if not initialize_live: self.evaluatePositions(timestamp) self.giveInfo() def evaluatePositions(self, timestamp): # self.balances is a dictionary with balance for each coin self.balances = self.api.getBalance() BuyOptions = [] SellOptions = [] list_of_trades = [] notTraded = [] # latest overall value becomes old value self.oldValue = self.ovrValue self.ovrValue = 0 # loops through pairs and checks if MFI indicates a buy or sell option for pair in self.pairs: if self.MFIs[timestamp][pair]: if self.MFIs[timestamp][pair] < 30: BuyOptions.append((pair, self.MFIs[timestamp][pair])) if self.MFIs[timestamp][pair] > 70: SellOptions.append(pair) # buy if MACD overtakes MACD Signal Line, sell if MACD gets overtaken by MACD Signal Line if len(self.MACD[timestamp][pair]) > int(86400 / self.period): if (0 > self.MACD[timestamp][pair][-2]) and ( self.MACD[timestamp][pair][-1] > 0): # BuyOptions.append(pair) print("According to MACD buy!", self.MACD[timestamp][pair][-2], self.MACD[timestamp][pair][-1], pair) ''' if (0 < self.MACD[timestamp][pair][-2]) and (self.MACD[timestamp][pair][-1] < 0): # SellOptions.append(pair) SellOptions.append(pair) ''' # sorts the definitive buy options starting with lowest MFI and takes the 5 with lowest MFI # todo: used for MFI, improve by spliting the money to different coins, somehow a voting system by different indicators definitiveBuyOptions = sorted(BuyOptions, key=lambda tup: tup[1])[:5] # definitiveBuyOptions = BuyOptions ## definitiveSellOptions.append(sorted(BuyOptions,key=lambda tup:tup[1])[-5:]) ## definitiveSellOptions=sorted(BuyOptions,key=lambda tup:tup[1]) # takes all Sell options as definitive (can be further improved) definitiveSellOptions = SellOptions print('MFIs:', self.MFIs[timestamp]) counter = 0 #########################################SELL################################### for sell in definitiveSellOptions: if sell == "BTCUSDT": continue other = sell[:-3] #other currency BTC = sell[-3:] #Bitcoin quantityTemp = self.balances[other] print(f"sell {sell}") quantity = self.api.filterSell(quantity=quantityTemp, pair=sell, closes=self.closes[timestamp]) if quantity: counter += 1 status, sellPrice = self.api.Sell(pair=sell, quantity=quantity) if status == "FILLED": list_of_trades.append(status) print(f'sold {sell} at {sellPrice}') else: notTraded.append(status, pair) print(status, pair) else: print(f"Would have sold but no coins of this currency, {sell}") # if there is any buy option, only the best option should be taken #########################Buy################################### print( f"Buy options look like (first pair, second MFI): {definitiveBuyOptions} " ) for i, buy in enumerate(definitiveBuyOptions): number_of_buys = len(definitiveBuyOptions) fraction = 1 / 5 # applied 10.September if buy[0] == "BTCUSDT": continue buy = buy[0] other = buy[:-3] # other currency BTC = buy[-3:] # Bitcoin quantityTemp = self.balances[BTC] * fraction if "BNB" not in [BTC, other]: quantityTemp = quantityTemp * (1 - self.fee['BTC']) else: quantityTemp = quantityTemp * (1 - self.fee['BNB']) print(f"quantityTemp is: {quantityTemp}") quantity = self.api.filterBuy(quantityBTCstart=quantityTemp, pair=buy, closes=self.closes[timestamp]) if quantity: counter += 1 status, buyPrice = self.api.Buy(pair=buy, quantity=quantity) if status == "FILLED": list_of_trades.append(status) print(f'bought {buy} at {buyPrice}') else: notTraded.append(status, buy) print(status, buy) else: print( f"Would have bought but no coins (BTC (or USDT)) to buy this currency, {buy}" ) # evaluate the portfolio value called overall if len(list_of_trades) == counter: self.balances = self.api.getBalance() else: print(f'{notTraded} is the list of not Traded pairs') time.sleep(10) print( f'{notTraded} is the list of not Traded pairs after additional 10 seconds, however the balance gets estimated now!' ) self.balances = self.api.getBalance() for pair in self.pairs: if pair == 'BTCUSDT': other = 'USDT' else: other = pair[:-3] # other currency self.ovrValue += self.balances[other] * self.closes[timestamp][ pair] * self.closes[timestamp]['BTCUSDT'] self.ovrValue += self.balances['USDT'] self.ovrValue += self.balances['BTC'] * self.closes[timestamp][ 'BTCUSDT'] print('USDT:', self.balances['USDT'], 'BTC:', self.balances['BTC'], 'overall value:', self.ovrValue) self.counter += self.period def giveInfo(self): Yield = self.ovrValue - self.oldValue if Yield > 1: print("The overall Value is:" + str(self.ovrValue) + color_front("The yield is: " + str(Yield), 0, 153, 76)) elif Yield > 0: print("The overall Value is:" + str(self.ovrValue) + color_front("The yield is: " + str(Yield), 0, 255, 0)) elif Yield < -1: print("The overall Value is:" + str(self.ovrValue) + color_front("The yield is: " + str(Yield), 255, 0, 0)) else: print("The overall Value is:" + str(self.ovrValue) + color_front("The yield is: " + str(Yield), 255, 128, 0)) print("{} days passed".format(self.counter / 86400))
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 = 1 self.indicators = BotIndicators() self.spreadsheet = [] def tick(self, candlestick): # print candlestick.priceAverage 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() mess = str(candlestick['weightedAverage']) self.GenSpreadsheetInfo(self.prices) 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, 20)): self.trades.append(BotTrade(self.currentPrice, stopLoss=.0001)) for trade in openTrades: if (self.currentPrice > self.indicators.movingAverage( self.prices, 20)): 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() def GenSpreadsheetInfo(self, prices): newList = [] if len(self.spreadsheet) == 0: newList.append("Price") newList.append("20_Per_MA") newList.append("50_per_MA") newList.append("TOP_STD") newList.append("BOT_STD") self.spreadsheet.append(newList) newList = [] newList.append(self.currentPrice) newList.append(self.indicators.movingAverage(self.prices, 20)) newList.append(self.indicators.movingAverage(self.prices, 50)) newList.append(self.currentPrice + (2 * self.indicators.standardDeviation(self.prices, 20))) newList.append(self.currentPrice - (2 * self.indicators.standardDeviation(self.prices, 20))) self.spreadsheet.append(newList) def GetSpreadsheetInfo(): return self.spreadsheet
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 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 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, startingBal): self.output = BotLog() self.trades = [] self.candlesticks = [] self.indicators = BotIndicators() self.currentBal = startingBal def evaluatePositions(self): prices = [] over_last_n_periods = 15 lastCandlestick = self.candlesticks[-1] for i in range(1, over_last_n_periods + 1): prices.append(self.candlesticks[-i].priceAverage) if (self.trades and self.trades[-1].status == "CLOSED") or not self.trades: # buy if lastCandlestick.priceAverage < self.indicators.movingAverage( prices): currentTrade = BotTrade(self.trades.__len__() + 1, lastCandlestick.close, lastCandlestick.date, self.currentBal) self.trades.append(currentTrade) # currentTrade.logBuy() if self.trades and self.trades[-1].status == "OPEN": lastTrade = self.trades[-1] # sell if lastCandlestick.priceAverage > self.indicators.movingAverage( prices): lastTrade.close(lastCandlestick.close, lastCandlestick.date) # lastTrade.logSell() self.currentBal = lastTrade.currentBal def showPositions(self, startingInvestment, displayTradeDetails): investment = startingInvestment tradeNum = 1 for trade in self.trades: if trade.exitPrice != '': invAtStartOfTrade = investment buyTax = investment * -0.0025 investment = investment + buyTax # amount of currency bought tradeProfit = investment * (float(trade.exitPrice) / float( trade.entryPrice)) - investment investment = investment * (float(trade.exitPrice) / float(trade.entryPrice)) sellTax = investment * -0.0025 investment = investment + sellTax net = investment - invAtStartOfTrade if displayTradeDetails: # color code net if net > 0: netStr = "\033[92m$" + str(format(net, ',.2f')) + "\033[0m" else: netStr = "\033[91m$" + str(format(net, ',.2f')) + "\033[0m" print("--------------------" + "Trade #" + str(format(tradeNum, ',')) + " | " + time.strftime('%m/%d/%Y %H:%M:%S', time.localtime(trade.timeTradeStart)) + " - " + time.strftime( '%H:%M:%S', time.localtime(trade.timeTradeEnd)) + "--------------------") trade.showTrade() print("\t\t Buy tax: $" + str(buyTax)) print("\t\t Sell tax: $" + str(sellTax)) print("\t\t Profit from trade: $" + str(tradeProfit)) print("\t\t Before Trade: $" + str(invAtStartOfTrade)) print("\t\t After Trade: $" + str(investment)) print("\t\t Net: " + netStr) tradeNum += 1 # color code investment if investment > startingInvestment: endStr = "\033[92m$" + str(format(investment, ',.2f')) + "\033[0m" else: endStr = "\033[91m$" + str(format(investment, ',.2f')) + "\033[0m" print("\nStart: $" + str(format(startingInvestment, ',.2f'))) print("End: " + endStr)
class BotChart(object): 'Draws a classic trading chart, humanely readable' def __init__(self, period, startTime, endTime, backTest=True): self.exchange = shared.exchange['name'] self.pair = shared.exchange['pair'] self.period = int(period) self.startTime = int(startTime) self.endTime = int(endTime) self.backTest = bool(backTest) self.output = BotLog() self.tempCandle = None self.indicators = BotIndicators() self.data = [] self.api = BotApi() if backTest: self.data = self.api.returnChartData(self.pair, period=int(self.period), start=self.startTime, end=self.endTime) def getPoints(self): return self.data def getCurrentPrice(self): if not self.backTest: currentValues = self.api.returnTicker(self.pair) lastPairPrice = {} lastPairPrice = currentValues["last"] return float(lastPairPrice) def drawChart(self, candlesticks, movingAverages, trades): # googlecharts output = open("./output/data.js", 'w') output.truncate() temp = [] x = 0 for candle in candlesticks: temp.append(candle.toDict()) if x < len(movingAverages): temp[x]['ma'] = movingAverages[x] x += 1 else: ma = self.indicators.movingAverage( candlesticks, shared.strategy['movingAverageLength']) temp[x]['ma'] = ma candlesticks = pd.DataFrame.from_records(temp) candlesticks.set_index('date', inplace=True) orders = [] for o in trades: orders.append({ 'date': o.date, 'orderRate': o.entryPrice, 'orderDirection': o.direction, 'stopLoss': o.stopLoss, 'takeProfit': o.takeProfit, 'exitPrice': o.exitPrice }) orders = pd.DataFrame(orders) if len(orders) > 1: orders.set_index('date', inplace=True) else: orders = pd.DataFrame() orders['orderRate'] = 0 orders['orderDirection'] = 'None' orders['stopLoss'] = 0 orders['takeProfit'] = 0 orders['exitPrice'] = 0 points = pd.concat([candlesticks, orders], axis=1) points['orderDirection'].fillna('None', inplace=True) points.fillna(0, inplace=True) # print(points) # points['orderRate'].fillna(0, inplace=True) # points['stopLoss'].fillna(0, inplace=True) # points['takeProfit'].fillna(0, inplace=True) # points['exitPrice'].fillna(0, inplace=True) output.write("var dataRows = [];") # New elements should be added to dataRows in accordance with the datatable in output.hmtl for date, point in points.iterrows(): output.write("dataRows.push([new Date(" + str(int(date) * 1000) + "), " + str(point.low) + ", " + str(point.open) + "," + str(point.close) + "," + str(point.high) + "," + str(point.ma) + "," + str(point.orderRate) + ",'" + str(point.orderDirection) + "'," + str(point.stopLoss) + "," + str(point.takeProfit) + "," + str(point.exitPrice) + "]);\n") output.write("var lastcall = '" + str(time.ctime()) + "'")
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, strat, chartmax, chartmin, chartlengths, pair, numofcharts, valuesAre, timestamps, extra, valuelist, intervals, beginag, endag, tlen, live=False, aggTrades=True, aggisNext=True, graphics=True, ma5on=True, handlon=True): self.masterDick = {} self.graphics = graphics #If we want these indicators graphed: self.ma5on = ma5on #***************************# #read api token from text file, hopefully I don't accidentally upload the text file to github lol f = open("token.txt", "r") contents = f.read() newline = False secretkey = "" apikey = "" for x in contents: if x == "\n": newline = True continue if not newline: apikey += x else: secretkey += x self.client = Client(apikey, secretkey) f.close() #### self.strat = strat self.stratlist = [ "", "self.firstone(lows, highs, k, o)#, nextTradeSeller)", "self.secondone(lows, highs, k, o)", "self.thirdone()" ] #this checks if ur trading larger(not fractional) currencies (BTCUSD, etc) self.largerpair = False largepairlist = ["BTCUSDT"] for f**k in largepairlist: if pair == f**k: self.largerpair = True self.aggisNext = aggisNext self.aggTrades = aggTrades #price change during market buying self.amtofups = 0 self.amtofdowns = 0 self.pair = pair self.indicators = BotIndicators() self.live = live #self.rsifirst = True self.rsiper = 12 self.stochper = 14 self.bollingerper = 20 self.chartlen = chartlengths self.last = False self.bigma = 0 self.ma15 = 0 self.ma5 = 0 self.bolup = 0 self.bollow = 0 self.bolmid = 0 self.bandwidth = 0 #BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB #BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB #slutty variables turned global #if u wanna call functions that used to take params like chartnumber, nextTrade, etc. but with a different chartnumber #or price or whatever, just update global chartnumber or whatevs, call the function, then set the var back to what it was self.price = 0 self.nextTrade = 0 self.chartnumber = 0 #doin these now self.high = 0 self.low = 0 #coins available to spend #A little f****d for larger pair, startbtc is going to actually be usdt if self.largerpair: #base is in USDT self.startbase = 100 else: #base is in BTC self.startbase = 10 self.availablebase = self.startbase #self.firstbuy = self.availablebase / 2.0 #self.secondbuy = self.availablebase - self.firstbuy self.amtofalt = 0 #self.secondtradeentries = 0 self.totalentries = 0 #how many trades can there be self.entries = 1 #stop loss percent self.stopPercent = 10 listofvars = [ "crosstime", "firstcross", "crossPointA", "crossPointB", "percentlist", "count", "currentPrice", "prices", "ma5list", "ma15list", "ma15", "ma5", "pchange", "ma5lower", "ma5higher", "lmaxes", "lmins", "ema", "rsi", "rsilist", "botmax", "botmin", "pricechg", "pag", "pal", "rsifirst", "highs", "lows", "stochfirst", "k", "fast", "bigma", "bigmalist", "bolup", "bolmid", "bollow", "bandwidth" ] ''' Vars Explained: crosstime idk firstcross idk crossPointA idk crossPointB idk percentlist list for how much price has gone up/down percentage-wise for each ticker. Usually compared to last price, is changeable though count i think -tick number currentPrice prices ma5list ma15list ma15 ma5 pchange ma5lower ma5higher lmaxes lmins ema rsi rsilist ''' for i in range(numofcharts): for item in range(len(listofvars)): key = listofvars[item] + str(i + 1) self.masterDick[key] = valuelist[item] print(self.masterDick) if self.graphics: self.graph = Graph(chartmax, chartmin, self.chartlen, pair, numofcharts, valuesAre, timestamps, extra, intervals, self.rsiper, self.stochper, self.bollingerper, ma5on=ma5on, handlon=handlon) #This only works for one chart at the moment self.entryprices = [] #U still need to deal with self.orderPercent listoforder = ["orderPercent", "avgentryprice"] ordervals = [0, 0] self.orders = {} for num in range(numofcharts): for thing in range(len(listoforder)): key = listoforder[thing] + str(num + 1) self.orders[key] = ordervals[thing] print(self.orders) self.dentry = {} #setting number of allowed entries: #NEED TO DELETE THESE FROM ABOVE LOOP entryshit = [ "placedOrder", "orderPrice", "orderGain", "buy", "tradeEntries" ] entvals = [False, 0, 0, 0, 0] for n in range(numofcharts): for entr in range(1, self.entries + 1): for i in range(len(entryshit)): key = entryshit[i] + str(entr) + str(n + 1) self.dentry[key] = entvals[i] self.prevEma = 0 #I'm lazy, we definitely can't run more than one chart now self.prevbigma = 0 self.prevma15 = 0 self.prevma5 = 0 self.prevma15list = [] self.prevma5list = [] self.prevbigmalist = [] self.prevPrices = [] self.prevPrevEma = 0 self.prevk = [] self.prevfast = 0 self.prevhighs = [] self.prevlows = [] self.prevrsi = 0 self.prevpag = 0 self.prevpal = 0 self.prevPriceChg = [] #Bollinger self.prevBolUp = 0 self.prevBolMid = 0 self.prevBolLow = 0 #analytical self.upcount = 0 self.downcount = 0 self.downsnups = {} ''' self.allAggs = [] #Get ALL aggregate trades time = 0 for time in range(time, tlen): self.allAggs.extend(self.client.get_aggregate_trades(symbol=self.pair, startTime=beginag + time * 3600000, endTime=beginag + (time + 1) * 3600000)) self.lastAggIter = 0 #print(self.allAggs) ''' def tick(self, price, chartnumber, high, low, o, t): ############################################# self.price = price self.chartnumber = chartnumber self.high = high self.low = low #nextTrade work nextTrades = [] nextTradeTimes = [] if self.last: #once we get to the latest kline we store current price into next trade vars self.nextTrade = float(price) #nextTradeSeller = float(price) nextTradeTime = 0 else: #testing to see if aggtrades enable/disable works #I'm setting nextTrades to current price so when we buy & sell it should be the same as if there was no nextTrades self.nextTrade = float(price) #nextTradeSeller = float(price) if self.aggTrades: #agtrades = self.client.get_aggregate_trades(symbol=self.pair, startTime=int(t),endTime=int(t) + 14400000) agtrades = self.client.get_aggregate_trades(symbol=self.pair, startTime=int(t), endTime=int(t) + 900000) print("agtrade len", len(agtrades)) print("timestamp for agtrade is ", t) nextTradeSeller = agtrades[0] print(price) print(self.nextTrade) firstNextTrade = float(self.nextTrade['p']) print("FirstNextTrade:", firstNextTrade) print("Kline price:", price) if float(self.nextTrade['p']) == float(price): print("Trade is equal :(") else: print( "Woohoo this means the next trade and not the current price is being used !! :)" ) if not self.aggisNext: counterbro = 1 while self.nextTrade['m']: if counterbro >= len(agtrades): self.nextTrade = agtrades[counterbro - 1] print("There was no buyer that was maker ! ! ! !") break else: self.nextTrade = agtrades[counterbro] counterbro += 1 counterbro = 1 while not nextTradeSeller['m']: if counterbro >= len(agtrades): nextTradeSeller = agtrades[counterbro - 1] print("There was no seller that was maker ! ! !") break else: nextTradeSeller = agtrades[counterbro] counterbro += 1 #get the fraction of nexttrade so we can plot it on x axis print("nextTrade time offset", str(float(self.nextTrade['T']) - t)) #These numbers are hardcoded f**k nextTradeTime = (float(self.nextTrade['T']) - t) / 14400000 nextTradeSeller = float(nextTradeSeller['p']) #print(nextTrade) self.nextTrade = float(self.nextTrade['p']) else: #ADDED THIS WHEN I RETURNED, TRYING TO ABANDON AGGTRADES #GOOD LUCK BRO pass #''' if self.masterDick["ema" + chartnumber] == 0: self.masterDick["ema" + chartnumber] = float(price) self.prevPrevEma = self.prevEma self.prevEma = self.masterDick["ema" + chartnumber] #ema period is 20 self.masterDick["ema" + chartnumber] = self.indicators.expMovingAverage( float(price), 20, self.prevEma) ema = self.masterDick["ema" + chartnumber] #this is the one screwing it up #lengpc = len(self.masterDick["pricechg" + chartnumber]) self.prevPriceChg = self.masterDick["pricechg" + chartnumber] if self.masterDick["count" + chartnumber] > 0: self.masterDick["pricechg" + chartnumber].append( float(price) - self.masterDick["currentPrice" + chartnumber]) pricechg = self.masterDick["pricechg" + chartnumber] if len(pricechg) > self.rsiper: del pricechg[0] self.masterDick["currentPrice" + chartnumber] = float(price) self.prevPrices = self.masterDick["prices" + chartnumber] self.masterDick["prices" + chartnumber].append( self.masterDick["currentPrice" + chartnumber]) prices = self.masterDick["prices" + chartnumber] #stochastic self.prevhighs = self.masterDick["highs" + chartnumber] self.prevlows = self.masterDick["lows" + chartnumber] self.masterDick["highs" + chartnumber].append(high) self.masterDick["lows" + chartnumber].append(low) highs = self.masterDick["highs" + chartnumber] lows = self.masterDick["lows" + chartnumber] if len(highs) > self.stochper: del highs[0] del lows[0] self.prevbigma = self.masterDick["bigma" + chartnumber] self.masterDick["bigma" + chartnumber] = self.indicators.movingAverage( self.masterDick["prices" + chartnumber], 250) self.bigma = self.masterDick["bigma" + chartnumber] self.prevbigmalist = self.masterDick["bigmalist" + chartnumber] self.masterDick["bigmalist" + chartnumber].append( self.masterDick["bigma" + chartnumber]) bigmalist = self.masterDick["bigmalist" + chartnumber] self.prevma15 = self.masterDick["ma15" + chartnumber] self.masterDick["ma15" + chartnumber] = self.indicators.movingAverage( self.masterDick["prices" + chartnumber], 15) self.ma15 = self.masterDick["ma15" + chartnumber] self.prevma15list = self.masterDick["ma15list" + chartnumber] self.masterDick["ma15list" + chartnumber].append( self.masterDick["ma15" + chartnumber]) ma15list = self.masterDick["ma15list" + chartnumber] self.prevma5 = self.masterDick["ma5" + chartnumber] self.masterDick["ma5" + chartnumber] = self.indicators.movingAverage( self.masterDick["prices" + chartnumber], 5) self.ma5 = self.masterDick["ma5" + chartnumber] self.prevma5list = self.masterDick["ma5list" + chartnumber] self.masterDick["ma5list" + chartnumber].append( self.masterDick["ma5" + chartnumber]) ma5list = self.masterDick["ma5list" + chartnumber] ####Bollinger#### #I think using greater than fixed something if (len(self.masterDick["prices" + chartnumber]) > self.bollingerper): self.bolmid = self.indicators.movingAverage( self.masterDick["prices" + chartnumber], self.bollingerper) self.masterDick["bolmid" + chartnumber].append(self.bolmid) self.bolup = self.bolmid + self.indicators.stddev(self.masterDick[ "prices" + chartnumber][(self.bollingerper * -1):]) * 2 self.masterDick["bolup" + chartnumber].append(self.bolup) self.bollow = self.bolmid - self.indicators.stddev(self.masterDick[ "prices" + chartnumber][(self.bollingerper * -1):]) * 2 self.masterDick["bollow" + chartnumber].append(self.bollow) self.bandwidth = (self.bolup - self.bollow) / float(price) * 100 self.masterDick["bandwidth" + chartnumber].append(self.bandwidth) #just untabbed these for reference in graph.listadd boluplist = self.masterDick["bolup" + chartnumber] bollowlist = self.masterDick["bollow" + chartnumber] bolmidlist = self.masterDick["bolmid" + chartnumber] bandwidth = self.masterDick["bandwidth" + chartnumber] #print("Bandwidth:",self.bandwidth) #----rsi start---- #If the data points hit the period of the rsi, start calculating it if self.masterDick["rsifirst" + chartnumber] and (len(pricechg) == self.rsiper): self.masterDick["rsi" + chartnumber] = self.indicators.rsi(pricechg) self.masterDick["pag" + chartnumber] = self.indicators.pag self.masterDick["pal" + chartnumber] = self.indicators.pal print("Ran on iteration", self.masterDick["count" + chartnumber]) self.masterDick["rsilist" + chartnumber].append( self.masterDick["rsi" + chartnumber]) elif not self.masterDick["rsifirst" + chartnumber]: #prev values self.prevrsi = self.masterDick["rsi" + chartnumber] self.prevpag = self.masterDick["pag" + chartnumber] self.prevpal = self.masterDick["pal" + chartnumber] self.masterDick["rsi" + chartnumber] = self.indicators.rsi( pricechg, self.masterDick["pag" + chartnumber], self.masterDick["pal" + chartnumber]) self.masterDick["pag" + chartnumber] = self.indicators.pag self.masterDick["pal" + chartnumber] = self.indicators.pal self.masterDick["rsilist" + chartnumber].append( self.masterDick["rsi" + chartnumber]) rsilist = self.masterDick["rsilist" + chartnumber] rsi = self.masterDick["rsi" + chartnumber] if len(pricechg) == self.rsiper and self.masterDick["rsifirst" + chartnumber]: self.masterDick["rsifirst" + chartnumber] = False print("Falsified rsifirst", self.masterDick["count" + chartnumber], len(pricechg)) #----rsi end---- #----stochastic start---- if len(highs) == self.stochper: #previous values if len(self.masterDick["k" + chartnumber]) > 0: self.prevk = self.masterDick["k" + chartnumber] self.prevfast = self.masterDick["fast" + chartnumber] self.masterDick["k" + chartnumber].append( self.indicators.stochastic(float(price), min(lows), max(highs))) k = self.masterDick["k" + chartnumber] if len(k) > 3: del k[0] self.masterDick["fast" + chartnumber] = self.indicators.movingAverage( k, len(k)) else: k = self.masterDick["k" + chartnumber] fast = self.masterDick["fast" + chartnumber] #----stochastic end---- #Local Maximums and Minimums if len(prices) > 1: lastwasmax = self.indicators.maxes(prices[-3:]) lastwasmin = self.indicators.mins(prices[-3:]) if lastwasmax: lmaxes = self.masterDick["lmaxes" + chartnumber] if lmaxes[0] == -1: lmaxes[0] = self.masterDick["count" + chartnumber] - 1 else: lmaxes.append(self.masterDick["count" + chartnumber] - 1) elif lastwasmin: lmins = self.masterDick["lmins" + chartnumber] if lmins[0] == -1: lmins[0] = self.masterDick["count" + chartnumber] - 1 else: lmins.append(self.masterDick["count" + chartnumber] - 1) self.checkCross(prices[0]) self.masterDick["pchange" + chartnumber] = self.indicators.percentChange( prices, 5) self.masterDick["percentlist" + chartnumber].append( self.masterDick["pchange" + chartnumber]) #setting these to clean up graph.add below lmax = self.masterDick["lmaxes" + chartnumber] lmins = self.masterDick["lmins" + chartnumber] if chartnumber == "1": #Buy/sell #I added +1 so we have the current and previous rsi/stochastic value available. could possibly need to change to +2 if self.masterDick[ "count" + chartnumber] >= self.stochper + 1 and self.masterDick[ "count" + chartnumber] >= self.rsiper + 1: #JUST TOOK OUT EVALUATEPOSITIONS() BECAUSE IT F****N SUCKS PASSING EVERYTHING THROUGH #self.evaluatePositions(price, lows, high, highs, k, o, rsi, chartnumber, t) #self.evaluatePositions(price, nextTrade, lows, high, highs, k, o, rsi, chartnumber, t)#, nextTradeSeller) prices = self.masterDick["prices" + chartnumber] if ((self.masterDick["currentPrice" + chartnumber] < self.ma5) and (self.masterDick["currentPrice" + chartnumber] < self.ma15)): if (self.masterDick["currentPrice" + chartnumber] > prices[-2] or self.masterDick["currentPrice" + chartnumber] == prices[-2]): #print("BUY") pass #you need to make sure the btc in your account matches up with availablebtc #This sets available trading funds (entries) if not self.dentry["placedOrder1" + chartnumber]: for y in range(1, self.entries + 1): self.dentry["buy" + str(y) + chartnumber] = self.availablebase / float( self.entries) #print("vbuy" + str(y),self.dentry["buy" + str(y) + chartnumber]) #trying moving entrycalc outside strats, check history to see if entrycalc is same in each #Most recent - it passed self through as an argument - deleting that self.entrycalc(lows, o) if self.strat > 0: eval(self.stratlist[self.strat]) #putting stoploss check after strat(so it doesn't buy again instantly, REVIEW THIS IN THE FUTURE if self.dentry["placedOrder1" + chartnumber]: self.stoploss() #error check if self.availablebase < 0: print("F**K BITCOIN IS IN THE NEGATIVES-ERROR") print(str(self.availablebase)) if self.graphics: self.graph.add(price, self.ma5, self.ma15, self.bigma, self.masterDick["pchange" + chartnumber], self.masterDick["crossPointA" + chartnumber], self.masterDick["crossPointB" + chartnumber], self.masterDick["crosstime" + chartnumber], self.masterDick["firstcross" + chartnumber], chartnumber, lmax[-1], lmins[-1], ema, rsi, high, low, k, fast, self.nextTrade, self.bolmid, self.bolup, self.bollow, self.bandwidth) #, nextTradeTime) #Since the line between the last two MAcrosses was just graphed, we #change the first point for the next line to the last point of #the current one if (self.masterDick["crosstime" + chartnumber]): self.masterDick["crossPointA" + chartnumber] = self.masterDick["crossPointB" + chartnumber] self.masterDick["crossPointB" + chartnumber] = 0 self.masterDick["firstcross" + chartnumber] = self.masterDick["count" + chartnumber] self.masterDick["crosstime" + chartnumber] = False self.masterDick["count" + chartnumber] += 1 #End of historical klines #DO NOT DELETE, THIS LAUNCHES THE GRAPH #if statement checks if is live and current chart hit the last iteration, self.last if (self.masterDick["count" + chartnumber] == self.chartlen[int(chartnumber) - 1]) and (not self.live): print("so this is the last item in chart" + chartnumber) #total percentage gain availableBasePlaceHolder = 0 if self.dentry["placedOrder1" + chartnumber]: if self.largerpair: availableBasePlaceHolder = self.availablebase + self.amtofalt * float( price) * .999 else: availableBasePlaceHolder = self.availablebase + int( self.amtofalt) * float(price) * .999 else: availableBasePlaceHolder = self.availablebase #percentageee = (availableBasePlaceHolder - self.startbase) * 100 / self.startbase percentageee = (availableBasePlaceHolder - self.startbase) * 100 / self.startbase if self.graphics: self.graph.listadd( ma5list, ma15list, bigmalist, self.masterDick["percentlist" + chartnumber], percentageee, rsilist, chartnumber, boluplist, bollowlist, bolmidlist, bandwidth) #change to if(chartnumber == "1"): print("just ran listadd" + chartnumber) if (self.last): #RETURN################################################^&*&^%$#$%^&*^%$#@$%^&*&^%$# #mas print("mas") #print("ma5",self.prevma5,"ma5list",self.prevma5list,"ma15",self.prevma15,"ma15list",self.prevma15list) #ema print('ema') print("prevEma", self.prevPrevEma, "ema", self.prevEma) #stochastic print('stochastic') print("k", self.prevk, "fast", self.prevfast) print("highs", self.prevhighs, "lows", self.prevlows) #RSI print('rsi') print("rsi", self.prevrsi, "pag", self.prevpag, "pal", self.prevpal) #Timestamps ?????? #if u use this code for liverun, DON'T ACTUALLY SELL if self.dentry["orderPrice1" + self.chartnumber] != 0: self.sell(final=True) print("Started with:", self.startbase, "Ended with:", self.availablebase) print("percent win:", percentageee) print("first entries:", self.totalentries) print("Times the price went up during market order buys:", self.amtofups) for keyz in self.downsnups: print(keyz) sumb = 0 for numb in self.downsnups[keyz]: sumb += numb sumb /= len(self.downsnups[keyz]) print(sumb) print() for poop in range(2, self.entries + 1): print( str(poop) + "entries:", self.dentry["tradeEntries" + str(poop) + chartnumber]) if self.graphics: self.graph.anal() #return data for further analysis #run with a spec strat for marketcomb? #analysis if len(prices) > 1: #add this in if float(price) == prices[-2]: #decide what to do pass #goin down elif float(price) - prices[-2] < 0: if self.upcount != 0: #add shit to dict if str(self.downcount) in self.downsnups: self.downsnups[str(self.downcount)].append( self.upcount) else: self.downsnups[str(self.downcount)] = [self.upcount] self.downcount = 0 self.upcount = 0 self.downcount += 1 #goin up else: #if it hasn't gone down hyet we don't care - decide what to do if price doesnt change above if self.downcount != 0: self.upcount += 1 print(self.downsnups) print("upc", self.upcount) print("downc", self.downcount) ##################### #####END OF TICK##### ##################### def buy(self): price = float(self.price) print("buy") print('avbl BTC:', self.availablebase) self.totalentries += 1 self.dentry["placedOrder1" + self.chartnumber] = True #self.orders["orderPrice" + chartnumber] = self.masterDick["currentPrice" + chartnumber] #######IMPLEMENTING NEXTTRADE #self.dentry["orderPrice1" + chartnumber] = price self.dentry["orderPrice1" + self.chartnumber] = self.nextTrade #if btc to usd, etc if self.largerpair: altbuy = self.dentry["buy1" + self.chartnumber] / self.nextTrade else: #altbuy = int(self.dentry["buy1" + chartnumber] / price) altbuy = int(self.dentry["buy1" + self.chartnumber] / self.nextTrade) #janky way of using nextTrade #Do I need this? already setting altbuy to nextTrade price secondattempt = False if price < self.nextTrade: altbuy = int(altbuy * .9) secondattempt = True self.amtofups += 1 #Hmmmmmm BTCUSDT etc pops this if altbuy * self.nextTrade > self.availablebase: print("ERROR ERROR ERROR ERROR ERROR") #COMBINE THIS TO IF STATEMENT A FEW LINES UP #also idk if will work self.availablebase -= altbuy * self.nextTrade altbuy -= altbuy * .0026 self.amtofalt += altbuy #self.entryprices.append(price) self.entryprices.append(self.nextTrade) print(self.entryprices) if self.graphics: self.graph.buy(self.masterDick["currentPrice" + self.chartnumber], self.masterDick["count" + self.chartnumber], self.chartnumber, 1) print("Fun:", self.amtofalt) print("Buy1", self.dentry["buy1" + self.chartnumber]) print("NextPrice:", self.nextTrade) if secondattempt: print("On second attempt") else: print("On first attempt") def sell(self, final=False, stopped=False): price = float(self.price) self.dentry["placedOrder1" + self.chartnumber] = False self.dentry["orderGain1" + self.chartnumber] = ( (self.masterDick["currentPrice" + self.chartnumber] - self.dentry["orderPrice1" + self.chartnumber]) / self.dentry["orderPrice1" + self.chartnumber]) * 100 self.dentry["orderGain1" + self.chartnumber] = self.dentry["orderGain1" + self.chartnumber] / float( self.entries) for x in range(2, self.entries + 1): if self.dentry["placedOrder" + str(x) + self.chartnumber]: self.dentry["placedOrder" + str(x) + self.chartnumber] = False self.dentry["orderGain" + str(x) + self.chartnumber] = ( (self.masterDick["currentPrice" + self.chartnumber] - self.dentry["orderPrice" + str(x) + self.chartnumber]) / self.dentry["orderPrice" + str(x) + self.chartnumber]) * 100 self.dentry["orderGain" + str(x) + self.chartnumber] = self.dentry["orderGain" + str( x) + self.chartnumber] / float(self.entries) #may or may not work if self.largerpair: self.availablebase += self.amtofalt * price * .9984 self.amtofalt -= self.amtofalt else: #self.availablebase += int(self.amtofalt) * nextTradeSeller self.availablebase += int(self.amtofalt) * price * .9984 self.amtofalt -= int(self.amtofalt) if self.graphics and not final: self.graph.sell(self.masterDick["currentPrice" + self.chartnumber], self.masterDick["count" + self.chartnumber], self.dentry["orderGain1" + self.chartnumber], self.chartnumber, stopped) print("sell", self.price) print("NextPrice:", self.nextTrade) print("BTC:", self.availablebase) #this gon f**k it up self.entryprices = [] def stoploss(self): """ Gets out of the buy if price dips below predetermined percent """ price = float(self.price) print("orderPrice1:", self.dentry["orderPrice1" + self.chartnumber]) if (self.dentry["orderPrice1" + self.chartnumber] - price ) / self.dentry["orderPrice1" + self.chartnumber] * 100 >= self.stopPercent: self.sell(stopped=True) def entrycalc(self, lows, o): """ I think this has something to do with how many times you go in, might wanna leave it to the strats """ price = float(self.price) #print(nextTrade==price,nextTradeSeller==price) for i in range(2, self.entries + 1): if len(self.entryprices) > 0: avgentryprice = sum(self.entryprices) / len(self.entryprices) #if previous entry has been placed and current hasn't and other args are met if self.dentry[ "placedOrder" + str(i - 1) + self.chartnumber] and price < avgentryprice and float( price) < lows[-2] and float(price) < float( o) and not self.dentry["placedOrder" + str(i) + self.chartnumber]: self.dentry["placedOrder" + str(i) + self.chartnumber] = True #add these to dict print("trade number", str(i)) self.dentry["tradeEntries" + str(i) + self.chartnumber] += 1 #self.totalentries += 1 #I changed these from price to nextTrade self.dentry["orderPrice" + str(i) + self.chartnumber] = price #self.dentry["orderPrice" + str(i) + chartnumber] = self.nextTrade #altbuy = int(self.dentry["buy" + str(i) + chartnumber] / price) altbuy = int( self.dentry["buy" + str(i) + self.chartnumber] / self.nextTrade) #self.availablebase -= altbuy * price self.availablebase -= altbuy * self.nextTrade altbuy -= altbuy * .001 self.amtofalt += altbuy ###HOW LONG TO WE WANT ENTRYPRICES TO BE?? #self.entryprices.append(price) self.entryprices.append(self.nextTrade) if self.graphics: self.graph.buy( self.masterDick["currentPrice" + self.chartnumber], self.masterDick["count" + self.chartnumber], self.chartnumber, i) #print("Fun:",self.amtofalt) print("Buy" + str(i), self.dentry["buy" + str(i) + self.chartnumber]) break def checkCross(self, price): #if moving avgs cross if (self.masterDick["count" + self.chartnumber] > 0): ma5list = self.masterDick["ma5list" + self.chartnumber] ma15list = self.masterDick["ma15list" + self.chartnumber] self.masterDick["ma5lower" + self.chartnumber] = ma15list[ -2] <= ma5list[-2] and ma15list[-1] > ma5list[-1] self.masterDick["ma5higher" + self.chartnumber] = ma15list[ -2] >= ma5list[-2] and ma15list[-1] < ma5list[-1] #This buys or sells due to a cross in the MAs, you'll want to #move this out of this if statement eventually bcoz it will #evaluate other factors as well #self.evaluatePositions(chartnumber) if (self.masterDick["ma5lower" + self.chartnumber] or self.masterDick["ma5higher" + self.chartnumber]): self.masterDick[ "crossPointA" + self.chartnumber], self.masterDick[ "crossPointB" + self.chartnumber] = self.indicators.MACross( ma5list[-2:], ma15list[-2:], self.masterDick["crossPointA" + self.chartnumber], price) self.masterDick["crosstime" + self.chartnumber] = True #evaluate the position of a chart only when it's gained an item. use smaller chart changes #to influence current buys in the bigger charts ''' def evaluatePositions(self, price, nextTrade, lows, high, highs, k, o, rsi, chartnumber, t, nextTradeSeller=None): prices = self.masterDick["prices" + chartnumber] if((self.masterDick["currentPrice" + chartnumber] < self.ma5) and (self.masterDick["currentPrice" + chartnumber] < self.ma15)): if(self.masterDick["currentPrice" + chartnumber] > prices[-2] or self.masterDick["currentPrice" + chartnumber] == prices[-2]): #print("BUY") pass #you need to make sure the btc in your account matches up with availablebtc #could have rounding errors and say you have more than you actually do, shouldn't be significant tho- #especially if you check your bitcoin funds after every sell if not self.dentry["placedOrder1" + chartnumber]: for y in range(1, self.entries + 1): self.dentry["buy" + str(y) + chartnumber] = self.availablebase / float(self.entries) #print("vbuy" + str(y),self.dentry["buy" + str(y) + chartnumber]) #trying moving entrycalc outside strats, check history to see if entrycalc is same in each self.entrycalc(self, price, chartnumber, nextTrade, lows, o) if self.strat > 0: eval(self.stratlist[self.strat]) #error check if self.availablebase < 0: print("F**K BITCOIN IS IN THE NEGATIVES-ERROR") print(str(self.availablebase)) ''' ######Strategies######################################################## #THIS ONE IS F*****G GREAT FOR FUNBTC def firstone(self, lows, highs, k, o): #, nextTradeSeller): price = float(self.price) prices = self.masterDick["prices" + self.chartnumber] #self.entrycalc(price, chartnumber, nextTrade, lows, o) #buy/sell #need 2 change stochastic #just added rsi for testing #print(self.price,self.dentry["orderPrice1" + self.chartnumber]) #print(type(self.dentry["orderPrice1" + self.chartnumber]), "butt") if price < prices[-2] and prices[-2] < prices[ -3] and self.high < highs[-2] and k[-1] < self.masterDick[ "fast" + self.chartnumber] and not self.dentry[ "placedOrder1" + self.chartnumber]: # and rsi < 50: self.buy() elif price > self.ma15 and price > highs[-2] and self.dentry[ "placedOrder1" + self. chartnumber]: # and (self.dentry["orderPrice1" + self.chartnumber] * 1.001 < price * 1.001 or price < self.bigma): self.sell() ############################################################################################################## ############################################################################################################## def secondone(self, lows, highs, k, o): price = float(self.price) prices = self.masterDick["prices" + self.chartnumber] #self.entrycalc(price, chartnumber, nextTrade, lows, o) #buy/sell #need 2 change stochastic #just added rsi for testing if price < prices[-2] and prices[-2] < prices[-3] and prices[ -3] < prices[-4] and self.high < highs[-2] and k[ -1] < self.masterDick[ "fast" + self.chartnumber] and not self.dentry[ "placedOrder1" + self.chartnumber]: # and rsi < 50: self.buy() elif price > self.ma15 and price > highs[-2] and self.dentry[ "placedOrder1" + self.chartnumber]: self.sell() #BTCUSDT on 12 hour interval def thirdone(self): #setting vars to simple names to reduce clutter price = float(self.price) rsi = self.masterDick["rsi" + self.chartnumber] #could do this or put something in botIndicators to check? - Maybe not if len(self.masterDick["prices" + self.chartnumber]) > self.bollingerper + 2: bws = self.masterDick["bandwidth" + self.chartnumber] if self.bandwidth < 14 and price > self.bolup and not self.dentry[ "placedOrder1" + self.chartnumber]: self.buy() #bandwidth less than last one AND rsi/stoch calmed down AND price is greater or smaller than last one elif self.bandwidth < bws[-2] and rsi > 50 and self.dentry[ "placedOrder1" + self.chartnumber]: self.sell()
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")