]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Trader.git/blobdiff - ccxt_wrapper.py
Merge branch 'dev'
[perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Trader.git] / ccxt_wrapper.py
index d37c306882aaae72fa7c56470eada65f77ef5fa1..bedf84b47dd3d908ace71fefde768e7cab693ea2 100644 (file)
@@ -1,12 +1,65 @@
 from ccxt import *
 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))])
 Exchange.sum = _cw_exchange_sum
 
 class poloniexE(poloniex):
+    RETRIABLE_CALLS = [
+            re.compile(r"^return"),
+            re.compile(r"^cancel"),
+            re.compile(r"^closeMarginPosition$"),
+            re.compile(r"^getMarginPosition$"),
+            ]
+
+    def request(self, path, api='public', method='GET', params={}, headers=None, body=None):
+        """
+        Wrapped to allow retry of non-posting requests"
+        """
+
+        origin_request = super().request
+        kwargs = {
+                "api": api,
+                "method": method,
+                "params": params,
+                "headers": headers,
+                "body": body
+                }
+
+        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, InvalidNonce))
+        else:
+            return origin_request(path, **kwargs)
+
+    def __init__(self, *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):
+            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__)
+
     @staticmethod
     def nanoseconds():
         return int(time.time() * 1000000000)
@@ -178,7 +231,7 @@ 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)
+        return super().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':