X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=portfolio.py;h=9e98c43ab3e3b656eed3db87208d5a626370a228;hb=5542e9e31a0074f4ed3b91cadce643ad60083cde;hp=9c586769575cf1ef33794856a161be40274fce01;hpb=7f3e7d27409fd7355db9ae4f8fe9a346cd50c712;p=perso%2FImmae%2FProjets%2FCryptomonnaies%2FCryptoportfolio%2FTrader.git diff --git a/portfolio.py b/portfolio.py index 9c58676..9e98c43 100644 --- a/portfolio.py +++ b/portfolio.py @@ -1,7 +1,7 @@ from datetime import datetime from retry import retry from decimal import Decimal as D, ROUND_DOWN -from ccxt import ExchangeError, InsufficientFunds, ExchangeNotAvailable, InvalidOrder, OrderNotCached, OrderNotFound, RequestTimeout +from ccxt import ExchangeError, InsufficientFunds, ExchangeNotAvailable, InvalidOrder, OrderNotCached, OrderNotFound, RequestTimeout, InvalidNonce class Computation: computations = { @@ -381,6 +381,14 @@ class Trade: self.orders.append(order) return order + def reopen_same_order(self, order): + new_order = Order(order.action, order.amount, order.rate, + order.base_currency, order.trade_type, self.market, + self, close_if_possible=order.close_if_possible) + self.orders.append(new_order) + new_order.run() + return new_order + def as_json(self): return { "action": self.action, @@ -477,7 +485,7 @@ class Order: def finished(self): return self.status.startswith("closed") or self.status == "canceled" or self.status == "error" - @retry((InsufficientFunds, RetryException)) + @retry((InsufficientFunds, RetryException, InvalidNonce)) def run(self): self.tries += 1 symbol = "{}/{}".format(self.amount.currency, self.base_currency) @@ -496,6 +504,14 @@ class Order: self.status = "closed" self.mark_finished_order() return + except InvalidNonce as e: + if self.tries < 5: + self.market.report.log_error(action, message="Retrying after invalid nonce", exception=e) + raise e + else: + self.market.report.log_error(action, message="Giving up {} after invalid nonce".format(self), exception=e) + self.status = "error" + return except RequestTimeout as e: if not self.retrieve_order(): if self.tries < 5: @@ -534,6 +550,15 @@ class Order: self.fetch() return self.status + def fix_disappeared_order(self): + if self.status.startswith("closed") and \ + len(self.mouvements) == 1 and \ + self.mouvements[0].total_in_base == 0: + self.status = "error_disappeared" + new_order = self.trade.reopen_same_order(self) + self.market.report.log_error("fetch", + message="Order {} disappeared, recreating it as {}".format(self, new_order)) + def mark_finished_order(self): if self.status.startswith("closed") and self.market.debug: self.market.report.log_debug_action("Mark {} as finished".format(self)) @@ -557,6 +582,8 @@ class Order: self.fetch_mouvements() + self.fix_disappeared_order() + self.mark_finished_order() # FIXME: consider open order with dust remaining as closed