Exemple #1
0
class Liqui:
    def __init__(self, key, secret):
        self.logger = Logger(__name__)

        try:
            self.client = Client(key, secret)
        except Exception as e:
            self.logger.log(e)
            raise ExchangeException(self.__class__.__name__, e)

    def getBalances(self):
        try:
            result = self.client.balances()
            balances = {}

            for currency in result.keys():
                name = currency.upper()
                value = float(result[currency])

                if value > Config.BALANCE_ZERO:
                    balances[name] = value

            return balances
        except Exception as e:
            self.logger.log(e)
            raise ExchangeException(self.__class__.__name__, e)
Exemple #2
0
    def __init__(self, key, secret):
        self.logger = Logger(__name__)

        try:
            self.client = Client(key, secret)
        except Exception as e:
            self.logger.log(e)
            raise ExchangeException(self.__class__.__name__, e)
Exemple #3
0
 def __init__(self):
     self.liqui = Liqui(settings.LIQUI.API_KEY, settings.LIQUI.API_SECRET)
     self.binance = Client(settings.BINANCE.API_KEY,
                           settings.BINANCE.API_SECRET)
     self.markets = {
         'LIQUI':
         ccxt.liqui({
             'apiKey': settings.LIQUI.API_KEY,
             'secret': settings.LIQUI.API_SECRET
         }),
         'BINANCE':
         ccxt.binance({
             'apiKey': settings.BINANCE.API_KEY,
             'secret': settings.BINANCE.API_SECRET
         })
     }
     self.minimum_order = settings.MINIMUM_AMOUNT_TO_TRADE
Exemple #4
0
    def __init__(self):
        self.liqui = Liqui(settings.LIQUI.API_KEY, settings.LIQUI.API_SECRET)
        self.binance = Client(settings.BINANCE.API_KEY,
                              settings.BINANCE.API_SECRET)
        self.markets = {
            'LIQUI':
            ccxt.liqui({
                'apiKey': settings.LIQUI.API_KEY,
                'secret': settings.LIQUI.API_SECRET,
                'timeout': settings.LIQUI.TIMEOUT
            }),
            'BINANCE':
            ccxt.binance({
                'apiKey': settings.BINANCE.API_KEY,
                'secret': settings.BINANCE.API_SECRET,
                'timeout': settings.BINANCE.TIMEOUT
            })
        }

        # Init markets
        for key, value in self.markets.items():
            value.load_markets()
Exemple #5
0
class Liqui:
    def __init__(self, key, secret):
        self.client = Client(key, secret)
        self.logger = Logger(__name__)

    def getBalances(self):
        try:
            result = self.client.balances()
            balances = {}

            for currency in result.keys():
                name = currency.encode('utf-8').upper()
                value = float(result[currency])

                if value > 0.0:
                    balances[name] = value

            return balances
        except Exception as e:
            self.logger.log(e)
            raise ExchangeException(self.__class__.__name__, e.message)
Exemple #6
0
 def __init__(self, key, secret):
     self.client = Client(key, secret)
     self.logger = Logger(__name__)
Exemple #7
0
class Trader(object):
    _sleep_time = 5
    _pair = "{}/ETH"
    _LIMIT = "limit"

    def __init__(self):
        self.liqui = Liqui(settings.LIQUI.API_KEY, settings.LIQUI.API_SECRET)
        self.binance = Client(settings.BINANCE.API_KEY,
                              settings.BINANCE.API_SECRET)
        self.markets = {
            'LIQUI':
            ccxt.liqui({
                'apiKey': settings.LIQUI.API_KEY,
                'secret': settings.LIQUI.API_SECRET,
                'timeout': settings.LIQUI.TIMEOUT
            }),
            'BINANCE':
            ccxt.binance({
                'apiKey': settings.BINANCE.API_KEY,
                'secret': settings.BINANCE.API_SECRET,
                'timeout': settings.BINANCE.TIMEOUT
            })
        }

        # Init markets
        for key, value in self.markets.items():
            value.load_markets()

    @staticmethod
    def new_exposure(exposure):
        current_profit = exposure - 1
        minimum_profit = settings.PROFIT_FACTOR - 1

        new_profit = current_profit * (
            1 - settings.PROFIT_REDUCTION / minimum_profit)
        new_exposure = round(1 + new_profit, 6)

        logger.info("New exposure: {}".format(new_exposure))

        return new_exposure

    @staticmethod
    def profit_reduction(exposure):
        current_profit = exposure - 1
        minimum_profit = settings.PROFIT_FACTOR - 1

        reduction = round(
            current_profit * settings.PROFIT_REDUCTION / minimum_profit, 10)

        logger.info("Profit reduction: {}".format(reduction))

        return reduction

    @staticmethod
    def fill_buy_sell_order(order, market):
        return Order(market, order.get('id'),
                     Analyser.extract_type(order, market),
                     Analyser.extract_start_amount(order, market),
                     Analyser.extract_remaining_amount2(order, market),
                     Analyser.extract_price2(order, market),
                     Analyser.extract_status(order, market))

    @staticmethod
    def fill_fetch_order(order, market):
        return Order(market, order.get('id'),
                     Analyser.extract_type(order, market),
                     Analyser.extract_start_amount(order, market),
                     Analyser.extract_remaining_amount_order(order, market),
                     Analyser.extract_price2(order, market),
                     Analyser.extract_status_order(order, market))

    def buy(self, market, coin, volume, rate):
        symbol = self._pair.format(coin)
        volume = self.markets.get(market).amount_to_lots(symbol, volume)
        return self.markets.get(market).create_order(symbol, self._LIMIT,
                                                     'buy', volume, rate)

    def sell(self, market, coin, volume, rate):
        symbol = self._pair.format(coin)
        volume = self.markets.get(market).amount_to_lots(symbol, volume)
        return self.markets.get(market).create_order(symbol, self._LIMIT,
                                                     'sell', volume, rate)

    def cancel_order(self, market, coin, order_id):
        symbol = self._pair.format(coin)
        return self.markets.get(market).cancel_order(order_id, symbol)

    def fetch_order(self, market, coin, order_id):
        symbol = self._pair.format(coin)
        return self.markets.get(market).fetch_order(order_id, symbol)

    def buy_coin(self, coin, market, amount, price):
        # Temporary origin market checking until abstracted
        if market == "LIQUI":
            pair = "{}_eth".format(coin).lower()
            order = self.liqui.buy(pair, price, amount)
            order_id = order.get("order_id")
        elif market == "BINANCE":
            symbol = "{}ETH".format(coin)
        else:
            logger.error("Unknown market: {}".format(market))
            return -1

        logger.info("Buying {} {} at {} on {}. ID: {}".format(
            amount, coin, price, market, order_id))
        return order_id

    def sell_coin(self, coin, market, amount, price):
        # Temporary origin market checking until abstracted
        if market == "LIQUI":
            pair = "{}_eth".format(coin).lower()
            order = self.liqui.sell(pair, price, amount)
            order_id = order.get("order_id")
        elif market == "BINANCE":
            symbol = "{}ETH".format(coin)
        else:
            logger.error("Unknown market: {}".format(market))
            return -1

        logger.info("Selling {} {} at {} on {}. ID: {}".format(
            amount, coin, price, market, order_id))
        return order_id

    def wait_for_order(self, order_id, market, timeout=300):
        completed = False
        while not completed:
            timeout -= self._sleep_time
            time.sleep(self._sleep_time)
            if timeout <= 0:
                logger.error(
                    "Order {} is taking too long to complete".format(order_id))
                return False

            # Temporary origin market checking until abstracted
            if market == "LIQUI":
                order_info = self.liqui.order_info(order_id)
                status = order_info.get(order_id).get("status")
                if status != 0:
                    completed = True
            elif market == "BINANCE":
                pass
            else:
                logger.error("Unknown market: {}".format(market))
                return False

        logger.info("Order {} completed".format(order_id))
        return True
Exemple #8
0
class Analyser(object):
    _pair = "{}/ETH"
    _LIMIT = "limit"

    def __init__(self):
        self.liqui = Liqui(settings.LIQUI.API_KEY, settings.LIQUI.API_SECRET)
        self.binance = Client(settings.BINANCE.API_KEY,
                              settings.BINANCE.API_SECRET)
        self.markets = {
            'LIQUI':
            ccxt.liqui({
                'apiKey': settings.LIQUI.API_KEY,
                'secret': settings.LIQUI.API_SECRET
            }),
            'BINANCE':
            ccxt.binance({
                'apiKey': settings.BINANCE.API_KEY,
                'secret': settings.BINANCE.API_SECRET
            })
        }
        self.minimum_order = settings.MINIMUM_AMOUNT_TO_TRADE

    def get_coin_analysis(self, coin, origin, destination):
        coin_analysis = CoinAnalysis(coin=coin,
                                     origin=origin,
                                     destination=destination)

        # Temporary origin market checking until abstracted
        if origin == "LIQUI":
            pair = "{}_eth".format(coin).lower()
            origin_ticker = self.liqui.ticker(pair)
            origin_last_price = origin_ticker.get(pair).get('last')
        elif origin == "BINANCE":
            symbol = "{}ETH".format(coin)
            origin_ticker = self.binance.get_ticker(symbol=symbol)
            origin_last_price = float(origin_ticker.get('lastPrice'))
        else:
            logger.error("Unknown origin market: {}".format(origin))
            return coin_analysis

        coin_analysis.origin_price = origin_last_price
        logger.debug("Last price for origin market {} is {:.7f}".format(
            origin, origin_last_price))

        # Temporary destination market checking until abstracted
        if destination == "LIQUI":
            pair = "{}_eth".format(coin).lower()
            destination_ticker = self.liqui.ticker(pair)
            destination_last_price = destination_ticker.get(pair).get('last')
        elif destination == "BINANCE":
            symbol = "{}ETH".format(coin)
            destination_ticker = self.binance.get_ticker(symbol=symbol)
            destination_last_price = float(destination_ticker.get('lastPrice'))
        else:
            logger.error("Unknown destination market: {}".format(origin))
            return coin_analysis

        coin_analysis.destination_price = destination_last_price
        logger.debug("Last price for destination market {} is {:.7f}".format(
            destination, destination_last_price))

        coin_analysis.profit_factor = round(
            destination_last_price / origin_last_price, 6)

        logger.debug("Profit Factor: {}".format(coin_analysis.profit_factor))

        return coin_analysis

    async def get_latest_depth(self, market, coin, params={}):
        return await self.markets.get(market).fetch_order_book(
            self._pair.format(coin), params=params)

    async def get_balance(self, market, params={}):
        return await self.markets.get(market).fetch_balance(params=params)

    def is_order_filled(self, order, order_id, market):
        """
        Use this method when parsing the result of an order fetch

        :param order:
        :param order_id:
        :param market:
        :return:
        """
        # TODO: Refactor to add markets more easily
        if market == "LIQUI":
            if order.get("info").get("return").get(
                    str(order_id)).get("status") == 1:
                return True
        elif market == "BINANCE":
            if order.get("info").get("status") == "FILLED":
                return True
        else:
            logger.error("Cannot extract status for market {}".format(market))
        return False

    def extract_amount(self, order, market):
        # TODO: Refactor to add markets more easily
        if market == "LIQUI":
            return order.get("info").get("return").get("received")
        elif market == "BINANCE":
            return float(order.get("info").get("executedQty"))
        else:
            logger.error("Cannot extract status for market {}".format(market))
        return 0

    def extract_remaining_amount(self, order, market):
        # TODO: Refactor to add markets more easily
        if market == "LIQUI":
            return order.get("info").get("return").get("remains")
        elif market == "BINANCE":
            price = float(order.get("info").get("origQty")) - float(
                order.get("info").get("executedQty"))
            logger.debug(price)
            return price
        else:
            logger.error(
                "Cannot remaining amount for market {}".format(market))
        return 0

    def extract_order_executed_amount(self, order, order_id, market):
        # TODO: Refactor to add markets more easily
        if market == "LIQUI":
            return order.get("info").get("return").get(
                str(order_id)).get("amount")
        elif market == "BINANCE":
            return float(order.get("info").get("executedQty"))
        else:
            logger.error("Cannot executed amount for market {}".format(market))
        return 0

    def extract_price(self, order, market):
        # TODO: Refactor to add markets more easily
        if market == "LIQUI":
            return order.get("price")
        elif market == "BINANCE":
            return float(order.get("info").get("price"))
        else:
            logger.error("Cannot extract status for market {}".format(market))
        return 0

    @staticmethod
    def extract_type(order, market):
        if market == "LIQUI":
            return Types[order.get("side").upper()]
        elif market == "BINANCE":
            return Types[order.get("info").get("side")]
        else:
            logger.error("Cannot extract type for market {}".format(market))
        return Types.UNKNOWN

    @staticmethod
    def extract_start_amount(order, market):
        if market == "LIQUI":
            return order.get("amount")
        elif market == "BINANCE":
            return float(order.get("info").get("origQty"))
        else:
            logger.error(
                "Cannot extract start amount for market {}".format(market))
        return 0

    @staticmethod
    def extract_remaining_amount2(order, market):
        if market == "LIQUI":
            return order.get("info").get("return").get("remains")
        elif market == "BINANCE":
            return float(order.get("info").get("origQty")) - float(
                order.get("info").get("executedQty"))
        else:
            logger.error(
                "Cannot extract remaining amount for market {}".format(market))
        return 0

    @staticmethod
    def extract_remaining_amount_order(order, market):
        if market == "LIQUI":
            return order.get("info").get("amount")
        elif market == "BINANCE":
            return float(order.get("info").get("origQty")) - float(
                order.get("info").get("executedQty"))
        else:
            logger.error(
                "Cannot extract remaining amount for market {} (order)".format(
                    market))
        return 0

    @staticmethod
    def extract_price2(order, market):
        if market == "LIQUI":
            return order.get("price")
        elif market == "BINANCE":
            return float(order.get("info").get("price"))
        else:
            logger.error("Cannot extract price for market {}".format(market))
        return 0

    @staticmethod
    def extract_status(order, market):
        if market == "LIQUI":
            if order.get("info").get("return").get("order_id") == 0:
                return Status.DONE
            else:
                return Status.ONGOING
        elif market == "BINANCE":
            if order.get("info").get("status") == "FILLED":
                return Status.DONE
            else:
                return Status.ONGOING
        else:
            logger.error("Cannot extract status for market {}".format(market))
        return Status.UNKNOWN

    @staticmethod
    def extract_status_order(order, market):
        if market == "LIQUI":
            return {
                0: Status.ONGOING,
                1: Status.DONE,
                2: Status.CANCELLED,
                3: Status.CANCELLED
            }[order.get("info").get("status")]
        elif market == "BINANCE":
            return {
                'NEW': Status.ONGOING,
                'PARTIALLY_FILLED': Status.ONGOING,
                'FILLED': Status.DONE,
                'CANCELED': Status.CANCELLED
            }[order.get("info").get("status")]
        else:
            logger.error(
                "Cannot extract status for market {} (order)".format(market))
        return Status.UNKNOWN

    @staticmethod
    def is_filled(order, market):
        if Analyser.extract_status(order, market) == Status.DONE:
            return True
        else:
            return False

    def extract_good_order(self, orders):
        for order in orders:
            if order[0] * order[1] > self.minimum_order:
                return order
        logger.error("No good order found")
        return [orders[0][0], 0]