X-Git-Url: https://git.immae.eu/?p=perso%2FImmae%2FProjets%2FCryptomonnaies%2FCryptoportfolio%2FTrader.git;a=blobdiff_plain;f=portfolio.py;h=6763fc67a6b56d759deb972cbd75795a424057ce;hp=0797de0a0489542ce02c20863625d33a2bb3eab8;hb=f70bb858007cd3be6766ee0aa4a3d9133952eb98;hpb=d24bb10c3cad1f144b76022481f46b4524873f4b diff --git a/portfolio.py b/portfolio.py index 0797de0..6763fc6 100644 --- a/portfolio.py +++ b/portfolio.py @@ -3,7 +3,8 @@ from datetime import datetime, timedelta from decimal import Decimal as D, ROUND_DOWN from json import JSONDecodeError from simplejson.errors import JSONDecodeError as SimpleJSONDecodeError -from ccxt import ExchangeError, ExchangeNotAvailable, InvalidOrder +from ccxt import ExchangeError, InsufficientFunds, ExchangeNotAvailable, InvalidOrder +from retry import retry import requests # FIXME: correctly handle web call timeouts @@ -476,6 +477,7 @@ class Order: self.close_if_possible = close_if_possible self.id = None self.fetch_cache_timestamp = None + self.tries = 0 def as_json(self): return { @@ -521,7 +523,9 @@ class Order: def finished(self): return self.status == "closed" or self.status == "canceled" or self.status == "error" + @retry(InsufficientFunds) def run(self): + self.tries += 1 symbol = "{}/{}".format(self.amount.currency, self.base_currency) amount = round(self.amount, self.market.ccxt.order_precision(symbol)).value @@ -530,16 +534,25 @@ class Order: symbol, self.action, amount, self.rate, self.account)) self.results.append({"debug": True, "id": -1}) else: + action = "market.ccxt.create_order('{}', 'limit', '{}', {}, price={}, account={})".format(symbol, self.action, amount, self.rate, self.account) try: self.results.append(self.market.ccxt.create_order(symbol, 'limit', self.action, amount, price=self.rate, account=self.account)) - except (ExchangeNotAvailable, InvalidOrder): + except InvalidOrder: # Impossible to honor the order (dust amount) self.status = "closed" self.mark_finished_order() return + except InsufficientFunds as e: + if self.tries < 5: + self.market.report.log_error(action, message="Retrying with reduced amount", exception=e) + self.amount = self.amount * D("0.99") + raise e + else: + self.market.report.log_error(action, message="Giving up {}".format(self), exception=e) + self.status = "error" + return except Exception as e: self.status = "error" - action = "market.ccxt.create_order('{}', 'limit', '{}', {}, price={}, account={})".format(symbol, self.action, amount, self.rate, self.account) self.market.report.log_error(action, exception=e) return self.id = self.results[0]["id"]