예제 #1
0
 def __init__(self, currency):
     self.name = self.__class__.__name__
     self.currency = currency
     self.depth_updated = 0
     self.update_rate = 60
     self.fc = FiatConverter()
     self.fc.update()
예제 #2
0
 def __init__(self, currency, cryptowatch_code=None):
     self.name = self.__class__.__name__
     self.currency = currency
     self.cryptowatch_code = cryptowatch_code
     self.cryptowatch_price = 0
     self.depth_updated = 0
     self.update_rate = 60
     self.fc = FiatConverter()
     self.fc.update()
예제 #3
0
 def __init__(self, currency, config):
     self.name = self.__class__.__name__
     self.currency = currency
     self.depth_updated = 0
     self.config = config or Configuration()
     self.update_rate = self.config.default_market_update_rate
     self.depth = None
     self.fc = FiatConverter(config)
     self.fc.update()
예제 #4
0
 def __init__(self):
     self.name = self.__class__.__name__
     self.btc_balance = 0.
     self.eur_balance = 0.
     self.usd_balance = 0.
     self.pair = config.pair
     pair_names = str.split(self.pair, "_")
     self.pair1_name = str.upper(pair_names[0])
     self.pair2_name = str.upper(pair_names[1])
     self.fc = FiatConverter()
예제 #5
0
class Market(object):
    def __init__(self, currency):
        self.name = self.__class__.__name__
        self.currency = currency
        self.depth_updated = 0
        self.update_rate = 60
        self.fc = FiatConverter()
        self.fc.update()

    def get_depth(self):
        timediff = time.time() - self.depth_updated
        if timediff > self.update_rate:
            self.ask_update_depth()
        timediff = time.time() - self.depth_updated
        if timediff > config.market_expiration_time:
            logging.warn("Market: %s order book is expired" % self.name)
            self.depth = {"asks": [{"price": 0, "amount": 0}], "bids": [{"price": 0, "amount": 0}]}
        return self.depth

    def convert_to_usd(self):
        if self.currency == "USD":
            return
        for direction in ("asks", "bids"):
            for order in self.depth[direction]:
                order["price"] = self.fc.convert(order["price"], self.currency, "USD")

    def ask_update_depth(self):
        try:
            self.update_depth()
            self.convert_to_usd()
            self.depth_updated = time.time()
        except (urllib.error.HTTPError, urllib.error.URLError) as e:
            logging.error("HTTPError, can't update market: %s" % self.name)
            log_exception(logging.DEBUG)
        except Exception as e:
            logging.error("Can't update market: %s - %s" % (self.name, str(e)))
            log_exception(logging.DEBUG)

    def get_ticker(self):
        depth = self.get_depth()
        res = {"ask": 0, "bid": 0}
        if len(depth["asks"]) > 0 and len(depth["bids"]) > 0:
            res = {"ask": depth["asks"][0], "bid": depth["bids"][0]}
        return res

    ## Abstract methods
    def update_depth(self):
        pass

    def buy(self, price, amount):
        pass

    def sell(self, price, amount):
        pass
예제 #6
0
class Market:
    def __init__(self):
        self.name = self.__class__.__name__
        self.btc_balance = 0.0
        self.eur_balance = 0.0
        self.usd_balance = 0.0
        self.fc = FiatConverter()

    def __str__(self):
        return "%s: %s" % (
            self.name,
            str(
                {
                    "btc_balance": self.btc_balance,
                    "eur_balance": self.eur_balance,
                    "usd_balance": self.usd_balance,
                }
            ),
        )

    def buy(self, amount, price):
        """Orders are always priced in USD"""
        local_currency_price = self.fc.convert(price, "USD", self.currency)
        logging.info(
            "Buy %f BTC at %f %s (%f USD) @%s"
            % (amount, local_currency_price, self.currency, price, self.name)
        )
        self._buy(amount, local_currency_price)

    def sell(self, amount, price):
        """Orders are always priced in USD"""
        local_currency_price = self.fc.convert(price, "USD", self.currency)
        logging.info(
            "Sell %f BTC at %f %s (%f USD) @%s"
            % (amount, local_currency_price, self.currency, price, self.name)
        )
        self._sell(amount, local_currency_price)

    def _buy(self, amount, price):
        raise NotImplementedError("%s.sell(self, amount, price)" % self.name)

    def _sell(self, amount, price):
        raise NotImplementedError("%s.sell(self, amount, price)" % self.name)

    def deposit(self):
        raise NotImplementedError("%s.sell(self, amount, price)" % self.name)

    def withdraw(self, amount, address):
        raise NotImplementedError("%s.sell(self, amount, price)" % self.name)

    def get_info(self):
        raise NotImplementedError("%s.sell(self, amount, price)" % self.name)
예제 #7
0
 def __init__(self, currency):
     self.name = self.__class__.__name__
     self.currency = currency
     self.depth_updated = 0
     self.update_rate = 0.5
     self.isWebsocket = False
     self.shouldReportWebsocketTimeout = False
     if currency == "BTC":
         self.fiat = False
     else:
         self.fiat = True
         self.fc = FiatConverter()
         self.fc.update()
예제 #8
0
class Market:
    def __init__(self):
        self.name = self.__class__.__name__
        self.btc_balance = 0.0
        self.eur_balance = 0.0
        self.usd_balance = 0.0
        self.fc = FiatConverter()

    def __str__(self):
        return "%s: %s" % (
            self.name,
            str({
                "btc_balance": self.btc_balance,
                "eur_balance": self.eur_balance,
                "usd_balance": self.usd_balance,
            }),
        )

    def buy(self, amount, price):
        """Orders are always priced in USD"""
        local_currency_price = self.fc.convert(price, "USD", self.currency)
        logging.info(
            "Buy %f BTC at %f %s (%f USD) @%s" %
            (amount, local_currency_price, self.currency, price, self.name))
        self._buy(amount, local_currency_price)

    def sell(self, amount, price):
        """Orders are always priced in USD"""
        local_currency_price = self.fc.convert(price, "USD", self.currency)
        logging.info(
            "Sell %f BTC at %f %s (%f USD) @%s" %
            (amount, local_currency_price, self.currency, price, self.name))
        self._sell(amount, local_currency_price)

    def _buy(self, amount, price):
        raise NotImplementedError("%s.sell(self, amount, price)" % self.name)

    def _sell(self, amount, price):
        raise NotImplementedError("%s.sell(self, amount, price)" % self.name)

    def deposit(self):
        raise NotImplementedError("%s.sell(self, amount, price)" % self.name)

    def withdraw(self, amount, address):
        raise NotImplementedError("%s.sell(self, amount, price)" % self.name)

    def get_info(self):
        raise NotImplementedError("%s.sell(self, amount, price)" % self.name)
예제 #9
0
 def __init__(self, currency):
     self.name = self.__class__.__name__
     self.currency = currency
     self.depth_updated = 0
     self.update_rate = 60
     self.fc = FiatConverter()
     self.fc.update()
예제 #10
0
 def __init__(self):
     self.clients = {
         # TODO: move that to the config file
         # "BitstampUSD": bitstampusd.PrivateBitstampUSD(),
     }
     self.fc = FiatConverter()
     self.trade_wait = 120  # in seconds
     self.last_trade = 0
     self.potential_trades = []
 def __init__(self):
     self.clients = {}
     for client in config.clients:
         client_module = importlib.import_module(
             "arbitrage.private_markets.{}".format(client.lower()))
         client_class = getattr(client_module, "Private{}".format(client))
         self.clients[client] = client_class()
     self.fc = FiatConverter()
     self.trade_wait = 120  # in seconds
     self.last_trade = 0
     self.potential_trades = []
예제 #12
0
class Market(object):
    def __init__(self, currency):
        self.name = self.__class__.__name__
        self.currency = currency
        self.depth_updated = 0
        self.update_rate = 0.5
        self.isWebsocket = False
        self.shouldReportWebsocketTimeout = False
        if currency == "BTC":
            self.fiat = False
        else:
            self.fiat = True
            self.fc = FiatConverter()
            self.fc.update()

    def get_depth(self):
        timediff = time.time() - self.depth_updated
        if timediff > self.update_rate:
            self.ask_update_depth()
        timediff = time.time() - self.depth_updated
        if timediff > config.market_expiration_time:
            _str = 'Market: %s order book is expired' % self.name
            logging.warn(_str)
            send_message(_str)
            self.depth = {
                'asks': [{
                    'price': 0,
                    'amount': 0
                }],
                'bids': [{
                    'price': 0,
                    'amount': 0
                }]
            }
            raise Exception('get depth timeout.')
        return self.depth

    def convert_to_usd(self):
        if self.currency == "USD":
            return
        for direction in ("asks", "bids"):
            for order in self.depth[direction]:
                order["price"] = self.fc.convert(order["price"], self.currency,
                                                 "USD")

    def ask_update_depth(self):
        try:
            self.update_depth()
            if self.fiat:
                self.convert_to_usd()
            self.depth_updated = time.time()
            self.shouldReportWebsocketTimeout = True
        except (urllib.error.HTTPError, urllib.error.URLError) as e:
            logging.error("HTTPError, can't update market: %s" % self.name)
            log_exception(logging.DEBUG)
        except Exception as e:
            if not self.isWebsocket:
                logging.error("Can't update market: %s - %s" %
                              (self.name, str(e)))
                log_exception(logging.DEBUG)
            else:
                #don't repeat report
                if self.shouldReportWebsocketTimeout:
                    logging.error(str(e))
                    self.shouldReportWebsocketTimeout = False

    def get_ticker(self):
        depth = self.get_depth()
        res = {'ask': 0, 'bid': 0}
        if len(depth['asks']) > 0 and len(depth["bids"]) > 0:
            res = {'ask': depth['asks'][0], 'bid': depth['bids'][0]}
        return res

    ## Abstract methods
    def update_depth(self):
        pass

    def buy(self, price, amount):
        pass

    def sell(self, price, amount):
        pass
예제 #13
0
 def __init__(self):
     self.name = self.__class__.__name__
     self.btc_balance = 0.0
     self.eur_balance = 0.0
     self.usd_balance = 0.0
     self.fc = FiatConverter()
예제 #14
0
class Market(object):
    def __init__(self, currency):
        self.name = self.__class__.__name__
        self.currency = currency
        self.depth_updated = 0
        self.update_rate = 60
        self.fc = FiatConverter()
        self.fc.update()

    def get_depth(self):
        timediff = time.time() - self.depth_updated
        if timediff > self.update_rate:
            self.ask_update_depth()
        timediff = time.time() - self.depth_updated
        if timediff > config.market_expiration_time:
            logging.warn("Market: %s order book is expired" % self.name)
            self.depth = {
                "asks": [{
                    "price": 0,
                    "amount": 0
                }],
                "bids": [{
                    "price": 0,
                    "amount": 0
                }]
            }
        return self.depth

    def convert_to_usd(self):
        if self.currency == "USD":
            return
        for direction in ("asks", "bids"):
            for order in self.depth[direction]:
                order["price"] = self.fc.convert(order["price"], self.currency,
                                                 "USD")

    def ask_update_depth(self):
        try:
            self.update_depth()
            self.convert_to_usd()
            self.depth_updated = time.time()
        except (urllib.error.HTTPError, urllib.error.URLError) as e:
            logging.error("HTTPError, can't update market: %s" % self.name)
            log_exception(logging.DEBUG)
        except Exception as e:
            logging.error("Can't update market: %s - %s" % (self.name, str(e)))
            log_exception(logging.DEBUG)

    def get_ticker(self):
        depth = self.get_depth()
        res = {"ask": 0, "bid": 0}
        if len(depth["asks"]) > 0 and len(depth["bids"]) > 0:
            res = {"ask": depth["asks"][0], "bid": depth["bids"][0]}
        return res

    ## Abstract methods
    def update_depth(self):
        pass

    def buy(self, price, amount):
        pass

    def sell(self, price, amount):
        pass
예제 #15
0
class Market(object):
    def __init__(self, currency, cryptowatch_code=None):
        self.name = self.__class__.__name__
        self.currency = currency
        self.cryptowatch_code = cryptowatch_code
        self.cryptowatch_price = 0
        self.depth_updated = 0
        self.update_rate = 60
        self.fc = FiatConverter()
        self.fc.update()

    def get_cryptowatch_price(self):
        if not self.cryptowatch_code:
            return

        url = ('https://api.cryptowat.ch/markets/' +
               self.name.lower().replace('usd', '').replace('eur', '') + '/' +
               self.cryptowatch_code + '/price')

        res = urllib.request.urlopen(url)
        jsonstr = res.read().decode('utf8')
        try:
            price = json.loads(jsonstr)
        except Exception:
            logging.error("Cryptowatch %s - Can't parse json: %s" %
                          (self.name, jsonstr))
        self.cryptowatch_price = self.fc.convert(price["result"]["price"],
                                                 self.currency, "USD")

    def double_ckeck_price(self, price, direction, allowed_percent=None):
        if self.cryptowatch_price == 0:
            self.get_cryptowatch_price()

        allowed_percent = allowed_percent if allowed_percent else 10

        if abs(price - self.cryptowatch_price
               ) > self.cryptowatch_price * allowed_percent / 100:
            logging.error(
                "Big diff. @%s depth price(%s) vs Cryptowatch price %f / %f" %
                (self.name, direction, price, self.cryptowatch_price))
            return False

        return True

    def get_depth(self):
        timediff = time.time() - self.depth_updated
        if timediff > self.update_rate:
            self.ask_update_depth()
        timediff = time.time() - self.depth_updated
        if timediff > config.market_expiration_time:
            logging.warning('Market: %s order book is expired' % self.name)
            self.depth = {
                'asks': [{
                    'price': 0,
                    'amount': 0
                }],
                'bids': [{
                    'price': 0,
                    'amount': 0
                }]
            }
        return self.depth

    def convert_to_usd(self):
        if self.currency == "USD":
            return
        for direction in ("asks", "bids"):
            for order in self.depth[direction]:
                # self.double_ckeck_price(order["price"], direction, order)
                # we don't do it here any more
                order["price"] = self.fc.convert(order["price"], self.currency,
                                                 "USD")

    # there are some prices inside the market depth that are ment to de destabilize the market
    # clear them out
    def sort_out_market_crush_prices(self):
        new_depth = {'asks': [], 'bids': []}
        for direction in ("asks", "bids"):
            for order in self.depth[direction]:
                if self.double_ckeck_price(order["price"], direction, 30):
                    new_depth[direction].append(order)

        if len(new_depth["ask"]) != len(self.depth["ask"]) or len(
                new_depth["bids"]) != len(self.depth["bids"]):
            logging.warning(
                'Market: %s removed some market crush crush items' % self.name)

        self.depth = new_depth

    def ask_update_depth(self):
        try:
            self.update_depth()
            self.convert_to_usd()
            self.get_cryptowatch_price()
            self.depth_updated = time.time()
        except (urllib.error.HTTPError, urllib.error.URLError) as e:
            logging.error("HTTPError, can't update market: %s" % self.name)
            log_exception(logging.DEBUG)
        except Exception as e:
            logging.error("Can't update market: %s - %s" % (self.name, str(e)))
            log_exception(logging.DEBUG)

    def get_ticker(self):
        depth = self.get_depth()
        res = {'ask': 0, 'bid': 0}
        if len(depth['asks']) > 0 and len(depth["bids"]) > 0:
            res = {'ask': depth['asks'][0], 'bid': depth['bids'][0]}
        return res

    ## Abstract methods
    def update_depth(self):
        pass

    def buy(self, price, amount):
        pass

    def sell(self, price, amount):
        pass
예제 #16
0
class Market(object):
    def __init__(self, currency):
        self.name = self.__class__.__name__
        self.currency = currency
        self.depth_updated = 0
        self.update_rate = 60
        self.fc = FiatConverter()
        self.fc.update()

    def get_depth(self):
        timediff = time.time() - self.depth_updated
        if timediff > self.update_rate:
            self.ask_update_depth()
        timediff = time.time() - self.depth_updated
        if timediff > config.market_expiration_time:
            logging.warn('Market: %s order book is expired' % self.name)
            self.depth = {
                'asks': [{
                    'price': 0,
                    'amount': 0
                }],
                'bids': [{
                    'price': 0,
                    'amount': 0
                }]
            }
        return self.depth

    def ask_update_depth(self):
        try:
            self.update_depth()
            self.invert()
            self.depth_updated = time.time()
        except (urllib.error.HTTPError, urllib.error.URLError) as e:
            logging.error("HTTPError, can't update market: %s" % self.name)
            log_exception(logging.DEBUG)
        except Exception as e:
            logging.error("Can't update market: %s - %s" % (self.name, str(e)))
            log_exception(logging.DEBUG)

    def get_ticker(self):
        depth = self.get_depth()
        res = {'ask': 0, 'bid': 0}
        if len(depth['asks']) > 0 and len(depth["bids"]) > 0:
            res = {'ask': depth['asks'][0], 'bid': depth['bids'][0]}
        return res

    def invert(self):
        if not self.should_invert():
            return
        for ask in self.depth['asks']:
            ask['amount'] = ask['amount'] * ask['price']
            ask['price'] = 1.0 / ask['price']
        for bid in self.depth['bids']:
            bid['amount'] = bid['amount'] * bid['price']
            bid['price'] = 1.0 / bid['price']
        bids = self.depth['asks']
        asks = self.depth['bids']
        self.depth['asks'] = asks
        self.depth['bids'] = bids

    ## Abstract methods
    def update_depth(self):
        pass

    def buy(self, price, amount):
        pass

    def sell(self, price, amount):
        pass

    def should_invert(self):
        return False
예제 #17
0
class Market(object):
    def __init__(self, currency):
        self.name = self.__class__.__name__
        self.currency = currency
        self.depth_updated = 0
        self.update_rate = 60
        self.fc = FiatConverter()
        self.fc.update()

    def get_depth(self):
        """
        @todo Use websocket and reduce the update_rate to realtime, only fall back to RESTful when wss is broken.
        """
        timediff = time.time() - self.depth_updated
        if timediff > self.update_rate:
            self.ask_update_depth()
        timediff = time.time() - self.depth_updated
        if timediff > config.market_expiration_time:  # depth data not updated properly. why? FIXME
            logging.warn("Market: %s order book is expired" % self.name)
            self.depth = {
                "asks": [{
                    "price": 0,
                    "amount": 0
                }],
                "bids": [{
                    "price": 0,
                    "amount": 0
                }]
            }
        return self.depth

    def convert_to_usd(self):
        if self.currency == "USD":
            return
        for direction in ("asks", "bids"):
            for order in self.depth[direction]:
                order["price"] = self.fc.convert(order["price"], self.currency,
                                                 "USD")

    def ask_update_depth(self):
        try:
            self.update_depth()
            self.convert_to_usd()
            self.depth_updated = time.time()
        except (urllib.error.HTTPError, urllib.error.URLError) as e:
            logging.error("HTTPError, can't update market: %s" % self.name)
            log_exception(logging.DEBUG)
        except Exception as e:
            logging.error("Can't update market: %s - %s" % (self.name, str(e)))
            log_exception(logging.DEBUG)

    def get_ticker(self):
        depth = self.get_depth()
        res = {"ask": 0, "bid": 0}
        if len(depth["asks"]) > 0 and len(depth["bids"]) > 0:
            res = {"ask": depth["asks"][0], "bid": depth["bids"][0]}
        return res

    ## Abstract methods
    def update_depth(self):
        pass

    def buy(self, price, amount):
        pass

    def sell(self, price, amount):
        pass

    def _depth_pct(self, pct):
        bid1 = float(self.depth['bids'][0]['price'])
        ask1 = float(self.depth['asks'][0]['price'])
        fair = bid1 * 0.5 + ask1 * 0.5
        ceiling, floor = fair * (1 + pct / 100), fair * (1 - pct / 100)

        bid_sum = 0
        for bid in self.depth['bids']:
            if float(bid['price']) > floor:
                bid_sum += float(bid['amount'])
            else:
                break

        ask_sum = 0
        for ask in self.depth['asks']:
            if float(ask['price']) < ceiling:
                ask_sum += float(ask['amount'])
            else:
                break

        def _f(v):
            return int(v * 100) / 100

        return 'pct depth [bid, ask]: [ %s, %s ]' % (_f(bid_sum), _f(ask_sum))

    def depth_1pct(self):
        return self._depth_pct(1)

    def depth_01pct(self):
        return self._depth_pct(0.1)
예제 #18
0
class MarketBase(object, metaclass=Plugin):
    """"""
    def __init__(self, currency, config):
        self.name = self.__class__.__name__
        self.currency = currency
        self.depth_updated = 0
        self.config = config or Configuration()
        self.update_rate = self.config.default_market_update_rate
        self.depth = None
        self.fc = FiatConverter(config)
        self.fc.update()

    def set_config(self, config):
        self.config = config

    def get_depth(self):
        time_diff = time.time() - self.depth_updated
        if time_diff > self.update_rate:
            self.ask_update_depth()
        time_diff = time.time() - self.depth_updated
        if time_diff > self.config.market_expiration_time:
            LOG.warning('Market: %s order book is expired' % self.name)
            self.depth = {
                'asks': [{
                    'price': 0,
                    'amount': 0
                }],
                'bids': [{
                    'price': 0,
                    'amount': 0
                }]
            }
        return self.depth

    def convert_to_usd(self):
        if self.currency == "USD":
            return
        for direction in ("asks", "bids"):
            for order in self.depth[direction]:
                order["price"] = self.fc.convert(order["price"], self.currency,
                                                 "USD")

    def ask_update_depth(self):
        try:
            self.update_depth()
            self.convert_to_usd()
            self.depth_updated = time.time()
        except (urllib.error.HTTPError, urllib.error.URLError) as e:
            LOG.exception("HTTPError, can't update market: %s" % self.name)
        except Exception as e:
            LOG.exception("Can't update market: %s - %s" % (self.name, str(e)))

    def get_ticker(self):
        depth = self.get_depth()
        res = {'ask': 0, 'bid': 0}
        if len(depth['asks']) > 0 and len(depth["bids"]) > 0:
            res = {'ask': depth['asks'][0], 'bid': depth['bids'][0]}
        return res

    def update_depth(self):
        pass

    def buy(self, price, amount):
        pass

    def sell(self, price, amount):
        pass
예제 #19
0
 def __init__(self):
     self.name = self.__class__.__name__
     self.btc_balance = 0.
     self.eur_balance = 0.
     self.usd_balance = 0.
     self.fc = FiatConverter()