class BotCandlestick(object):
    def __init__(self, period=300,open=None,close=None,high=None,low=None,priceAverage=None):
        self.current = None
        self.open = open
        self.close = close
        self.high = high
        self.low = low
        self.startTime = time.time()
        self.period = period
        self.output = BotLog()
        self.priceAverage = priceAverage

    def tick(self,price):
        self.current = float(price)
        if (self.open is None):
            self.open = self.current

        if ( (self.high is None) or (self.current > self.high) ):
            self.high = self.current

        if ( (self.low is None) or (self.current < self.low) ):
            self.low = self.current

        if ( time.time() >= ( self.startTime + self.period) ):
            self.close = self.current
            self.priceAverage = ( self.high + self.low + self.close ) / float(3)

        self.output.log("Open: "+str(self.open)+"  Close: "+str(self.close)+"  High: "+str(self.high)+"  Low: "+str(self.low)+"  Current: "+str(self.current))

    def isClosed(self):
        if (self.close is not None):
            return True
        else:
            return False
Exemplo n.º 2
0
class BotCandlestick(object):
    def __init__(self, period=None, open=None, close=None, high=None, low=None, typical_price=None):
        """"""
        self.output = BotLog()
        self.current = None
        self.open = open
        self.close = close
        self.high = high
        self.low = low
        self.period = period
        self.startTime = time.time()
        self.typical_price = typical_price

    def tick(self, price, **kwargs):
        self.current = float(price)

        # If it's a brand new price the open price hasn't been set yet
        # then the current price is the open price.
        if self.open is None:
            self.open = self.current

        # If it's a brand new price the high price hasn't been set yet,
        # or if the current price is greater than the current high
        # then set this current price as the high.
        if (self.high is None) or (self.current > self.high):
            self.high = self.current

        # If it's a brand new price the low price hasn't been set yet,
        # or if the current price is less than the current low
        # then set this current price as the low.
        if (self.low is None) or (self.current < self.low):
            self.low = self.current

        # If the current time is at or after the start time plus the period
        # (i.e. this will be the last price that goes into this candlestick before
        # it is added to the list of past candlesticks) then set this current price
        # as the closing price.
        if time.time() >= (self.startTime + (self.period * 60)):
            self.close = self.current
            # Determine the typical price over entire period of the candlestick.
            self.typical_price = (self.high + self.low + self.close) / float(3)

        # Show OHLC data on each tick
        self.output.log(" Open: " + str(self.open) +
                        " Close: " + str(self.close) +
                        " High: " + str(self.high) +
                        " Low: " + str(self.low) +
                        " Current: " + str(self.current))

        statsd.histogram('candlestick.price.close', self.close, tags=['candlestick.price.close', 'bot_name:{}.bot_id:{}'.format(BOT_NAME, BOT_ID)])
        statsd.histogram('candlestick.price.high', self.high, tags=['candlestick.price.high', 'bot_name:{}.bot_id:{}'.format(BOT_NAME, BOT_ID)])
        statsd.histogram('candlestick.price.low', self.low, tags=['candlestick.price.low', 'bot_name:{}.bot_id:{}'.format(BOT_NAME, BOT_ID)])
        statsd.histogram('candlestick.price.typical_price', self.typical_price, tags=['candlestick.price.typical_price', 'bot_name:{}.bot_id:{}'.format(BOT_NAME, BOT_ID)])

    def isClosed(self):
        if self.close is not None:
            return True
        else:
            return False
Exemplo n.º 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 = 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()
Exemplo n.º 4
0
class BotPosition(object):
    def __init__(self,
                 current_price,
                 start_time,
                 short,
                 takeProfit=0,
                 stopLoss=0):
        self.output = BotLog()
        self.status = "OPEN"
        self.entry_price = current_price
        self.exit_price = 0.
        self.start_time = start_time
        self.exitTime = 0.
        self.stopLoss = stopLoss
        self.takeProfit = takeProfit
        self.short = short
        if short:
            self.output.log("OPEN SELL : " + str(self.entry_price))
        else:
            self.output.log("OPEN BUY : " + str(self.entry_price))

    def close(self, current_price, endTime):
        self.status = "CLOSED"
        self.exit_price = current_price
        self.exitTime = endTime
        if self.short:
            self.output.log("CLOSE BUY : " + str(current_price) + "\n")
        else:
            self.output.log("CLOSE SELL : " + str(current_price) + "\n")

    def tick(self, current_price, candlestick):
        if self.stopLoss != 0:
            if self.short and current_price > self.stopLoss:
                self.close(current_price, candlestick.start_time)
                return
            elif not (self.short) and current_price < self.stopLoss:
                self.close(current_price, candlestick.start_time)
                return
        if self.takeProfit != 0:
            if self.short and current_price < self.takeProfit:
                self.close(current_price, candlestick.start_time)
                return
            elif not (self.short) and current_price > self.takeProfit:
                self.close(current_price, candlestick.start_time)
                return

    def showTrade(self):
        tradeStatus = "Entry Price: " + str(
            self.entry_price) + " Status: " + str(
                self.status) + " Exit Price: " + str(self.exit_price)

        if (self.status == "CLOSED"):
            tradeStatus = tradeStatus + " Profit: "
            if (self.exit_price > self.entry_price):
                tradeStatus = tradeStatus + "\033[92m"
            else:
                tradeStatus = tradeStatus + "\033[91m"

            tradeStatus = tradeStatus + str(self.exit_price -
                                            self.entry_price) + "\033[0m"
Exemplo n.º 5
0
class BotTrade(object):
	def __init__(self,currentPrice,stopLoss=0):
		self.output = BotLog()
		self.status = "OPEN"
		self.entryPrice = currentPrice
		self.exitPrice = ""
		self.output.log("Trade opened")
		if (stopLoss):
			self.stopLoss = currentPrice - stopLoss
	#shows closing price
	def close(self,currentPrice):
		self.status = "CLOSED"
		self.exitPrice = currentPrice
		self.output.log("Trade closed")
    #shows previous ticks
	def tick(self, currentPrice):
		if (self.stopLoss):
			if (currentPrice < self.stopLoss):
				self.close(currentPrice)
Exemplo n.º 6
0
class BotTrade(object):
	def __init__(self,currentPrice,stopLoss=0):
		self.output = BotLog()
		self.status = "OPEN"
		self.currentPrice = currentPrice
		self.entryPrice = currentPrice
		self.exitPrice = 0
		self.output.log("Trade opened")
		if (stopLoss):
			self.stopLoss = currentPrice - stopLoss
	
	def close(self,currentPrice):
		self.status = "CLOSED"
		self.exitPrice = currentPrice
		self.output.log("Trade closed")
		#trade_end_time.append(datetime.fromtimestamp(int(time.time())).strftime('%Y-%m-%d %H:%M:%S')) #
		#total.append(sum(ar_pro))


	def tick(self, currentPrice):
		if (self.stopLoss):
			if (currentPrice < self.stopLoss):
				self.close(currentPrice)

	def showTrade(self):
		tradeStatus = "Entry Price: "+str(self.entryPrice)+" Status: "+str(self.status)+" Exit Price: "+str(self.exitPrice)

		if (self.status == "CLOSED"):
			tradeStatus = tradeStatus + " Profit: "
			if (self.exitPrice > self.entryPrice):
				tradeStatus = tradeStatus + "\033[92m"
			else:
				tradeStatus = tradeStatus + "\033[91m"

			tradeStatus = tradeStatus+str(self.exitPrice - self.entryPrice)+"\033[0m"
			ar_pro.append(self.exitPrice - self.entryPrice)


		self.output.log(tradeStatus)
		self.output.log("SubTotal: " + str((sum(ar_pro))))
		trade_end_time.append(time.time())#(datetime.fromtimestamp(int(time.time())).strftime('%Y-%m-%d %H:%M:%S')) #
		total.append(sum(ar_pro))

	
	def export():

		filename = open("export.csv",'w')
		#for i in total:
		#	print('{:.20f}'.format(i[0]) + ',' + str(i[1]) ,file=filename)

		for i in range(len(trade_end_time)):
		    filename.write("{},{}\n".format(trade_end_time[i],total[i]))
Exemplo n.º 7
0
class BotTrade(object):
    def __init__(self, currentPrice, stopLossEdge):
        self.output = BotLog()
        self.status = "OPEN"
        self.entryPrice = currentPrice
        self.exitPrice = 0
        self.pnl = 0
        self.side = "Buy"
        self.entryTime = datetime.datetime.now()
        self.exitTime = ""
        self.output.log("Trade opened")
        self.stopLoss = currentPrice - stopLossEdge

    def close(self, currentPrice):
        self.exitTime = datetime.datetime.now()
        self.status = "CLOSED"
        self.side = "Sell"
        self.exitPrice = currentPrice
        self.output.log("Trade closed")
        self.pnl = self.exitPrice - self.entryPrice

        tradeStatus = "Entry Price: " + str(round(self.entryPrice, 3)) + " Status: " + \
                      str(self.status) + " Exit Price: " + str(round(self.exitPrice, 3))
        tradeStatus = tradeStatus + " Pnl: " + str(round(self.pnl, 3))
        if (self.pnl > 0):
            tradeStatus = crayons.green(tradeStatus)
        else:
            tradeStatus = crayons.red(tradeStatus)
        self.output.log(tradeStatus)

    def tick(self, currentPrice):
        if (self.stopLoss > 0):
            if (currentPrice <= self.stopLoss):
                self.output.log(crayons.magenta("Exit By Stop Loss"))
                self.close(currentPrice)

    def showStatus(self):
        if (self.status == "OPEN"):
            tradeStatus = "Entry Price: " + str(round(
                self.entryPrice, 3)) + " Status: " + str(self.status)
            tradeStatus = crayons.yellow(tradeStatus)
            self.output.log(tradeStatus)
Exemplo n.º 8
0
class BotTrade(object):
    def __init__(self, currentPrice, startTime, stopLoss=0):
        self.output = BotLog()
        self.status = "OPEN"
        self.entryPrice = currentPrice
        self.exitPrice = 0.
        self.startTime = startTime
        self.exitTime = 0.
        self.stopLoss = stopLoss
        self.output.log("Trade opened: " + str(self.entryPrice) +
                        " StopLoss: " + str(self.stopLoss))
        # if (stopLoss):
        # self.stopLoss = currentPrice - stopLoss

    def close(self, currentPrice, endTime):
        self.status = "CLOSED"
        self.exitPrice = currentPrice
        self.exitTime = endTime
        # self.output.log("Trade closed")

    def tick(self, currentPrice, candlestick):
        if (self.stopLoss != 0):
            if (currentPrice < self.entryPrice - self.stopLoss):
                print("vendu par stopLoss")
                self.close(currentPrice, candlestick.startTime)

    def showTrade(self):
        tradeStatus = "Entry Price: " + str(
            self.entryPrice) + " Status: " + str(
                self.status) + " Exit Price: " + str(self.exitPrice)

        if (self.status == "CLOSED"):
            tradeStatus = tradeStatus + " Profit: "
            if (self.exitPrice > self.entryPrice):
                tradeStatus = tradeStatus + "\033[92m"
            else:
                tradeStatus = tradeStatus + "\033[91m"

            tradeStatus = tradeStatus + str(self.exitPrice -
                                            self.entryPrice) + "\033[0m"
Exemplo n.º 9
0
class BotTrade(object):
    def __init__(self, currentPrice, stopLoss=0):
        self.output = BotLog()
        self.status = "OPEN"
        self.entryPrice = currentPrice
        self.exitPrice = ""
        self.output.log("Trade opened")
        if (stopLoss):
            self.stopLoss = currentPrice - stopLoss

    def close(self, currentPrice):
        self.status = "CLOSED"
        self.exitPrice = currentPrice
        self.output.log("Trade closed")

    def tick(self, currentPrice):
        if (self.stopLoss):
            if (currentPrice < self.stopLoss):
                self.close(currentPrice)

    def showTrade(self):
        tradeStatus = "Entry Price: " + str(
            self.entryPrice) + " Status: " + str(
                self.status) + " Exit Price: " + str(self.exitPrice)
        if (self.status == "CLOSED"):
            tradeStatus = tradeStatus + " Profit: "
            if (self.exitPrice > self.entryPrice):
                tradeStatus = tradeStatus + "\033[92m"
            else:
                tradeStatus = tradeStatus + "\033[91m"
            tradeStatus = tradeStatus + str(self.exitPrice -
                                            self.entryPrice) + "\033[0m"
        self.output.log(tradeStatus)
Exemplo n.º 10
0
class BotChart(object):
    def __init__(self, functions, pair):
        self.pair = pair
        self.output = BotLog()
        self.conn = functions.poloniex_conn

    def getHistorical(self, period, startTime, endTime):
        self.period = period
        self.startTime = startTime
        self.endTime = endTime

        if not os.path.exists("Data/" + self.pair + "_" + str(startTime) +
                              "_" + str(endTime) + "_" + str(self.period) +
                              ".pkl"):
            self.output.log("Getting chart data (API)...")
            while True:
                try:
                    self.data = pd.DataFrame(
                        self.conn.getHistoricTicks(self.pair, self.startTime,
                                                   self.endTime, self.period))
                    self.data.to_pickle("Data/" + self.pair + "_" +
                                        str(startTime) + "_" + str(endTime) +
                                        "_" + str(self.period) + ".pkl")
                    break
                except Exception as e:
                    self.output.log("Error: " + str(e))
                    time.sleep(20)
                    continue
        else:
            self.output.log("Getting chart data (Local)...")
            self.data = self.__getDataFromFile("Data/" + self.pair + "_" +
                                               str(startTime) + "_" +
                                               str(endTime) + "_" +
                                               str(self.period) + ".pkl")

    def getPoints(self):
        return self.data

    def __getDataFromFile(self, path):

        return pd.read_pickle(path)

    def getNext(self):
        self.output.log("Getting next tick...")
        return self.conn.getNextTick(self.pair)
Exemplo n.º 11
0
def main(argv):

    pairs = []

    try:
        opts, args = getopt.getopt(argv, "hm:p:c:",
                                   ["mode=", "period=", "currency="])
    except getopt.GetoptError:
        print(
            "bot.py -m <backtest | paper | live> -p <period length in sec> -c <currency pair>"
        )
        sys.exit(2)

    for opt, arg in opts:
        if opt == '-h':
            print(
                "bot.py -m <backtest | paper | live> -p <period length in sec> -c <currency pair>"
            )
            sys.exit()
        elif opt in ("-m", "--mode"):
            if (arg == "backtest"):
                mode = arg
            elif (arg == "paper"):
                mode = arg
            elif (arg == "live"):
                mode = arg
            else:
                print("Requires mode to be 'backtest', 'paper' or 'live'")
                sys.exit(2)
        elif opt in ("-p", "--period"):
            if (int(arg) in [300, 900, 1800, 7200, 14400, 86400]):
                period = int(arg)
            else:
                print(
                    "Requires periods to be 300, 900, 1800, 7200, 14400, or 86400 second increments"
                )
                sys.exit(2)
        elif opt in ("-c", "--currency"):
            pairs.append(arg)

    start_time = time.time()

    output = BotLog()

    exchanges = ["poloniex"]
    #pairs = ["USDT_BTC",  "USDT_ETH", "USDT_LTC", "USDT_ZEC"]
    #modes = ["RSI"]
    #modes = ["BBAND"]
    #modes = ["BBAND", "MACD2", "ALL"]
    algos = ["MACD"]
    #modes = ["RSI", "BBAND", "MACD2", "MACD", "DROP", "ALL"]

    charts = []
    strategies = []

    target = 0.04
    stoploss = 0.18

    for pair in pairs:
        for exchange in exchanges:
            if (mode == "backtest"):
                charts.append(BotChart(exchange, pair, period, mode, output))
            else:
                charts.append(
                    BotChart(exchange, pair, period, "warm", output,
                             int(time.time() - (24 * 60 * 60)),
                             int(time.time())))

            for algo in algos:
                if (mode == "backtest"):
                    strategies.append(
                        BotStrategy(exchange + "-" + pair, algo, pair, 1, 5000,
                                    0, int(5000 - 1), stoploss, target, mode,
                                    output))
                    # Parameters: max trades, initial fiat, initial holding, trade amount, stop loss, target
                else:
                    strategies.append(
                        BotStrategy(exchange + "-" + pair, algo, pair, 1, 5000,
                                    0, int(5000 - 1), stoploss, target, "warm",
                                    output))

    if (mode == "backtest"):
        for i, chart in enumerate(charts):
            for j, algo in enumerate(algos):
                strategy = strategies[len(algos) * i + j]
                for candlestick in chart.getPoints():
                    strategy.tick(candlestick)

                strategy.showPositions()
                strategy.showProfit()
                strategy.drawGraph()
                output.log("\n--- %s seconds ---" % (time.time() - start_time))
    else:
        candlesticks = []
        developingCandlestick = BotCandlestick(output, int(time.time()),
                                               period)

        for i, chart in enumerate(charts):
            for j, algo in enumerate(algos):

                strategy = strategies[len(algos) * i + j]

                for candlestick in chart.getPoints():
                    strategy.tick(candlestick)

                strategy.drawGraph()
                strategy.backtest = mode

                while True:
                    try:
                        developingCandlestick.tick(chart.getCurrentPrice())
                    except urllib.error.URLError:
                        time.sleep(int(period / 10))
                        developingCandlestick.tick(chart.getCurrentPrice())

                    if (developingCandlestick.isClosed()):
                        candlesticks.append(developingCandlestick)
                        strategy.tick(developingCandlestick)
                        developingCandlestick = BotCandlestick(
                            output, int(time.time()), period)

                        strategy.showPositions()
                        strategy.showProfit()
                        strategy.drawGraph()

                    time.sleep(int(period / 10))

    output.close()
Exemplo n.º 12
0
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()
Exemplo n.º 13
0
class BotStrategy(object):
    """
    This is the base Strategy object.
    Any new strategies must extend from this class to inherit key functionality.
    """
    _NAME = NotImplemented

    def __init__(self, pair, period):
        self.output = BotLog()
        self.prices = []
        self.trades = []
        self.current_price = NotImplemented

        self.period = period

        self.num_simultaneous_trades = 3  # Max number of simultaneous trades

    @classmethod
    def get_name(cls):
        return cls._NAME

    def tick(self, candlestick):
        raise NotImplementedError

    def evaluate_positions(self):
        raise NotImplementedError

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

    def show_positions(self):
        for trade in self.trades:
            trade.show_trade()

    def get_past_prices(self, candle_width, lookback):
        """Get past close prices
         :param candle_width Candlestick width in minutes, [1, 5, 15, 30, 60, 240, 1440, 10080, 21600]
         :param lookback How many past candlesticks to get.
         """
        logger.info("Fetching historical OHLC data for technical indicators...")
        ohlc = OHLC(pair='XXBTZUSD', interval=candle_width)
        if not ohlc['error']:
            past_data = ohlc['result'][self.pair][-lookback:]
        else:
            self.output.log(ohlc['error'])
            return

        # Make a list of past prices.
        past_typical_prices = []  # Arithmetic averages of the high, low, and closing prices for a given period.
        past_open_prices = []
        past_close_prices = []
        past_high_prices = []
        past_low_prices = []
        for data in past_data:
            typical_price = (float(data[2]) + float(data[3]) + float(data[4])) / 3
            past_typical_prices.append(typical_price)
            past_open_prices.append(float(data[1]))
            past_close_prices.append(float(data[4]))
            past_high_prices.append(float(data[2]))
            past_low_prices.append(float(data[3]))
        return past_typical_prices, past_open_prices, past_close_prices, past_high_prices, past_low_prices
Exemplo n.º 14
0
class poloniex_functions(object):
    def __init__(self):
        self.output = BotLog()
        self.conn = Poloniex('secret', 'key')

    def getBalance(self):
        while True:
            try:
                balData = {
                    k: v
                    for k, v in self.conn.returnBalances().items()
                    if float(v) != 0
                }
                break
            except Exception as e:
                self.output.log("Error: " + str(e))
                time.sleep(20)
                continue
        return balData

    def getCurrencies(self):
        while True:
            try:
                tickData = [k for k, v in self.conn.returnTicker().items()]
                break
            except Exception as e:
                self.output.log("Error: " + str(e))
                time.sleep(20)
                continue
        return tickData

    def getNextTick(self, pair):
        while True:
            try:
                tickData = self.conn.returnTicker()[pair]
                break
            except Exception as e:
                self.output.log("Error: " + str(e))
                time.sleep(20)
                continue
        return tickData

    def getHistoricTicks(self, pair, startTime, endTime, period):
        while True:
            try:
                result = self.conn.returnChartData(currencyPair=pair,
                                                   start=startTime,
                                                   end=endTime,
                                                   period=period)
                break
            except Exception as e:
                self.output.log("Error: " + str(e))
                time.sleep(20)
                continue
        return result

    def sell(self, pair, rate, amount):
        try:
            result = self.conn.sell(currencyPair=pair,
                                    rate=rate,
                                    amount=amount)
        except Exception as e:
            self.output.log("Error: " + str(e))
            time.sleep(20)
        return result

    def buy(self, pair, rate, amount):
        try:
            result = self.conn.buy(currencyPair=pair, rate=rate, amount=amount)
        except Exception as e:
            self.output.log("Error: " + str(e))
            time.sleep(20)
        return result

    def returnOrderTrades(self, orderId):
        while True:
            try:
                result = self.conn.returnOrderTrades(orderId)
                break
            except Exception as e:
                self.output.log("Error: " + str(e))
                time.sleep(20)
                continue
        return result

#==============================================================================
#     Returns your open orders for a given market, specified by the "currencyPair" POST parameter,
#     e.g. "BTC_XCP". Set "currencyPair" to "all" to return open orders for all markets. Sample output for single market:
#==============================================================================

    def returnOpenOrders(self, currencyPair='All'):
        while True:
            try:
                result = self.conn.returnOpenOrders(currencyPair)
                break
            except Exception as e:
                self.output.log("Error: " + str(e))
                time.sleep(20)
                continue
        return result

#==============================================================================
#     Cancels an order you have placed in a given market. Required POST parameter is "orderNumber". If successful, the method will return:
#==============================================================================

    def cancelOrder(self, orderNumber):
        while True:
            try:
                result = self.conn.cancelOrder(orderNumber)
                break
            except Exception as e:
                self.output.log("Error: " + str(e))
                time.sleep(20)
                continue
        return result

#==============================================================================
#     Cancels an order and places a new one of the same type in a single atomic transaction, meaning either both operations will succeed or both will fail.
#     Required POST parameters are "orderNumber" and "rate"; you may optionally specify "amount" if you wish to change
#     the amount of the new order. "postOnly" or "immediateOrCancel" may be specified for exchange orders, but will have no effect on margin orders.
#==============================================================================

    def moveOrder(self, orderNumber, rate, amount):
        while True:
            try:
                result = self.conn.moveOrder(orderNumber, rate, amount)
                break
            except Exception as e:
                self.output.log("Error: " + str(e))
                time.sleep(20)
                continue
        return result
Exemplo n.º 15
0
class BotStrategy(object):
    def __init__(self, backtest=True, forwardtest=True):
        self.output = BotLog()
        self.pair = shared.exchange['pair']
        self.coinsInOrder = shared.exchange['coinsInOrder']
        self.marketInOrder = shared.exchange['marketInOrder']
        self.trades = []
        self.currentPrice = ""
        self.currentClose = ""
        self.lowestAsk = 0.00
        self.highestBid = 0.00
        self.simultaneousTrades = 4
        self.tradeMultiplier = 0.1
        self.ticker = {}
        self.backTest = backtest
        self.forwardTest = forwardtest
        self.indicators = BotIndicators()

        self.candlesticks = []
        self.movingAverages = []
        self.movingAveragePeriod = shared.strategy['movingAverageLength']
        self.trueRanges = []
        self.averageTrueRanges = []

        # portfolio
        self.openOrders = []

        #api
        self.api = BotApi()

    def tick(self, candlestick):

        #strategy works on closed candles only
        if not candlestick.isClosed():
            return
        else:
            self.candlesticks.append(candlestick)

        self.currentPrice = candlestick.currentPrice
        ma = self.indicators.sma(self.candlesticks,
                                 shared.strategy['movingAverageLength'],
                                 'close')
        self.movingAverages.append(ma)

        tr = self.indicators.trueRange(self.candlesticks)
        self.trueRanges.append(tr)

        atr = self.indicators.averageTrueRange(self.trueRanges, 5)
        self.averageTrueRanges.append(atr)

        self.ticker = self.getTicker(self.pair)

        portfolioUpdated = self.updatePortfolio()
        # If live and portfolio not updated, we may run into some unpleasant issues.
        # Better stop here for now
        if not portfolioUpdated:
            return

        # Strategy needs at least 2 candles to work
        if len(self.candlesticks) > 1 and candlestick.isClosed():
            self.updateOpenTrades(self.pair)
            self.evaluatePositions()

    def evaluatePositions(self):

        openOrders = self.getOpenOrders(self.pair)
        '''
            Go Long (buy) if all of these are met:
                Previous  price is lower movingAverage
                Current price is higher than moving average
            Go short (sell) if:
                Previous price is higher than moving average
                Current Price is lower than moving average
        '''

        golong1 = self.candlesticks[-2].close < self.movingAverages[-1]
        golong2 = self.currentPrice > self.movingAverages[-1]
        goshort1 = self.candlesticks[-2].close > self.movingAverages[-1]
        goshort2 = self.currentPrice < self.movingAverages[-1]

        if golong1 and golong2 and len(openOrders) < self.simultaneousTrades:
            rate = float(self.ticker['lowestAsk'])
            total = (shared.exchange['nbMarket'] -
                     shared.exchange['marketInOrder']) * self.tradeMultiplier
            stoploss = self.currentPrice - self.averageTrueRanges[-1]
            takeprofit = self.currentPrice + (2 * self.averageTrueRanges[-1])
            self.buy(rate, total, self.candlesticks[-1].date, stoploss,
                     takeprofit)

        if goshort1 and goshort2 and len(openOrders) < self.simultaneousTrades:
            rate = float(self.ticker['highestBid'])
            amount = (shared.exchange['nbCoin'] -
                      shared.exchange['coinsInOrder']) * self.tradeMultiplier
            stoploss = self.currentPrice + self.averageTrueRanges[-1]
            takeprofit = self.currentPrice - (2 * self.averageTrueRanges[-1])
            self.sell(rate, amount, self.candlesticks[-1].date, stoploss,
                      takeprofit)

    def updateOpenTrades(self, pair):
        openOrders = self.getOpenOrders(pair)
        # TODO: implement not backtest
        for trade in openOrders:
            trade.tick(self.candlesticks[-1], self.candlesticks[-1].date)

    def getOpenOrders(self, pair):
        if not self.backTest and not self.forwardTest:
            orders = self.api.returnOpenOrders(pair)
            return orders
        else:
            openOrders = []
            for order in self.trades:
                if order.status == 'OPEN':
                    openOrders.append(order)
            return openOrders

    def getCurrentPrice(self, pair):
        if not self.backTest:
            return self.api.returnTicker(pair)['last']
        else:
            return self.candlesticks[-1].close

    def getTicker(self, pair):
        if not self.backTest:
            return self.api.returnTicker(pair)
        else:
            return {
                'last':
                self.currentPrice,
                'highestBid':
                self.currentPrice -
                self.currentPrice * shared.exchange['spreadPercentage'],
                'lowestAsk':
                self.currentPrice +
                self.currentPrice * shared.exchange['spreadPercentage']
            }

    def updatePortfolio(self):
        if not self.backTest and not self.forwardTest:
            try:
                portfolio = self.api.returnBalances()
                if shared.exchange['market'] in portfolio:
                    shared.exchange['nbMarket'] = float(
                        portfolio[shared.exchange['market']])
                else:
                    shared.exchange['nbMarket'] = 0.00
                if shared.exchange['coin'] in portfolio:
                    shared.exchange['nbCoin'] = float(
                        portfolio[shared.exchange['coin']])
                else:
                    shared.exchange['nbCoin'] = 0.00
                return True
            except Exception as e:
                self.output.warning("Error updating portfolio")
                print(e)
                return False
        else:
            return True

    def showPortfolio(self):
        if not self.backTest and not self.forwardTest:
            self.updatePortfolio()
        self.output.log(
            str(shared.exchange['nbMarket']) + " " +
            str(shared.exchange['market']) + ' - ' +
            str(shared.exchange['nbCoin']) + " " +
            str(shared.exchange['coin']))

    def buy(self, rate, total, date, stopLoss=0, takeProfit=0):
        amount = total / rate
        order = BotTrade('BUY',
                         rate=rate,
                         amount=amount,
                         total=total,
                         date=date,
                         stopLoss=stopLoss,
                         takeProfit=takeProfit,
                         backtest=self.backTest,
                         forwardtest=self.forwardTest)
        self.trades.append(order)

    def sell(self, rate, amount, date, stopLoss=0, takeProfit=0):
        total = rate * amount
        order = BotTrade('SELL',
                         rate=rate,
                         amount=amount,
                         total=total,
                         date=date,
                         stopLoss=stopLoss,
                         takeProfit=takeProfit,
                         backtest=self.backTest,
                         forwardtest=self.forwardTest)
        self.trades.append(order)
Exemplo n.º 16
0
class Trading_Gui:
    def __init__(self, top=None):
        '''This class configures and populates the toplevel window.
           top is the toplevel containing window.'''
        _bgcolor = '#d9d9d9'  # X11 color: 'gray85'
        _fgcolor = '#000000'  # X11 color: 'black'
        _compcolor = '#d9d9d9' # X11 color: 'gray85'
        _ana1color = '#d9d9d9' # X11 color: 'gray85'
        _ana2color = '#d9d9d9' # X11 color: 'gray85'
        self.root = root
        self.style = ttk.Style()
        self.style.theme_use("vista")
        self.style.configure('.',background=_bgcolor)
        self.style.configure('.',foreground=_fgcolor)
        self.style.configure('.',font="TkDefaultFont")
        self.style.map('.',background= [('selected', _compcolor), ('active',_ana2color)])
        self.strategy= []
        self.showChart = False
        self.startTrading = False
        self.closeAll= False
        self.stopRunning= False
        self.numberOfExecutions= 0
        self.numberOfTrades = 0
        self.output = BotLog()
        self.liveChartObject= []
        self.CheckVar = IntVar()

        top.geometry("990x518+446+155")
        top.title("Trading Gui")
        top.configure(background="#d9d9d9")

        self.TFrame1 = ttk.Frame(top)
        self.TFrame1.place(relx=0.01, rely=0.02, relheight=0.98, relwidth=0.11)
        self.TFrame1.configure(relief=GROOVE)
        self.TFrame1.configure(borderwidth="2")
        self.TFrame1.configure(relief=GROOVE)
        self.TFrame1.configure(width=95)

        self.Run = ttk.Button(self.TFrame1, command=self.main)
        self.Run.place(relx=0.11, rely=0.07, height=35, width=76)
        self.Run.configure(takefocus="")
        self.Run.configure(text='''Run''')
        self.Run.configure(width=76)

        self.Stop = ttk.Button(self.TFrame1, command=self.stopRun)
        self.Stop.place(relx=0.11, rely=0.17, height=35, width=76)
        self.Stop.configure(takefocus="")
        self.Stop.configure(text='''Stop''')
        self.Stop.configure(width=76)

        self.StartTrade = ttk.Button(self.TFrame1, command= self.useStartegy)
        self.StartTrade.place(relx=0.11, rely=0.27, height=35, width=76)
        self.StartTrade.configure(takefocus="")
        self.StartTrade.configure(text='''StartTrade''')
        self.StartTrade.configure(width=76)

        self.StopTrade = ttk.Button(self.TFrame1, command=self.stopTrade)
        self.StopTrade.place(relx=0.11, rely=0.37, height=35, width=76)
        self.StopTrade.configure(takefocus="")
        self.StopTrade.configure(text='''StopTrade''')
        self.StopTrade.configure(width=76)

        self.ShowChart = ttk.Button(self.TFrame1, command= self.chartOpen)
        self.ShowChart.place(relx=0.11, rely=0.47, height=35, width=76)
        self.ShowChart.configure(takefocus="")
        self.ShowChart.configure(text='''ShowChart''')
        self.ShowChart.configure(width=76)

        self.CloseChart = ttk.Button(self.TFrame1, command= self.chartClose)
        self.CloseChart.place(relx=0.11, rely=0.57, height=35, width=76)
        self.CloseChart.configure(takefocus="")
        self.CloseChart.configure(text='''CloseChart''')
        self.CloseChart.configure(width=76)

        self.ClosePos = ttk.Button(self.TFrame1, command= self.closeAllPositions)
        self.ClosePos.place(relx=0.11, rely=0.67, height=35, width=76)
        self.ClosePos.configure(takefocus="")
        self.ClosePos.configure(text='''ClosePos''')

        self.CheckVar.set(1)
        self.SaveTrades = Checkbutton(self.TFrame1, text="SaveHistory", variable=self.CheckVar, bg=_bgcolor)
        self.SaveTrades.place(relx=0.11, rely=0.77, height=35, width=80)

        self.Exit = ttk.Button(self.TFrame1, command= self.CloseWindow)
        self.Exit.place(relx=0.11, rely=0.9, height=35, width=76)
        self.Exit.configure(takefocus="")
        self.Exit.configure(text='''Exit''')
        self.Exit.configure(width=76)

        self.TFrame3 = Frame(top)
        self.TFrame3.place(relx=0.15, rely=0.05, relheight=0.1, relwidth=0.8)
        self.TFrame3.configure(relief=GROOVE)
        self.TFrame3.configure(borderwidth="2")
        self.TFrame3.configure(relief=GROOVE)
        self.TFrame3.configure(width=475)
        self.TFrame3.configure(takefocus="0")

        self.TLabel5 = Label(self.TFrame3)
        self.TLabel5.place(relx=0.01, rely=0.18, height=19, width=55)
        self.TLabel5.configure(font=('Helvetica', 8))
        self.TLabel5.configure(foreground="#075bb8")
        self.TLabel5.configure(relief=FLAT)
        self.TLabel5.configure(text='''Ticker:''')

        self.ticker = Entry(self.TFrame3)
        self.ticker.insert(END, str("USDT_BTC"))
        self.ticker.place(relx=0.07, rely=0.18, relheight=0.44, relwidth=0.09)
        self.ticker.configure(font=('Helvetica', 10))
        self.ticker.configure(background="white")
        self.ticker.configure(font="TkTextFont")
        self.ticker.configure(foreground="black")
        self.ticker.configure(highlightbackground="#d9d9d9")
        self.ticker.configure(highlightcolor="black")
        self.ticker.configure(insertbackground="black")
        self.ticker.configure(selectbackground="#c4c4c4")
        self.ticker.configure(selectforeground="black")
        self.ticker.configure(takefocus="0")

        self.TLabel4 = Label(self.TFrame3)
        self.TLabel4.place(relx=0.18, rely=0.18, height=19, width=75)
        self.TLabel4.configure(font=('Helvetica', 8))
        self.TLabel4.configure(foreground="#075bb8")
        self.TLabel4.configure(relief=FLAT)
        self.TLabel4.configure(text='''StopLossEdge:''')

        self.StopLossEdge = Entry(self.TFrame3)
        self.StopLossEdge.insert(END, str(10))
        self.StopLossEdge.place(relx=0.28, rely=0.18, relheight=0.44, relwidth=0.09)
        self.StopLossEdge.configure(font=('Helvetica', 10))
        self.StopLossEdge.configure(background="white")
        self.StopLossEdge.configure(font="TkTextFont")
        self.StopLossEdge.configure(foreground="black")
        self.StopLossEdge.configure(highlightbackground="#d9d9d9")
        self.StopLossEdge.configure(highlightcolor="black")
        self.StopLossEdge.configure(insertbackground="black")
        self.StopLossEdge.configure(selectbackground="#c4c4c4")
        self.StopLossEdge.configure(selectforeground="black")
        self.StopLossEdge.configure(takefocus="0")

        self.TLabel5 = Label(self.TFrame3)
        self.TLabel5.place(relx=0.39, rely=0.2, height=19, width=65)
        self.TLabel5.configure(font=('Helvetica', 8))
        self.TLabel5.configure(foreground="#075bb8")
        self.TLabel5.configure(relief=FLAT)
        self.TLabel5.configure(takefocus="0")
        self.TLabel5.configure(text='''EntryEdge:''')

        self.EntryEdge = Entry(self.TFrame3)
        self.EntryEdge.insert(END, str(1))
        self.EntryEdge.place(relx=0.47, rely=0.15, relheight=0.44, relwidth=0.09)
        self.EntryEdge.configure(background="white")
        self.EntryEdge.configure(font="TkTextFont")
        self.EntryEdge.configure(foreground="black")
        self.EntryEdge.configure(highlightbackground="#d9d9d9")
        self.EntryEdge.configure(highlightcolor="black")
        self.EntryEdge.configure(insertbackground="black")
        self.EntryEdge.configure(selectbackground="#c4c4c4")
        self.EntryEdge.configure(selectforeground="black")
        self.EntryEdge.configure(takefocus="0")

        self.TLabel6 = Label(self.TFrame3)
        self.TLabel6.place(relx=0.58, rely=0.2, height=19, width=85)
        self.TLabel6.configure(font=('Helvetica', 8))
        self.TLabel6.configure(foreground="#075bb8")
        self.TLabel6.configure(relief=FLAT)
        self.TLabel6.configure(takefocus="0")
        self.TLabel6.configure(text='''OpenTradesLimit:''')

        self.OpenTradesLimit = Entry(self.TFrame3)
        self.OpenTradesLimit.insert(END, str(4))
        self.OpenTradesLimit.place(relx=0.69, rely=0.15, relheight=0.44, relwidth=0.09)
        self.OpenTradesLimit.configure(background="white")
        self.OpenTradesLimit.configure(font="TkTextFont")
        self.OpenTradesLimit.configure(foreground="black")
        self.OpenTradesLimit.configure(highlightbackground="#d9d9d9")
        self.OpenTradesLimit.configure(highlightcolor="black")
        self.OpenTradesLimit.configure(insertbackground="black")
        self.OpenTradesLimit.configure(selectbackground="#c4c4c4")
        self.OpenTradesLimit.configure(selectforeground="black")
        self.OpenTradesLimit.configure(takefocus="0")


        self.TLabel7 = Label(self.TFrame3)
        self.TLabel7.place(relx=0.79, rely=0.2, height=19, width=85)
        self.TLabel7.configure(font=('Helvetica', 8))
        self.TLabel7.configure(foreground="#075bb8")
        self.TLabel7.configure(relief=FLAT)
        self.TLabel7.configure(takefocus="0")
        self.TLabel7.configure(text='''Maintenance:''')

        self.Maintenance = Entry(self.TFrame3)
        self.Maintenance.insert(END, str(1))
        self.Maintenance.place(relx=0.89, rely=0.15, relheight=0.44, relwidth=0.09)
        self.Maintenance.configure(background="white")
        self.Maintenance.configure(font="TkTextFont")
        self.Maintenance.configure(foreground="black")
        self.Maintenance.configure(highlightbackground="#d9d9d9")
        self.Maintenance.configure(highlightcolor="black")
        self.Maintenance.configure(insertbackground="black")
        self.Maintenance.configure(selectbackground="#c4c4c4")
        self.Maintenance.configure(selectforeground="black")
        self.Maintenance.configure(takefocus="0")


        self.style.configure('Treeview.Heading',  font="TkDefaultFont")
        self.Scrolledtreeview1 = ScrolledTreeView(top)
        self.Scrolledtreeview1.place(relx=0.15, rely=0.23, relheight=0.28, relwidth=0.6)
        self.Scrolledtreeview1.configure(columns="Col1 Col2 Col3 Col4 Col5")
        self.Scrolledtreeview1.configure(takefocus="0")
        self.Scrolledtreeview1.heading("#0",text="Id")
        self.Scrolledtreeview1.heading("#0",anchor="center")
        self.Scrolledtreeview1.column("#0",width="35")
        self.Scrolledtreeview1.column("#0",minwidth="20")
        self.Scrolledtreeview1.column("#0",stretch="1")
        self.Scrolledtreeview1.column("#0",anchor="w")
        self.Scrolledtreeview1.heading("Col1",text="Time")
        self.Scrolledtreeview1.heading("Col1",anchor="center")
        self.Scrolledtreeview1.column("Col1",width="150")
        self.Scrolledtreeview1.column("Col1",minwidth="20")
        self.Scrolledtreeview1.column("Col1",stretch="1")
        self.Scrolledtreeview1.column("Col1",anchor="w")
        self.Scrolledtreeview1.heading("Col2",text="Symbol")
        self.Scrolledtreeview1.heading("Col2",anchor="center")
        self.Scrolledtreeview1.column("Col2",width="80")
        self.Scrolledtreeview1.column("Col2",minwidth="20")
        self.Scrolledtreeview1.column("Col2",stretch="1")
        self.Scrolledtreeview1.column("Col2",anchor="w")
        self.Scrolledtreeview1.heading("Col3",text="Side")
        self.Scrolledtreeview1.heading("Col3",anchor="center")
        self.Scrolledtreeview1.column("Col3",width="80")
        self.Scrolledtreeview1.column("Col3",minwidth="20")
        self.Scrolledtreeview1.column("Col3",stretch="1")
        self.Scrolledtreeview1.column("Col3",anchor="w")
        self.Scrolledtreeview1.heading("Col4",text="Price")
        self.Scrolledtreeview1.heading("Col4",anchor="center")
        self.Scrolledtreeview1.column("Col4",width="80")
        self.Scrolledtreeview1.column("Col4",minwidth="20")
        self.Scrolledtreeview1.column("Col4",stretch="1")
        self.Scrolledtreeview1.column("Col4",anchor="w")
        self.Scrolledtreeview1.heading("Col5",text="Pnl")
        self.Scrolledtreeview1.heading("Col5",anchor="center")
        self.Scrolledtreeview1.column("Col5",width="80")
        self.Scrolledtreeview1.column("Col5",minwidth="20")
        self.Scrolledtreeview1.column("Col5",stretch="1")
        self.Scrolledtreeview1.column("Col5",anchor="w")


        self.menubar = Menu(top,font="TkMenuFont",bg='#bef7bb',fg=_fgcolor)
        top.configure(menu = self.menubar)

        self.Scrolledtreeview2 = ScrolledTreeView(top)
        self.style.configure("Scrolledtreeview2", font='helvetica 24')
        self.Scrolledtreeview2.place(relx=0.15, rely=0.61, relheight=0.32, relwidth=0.8)
        self.Scrolledtreeview2.configure(columns="Col1 Col2 Col3 Col4 Col5 Col6 Col7")
        self.Scrolledtreeview2.configure(takefocus="0")
        self.Scrolledtreeview2.heading("#0", text="Id")
        self.Scrolledtreeview2.heading("#0", anchor="center")
        self.Scrolledtreeview2.column("#0", width="35")
        self.Scrolledtreeview2.column("#0", minwidth="20")
        self.Scrolledtreeview2.column("#0", stretch="1")
        self.Scrolledtreeview2.column("#0", anchor="w")
        self.Scrolledtreeview2.heading("Col1", text="EntryTime")
        self.Scrolledtreeview2.heading("Col1", anchor="center")
        self.Scrolledtreeview2.column("Col1", width="150")
        self.Scrolledtreeview2.column("Col1", minwidth="20")
        self.Scrolledtreeview2.column("Col1", stretch="1")
        self.Scrolledtreeview2.column("Col1", anchor="w")
        self.Scrolledtreeview2.heading("Col2", text="ExitTime")
        self.Scrolledtreeview2.heading("Col2", anchor="center")
        self.Scrolledtreeview2.column("Col2", width="150")
        self.Scrolledtreeview2.column("Col2", minwidth="20")
        self.Scrolledtreeview2.column("Col2", stretch="1")
        self.Scrolledtreeview2.column("Col2", anchor="w")
        self.Scrolledtreeview2.heading("Col3", text="Symbol")
        self.Scrolledtreeview2.heading("Col3", anchor="center")
        self.Scrolledtreeview2.column("Col3", width="81")
        self.Scrolledtreeview2.column("Col3", minwidth="20")
        self.Scrolledtreeview2.column("Col3", stretch="1")
        self.Scrolledtreeview2.column("Col3", anchor="w")
        self.Scrolledtreeview2.heading("Col4", text="Side")
        self.Scrolledtreeview2.heading("Col4", anchor="center")
        self.Scrolledtreeview2.column("Col4", width="80")
        self.Scrolledtreeview2.column("Col4", minwidth="20")
        self.Scrolledtreeview2.column("Col4", stretch="1")
        self.Scrolledtreeview2.column("Col4", anchor="w")
        self.Scrolledtreeview2.heading("Col5", text="EntryPrice")
        self.Scrolledtreeview2.heading("Col5", anchor="center")
        self.Scrolledtreeview2.column("Col5", width="80")
        self.Scrolledtreeview2.column("Col5", minwidth="20")
        self.Scrolledtreeview2.column("Col5", stretch="1")
        self.Scrolledtreeview2.column("Col5", anchor="w")
        self.Scrolledtreeview2.heading("Col6", text="ExitPrice")
        self.Scrolledtreeview2.heading("Col6", anchor="center")
        self.Scrolledtreeview2.column("Col6", width="80")
        self.Scrolledtreeview2.column("Col6", minwidth="20")
        self.Scrolledtreeview2.column("Col6", stretch="1")
        self.Scrolledtreeview2.column("Col6", anchor="w")
        self.Scrolledtreeview2.heading("Col7", text="Pnl")
        self.Scrolledtreeview2.heading("Col7", anchor="center")
        self.Scrolledtreeview2.column("Col7", width="80")
        self.Scrolledtreeview2.column("Col7", minwidth="20")
        self.Scrolledtreeview2.column("Col7", stretch="1")
        self.Scrolledtreeview2.column("Col7", anchor="w")

        self.Label1 = Label(top)
        self.Label1.place(relx=0.15, rely=0.17, height=25, width=595)
        self.Label1.configure(font=('Helvetica', 10))
        self.Label1.configure(anchor=N)
        self.Label1.configure(background="#b4c2fe")
        self.Label1.configure(compound="left")
        self.Label1.configure(cursor="bottom_left_corner")
        self.Label1.configure(disabledforeground="#a3a3a3")
        self.Label1.configure(foreground="#000000")
        self.Label1.configure(justify=LEFT)
        self.Label1.configure(relief=RIDGE)
        self.Label1.configure(text='''Opened Positions''')
        self.Label1.configure(textvariable=test_support)
        self.Label1.configure(width=459)

        self.Label2 = Label(top)
        self.Label2.place(relx=0.15, rely=0.55, height=25, width=788)
        self.Label2.configure(font=('Helvetica', 10))
        self.Label2.configure(activebackground="#f9f9f9")
        self.Label2.configure(activeforeground="black")
        self.Label2.configure(anchor=N)
        self.Label2.configure(background="#b4c2fe")
        self.Label2.configure(compound="left")
        self.Label2.configure(cursor="bottom_left_corner")
        self.Label2.configure(disabledforeground="#a3a3a3")
        self.Label2.configure(foreground="#000000")
        self.Label2.configure(highlightbackground="#d9d9d9")
        self.Label2.configure(highlightcolor="black")
        self.Label2.configure(justify=LEFT)
        self.Label2.configure(relief=RIDGE)
        self.Label2.configure(text='''Trades''')
        self.Label2.configure(width=459)

        self.TFrame2 = Frame(top)
        self.TFrame2.place(relx=0.76, rely=0.23, relheight=0.22, relwidth=0.2)
        self.TFrame2.configure(relief=SUNKEN)
        self.TFrame2.configure(borderwidth="2")
        self.TFrame2.configure(relief=SUNKEN)
        self.TFrame2.configure(width=150)
        self.TFrame2.configure(takefocus="0")

        self.TotalPnl = Label(self.TFrame2)
        self.TotalPnl.place(relx=0.002, rely=0.17, height=29, width=86)
        self.TotalPnl.configure(font=('Helvetica', 11))
        self.TotalPnl.configure(foreground="#075bb8")
        self.TotalPnl.configure(relief=FLAT)
        self.TotalPnl.configure(justify=RIGHT)
        self.TotalPnl.configure(takefocus="0")
        self.TotalPnl.configure(text='''TotalPnl:''')

        self.TradesCount = Label(self.TFrame2)
        self.TradesCount.place(relx=0.01, rely=0.63, height=29, width=106)
        self.TradesCount.configure(font=('Helvetica', 11))
        self.TradesCount.configure(foreground="#075bb8")
        self.TradesCount.configure(relief=FLAT)
        self.TradesCount.configure(justify=RIGHT)
        self.TradesCount.configure(takefocus="0")
        self.TradesCount.configure(text='''TradesCount:''')

        self.tradesCount = Text(self.TFrame2)
        self.tradesCount.configure(font=('Helvetica', 10))
        self.tradesCount.place(relx=0.52, rely=0.6, relheight=0.3, relwidth=0.4)
        self.tradesCount.configure(font=('Helvetica', 10))
        self.tradesCount.configure(background="white")
        self.tradesCount.configure(font="TkTextFont")
        self.tradesCount.configure(foreground="black")
        self.tradesCount.configure(highlightbackground="#d9d9d9")
        self.tradesCount.configure(highlightcolor="black")
        self.tradesCount.configure(insertbackground="black")
        self.tradesCount.configure(selectbackground="#c4c4c4")
        self.tradesCount.configure(selectforeground="black")
        self.tradesCount.configure(takefocus="0")
        self.tradesCount.configure(width=104)

        self.totalPnl = Text(self.TFrame2, font= ('Times', '24', 'bold italic') )
        self.totalPnl.place(relx=0.52, rely=0.1, relheight=0.3, relwidth=0.4)
        self.totalPnl.configure(font=('Helvetica', 10))
        self.totalPnl.configure(background="white")
        self.totalPnl.configure(font="TkTextFont")
        self.totalPnl.configure(foreground="black")
        self.totalPnl.configure(highlightbackground="#d9d9d9")
        self.totalPnl.configure(highlightcolor="black")
        self.totalPnl.configure(insertbackground="black")
        self.totalPnl.configure(selectbackground="#c4c4c4")
        self.totalPnl.configure(selectforeground="black")
        self.totalPnl.configure(takefocus="0")
        self.totalPnl.configure(width=104)


    def stopRun(self):
        self.root.update()
        self.stopRunning= True
        self.output.log(crayons.red("System stop.........."))

    def CloseWindow(self) :
        self.root.destroy()

    def chartOpen(self) :
        self.liveChartObject = botChart()
        self.root.update()
        self.showChart= True

    def chartClose(self) :
        self.root.update()
        self.showChart= False
        plt.close()

    def useStartegy(self) :
        self.root.update()
        self.startTrading= True
        self.stopRunning= False
        self.output.log(crayons.green("Start trading.........."))

    def stopTrade(self) :
        self.root.update()
        try:
            opPos= self.strategy.openedPositions
        except:
            opPos= []
        if len(opPos)>0:
            messagebox.showinfo("Warning", "There are opened position. Close all before stopping trading!")
        else:
            self.startTrading = False
            self.output.log(crayons.green("End trading.........."))

    def closeAllPositions(self) :
        self.root.update()
        self.closeAll = True

    def insertDataExecutions(self, executions):
        n= len(executions)
        if n>self.numberOfExecutions:
            newExecutions= executions[-(n-self.numberOfExecutions):]
            k= n
            for row in newExecutions:
                self.Scrolledtreeview1.insert('', 'end', text=str(k),\
                                  values=( str(row[0]).split(" ")[-1], row[1], row[3], round(row[2],2), round(row[4],3)))
                k= k+1
            self.numberOfExecutions= n


    def insertDataTrades(self, trades):
        n= len(trades)
        if n>self.numberOfTrades:
            newTrades= trades[-(n-self.numberOfTrades):]
            k= self.numberOfTrades
            for row in newTrades:
                self.Scrolledtreeview2.insert('', 'end', text=str(k),\
                                  values=( str(row[0]).split(" ")[-1], str(row[1]).split(" ")[-1], row[2], \
                                           row[5], round(row[3],2), round(row[4],2), round(row[6],3)))
                k= k+1
            self.numberOfTrades= n

    def insertOpenData(self, openedPositions):
        self.Scrolledtreeview1.delete(*self.Scrolledtreeview1.get_children())
        for i,row in enumerate(openedPositions):
            self.Scrolledtreeview1.insert('', 'end', text=str(i),\
                                values=( str(row[0]).split(" ")[-1],  row[1], \
                                       row[2], round(row[3], 2), round(row[4], 2)), tags=('new'))

    def saveTradeHistory(self, strategy):
        if self.CheckVar:
            data= strategy.showExecutions()
            if len(data)>0:
                data.to_csv("TradingHistory.csv", index=False)
            else:
                with open("TradingHistory.csv", 'w'):
                    pass


    def main(self):
        period = 10
        pair = "USDT_BTC"
        lengthMA = 50
        error=False
        self.stopRunning= False
        self.numberOfTrades= 0
        try:
            data = BotGetData(pair, period)
            historical = data.historicalData
        except Exception as e:
            historical = []
            messagebox.showinfo("Error", e)
            error= True
        try:
            stopLossEdge= float(self.StopLossEdge.get())
        except:
            messagebox.showinfo("Error", "Wrong StopLoss input. Must be integer.")
            error= True
        try:
            entryEdge= float(self.EntryEdge.get())
            entryEdge= 0
        except:
            messagebox.showinfo("Error", "Wrong StopLoss input. Must be numeric.")
            error= True
        try:
            openPosLimit= int(self.OpenTradesLimit.get())
            if openPosLimit<=0:
                messagebox.showinfo("Error", "Wrong openPosLimit input. Must be integer>0.")
                openPosLimit= 1
        except:
            messagebox.showinfo("Error", "Wrong openPosLimit input. Must be integer.")
            error= True
        try:
            timePosEdge= int(self.Maintenance.get())
            if timePosEdge<0:
                messagebox.showinfo("Error", "Wrong Maintenance input. Must be integer>=0.")
                timePosEdge= 1
        except:
            messagebox.showinfo("Error", "Wrong Maintenance input. Must be integer.")
            error= True
        if not error:
            prices = historical.Price.tolist()
            if (len(historical) > lengthMA):
                prices = prices[-lengthMA:]
            else:
                print("Not enough historical data for MA=" + str(lengthMA))
                lengthMA = len(prices)

            self.strategy = BotStrategy(prices=prices, pair=pair, lengthMA=lengthMA, \
                                        openPosLimit=openPosLimit, stopLossEdge=stopLossEdge, \
                                        entryEdge=entryEdge, timePosEdge=timePosEdge)
            while True:
                try:
                    if self.stopRunning:
                        self.startTrading = False
                        self.saveTradeHistory(strategy=self.strategy)
                        self.Scrolledtreeview1.delete(*self.Scrolledtreeview1.get_children())
                        self.Scrolledtreeview2.delete(*self.Scrolledtreeview2.get_children())
                        self.strategy.closeAll()
                        self.strategy.clearExecutions()
                        break
                    data.updateData()
                    lastPairPrice = data.lastPrice
                    prices.append(lastPairPrice)
                    prices = prices[-lengthMA:]
                    self.strategy.tick(lastPairPrice, self.startTrading)
                    executions = self.strategy.allExecutions.execData
                    trades = self.strategy.allTrades.tradesData
                    histDataUpdated = chartHorizon(histDataUpdated=data.historicalData, interval=15)
                    openedPositions= self.strategy.openedPositions
                    self.insertDataTrades(trades)
                    self.insertOpenData(openedPositions)
                    self.tradesCount.delete(1.0, END)
                    self.tradesCount.insert(END, str(len(trades)))
                    self.totalPnl.delete(1.0, END)
                    self.totalPnl.insert(END, str(round(self.strategy.totalPnl,1)))
                    if self.closeAll:
                        self.strategy.closeAll()
                        self.saveTradeHistory(strategy=self.strategy)
                    if self.showChart:
                        self.liveChartObject.botLiveChart(x=histDataUpdated.Date, y=histDataUpdated.Price, \
                                            tradesLive=executions, lastTradePnl=self.strategy.lastTradePnl, \
                                            totalPnl=self.strategy.totalPnl, percentChange=data.percentChange)
                    self.root.update()

                except Exception as e:
                    messagebox.showinfo("Error", str(e))
                    self.strategy.closeAll()
                    self.saveTradeHistory(strategy=self.strategy)
                    break
class BotStrategy(object):
    def __init__(self):
        self.output = BotLog()
        self.prices = []
        self.currentPrice = ""
        self.indicators = BotIndicators()
        self.GRC_bal = False
        self.BTC_bal = False
        self.Total_bal = False
        self.can_buy = False
        self.can_sell = False
        self.trade_amount = .00059  # BTC
        self.to_buy = False
        self.to_sell = False
        self.pair = 'BTC_GRC'
        self.order_num = False
        self.orders = []
        self.high_bid_price = False
        self.low_ask_price = False
        self.low_ask_amount = False
        self.high_bid_amount = False
        self.price_to_buy = False
        self.price_to_sell = False
        self.openTrades = []
        self.open_Bids = []
        self.open_Asks = []
        self.orders = []
        self.last_sell_price = False
        self.last_buy_price = False
        self.open_sell_flag = False
        self.open_buy_flag = False
        self.raw_spread = 0
        self.mod_spread = 0
        self.place_orders_flag = True

    def tick(self, candlestick):
        print('')
        print('############## Gridcoin data ###############')
        self.currentPrice = float(candlestick.priceAverage)
        self.prices.append(self.currentPrice)
        print("Price: " + str(candlestick.priceAverage))
        self.set_order_prices()
        self.updateOpenTrades()
        self.evaluatePositions_Market_Make()
        print('############## End Gridcoin data ###############')

    def evaluatePositions_Market_Make(self):
        # Have to re-check balances after possibly cancelling orders
        self.balance = polo.returnBalances()
        self.GRC_bal = float(self.balance['GRC'])
        self.BTC_bal = float(self.balance['BTC'])
        self.Total_bal = self.GRC_bal + (self.BTC_bal /
                                         float(self.currentPrice))

        if self.place_orders_flag == True:
            # Current code uses a BTC constant for trade amount, defined above

            if self.open_buy_flag == False:
                # self.can_buy = self.BTC_bal / self.price_to_buy
                if self.BTC_bal > 0.95 * self.trade_amount:  #extra padding was to allow for FLDC trading
                    if self.BTC_bal > self.trade_amount:
                        self.to_buy = self.trade_amount / self.price_to_buy
                    else:
                        self.to_buy = self.BTC_bal * 0.99 / self.price_to_buy
                    val_check = "Value check " + self.pair + " " + "{:.8f}".format(
                        self.price_to_buy) + " " + "{:.8f}".format(self.to_buy)
                    print(val_check)
                    placed_order = polo.buy(self.pair,
                                            "{:.8f}".format(self.price_to_buy),
                                            "{:.8f}".format(self.to_buy))
                    print("Buy order placed!")
                    print(placed_order)

            if self.open_sell_flag == False:
                if self.GRC_bal > self.trade_amount / self.price_to_sell * 0.95:
                    if self.GRC_bal > self.trade_amount / self.price_to_sell:
                        self.to_sell = self.trade_amount / self.price_to_sell
                    else:
                        self.to_sell = self.GRC_bal * 0.99
                    val_check = "Value check " + self.pair + " " + "{:.8f}".format(
                        self.price_to_sell) + " " + "{:.8f}".format(
                            self.to_sell)
                    print(val_check)
                    placed_order = polo.sell(
                        self.pair, "{:.8f}".format(self.price_to_sell),
                        "{:.8f}".format(self.to_sell))
                    print("Sell order placed!")
                    print(placed_order)

        # Code for trading with a GRC constant
        # if self.place_orders_flag == True:
        #
        #     if self.open_buy_flag == False:
        #         self.can_buy = self.BTC_bal / self.price_to_buy
        #         if self.can_buy > 90:
        #             if self.can_buy > 100:
        #                 self.to_buy = 100
        #             else:
        #                 self.to_buy = self.can_buy - 1
        #             val_check = "Value check " + self.pair + " " + "{:.8f}".format(self.price_to_buy) + " " + "{:.8f}".format(self.to_buy)
        #             print(val_check)
        #             placed_order = polo.buy(self.pair, "{:.8f}".format(self.price_to_buy), "{:.8f}".format(self.to_buy))
        #             print("Buy order placed!")
        #             print(placed_order)
        #
        #     if self.open_sell_flag == False and self.GRC_bal > 90:
        #         if self.GRC_bal > 100:
        #              self.to_sell = 100
        #         else:
        #             self.to_sell = self.GRC_bal - 1
        #         val_check = "Value check " + self.pair + " " + "{:.8f}".format(self.price_to_sell) + " " + "{:.8f}".format(self.to_sell)
        #         print(val_check)
        #         placed_order = polo.sell(self.pair, "{:.8f}".format(self.price_to_sell), "{:.8f}".format(self.to_sell))
        #         print("Sell order placed!")
        #         print(placed_order)

    # def Order_book(self, pair):
    #     self.orders = polo.returnOrderBook(pair, 5)
    #     self.high_bid_price = float(self.orders['bids'][0][0])
    #     self.high_bid_amount = float(self.orders['bids'][0][1])
    #     self.low_ask_price = float(self.orders['asks'][0][0])
    #     self.low_ask_amount = float(self.orders['asks'][0][1])

    def updateOpenTrades(self):
        print('BEFORE trade update the flags were:')
        print('Place orders flag = ' + str(self.place_orders_flag))
        print('Open buy flag = ' + str(self.open_buy_flag))
        print('Open sell flag = ' + str(self.open_sell_flag))

        self.openTrades = polo.returnOpenOrders(self.pair)
        self.open_Bids = []
        self.open_Asks = []

        if len(self.openTrades) == 0:
            self.open_buy_flag = False
            self.open_sell_flag = False
            print('Open trade flags set to False because openTrades was empty')

        elif len(self.openTrades) > 0:
            for trade in self.openTrades:
                order_Type = trade['type']
                order_Num = trade['orderNumber']
                if order_Type == 'buy':
                    self.open_Bids.append(order_Num)
                elif order_Type == 'sell':
                    self.open_Asks.append(order_Num)

        if len(self.open_Bids) == 0:
            self.open_buy_flag = False
            print(
                'Open buy flag set to false because openTrades > 0 and no bids'
            )
        if len(self.open_Asks) == 0:
            self.open_sell_flag = False
            print(
                'Open sell flag set to false because openTrades > 0 and no asks'
            )

        # Originally was outside the above if block
        # for trade in self.openTrades:
        #     order_Type = trade['type']
        #     order_Num = trade['orderNumber']
        #     if order_Type == 'buy':
        #         self.open_Bids.append(order_Num)
        #     elif order_Type == 'sell':
        #         self.open_Asks.append(order_Num)
        #
        # if len(self.open_Bids) == 0:
        #     self.open_buy_flag = False
        # if len(self.open_Asks) == 0:
        #     self.open_sell_flag = False

        if len(self.openTrades) > 0:
            print('openTrades was not empty so trades were checked')
            self.output.log(self.openTrades)

            if self.place_orders_flag == False:
                for trade in self.openTrades:
                    order_Num = trade['orderNumber']
                    polo.cancelOrder(order_Num)
                print('Spread too small, all orders cancelled')

            elif self.place_orders_flag == True:

                for trade in self.openTrades:
                    order_Num = trade['orderNumber']
                    order_Type = trade['type']
                    order_price = float(trade['rate'])
                    if order_Type == "buy":
                        if order_price == self.price_to_buy:
                            self.open_buy_flag = True
                            print(
                                "Previous buy order still open at target price"
                            )
                            print(
                                'Open buy flag set to True because previous order exists'
                            )
                        elif order_price != self.price_to_buy:
                            polo.cancelOrder(order_Num)
                            print("Buy order closed")
                            self.open_buy_flag = False
                            print(
                                'Open buy flag set to False due to cancelled trade'
                            )
                    elif order_Type == "sell":
                        if order_price == self.price_to_sell:
                            self.open_sell_flag = True
                            print(
                                "Previous sell order still open at target price."
                            )
                            print(
                                'Open sell flag set to True because previous order exists'
                            )
                        elif order_price != self.price_to_sell:
                            polo.cancelOrder(order_Num)
                            print("Sell order closed")
                            self.open_sell_flag = False
                            print(
                                'Open sell flag set to False due to cancelled trade'
                            )
            self.openTrades = polo.returnOpenOrders(self.pair)

        print('AFTER trade update the flags were:')
        print('Place orders flag = ' + str(self.place_orders_flag))
        print('Open buy flag = ' + str(self.open_buy_flag))
        print('Open sell flag = ' + str(self.open_sell_flag))

    def set_order_prices(self):
        self.balance = polo.returnBalances()
        self.GRC_bal = float(self.balance['GRC'])
        self.BTC_bal = float(self.balance['BTC'])
        self.Total_bal = self.GRC_bal + (self.BTC_bal /
                                         float(self.currentPrice))

        self.orders = polo.returnOrderBook(self.pair, 5)
        self.high_bid_price = float(self.orders['bids'][0][0])
        self.high_bid_amount = float(self.orders['bids'][0][1])
        self.low_ask_price = float(self.orders['asks'][0][0])
        self.low_ask_amount = float(self.orders['asks'][0][1])
        self.output.log("High bid: " + str(self.high_bid_price) +
                        " Low ask: " + str(self.low_ask_price))

        self.raw_spread = self.low_ask_price - self.high_bid_price
        print('Raw spread = ' + str(self.raw_spread))

        if self.raw_spread >= 7E-8:
            if self.high_bid_amount > 100:
                self.price_to_buy = self.high_bid_price + 1E-8
            else:
                self.price_to_buy = self.high_bid_price

            if self.low_ask_amount > 100:
                self.price_to_sell = self.low_ask_price - 1E-8
            else:
                self.price_to_sell = self.low_ask_price

            self.place_orders_flag = True

        elif self.raw_spread < 7E-8:
            orders = self.orders

            bids = []

            for x in orders['bids']:
                bid_price = x[0]
                bid_amount = x[1]
                bids.append([bid_price, bid_amount])

            bids_running_sum = 0
            bids_index_counter = 0

            for y in bids:
                bids_running_sum += float(y[1])
                if bids_running_sum > 1000 and bids_index_counter == 0:
                    buy_price_index = 0
                    overcut = True
                    break
                elif bids_running_sum > 1000 and bids_index_counter > 0:
                    buy_price_index = bids_index_counter - 1
                    overcut = False
                    break
                else:
                    buy_price_index = bids_index_counter
                    overcut = False
                bids_index_counter += 1

            if overcut == True:
                self.price_to_buy = self.high_bid_price + 1E-8
                print('Overcutting')
            else:
                print('Buy at index: ' + str(buy_price_index))
                price_to_buy_txt = str(bids[buy_price_index][0])
                self.price_to_buy = float(price_to_buy_txt)

            asks = []

            for x in orders['asks']:
                ask_price = x[0]
                ask_amount = x[1]
                asks.append([ask_price, ask_amount])

            asks_running_sum = 0
            asks_index_counter = 0

            for y in asks:
                asks_running_sum += float(y[1])
                if asks_running_sum > 1000 and asks_index_counter == 0:
                    sell_price_index = 0
                    undercut = True
                    break
                elif asks_running_sum > 1000 and asks_index_counter > 0:
                    sell_price_index = asks_index_counter - 1
                    undercut = False
                    break
                else:
                    sell_price_index = asks_index_counter
                    undercut = False
                asks_index_counter += 1

            if undercut == True:
                self.price_to_sell = self.low_ask_price - 1E-8
                print('Undercutting')
            else:
                price_to_sell_txt = str(asks[sell_price_index][0])
                self.price_to_sell = float(price_to_sell_txt)

            print('Sell price = ' + str(self.price_to_sell))
            print('Buy price = ' + str(self.price_to_buy))
            self.mod_spread = self.price_to_sell - self.price_to_buy
            print('Modified spread = ' + str(self.mod_spread))

            if self.mod_spread <= 1.01E-8:
                self.place_orders_flag = False
                print(
                    'Set place orders flag to False because spread too small')
            elif self.price_to_sell <= self.high_bid_price:
                self.place_orders_flag = False
                print(
                    'Set place orders flag to false due to avoid cross-selling'
                )
            elif self.price_to_buy >= self.low_ask_price:
                self.place_orders_flag = False
                print(
                    'Set place orders flag to false due to avoid cross-buying')
            else:
                self.place_orders_flag = True
                print('Set place orders flag to True, all conditions met')

            print('Place orders flag = ' + str(self.place_orders_flag))
Exemplo n.º 18
0
class BotChart(object):
    def __init__(self,
                 exchange,
                 pair,
                 period,
                 backtest=True
                 ):  # TODO: pass in start and end timestamps for backtesting
        self.output = BotLog()
        self.exchange = exchange
        self.pair = pair
        self.period = period
        self.startTime = time.time(
        ) - SECONDS_IN_DAY * 2  # TODO: use passed in start and end timestamps
        self.endTime = time.time(
        )  # Backtest up to now TODO: move this to __init__ param so it can be changed

        self.data = []

        if self.exchange == "kraken" and backtest:
            logger.info("Fetching historical OHLC data for back testing...")
            kraken_data = OHLC(pair='XXBTZUSD',
                               since=self.startTime,
                               interval=self.period)
            historical_kraken_data = kraken_data['result'][self.pair]
            for datum in historical_kraken_data:
                if datum[1] and datum[4] and datum[2] and datum[3] and datum[5]:
                    # list entries: (0: <timestamp>, 1: <open>, 2: <high>, 3: <low>, 4: <close>, 5: <vwap>, 6: <volume>, 7: <count>)
                    self.data.append(
                        BotCandlestick(self.period, datum[1], datum[4],
                                       datum[2], datum[3], datum[5]))

    def get_points(self):
        return self.data

    def get_current_price_and_vol(self):
        """"
        Get last price from ticker
        """
        current_values = Ticker()
        last_pair_price = current_values['result'][self.pair]['c'][0]
        last_pair_volume = current_values['result'][self.pair]['c'][1]

        # inside_bid = current_values['result'][self.pair]['b'][0]
        # inside_ask = current_values['result'][self.pair]['a'][0]
        return last_pair_price, last_pair_volume

    def get_ticker(self):
        """
        Get ticker info

        :return dict of ticker results or empty dict if error.
        """
        ticker = Ticker(pair=self.pair)
        if not ticker['error']:
            return ticker['result']
        else:
            self.output.log(ticker)
            return {}

    def midpoint_price(self):
        """
        The price between the best price of the sellers of the
        stock or commodity offer price or ask price and the best price
        of the buyers of the stock or commodity bid price. It can simply
        be defined as the average of the current bid and ask prices being quoted.
        AKA the "fair price".
        """
        ticker = Ticker()
        best_bid_price = ticker.get('result')[self.pair]['b'][0]
        best_ask_price = ticker.get('result')[self.pair]['a'][0]
        return (float(best_bid_price) + float(best_ask_price)) / 2

    def spread_percentage(self):
        """
        Bid-Ask spread as a percentage.
        """
        ticker = Ticker()
        b = ticker['result'][self.pair]['b'][0]
        a = ticker['result'][self.pair]['a'][0]
        return 100 * ((float(a) - float(b)) / float(a))
Exemplo n.º 19
0
class BotAccount(object):
    def __init__(self, functions):
        self.output = BotLog()
        self.output.log("Getting balance data...")
        self.conn = functions.poloniex_conn
        self.data = self.__updateBalance()

    def getBalance(self):
        return self.data

    def createBalancePage(self):
        with open("balance.html", "w") as text_file:
            print("""<!DOCTYPE html>
        <html>
        <head>
        <style>
        table {
            font-family: arial, sans-serif;
            border-collapse: collapse;
            width: 100%;
        }
        
        td, th {
            border: 1px solid #dddddd;
            text-align: left;
            padding: 8px;
        }
        
        tr:nth-child(even) {
            background-color: #dddddd;
        }
        </style>
        </head>
        <body>
        <h1>BALANCE</h1><table id="example" class="display" cellspacing="0" width="100%">
        <thead>
            <tr>
                <th>Pair</th>
                <th>Amount</th>
            </tr>
        </thead>
        <tfoot>
            <tr>
                <th>Pair</th>
                <th>Amount</th>
            </tr>
        </tfoot>
        <tbody>
            <tr>""",
                  file=text_file)
            for k, v in self.data.items():
                print("<tr><td>{0}</td><td>{1}</td></tr>".format(k, v),
                      file=text_file)
            print("""</tbody>
    </table>
    <br/>
    <div align="right" >
    <button onclick="javascript:history.back()">Go back to index</button>
    </div>
    </body>
    </html>""",
                  file=text_file)

    def __updateBalance(self):
        # return self.functions.getBalance()
        return {'BTC_XMR': 50, 'BTC_LTC': 20}
Exemplo n.º 20
0
        # Create the EventHandler and pass in your bot's token.
        updater = Updater(TELEGRAM_TOKEN)

        # Get the dispatcher to register handlers
        dp = updater.dispatcher

        # on different commands - answer in Telegram
        dp.add_handler(CommandHandler("start", self.start))
        dp.add_handler(CallbackQueryHandler(self.button))
        dp.add_handler(CommandHandler("help", self.help))

        # on noncommand i.e message - echo the message on Telegram
        dp.add_handler(MessageHandler(Filters.text, self.onMessage))

        # log all errors
        dp.add_error_handler(self.error_callback)

        # Start the Bot
        updater.start_polling()

        # Run the bot until you press Ctrl-C or the process receives SIGINT,
        # SIGTERM or SIGABRT. This should be used most of the time, since
        # start_polling() is non-blocking and will stop the bot gracefully.
        updater.idle()


if __name__ == '__main__':
    log.log('Starting Telegram Bot')
    diag_telegram = DIAG_TLGM()
    diag_telegram.main()
Exemplo n.º 21
0
class BotCandlestick(object):
    def __init__(self,date=None,open=None,high=None,low=None,close=None,volume=None):
        self.close = close
        self.currentPrice = close
        self.date = date
        self.high = high
        self.low = low
        self.open = open
        self.output = BotLog()
        self.priceAverage = False
        self.startTime = time.time()
        self.volume = volume

        if self.close:
            self.currentPrice = self.close

    def __setitem__(self, key, value):
          setattr(self, key, value)

    def __getitem__(self, key):
          return getattr(self, key)

    def toDict(self):
        return {
            'close': self.close,
            'currentPrice': self.currentPrice,
            'date': self.date,
            'high': self.high,
            'low': self.low,
            'open' : self.open,
            'priceAverage': self.priceAverage,
            'startTime': self.startTime,
            'volume': self.volume
        }

    def tick(self, price):
        self.currentPrice = float(price)

        if self.date is None:
            self.date = time.time()
        if (self.open is None):
            self.open = self.currentPrice

        if (self.high is None) or (self.currentPrice > self.high):
            self.high = self.currentPrice

        if (self.low is None) or (self.currentPrice < self.low):
            self.low = self.currentPrice


        timedelta = utils.parseTimedelta(shared.strategy['timeframe'])
        if time.time() >= ( self.startTime + timedelta):
            self.close = self.currentPrice
            self.priceAverage = ( self.high + self.low + self.close ) / float(3)

        self.output.log("Start time: "+str(self.startTime)+",  Open: "+str(self.open)+" Close: "+str(self.close)+" High: "+str(self.high)+" Low: "+str(self.low)+" currentPrice: "+str(self.currentPrice))

    def isClosed(self):
        if (self.close is not None):
            return True
        else:
            return False
Exemplo n.º 22
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()
Exemplo n.º 23
0
class BotTrade(object):
    def __init__(self,direction,amount,rate,total,date,stopLoss=0, takeProfit=0, backtest=True, live=False):
        global orderNb
        self.amount = amount
        self.backTest = backtest
        self.date = date
        self.direction = direction
        self.exitDate = 0.0
        self.exitRate = 0.0
        self.fee = float(shared.exchange['fee'])
        self.filledOn = ""
        self.live = live
        self.orderNumber = orderNb
        self.output = BotLog()
        self.rate = rate
        self.status = "OPEN"
        self.stopLoss = stopLoss
        self.takeProfit = takeProfit
        self.total = total

        # API
        self.api = BotApi()

        orderSuccess = True
        if self.direction == "BUY":
            if not self.backTest and self.live:
                try:
                    order = self.api.exchange.createLimitBuyOrder(shared.exchange['pair'], amount, rate)
                    self.orderNumber = order['id']
                except Exception as e:
                    self.output.fail(str(e))
                    orderSuccess = False
                    self.output.fail("Buy order failed")
            elif self.total < 0.00001:
                orderSuccess = False
                self.output.fail("Not enough funds to place Buy Order")
            if orderSuccess:
                shared.exchange['nbMarket'] -= self.total
                self.amount -= self.amount*self.fee
                self.output.info(str(time.ctime(date)) + " - Order "+str(self.orderNumber)+": Buy "+str(self.amount)+' '+shared.exchange['asset']+' ('+str(self.fee*100)+'% fees) at '+str(self.rate)+' for '+str(self.total)+' '+shared.exchange['market']+' - stopLoss: '+str(self.stopLoss)+' - takeProfit: '+str(self.takeProfit))

        elif self.direction == "SELL":
            if not self.backTest and self.live:
                try:
                    order = self.api.exchange.createLimitSellOrder(shared.exchange['pair'], amount, rate)
                    self.orderNumber = order['id']
                except Exception as e:
                    print(e)
                    orderSuccess = False
                    self.output.warning("Sell order failed")
            elif self.total < 0.00001:
                orderSuccess = False
                self.output.fail("Not enough funds to place Sell Order")
            if orderSuccess:
                shared.exchange['nbAsset'] -= self.amount
                self.total -= self.total*self.fee
                self.output.info(str(time.ctime(date)) + " - Order "+str(self.orderNumber)+": Sell "+str(self.amount)+' '+shared.exchange['asset']+' at '+str(self.rate)+' for '+str(self.total)+' ('+str(self.fee*100)+'% fees) '+shared.exchange['market']+' - stopLoss: '+str(self.stopLoss)+' - takeProfit: '+str(self.takeProfit))


        orderNb+=1
        if not orderSuccess:
            self.status = 'FAILED'

    def __setitem__(self, key, value):
          setattr(self, key, value)

    def __getitem__(self, key):
          return getattr(self, key)

    def toDict(self):
        return {
            'date': self.date,
            'direction': self.direction,
            'amount': self.amount,
            'rate': self.rate,
            'total': self.total,
            'stopLoss': self.stopLoss,
            'takeProfit': self.takeProfit,
            'exitRate': self.exitRate,
            'filledOn': self.filledOn,
            'exitDate': self.exitDate,
            'orderNumber': self.orderNumber
        }

    def tick(self, candlestick, date):
        if not self.backTest and self.live:
            date = float(time.time())
            # TODO: implement not backtest
            pass
        if not self.filledOn:
            if (self.direction == 'BUY' and candlestick.high > self.rate) or (self.direction == 'SELL' and candlestick.low < self.rate):
                self.filledOn = date
                if self.direction == 'BUY':
                    shared.exchange['nbAsset'] += self.amount
                elif self.direction == 'SELL':
                    shared.exchange['nbMarket'] += self.total
                if not self.stopLoss and not self.takeProfit:
                    self.status = 'CLOSED'
                else:
                    if self.direction =='BUY':
                        shared.exchange['coinsInOrder'] += self.amount
                    elif self.direction =='SELL':
                        shared.exchange['marketInOrder'] += self.total
                self.output.info(str(time.ctime(date)) + " - Order "+str(self.orderNumber)+" filled")

        if self.stopLoss and self.filledOn:
            # TODO: implement live
            if self.direction == 'BUY' and candlestick.low < self.stopLoss:
                self.total -= self.total*self.fee
                shared.exchange['nbAsset'] -= self.amount
                shared.exchange['coinsInOrder'] -= self.amount
                self.output.warning(str(time.ctime(date)) + " - Order "+str(self.orderNumber)+": Stop Loss - Sell "+str(self.amount)+' '+shared.exchange['asset']+' at '+str(self.stopLoss)+' for '+str(self.total)+' '+shared.exchange['market']+' ('+str(self.fee*100)+'% fees)')
                self.close(self.stopLoss, date)
                return
            elif self.direction == 'SELL' and candlestick.high > self.stopLoss:
                self.amount -= self.amount*self.fee
                shared.exchange['nbMarket'] -= self.total
                shared.exchange['marketInOrder'] -= self.total
                self.output.warning(str(time.ctime(date)) + " - Order "+str(self.orderNumber)+": Stop Loss - Buy "+str(self.amount)+' '+shared.exchange['asset']+' ('+str(self.fee*100)+'% fees) at '+str(self.stopLoss)+' for '+str(self.total)+' '+shared.exchange['market'])
                self.close(self.stopLoss, date)
                return
        if self.takeProfit and self.filledOn:
            if self.direction == 'BUY' and candlestick.high > self.takeProfit:
                self.total -= self.total*self.fee
                shared.exchange['nbAsset'] -= self.amount
                shared.exchange['coinsInOrder'] -= self.amount
                self.output.success(str(time.ctime(date)) + " - Order "+str(self.orderNumber)+": Take Profit - Sell "+str(self.amount)+' '+shared.exchange['asset']+' at '+str(self.stopLoss)+' for '+str(self.total)+' '+shared.exchange['market']+' ('+str(self.fee*100)+'% fees)')
                self.close(self.takeProfit, date)
                return
            elif self.direction == 'SELL' and candlestick.low < self.takeProfit:
                self.amount -= self.amount*self.fee
                shared.exchange['nbMarket'] -= self.total
                shared.exchange['marketInOrder'] -= self.total
                self.output.success(str(time.ctime(date)) + " - Order "+str(self.orderNumber)+": Take Profit - Buy "+str(self.amount)+' '+shared.exchange['asset']+' ('+str(self.fee*100)+'% fees) at '+str(self.stopLoss)+' for '+str(self.total)+' '+shared.exchange['market'])
                self.close(self.takeProfit, date)
                return

    def close(self, currentPrice, date=0.0):
        if not self.backTest and self.live:
            date = float(time.time())
            # TODO: implement not backtest
            pass
        self.status = "CLOSED"
        self.exitRate = currentPrice
        self.exitDate =  date
        if self.direction == 'BUY':
            shared.exchange['nbMarket'] += self.total
        elif self.direction == 'SELL':
            shared.exchange['nbAsset'] += self.amount
        self.output.info(str(time.ctime(date)) + " - Order "+str(self.orderNumber)+" Closed")
        self.showTrade()

    def showTrade(self):
        tradeStatus = "Order #"+str(self.orderNumber)+" - Entry Price: "+str(self.rate)+" Status: "+str(self.status)+" Exit Price: "+str(self.exitRate)

        if (self.status == "CLOSED"):
            if (self.direction == 'BUY' and self.exitRate > self.rate) or (self.direction == 'SELL' and self.exitRate < self.rate):
                tradeStatus = tradeStatus + " Profit: \033[92m"
            else:
                tradeStatus = tradeStatus + " Loss: \033[91m"
            if self.direction == 'BUY':
                tradeStatus = tradeStatus+str((self.exitRate - self.rate)/self.total)+str(shared.exchange['market'])+"\033[0m"
            else:
                tradeStatus = tradeStatus+str((self.rate - self.exitRate)/self.exitRate*self.amount)+str(shared.exchange['asset'])+"\033[0m"

        self.output.log(tradeStatus)

    def updateStop(self, newStop):
        oldStop = self.stopLoss
        self.stopLoss = float(newStop);
        self.output.log("Trade stop moved from "+str(oldStop)+" to "+str(newStop))
Exemplo n.º 24
0
class BotStrategy(object):

    def __init__(self, prices, pair, lengthMA, openPosLimit, stopLossEdge, entryEdge, timePosEdge):
        self.output = BotLog()
        self.prices = prices
        self.closes = []  # Needed for Momentum Indicator
        self.trades = []
        self.currentPrice = 0
        self.numSimulTrades = openPosLimit
        self.pair= pair
        self.side= ""
        self.lengthMA= lengthMA
        self.movAverage= 0
        self.expMovAverage= 0
        self.strategyTradingMetric= 0
        self.allExecutions = executionsData()
        self.allTrades = tradesData()
        self.metrics= botMetrics()
        self.openedPositions =[]
        self.lastTradePnl=0
        self.totalPnl=0
        self.stopLossEdge= stopLossEdge
        self.entryEdge= entryEdge
        self.timePosEdge= timePosEdge

    def movingAverage(self, data, period):
        ma= 0
        if len(data)> 1:
            ma= sum(data[-period:])/len(data[-period:])
        return(ma)

    def tick(self, price, startTrade):
        self.currentPrice= price
        self.prices.append(self.currentPrice)
        self.movAverage= self.metrics.movingAverage(data=self.prices, period=self.lengthMA)
        self.expMovAverage = self.metrics.EMA(prices=self.prices, period=self.lengthMA)
        self.strategyTradingMetric= self.expMovAverage
        self.output.log("Price: " + str(round(price, 3)) + "  MA: " + str(round(self.movAverage ,3)) + \
                 "  EMA: "+str(round(self.expMovAverage ,3)))

        if startTrade:
            self.evaluatePositions()
            if self.stopLossEdge>0:
                self.updateOpenTrades()
            self.showPositions()
            self.updateOpenPositions()

    def evaluatePositions(self):
        currentTime= datetime.datetime.now()
        openTrades = []
        for trade in self.trades:
            if (trade.status == "OPEN"):
                openTrades.append(trade)

        if (len(openTrades) < self.numSimulTrades):
            if ((self.strategyTradingMetric-self.currentPrice)> self.entryEdge):
                btrade= BotTrade(self.currentPrice, stopLossEdge=self.stopLossEdge)
                self.trades.append(btrade)
                self.updateExecutions(trade=btrade, executionTime=btrade.entryTime, executionPrice=btrade.entryPrice)

        for trade in openTrades:
            if (self.currentPrice > self.strategyTradingMetric):
                if (currentTime-trade.entryTime).seconds>self.timePosEdge:
                    trade.close(self.currentPrice)
                    self.updateExecutions(trade=trade, executionTime=trade.exitTime, executionPrice=trade.exitPrice)
                    self.updateTrades(trade=trade)
                    self.lastTradePnl= trade.pnl
                    self.totalPnl= self.totalPnl+self.lastTradePnl

    def closeAll(self):
        for trade in self.trades:
            if (trade.status == "OPEN"):
                trade.close(self.currentPrice)
                self.updateExecutions(trade=trade, executionTime=trade.exitTime, executionPrice=trade.exitPrice)
                self.updateTrades(trade=trade)
                self.lastTradePnl = trade.pnl
                self.totalPnl = self.totalPnl + self.lastTradePnl
        self.trades= []
        self.openedPositions =[]


    def updateExecutions(self, trade, executionTime, executionPrice):
        self.allExecutions.addExecutions(entryTime=executionTime, pair=self.pair, \
                                         entryPrice=executionPrice, side=trade.side, pnl=trade.pnl)
    def updateTrades(self, trade):
        self.allTrades.addTrades(entryTime=trade.entryTime, exitTime=trade.exitTime, pair=self.pair,\
                                 entryPrice=trade.entryPrice, exitPrice=trade.exitPrice, side=trade.side,
                                 pnl=trade.pnl)
    def updateOpenTrades(self):
        for trade in self.trades:
            if (trade.status == "OPEN"):
                if (self.currentPrice < trade.stopLoss):
                    print("Exit StopLoss")
                    self.output.log(crayons.magenta("Exit By Stop Loss"))
                    trade.close(self.currentPrice)
                    self.updateExecutions(trade=trade, executionTime=trade.exitTime, executionPrice=trade.exitPrice)
                    self.updateTrades(trade=trade)
                    self.lastTradePnl = trade.pnl
                    self.totalPnl = self.totalPnl + self.lastTradePnl

    def updateOpenPositions(self):
        openedPositions = []
        for trade in self.trades:
            if (trade.status=="OPEN"):
                openedPositions.append([trade.entryTime, self.pair, trade.side, \
                                       round(trade.entryPrice,2), round(trade.pnl,2)])
        self.openedPositions= openedPositions


    def showPositions(self):
        openedPositions= []
        for trade in self.trades:
            trade.showStatus()
        return openedPositions

    def showOpenedPositions(self):
        temp= pd.DataFrame(self.openedPositions)
        if len(temp)>0:
            temp.columns= ["Time", "Pair", "Side", "EntryPrice", "Pnl"]
        return temp

    def showExecutions(self):
        temp= pd.DataFrame(self.allExecutions.execData)
        if len(temp)>0:
            temp.columns= ["Time", "Pair", "Price", "Side", "Pnl"]
        return temp

    def showTrades(self):
        temp = pd.DataFrame(self.allTrades.tradesData)
        if len(temp) > 0:
            temp.columns = ["EntryTime", "ExitTime", "Pair", "EntryPrice", "ExitPrice", "Side", "Pnl"]
        return temp

    def clearExecutions(self):
        self.allExecutions = executionsData()
        self.allTrades = tradesData()
Exemplo n.º 25
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 = 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(object):
    def __init__(self):
        self.output = BotLog()
        self.prices = 0
        self.trades = []
        self.currentClose = ""
        self.numSimulTrades = 1
        self.btc_historical_percent = 0
        self.btc_historical_positive = 0
        self.btc_historical_negative = 0
        self.btc_historical_score = 0
        self.btc_historical_total = 0
        self.btc_sinceID = 0
        self.btc_trading_percent = 0
        self.eth_historical_percent = 0
        self.eth_historical_positive = 0
        self.eth_historical_negative = 0
        self.eth_historical_score = 0
        self.eth_historical_total = 0
        self.eth_sinceID = 0
        self.eth_trading_percent = 0
        self.type_of_trade = ''
        self.api = bittrex('', '')
        self.btc_sentiments = []
        self.eth_sentiments = []

    def tick(self):

        currentPrice = self.api.getticker('BTC-ETH')
        self.prices = currentPrice['Ask']

        #self.currentClose = float(candlestick['close'])
        #self.closes.append(self.currentClose)

        self.output.log("Price: " + '{0:.8f}'.format(self.prices))

        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.btc_historical_total <= 100000):
                bitcoin_query = 'BTC OR Bitcoin OR $BTC'

                btc_historical_tweets, self.btc_sinceid = tweets.get_tweets(
                    50, self.btc_sinceID, bitcoin_query)
                btc_total_score, btc_positive, btc_negative, btc_total = tweets.classify(
                    btc_historical_tweets)
                self.btc_historical_positive = self.btc_historical_positive + btc_positive
                self.btc_historical_negative = self.btc_historical_negative + btc_negative
                self.btc_historical_score = self.btc_historical_score + btc_total_score
                self.btc_historical_total = self.btc_historical_total + btc_total

                self.btc_historical_percent = (self.btc_historical_positive /
                                               self.btc_historical_total) * 100

                ethereum_query = 'Ethereum OR ETH OR $ETH'

                eth_historical_tweets, self.eth_sinceID = tweets.get_tweets(
                    50, self.eth_sinceID, ethereum_query)
                eth_total_score, eth_positive, eth_negative, eth_total = tweets.classify(
                    eth_historical_tweets)
                self.eth_historical_positive = self.eth_historical_positive + eth_positive
                self.eth_historical_negative = self.eth_historical_negative + eth_negative
                self.eth_historical_score = self.eth_historical_score + eth_total_score
                self.eth_historical_total = self.eth_historical_total + eth_total

                self.eth_historical_percent = (self.eth_historical_positive /
                                               self.eth_historical_total) * 100

                if self.btc_historical_total >= 100000:
                    print '\033[1m' + "Historical Tweets Analyzed"
                    print "historical btc percent: " + str(
                        self.btc_historical_percent)
                    print "historical eth percent: " + str(
                        self.eth_historical_percent)
                    print '\033[0m'

            elif (self.btc_historical_total > 100000):
                bitcoin_query = 'BTC OR Bitcoin OR $BTC'

                btc_tweets, sinceid_recent = tweets.get_tweets(
                    50, 0, bitcoin_query)
                btc_total_score2, btc_positive2, btc_negative2, btc_total2 = tweets.classify(
                    btc_tweets)
                btc_percent = (btc_positive2 / btc_total2) * 100

                ethereum_query = 'Ethereum OR ETH OR $ETH'

                eth_tweets, sinceid_recent = tweets.get_tweets(
                    50, 0, ethereum_query)
                eth_total_score2, eth_positive2, eth_negative2, eth_total2 = tweets.classify(
                    eth_tweets)
                eth_percent = (eth_positive2 / eth_total2) * 100

                if (eth_percent > 1.042 * self.eth_historical_percent
                        or btc_percent < 0.943 * self.btc_historical_percent):

                    if btc_percent < 0.943 * self.btc_historical_percent:
                        self.btc_sentiments = []
                        self.btc_trading_percent = btc_percent
                        self.type_of_trade = 'BTC'
                        self.trades.append(BotTrade(self.prices,
                                                    stopLoss=0.01))
                    elif (eth_percent > 1.042 * self.eth_historical_percent):
                        self.eth_sentiments = []
                        self.eth_trading_percent = eth_percent
                        self.type_of_trade = 'ETH'
                        self.trades.append(BotTrade(self.prices,
                                                    stopLoss=0.01))
                    else:
                        self.type_of_trade = ''

                time.sleep(60 * 5)

        for trade in openTrades:

            if (self.type_of_trade == 'BTC'):

                bitcoin_query = 'BTC OR Bitcoin OR $BTC'
                btc_tweets, sinceid_recent = tweets.get_tweets(
                    10, 0, bitcoin_query)

                btc_total_score2, btc_positive2, btc_negative2, btc_total2 = tweets.classify(
                    btc_tweets)
                btc_percent = (btc_positive2 / btc_total2) * 100

                self.btc_sentiments.append(btc_percent)

                if (len(self.btc_sentiments) > 5):

                    mean_sentiment = np.mean(self.btc_sentiments)
                    std_sentiment = np.std(self.btc_sentiments)

                    if btc_percent >= mean_sentiment + (
                        (0.800 * std_sentiment) /
                            math.sqrt(len(self.btc_sentiments))):
                        price = self.api.getticker('BTC-ETH')
                        self.currentClose = price['Bid']
                        trade.close(self.currentClose)
                else:
                    time.sleep(60 * 3)

            elif (self.type_of_trade == 'ETH'):

                ethereum_query = 'Ethereum OR ETH OR $ETH'
                eth_tweets, sinceid_recent = tweets.get_tweets(
                    10, 0, ethereum_query)

                eth_total_score2, eth_positive2, eth_negative2, eth_total2 = tweets.classify(
                    eth_tweets)
                eth_percent = (eth_positive2 / eth_total2) * 100

                self.eth_sentiments.append(eth_percent)

                if (len(self.eth_sentiments) > 5):

                    mean_sentiment = np.mean(self.eth_sentiments)
                    std_sentiment = np.std(self.eth_sentiments)

                    if eth_percent <= mean_sentiment - (
                        (0.674 * std_sentiment) /
                            math.sqrt(len(self.eth_sentiments))):
                        price = self.api.getticker('BTC-ETH')
                        self.currentClose = price['Bid']
                        trade.close(self.currentClose)
                else:
                    time.sleep(60 * 3)
            else:
                price = self.api.getticker('BTC-ETH')
                self.currentClose = price['Bid']
                trade.close(self.currentClose)

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

    def showPositions(self):
        for trade in self.trades:
            trade.showTrade()
Exemplo n.º 27
0
class BotTrade(object):
    def __init__(self, pair, current_price, trade_type=None, order_type='market', stop_loss_percent=0):
        self.output = BotLog()
        self.pair = pair
        self.status = "OPEN"
        self.entry_price = 0.0
        self.exit_price = 0.0
        self.entry_cost = 0.0
        self.exit_cost = 0.0
        self.profit = 0.0
        self.fees = 0.0
        self.fee_percentage = 0.0
        self.exit_minus_entry_less_fees = 0.0
        self.trade_pl = None
        self.trade_net_precent = 0.0
        self.trade_type = trade_type  # BUY/SELL
        self.order_type = order_type  # Market/Limit/stop loss/settle position/etc.
        self.min_bid = 0.002
        self.open_time = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')
        self.close_time = "---------- --:--:--"
        self.stop_loss_percent = stop_loss_percent

        self.open_order_id = ""
        self.close_order_id = ""

        # user reference id.  32-bit signed number.
        # 1-bit for sign, 3-bits for 3 decimal digit (0-999), 8-bits for for randomly generated id.
        self.user_ref_id = int(str(BOT_ID) + str(int(random.getrandbits(7))))

        # self.usd_balance = float(Balance())

        # Set volume to higher of 1% of wallet and min bid
        # self.bid_volume = max(self.usd_balance * 0.01 / current_price, 0.002) if current_price else 0.002
        self.bid_volume = 0.002

        # Instantiating a BotTrade object is equivalent to opening a trade. TODO: move open to a function
        if self.trade_type.upper() == 'BUY':
            self._handle_entry_order('buy', current_price)

        if self.trade_type.upper() == 'SELL':
            self._handle_entry_order('sell', current_price)

        statsd.increment('open.order', tags=['name:{}'.format(BOT_NAME),
                                             'pair:{}'.format(self.pair),
                                             'type:{}'.format(self.trade_type),
                                             'order:{}'.format(self.order_type),
                                             'volume:{}'.format(self.bid_volume),
                                             'cur_price:{}'.format(current_price),
                                             'bot_name:{}.bot_id:{}'.format(BOT_NAME, BOT_ID)])

        statsd.increment('total_trading_volume', self.entry_cost, tags=['bot_name:{}.bot_id:{}'.format(BOT_NAME, BOT_ID)])

        statsd.event(title='Order Open',
                     text='{}/{} - {} {} @ {} / Cost: {}'.format(self.open_order_id, self.pair, self.trade_type, self.bid_volume, self.entry_price, self.entry_cost),
                     alert_type='success',
                     tags=['bot_name:{}.bot_id:{}'.format(BOT_NAME, BOT_ID)])

        self.output.log("{c1}{trade_type} Trade opened - order_id: {order_id}{c2}".format(c1=Yellow,
                                                                                          trade_type=self.trade_type.upper(),
                                                                                          order_id=self.open_order_id,
                                                                                          c2=White))

        # TODO: Implement trailing stop loss - might be available on Kraken as a special order type
        # TODO: Implement a daily stop loss, 3% of wallet
        self.stop_loss = current_price * (1.0 - (stop_loss_percent / 100)) if stop_loss_percent else 0

    def close(self, current_price):
        self.status = "CLOSED"
        self.close_time = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')

        if self.trade_type.upper() == "BUY":
            # Make oppostie trade type to close
            self._handle_exit_order('sell', current_price)

        elif self.trade_type.upper() == "SELL":
            # Make oppostie trade type to close
            self._handle_exit_order('buy', current_price)

        statsd.increment('close.order', tags=['name:{}'.format(BOT_NAME),
                                              'pair:{}'.format(self.pair),
                                              'type:{}'.format(self.trade_type),
                                              'order:{}'.format(self.order_type),
                                              'volume:{}'.format(self.bid_volume),
                                              'cur_price:{}'.format(current_price),
                                              'bot_name:{}.bot_id:{}'.format(BOT_NAME, BOT_ID)])

        statsd.event(title='Order Close',
                     text='{}/{} - {} {} @ {} / Cost: {}'.format(self.close_order_id, self.pair, self.trade_type, self.bid_volume, self.exit_price, self.exit_cost),
                     alert_type='success',
                     tags=['bot_name:{}.bot_id:{}'.format(BOT_NAME, BOT_ID)])

        self.output.log("{c1}{trade_type} Trade closed - order_id: {order_id}{c2}".format(c1=Yellow,
                                                     trade_type=self.trade_type.upper(),
                                                     order_id=self.close_order_id,
                                                     c2=White))

        if self.profit >= 0.0:
            self.output.log("Profit/Loss before fees {}".format(self.profit))
            statsd.increment('bottrade.profit', self.profit, tags=['bot_name:{}.bot_id:{}'.format(BOT_NAME, BOT_ID)])
            statsd.increment('bottrade.win_rate', 1, tags=['bot_name:{}.bot_id:{}'.format(BOT_NAME, BOT_ID)])
        else:
            self.output.log("Profit/Loss before fees {}".format(self.profit))
            # Decrement by the absolute value if profit is negative
            statsd.decrement('bottrade.profit', abs(self.profit), tags=['bot_name:{}.bot_id:{}'.format(BOT_NAME, BOT_ID)])
            statsd.decrement('bottrade.win_rate', 1, tags=['bot_name:{}.bot_id:{}'.format(BOT_NAME, BOT_ID)])

        self.output.log("Trade fees at closing: {}".format(self.fees))
        statsd.increment('trading_fees', self.fees, tags=['bot_name:{}.bot_id:{}'.format(BOT_NAME, BOT_ID)])

    def tick(self, current_price):
        if self.stop_loss:
            if current_price < self.stop_loss:  # TODO: Does this work for short trade?
                self.output.log("Closed on stop loss set to {}".format(self.stop_loss_percent))
                self.close(current_price)

    def show_trade(self):
        trade_status = "{c1}{open_time} / {close_time} {order_id} {c2}{order_type}{c3} {bid_vol} @ {entry_price} = ${cost}{c1} {close_order_id} {status} Exit Price: {exit_price}".format(
            bid_vol=self.bid_volume,
            open_time=self.open_time,
            close_time=self.close_time,
            entry_price=str(self.entry_price),
            cost=str(self.entry_cost),
            status=str(self.status),
            exit_price=str(self.exit_price),
            order_id=str(self.open_order_id),
            close_order_id=str(self.close_order_id),
            order_type=str(self.trade_type),
            c1=Purple,
            c2=Red,
            c3=Cyan)

        # TODO: Refactor
        if self.status == "CLOSED":
            trade_status = trade_status + " P/L: "

            self.exit_minus_entry_less_fees = (self.exit_price - self.entry_price) - self.fees

            if self.exit_minus_entry_less_fees > 0:
                if self.trade_type.upper() == 'BUY':
                    trade_status = trade_status + Green
                elif self.trade_type.upper() == 'SELL':
                    trade_status = trade_status + Red

                self.exit_minus_entry_less_fees = (self.exit_price - self.entry_price) - self.fees

            elif self.exit_minus_entry_less_fees < 0:
                if self.trade_type.upper() == 'BUY':
                    trade_status = trade_status + Red
                elif self.trade_type.upper() == 'SELL':
                    trade_status = trade_status + Green

                self.exit_minus_entry_less_fees = (self.entry_price - self.exit_price) - self.fees

            else:
                trade_status = trade_status + White

            # Percent change in market.
            if self.exit_price > 0:
                self.trade_net_precent = 100 * (float(self.exit_price) - (self.entry_price)) / self.exit_price
                self.trade_pl = round((self.entry_price * self.bid_volume) * (self.trade_net_precent / 100) - self.fees, 4)
            else:
                self.trade_net_precent = 0
                self.trade_pl = 0

            trade_status = trade_status + " $" + str(self.trade_pl) + " | $" + str(self.exit_minus_entry_less_fees) + " (" + str(round(self.trade_net_precent, 3)) + "%)" + White

        self.output.log(trade_status + White)

    @staticmethod
    def get_order_price(order_obj):
        order_id = order_obj.get('result').keys()[0]
        return float(order_obj.get('result', {}).get(order_id, {}).get('price'))

    def get_trade_fee_from_order_object(self, order_obj):
        """
        Given a filled order object extracts the trade fee from the associated trade object.

        :param order_obj = Full order object from calling QueryOrders()
        Returns None if order has not yet been filled.
        Returns trade fee amount in dollars.
        """
        fees = 0.0
        try:
            result = order_obj.get('result', {})
            order_id = next(iter(result))
            trade_id_lst = order_obj.get('result', {}).get(order_id, {}).get('trades')
            for id in trade_id_lst:
                trade = QueryTrades(id)
                result = trade.get('result', {})
                trade_obj = result.get(id, {})
                trade_fee = float(trade_obj.get('fee'))
                fees += trade_fee
            return fees
        except Exception:
            return fees

    def _handle_entry_order(self, trade_type, current_price):
        response = AddOrder(self.pair,
                            trade_type.lower(),
                            self.order_type.lower(),
                            self.bid_volume,
                            round(current_price, 1),
                            userref=self.user_ref_id,
                            validate=VALIDATE)

        # Used in paper trading and backtesting
        if VALIDATE:
            self.entry_price = current_price
            self.entry_cost = self.entry_price * self.bid_volume
            self.fee_percentage = float(TradeVolume().get('result', {}).get('fees', {}).get(self.pair, {}).get('fee', 0.2600)) / 100
            self.output.log("fee_percentage: {}".format(self.fee_percentage))
            self.output.log("Trade entry cost {}".format(self.entry_cost))
            self.fees += float(self.entry_cost) * self.fee_percentage

        if response is not None and not response['error']:
            # Extract order id
            self.open_order_id = response.get('result', {'txid': 'N/A'}).get('txid', 'N/A')[0]
            self.open_order_obj = QueryOrders(self.open_order_id, trades=True)
            if not self.open_order_obj['error']:
                # Extract order price
                self.entry_price = self.get_order_price(self.open_order_obj) if not VALIDATE else current_price * self.bid_volume
                self.entry_cost = self.entry_price * self.bid_volume
                self.output.log("Trade entry cost {}".format(self.entry_cost))
                # Extract fees
                self.fees += self.get_trade_fee_from_order_object(self.open_order_obj) if not VALIDATE else 0.0

            if not __debug__:
                msg = json.dumps(response.get('result', {}))
                slack.post("`{}`\n`Price: {} fee: {} cost: {}`".format(msg, self.entry_price, self.fees, self.entry_cost), username=BOT_NAME)

    def _handle_exit_order(self, trade_type, current_price):
        response = AddOrder(self.pair,
                            trade_type.lower(),
                            self.order_type.lower(),
                            self.bid_volume,
                            round(current_price, 1),
                            userref=self.user_ref_id,
                            validate=VALIDATE)

        # Used in paper trading and backtesting
        if VALIDATE:
            self.exit_price = current_price
            self.exit_cost = self.exit_price * self.bid_volume
            self.output.log("fee_percentage: {}".format(self.fee_percentage))
            self.output.log("Trade entry cost {}".format(self.exit_cost))
            self.profit = self.exit_cost - self.entry_cost
            self.fees += float(self.exit_cost) * float(self.fee_percentage)

        if response is not None and not response['error']:
            # Extract order id.
            self.close_order_id = response.get('result', {'txid': '-'}).get('txid', '-')[0]
            self.close_order_obj = QueryOrders(self.close_order_id, trades=True)
            if not self.close_order_obj['error']:
                # Extract order price
                self.exit_price = self.get_order_price(self.close_order_obj) if not VALIDATE else current_price * self.bid_volume
                self.exit_cost = self.exit_price * self.bid_volume
                self.profit = self.exit_cost - self.entry_cost
                self.output.log("Trade exit cost {}".format(self.entry_cost))
                # Extract fees
                self.fees += self.get_trade_fee_from_order_object(self.close_order_obj) if not VALIDATE else 0

            if not __debug__:
                msg = json.dumps(response.get('result', {}))
                slack.post("`{}`\n`Price: {} fee: {} cost: {}`".format(msg, self.exit_price, self.fees, self.exit_cost), username=BOT_NAME)
Exemplo n.º 28
0
def main(argv):
    """
    Main entry point
    """

    # Logging
    output = BotLog()

    supported_exchanges = ['kraken']
    exchange = 'kraken'
    pair = "XXBTZUSD"  # Bitcoin/USD pair on Kraken

    period = 5  # Time frame interval in minutes, e.g. width of candlestick.
    poll_time = 1  # How often an API query is made when using real time data.

    script_help = '\n\t-c --currency <currency pair>\n\t-x --exchange <name of the exchange {exchanges}>\n\t-t --poll <poll period length in minutes>\n\nHistorical Mode\n\t-p --period <period of frame>\n\t-s --start <start time in unix timestamp>\n\t-e --end <end time in unix timestamp>\n'.format(
        exchanges=supported_exchanges)

    start_time = False
    end_time = False

    try:
        opts, args = getopt.getopt(
            argv, "h:x:p:c:t:s:e:y:",
            ["exchange=", "period=", "currency=", "poll=", "start=", "end="])
    except getopt.GetoptError:
        output.log(sys.argv[0] + script_help)
        sys.exit(2)

    for opt, arg in opts:
        if opt == ("-h", "--help"):
            output.log(sys.argv[0] + script_help)
            sys.exit()
        elif opt in ("-s", "--start"):
            start_time = arg
        elif opt in ("-e", "--end"):
            end_time = arg
        elif opt in ("-x", "--exchange"):
            if arg in supported_exchanges:
                exchange = arg
            else:
                output.log(
                    'Supported exchanges are {}'.format(supported_exchanges))
                sys.exit(2)
        elif opt in ("-p", "--period"):
            if exchange.lower() == 'kraken':
                # Kraken uses minutes for getting historical data.
                mins = [1, 5, 15, 30, 60, 240, 1440, 10080, 21600]
                if (int(arg) in mins):
                    period = int(arg)
                else:
                    output.log(
                        'Kraken requires intervals 1, 5, 15, 30, 60, 240, 1440, 10080, 21600 minute intervals'
                    )
                    sys.exit(2)
            else:
                period = int(arg)
        elif opt in ("-c", "--currency"):
            pair = arg
        elif opt in ("-t", "--poll"):
            poll_time = arg

    ################ Strategy in use ################
    strategy = MACDStrategy(pair, period)
    strategy_name = strategy.get_name()
    #################################################

    # Log bot startup event to DataDog
    statsd.event(title='Bot started',
                 text='{}:{} started on {} trading {} using {}'.format(
                     BOT_ID, BOT_NAME, exchange, pair, strategy_name),
                 alert_type='success',
                 tags=['bot_name:{}.bot_id:{}'.format(BOT_NAME, BOT_ID)])

    trade_session_details = "{bg}Trading {pair} on {exchange} with {strat}" \
                            " @ {period} minute period{White}".format(pair=pair,
                                                                      exchange=exchange.upper(),
                                                                      strat=strategy_name,
                                                                      period=period,
                                                                      bg=On_Cyan,
                                                                      White=White)

    if start_time:
        # Backtesting
        chart = BotChart(exchange, pair, period)
        for candlestick in chart.get_points():
            strategy.tick(candlestick)

        output.log(trade_session_details)

    else:
        # Live Trading
        output.log(trade_session_details)

        chart = BotChart(exchange, pair, period, backtest=False)

        candlesticks = []
        developing_candlestick = BotCandlestick(period)

        progress_counter = 0
        while True:
            # Log trade details every so often
            if progress_counter == 50:
                output.log(trade_session_details)
                progress_counter = 0
            progress_counter += 1

            try:
                developing_candlestick.tick(
                    chart.get_current_price_and_vol()[0])
            except urllib2.URLError, err:
                # If network or site is down
                output.log("{}... Continuing".format(err[0]))
                # TODO: These calls to statsd should be Rollbar. Set up Rollbar
                statsd.histogram(
                    'main_loop.urllib2.URLError',
                    err,
                    tags=['bot_name:{}.bot_id:{}'.format(BOT_NAME, BOT_ID)])
                continue
            except ValueError, err:
                # For screwy JSON
                output.log('{}... Continuing'.format(err[0]))
                statsd.histogram(
                    'main_loop.ValueError',
                    err,
                    tags=['bot_name:{}.bot_id:{}'.format(BOT_NAME, BOT_ID)])
                continue
            except urllib2.ssl.SSLError, err:
                # For read timeouts
                output.log("{}... Continuing".format(err[0]))
                statsd.histogram(
                    'main_loop.urllib2.ssl.SSLError',
                    err,
                    tags=['bot_name:{}.bot_id:{}'.format(BOT_NAME, BOT_ID)])
                continue
Exemplo n.º 29
0
class BotTrade(object):
    def __init__(self, order_num, currentPrice, type_trade, loss_break):
        self.output = BotLog()
        self.status = "OPEN"
        self.entryPrice = currentPrice
        self.exitPrice = ""
        self.output.log("Trade opened")
        self.type_trade = type_trade
        self.exit_time = False
        self.Order_num = order_num
        self.Loss_break = loss_break
        self.Balance = False
        self.GRC_bal = False
        self.BTC_bal = False
        self.pair = "BTC_GRC"
        self.out_amount = False

    def close(self, currentPrice):
        self.status = "CLOSED"
        self.exitPrice = currentPrice
        self.output.log("Trade closed")
        self.exit_time = datetime.datetime.now()
        polo.cancelOrder(self.Order_num)

    def tick(self, currentPrice):
        if currentPrice > self.Loss_break * 1.1:
            self.close(currentPrice)
            self.get_out(currentPrice)

    def get_out(self, currentPrice):
        self.Balance = polo.returnBalances()
        self.GRC_bal = float((self.Balance['GRC']))
        self.BTC_bal = float((self.Balance['BTC']))
        self.out_amount = self.BTC_bal / float(currentPrice)
        polo.buy(self.pair, currentPrice, self.out_amount)
        sys.exit()

    def showTrade(self):
        tradeStatus = "Order #: " + str(
            self.Order_num) + " Entry Price: " + str(
                self.entryPrice) + " Status: " + str(
                    self.status) + " Exit Price: " + str(
                        self.exitPrice) + " Trade Type " + str(self.type_trade)
        #+ " Exit Time: " + str(self.exit_time

        if (self.status == "CLOSED") and self.type_trade == "LONG":
            tradeStatus = tradeStatus + " Profit: "
            if (self.exitPrice > self.entryPrice):
                tradeStatus = tradeStatus + "\033[92m"
            else:
                tradeStatus = tradeStatus + "\033[91m"
            tradeStatus = tradeStatus + str(self.exitPrice -
                                            self.entryPrice) + "\033[0m"

        elif (self.status == "CLOSED") and self.type_trade == "SHORT":
            tradeStatus = tradeStatus + " Profit: "
            if (self.exitPrice < self.entryPrice):
                tradeStatus = tradeStatus + "\033[92m"
            else:
                tradeStatus = tradeStatus + "\033[91m"

            tradeStatus = tradeStatus + str(self.entryPrice -
                                            self.exitPrice) + "\033[0m"

        self.output.log(tradeStatus)
Exemplo n.º 30
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)))