]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Trader.git/blobdiff - ccxt_wrapper.py
Don’t raise when some market is disabled
[perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Trader.git] / ccxt_wrapper.py
index 4ed37d9376e53f9935c21db0c40944eb9daef95b..aaccc612ba036ff92123d377aed2ff208c02725d 100644 (file)
@@ -3,6 +3,8 @@ import decimal
 import time
 from retry.api import retry_call
 import re
+from requests.exceptions import RequestException
+from ssl import SSLError
 
 def _cw_exchange_sum(self, *args):
     return sum([arg for arg in args if isinstance(arg, (float, int, decimal.Decimal))])
@@ -21,7 +23,7 @@ class poloniexE(poloniex):
         Wrapped to allow retry of non-posting requests"
         """
 
-        origin_request = super(poloniexE, self).request
+        origin_request = super().request
         kwargs = {
                 "api": api,
                 "method": method,
@@ -33,22 +35,30 @@ class poloniexE(poloniex):
         retriable = any(re.match(call, path) for call in self.RETRIABLE_CALLS)
         if api == "public" or method == "GET" or retriable:
             return retry_call(origin_request, fargs=[path], fkwargs=kwargs,
-                    tries=10, delay=1, exceptions=(RequestTimeout,))
+                    tries=10, delay=1, exceptions=(RequestTimeout, InvalidNonce))
         else:
             return origin_request(path, **kwargs)
 
     def __init__(self, *args, **kwargs):
-        super(poloniexE, self).__init__(*args, **kwargs)
+        super().__init__(*args, **kwargs)
 
         # For requests logging
         self.session.origin_request = self.session.request
         self.session._parent = self
 
         def request_wrap(self, *args, **kwargs):
-            r = self.origin_request(*args, **kwargs)
-            self._parent._market.report.log_http_request(args[0],
-                    args[1], kwargs["data"], kwargs["headers"], r)
-            return r
+            kwargs["headers"]["X-market-id"] = str(self._parent._market.market_id)
+            kwargs["headers"]["X-user-id"] = str(self._parent._market.user_id)
+            try:
+                r = self.origin_request(*args, **kwargs)
+                self._parent._market.report.log_http_request(args[0],
+                        args[1], kwargs["data"], kwargs["headers"], r)
+                return r
+            except (SSLError, RequestException) as e:
+                self._parent._market.report.log_http_request(args[0],
+                        args[1], kwargs["data"], kwargs["headers"], e)
+                raise e
+
         self.session.request = request_wrap.__get__(self.session,
                 self.session.__class__)
 
@@ -56,6 +66,13 @@ class poloniexE(poloniex):
     def nanoseconds():
         return int(time.time() * 1000000000)
 
+    def is_dust_trade(self, amount, rate):
+        if abs(amount) < decimal.Decimal("0.000001"):
+            return True
+        if abs(amount * rate) < decimal.Decimal("0.0001"):
+            return True
+        return False
+
     def fetch_margin_balance(self):
         """
         portfolio.market.privatePostGetMarginPosition({"currencyPair": "BTC_DASH"})
@@ -222,39 +239,9 @@ class poloniexE(poloniex):
 
         return all_balances
 
-    def create_exchange_order(self, symbol, type, side, amount, price=None, params={}):
-        return super(poloniexE, self).create_order(symbol, type, side, amount, price=price, params=params)
-
-    def create_margin_order(self, symbol, type, side, amount, price=None, lending_rate=None, params={}):
-        if type == 'market':
-            raise ExchangeError(self.id + ' allows limit orders only')
-        self.load_markets()
-        method = 'privatePostMargin' + self.capitalize(side)
-        market = self.market(symbol)
-        price = float(price)
-        amount = float(amount)
-        if lending_rate is not None:
-            params = self.extend({"lendingRate": lending_rate}, params)
-        response = getattr(self, method)(self.extend({
-            'currencyPair': market['id'],
-            'rate': self.price_to_precision(symbol, price),
-            'amount': self.amount_to_precision(symbol, amount),
-        }, params))
-        timestamp = self.milliseconds()
-        order = self.parse_order(self.extend({
-            'timestamp': timestamp,
-            'status': 'open',
-            'type': type,
-            'side': side,
-            'price': price,
-            'amount': amount,
-        }, response), market)
-        id = order['id']
-        self.orders[id] = order
-        return self.extend({'info': response}, order)
-
     def order_precision(self, symbol):
-        return 8
+        self.load_markets()
+        return self.markets[symbol]['precision']['price']
 
     def transfer_balance(self, currency, amount, from_account, to_account):
         result = self.privatePostTransferBalance({
@@ -312,6 +299,10 @@ class poloniexE(poloniex):
                 "total": decimal.Decimal(summary["totalValue"]),
                 }
 
+    def fetch_nth_order_book(self, symbol, action, number):
+        book = self.fetch_order_book(symbol, limit=number)
+        return decimal.Decimal(book[action + "s"][-1][0])
+
     def nonce(self):
         """
         Wrapped to allow nonce with other libraries
@@ -372,13 +363,58 @@ class poloniexE(poloniex):
 
     def create_order(self, symbol, type, side, amount, price=None, account="exchange", lending_rate=None, params={}):
         """
-        Wrapped to handle margin and exchange accounts
+        Wrapped to handle margin and exchange accounts, and get decimals
         """
+        if type == 'market':
+            raise ExchangeError(self.id + ' allows limit orders only')
+        self.load_markets()
         if account == "exchange":
-            return self.create_exchange_order(symbol, type, side, amount, price=price, params=params)
+            method = 'privatePost' + self.capitalize(side)
         elif account == "margin":
-            return self.create_margin_order(symbol, type, side, amount, price=price, lending_rate=lending_rate, params=params)
+            method = 'privatePostMargin' + self.capitalize(side)
+            if lending_rate is not None:
+                params = self.extend({"lendingRate": lending_rate}, params)
         else:
             raise NotImplementedError
+        market = self.market(symbol)
+        response = getattr(self, method)(self.extend({
+            'currencyPair': market['id'],
+            'rate': self.price_to_precision(symbol, price),
+            'amount': self.amount_to_precision(symbol, amount),
+        }, params))
+        timestamp = self.milliseconds()
+        order = self.parse_order(self.extend({
+            'timestamp': timestamp,
+            'status': 'open',
+            'type': type,
+            'side': side,
+            'price': price,
+            'amount': amount,
+        }, response), market)
+        id = order['id']
+        self.orders[id] = order
+        return self.extend({'info': response}, order)
+
+    def price_to_precision(self, symbol, price):
+        """
+        Wrapped to avoid float
+        """
+        return ('{:.' + str(self.markets[symbol]['precision']['price']) + 'f}').format(price).rstrip("0").rstrip(".")
 
+    def amount_to_precision(self, symbol, amount):
+        """
+        Wrapped to avoid float
+        """
+        return ('{:.' + str(self.markets[symbol]['precision']['amount']) + 'f}').format(amount).rstrip("0").rstrip(".")
 
+    def common_currency_code(self, currency):
+        """
+        Wrapped to avoid the currency translation
+        """
+        return currency
+
+    def currency_id(self, currency):
+        """
+        Wrapped to avoid the currency translation
+        """
+        return currency