示例#1
0
class BotStrategy(object):
    def __init__(self):
        #connect; read and write to db
        self.TradeDatabase = TradeDatabase()
        self.TradeDatabase.connect()
        #amount to trade (capital):
        self.amountInUSD = 300
        #prices information
        self.prices = []
        self.currentPrice = ""
        #graph and indicators
        self.output = BotLog()
        self.indicators = BotIndicators()
        #self.graphdataPoints = []
        self.dataDate = ""
        self.SMA = ""
        self.CResistance = 0.0
        self.EMA9 = []
        self.MACD = []
        #trade details
        self.tradePlaced = []
        self.typeOfTrade = []
        self.cumulatedProfits = 0.0
        #wins and loses
        self.numofwins = 0
        self.numofloses = 0

    def tick(self):
        #only call API once
        try:
            self.APIlist = FinexAPI.ticker()
        except:
            try:
                time.sleep(10)
                self.APIlist = FinexAPI.ticker()
            except:
                try:
                    time.sleep(10)
                    self.APIlist = FinexAPI.ticker()
                except:
                    pass

        #date
        self.dataDate = datetime.datetime.fromtimestamp(
            int(float(
                self.APIlist["timestamp"]))).strftime('%Y-%m-%d %H:%M:%S')
        #prices
        self.currentPrice = float(self.APIlist["last_price"])
        #insert into SQL db
        self.TradeDatabase.insertStatement01(self.dataDate, self.currentPrice)
        #load datelist, prices from db
        self.datelist, self.prices = self.TradeDatabase.readtolist01()

        #indicators
        self.SMA = self.indicators.movingAverage(self.prices, 200)
        self.CResistance = self.indicators.trendline(self.prices)
        self.RSI = self.indicators.RSI(self.prices)

        #macd indicators & insert into DB
        if len(self.prices) > 26:  #get macd indicators
            emaslow, emafast, self.MACD = self.indicators.MACD(self.prices)
            self.EMA9 = self.indicators.EMA(self.MACD, 9)

        #Insert all to DB (no need for macd and ema9 - they are self generated and contained lists)
        self.TradeDatabase.insertStatement02(self.dataDate, self.CResistance,
                                             self.SMA, self.RSI)

        #graph
        #archaic : self.graphdataPoints.append({'date':self.dataDate, 'price': self.currentPrice, 'trend': self.CResistance, 'SMA': self.SMA, 'RSI':self.RSI, 'short': np.nan, 'long':np.nan,'closedLong':np.nan,'closedShort':np.nan})

        #graph with pdDataFrame obj
        self.graphdataPoints = self.TradeDatabase.frameit()

        #if/else indicators
        self.tradePlaced, self.typeOfTrade, self.cryptoAmount = self.TradeDatabase.readtolist02(
        )
        self.tradePlaced = [i for i in self.tradePlaced
                            if i * 0 == 0]  #only get the numbers
        self.typeOfTrade = [i for i in self.typeOfTrade
                            if i != None]  #only get the strings
        self.cryptoAmount = [i for i in self.cryptoAmount
                             if i * 0 == 0]  #only get the numbers

        #print timestamp and price to cmd line for logging purposes
        self.output.log(self.dataDate + "\tPrice: " + str(self.currentPrice) +
                        "\tMoving Average: " + str(self.SMA))
        #print numofwins, numofloses and cumulated profits to cmd line
        self.cumulatedProfits, self.numofwins, self.numofloses = self.TradeDatabase.cumwinloss(
        )
        self.output.log(
            "No. of Wins: {}, No. of Loses: {}, Cumulated Profits: {}".format(
                self.numofwins, self.numofloses, self.cumulatedProfits))

    #decide when to buy and when to sell - MACD strat + 200 period SMA  - maybe can implement stops (?) GOLDEN GRAIL!!!
    def evaluatePositions(self):
        try:
            if len(self.tradePlaced) == 0 or self.tradePlaced[-1] == 0:
                #if market is bullish - only take buy signals
                if self.currentPrice > self.SMA:
                    #MACD indicator - when EMA9 crosses higher than the MACD curve - buy
                    if (len(self.MACD) > 1) and (
                            self.EMA9[-2] < self.MACD[-2]) and (self.EMA9[-1] >
                                                                self.MACD[-1]):
                        self.buyposition()
                #elif market is bearish - only take sell signals
                elif self.currentPrice < self.SMA:
                    #MACD indicator - when EMA9 crosses lower than the MACD curve - sell
                    if (len(self.MACD) > 1) and (
                            self.EMA9[-2] > self.MACD[-2]) and (self.EMA9[-1] <
                                                                self.MACD[-1]):
                        self.sellposition()
            elif self.typeOfTrade[-1] == "long":
                #MACD indicator - when EMA9 crosses lower than the MACD curve - sell
                if ((self.EMA9[-2] > self.MACD[-2])
                        and (self.EMA9[-1] < self.MACD[-1])
                        and (self.cryptoAmount[-1] * self.currentPrice >
                             0.95 * self.amountInUSD)):
                    self.closeLong()
                #if bullish trend ends and you are stuck, immediately sell to recoup loss
                elif self.currentPrice < self.SMA:
                    self.closeLong()
            elif self.typeOfTrade[-1] == "short":
                #MACD indicator - when EMA9 crosses higher than the MACD curve - buy
                if ((self.EMA9[-2] < self.MACD[-2])
                        and (self.EMA9[-1] > self.MACD[-1])
                        and (0.996 * self.amountInUSD) > 0.95 *
                    (self.currentPrice * self.cryptoAmount[-1])):
                    self.closeShort()
                #if bearish trend ends and you are stuck, immediately buy to recoup loss
                elif self.currentPrice > self.SMA:
                    self.closeShort()
        except TypeError:
            pass

    #buy and sell positions
    def buyposition(self):
        amountincryptos = 0.996 * float(self.amountInUSD) / self.currentPrice
        self.output.log("BUY {} Cryptos at {}USD".format(
            amountincryptos, self.amountInUSD))
        self.TradeDatabase.insertStatement03(self.dataDate, amountincryptos,
                                             self.currentPrice, 1, "long")

    def sellposition(self):
        amountincryptos = float(self.amountInUSD) / self.currentPrice
        self.output.log("SELL {} Cryptos at {}USD".format(
            amountincryptos, self.amountInUSD))
        self.TradeDatabase.insertStatement04(self.dataDate, amountincryptos,
                                             self.currentPrice, 1, "short")

    def closeLong(self):
        netProfit = self.cryptoAmount[-1] * self.currentPrice - self.amountInUSD
        self.TradeDatabase.insertStatement05(self.dataDate, netProfit)
        self.cumulatedProfits, self.numofwins, self.numofloses = self.TradeDatabase.cumwinloss(
        )
        self.TradeDatabase.insertStatement06(self.dataDate, self.currentPrice,
                                             0)
        if netProfit >= 0:
            self.output.log(
                "Closed LONG ORDER at {}".format(self.currentPrice) +
                self.output.color("\tNet Profit: {}".format(netProfit),
                                  'green') +
                "\tCumulated Profits: {}".format(self.cumulatedProfits))
            self.output.log(
                "No. of Wins: {}, No. of Loses: {}, Win Rate: {}".format(
                    self.numofwins, self.numofloses,
                    round(self.numofwins / (self.numofwins + self.numofloses),
                          2)))
        else:
            self.output.log(
                "Closed LONG ORDER at {}".format(self.currentPrice) +
                self.output.color("\tNet Profit: {}".format(netProfit), 'red')
                + "\tCumulated Profits: {}".format(self.cumulatedProfits))
            self.output.log(
                "No. of Wins: {}, No. of Loses: {}, Win Rate: {}".format(
                    self.numofwins, self.numofloses,
                    round(self.numofwins / (self.numofwins + self.numofloses),
                          2)))

    def closeShort(self):
        netProfit = (0.996 * self.amountInUSD) - (self.currentPrice *
                                                  self.cryptoAmount[-1])
        self.TradeDatabase.insertStatement05(self.dataDate, netProfit)
        self.cumulatedProfits, self.numofwins, self.numofloses = self.TradeDatabase.cumwinloss(
        )
        self.TradeDatabase.insertStatement07(self.dataDate, self.currentPrice,
                                             0)
        if netProfit >= 0:
            self.output.log(
                "Closed SHORT ORDER at {}".format(self.currentPrice) +
                self.output.color("\tNet Profit: {}".format(netProfit),
                                  'green') +
                "\tCumulated Profits: {}".format(self.cumulatedProfits))
            self.output.log(
                "No. of Wins: {}, No. of Loses: {}, Win Rate: {}".format(
                    self.numofwins, self.numofloses,
                    round(self.numofwins / (self.numofwins + self.numofloses),
                          2)))
        else:
            self.output.log(
                "Closed SHORT ORDER at {}".format(self.currentPrice) +
                self.output.color("\tNet Profit: {}".format(netProfit), 'red')
                + "\tCumulated Profits: {}".format(self.cumulatedProfits))
            self.output.log(
                "No. of Wins: {}, No. of Loses: {}, Win Rate: {}".format(
                    self.numofwins, self.numofloses,
                    round(self.numofwins / (self.numofwins + self.numofloses),
                          2)))
class BotStrategy():
    def __init__(self, pair):
        if (not config.CONFIG["VERBOSE"]):
            print("Calculating indicators")
        self.pair = pair
        self.output = BotLog()
        self.path = config.CONFIG['PATH']
        self.prices = []
        self.closes = []
        self.trades = []
        self.movingAVG = []
        self.momentum = []
        self.RSI = []
        self.currentPrice = ""
        self.currentClose = ""
        self.numSimulTrades = 1
        self.indicators = BotIndicators()
        self.graph_data = {
            "date": [],
            "movingAverage": [],
            "momentum": [],
            "RSI": []
        }

    def tick(self, candlestick):
        self.currentPrice = float(candlestick.priceAverage)
        self.currentClose = float(candlestick.close)
        self.movingAVG = self.indicators.movingAverage(self.prices, 15)
        self.momentum = self.indicators.momentum(self.closes, 15)
        self.RSI = self.indicators.RSI(self.prices, 15)
        self.MACD = self.indicators.MACD(self.prices)
        self.prices.append(self.currentPrice)
        self.closes.append(self.currentClose)
        self.output.log("Price: " + str(candlestick.priceAverage) +
                        "\tMoving Average: " + str(self.movingAVG))

        self.evaluatePositions(candlestick)
        self.updateOpenTrades()
        self.showPositions()

    def evaluatePositions(self, candlestick):
        openTrades = []

        for trade in self.trades:
            if (trade.status == "OPEN"):
                openTrades.append(trade)

        # Make sure NoneType is handled
        if (self.movingAVG is None):
            self.movingAVG = 0

        if (len(openTrades) < self.numSimulTrades):
            if (self.currentPrice < self.movingAVG):
                self.trades.append(BotTrade(self.currentPrice, stopLoss=.0001))

        for trade in openTrades:
            if (self.currentPrice > self.movingAVG):
                trade.close(self.currentPrice)

        self.graph_data['date'].append(candlestick.date.astype(int))
        self.graph_data['movingAverage'].append(self.movingAVG)
        self.graph_data['momentum'].append(self.momentum)
        self.graph_data['RSI'].append(self.RSI)

        df = pd.DataFrame(self.graph_data)
        df.to_csv(
            util.os.path.join(
                self.path, 'data/' + self.pair.replace('/', '-') + "/" +
                'indicators.csv'))

    def updateOpenTrades(self):
        for trade in self.trades:
            if (trade.status == "OPEN"):
                trade.tick(self.currentPrice)

    def showPositions(self):
        for trade in self.trades:
            trade.showTrade()
示例#3
0
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
示例#4
0
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'
            })
示例#5
0
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()
示例#6
0
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
示例#7
0
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")