aboutsummaryrefslogtreecommitdiff
path: root/portfolio.py
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2018-02-26 14:18:34 +0100
committerIsmaël Bouya <ismael.bouya@normalesup.org>2018-02-26 14:18:34 +0100
commitf70bb858007cd3be6766ee0aa4a3d9133952eb98 (patch)
tree0c56dd45d99ab6409cda4ef240759ec56981a351 /portfolio.py
parentd24bb10c3cad1f144b76022481f46b4524873f4b (diff)
downloadTrader-f70bb858007cd3be6766ee0aa4a3d9133952eb98.tar.gz
Trader-f70bb858007cd3be6766ee0aa4a3d9133952eb98.tar.zst
Trader-f70bb858007cd3be6766ee0aa4a3d9133952eb98.zip
Retry running order when available balance is insufficient
Diffstat (limited to 'portfolio.py')
-rw-r--r--portfolio.py19
1 files changed, 16 insertions, 3 deletions
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
3from decimal import Decimal as D, ROUND_DOWN 3from decimal import Decimal as D, ROUND_DOWN
4from json import JSONDecodeError 4from json import JSONDecodeError
5from simplejson.errors import JSONDecodeError as SimpleJSONDecodeError 5from simplejson.errors import JSONDecodeError as SimpleJSONDecodeError
6from ccxt import ExchangeError, ExchangeNotAvailable, InvalidOrder 6from ccxt import ExchangeError, InsufficientFunds, ExchangeNotAvailable, InvalidOrder
7from retry import retry
7import requests 8import requests
8 9
9# FIXME: correctly handle web call timeouts 10# FIXME: correctly handle web call timeouts
@@ -476,6 +477,7 @@ class Order:
476 self.close_if_possible = close_if_possible 477 self.close_if_possible = close_if_possible
477 self.id = None 478 self.id = None
478 self.fetch_cache_timestamp = None 479 self.fetch_cache_timestamp = None
480 self.tries = 0
479 481
480 def as_json(self): 482 def as_json(self):
481 return { 483 return {
@@ -521,7 +523,9 @@ class Order:
521 def finished(self): 523 def finished(self):
522 return self.status == "closed" or self.status == "canceled" or self.status == "error" 524 return self.status == "closed" or self.status == "canceled" or self.status == "error"
523 525
526 @retry(InsufficientFunds)
524 def run(self): 527 def run(self):
528 self.tries += 1
525 symbol = "{}/{}".format(self.amount.currency, self.base_currency) 529 symbol = "{}/{}".format(self.amount.currency, self.base_currency)
526 amount = round(self.amount, self.market.ccxt.order_precision(symbol)).value 530 amount = round(self.amount, self.market.ccxt.order_precision(symbol)).value
527 531
@@ -530,16 +534,25 @@ class Order:
530 symbol, self.action, amount, self.rate, self.account)) 534 symbol, self.action, amount, self.rate, self.account))
531 self.results.append({"debug": True, "id": -1}) 535 self.results.append({"debug": True, "id": -1})
532 else: 536 else:
537 action = "market.ccxt.create_order('{}', 'limit', '{}', {}, price={}, account={})".format(symbol, self.action, amount, self.rate, self.account)
533 try: 538 try:
534 self.results.append(self.market.ccxt.create_order(symbol, 'limit', self.action, amount, price=self.rate, account=self.account)) 539 self.results.append(self.market.ccxt.create_order(symbol, 'limit', self.action, amount, price=self.rate, account=self.account))
535 except (ExchangeNotAvailable, InvalidOrder): 540 except InvalidOrder:
536 # Impossible to honor the order (dust amount) 541 # Impossible to honor the order (dust amount)
537 self.status = "closed" 542 self.status = "closed"
538 self.mark_finished_order() 543 self.mark_finished_order()
539 return 544 return
545 except InsufficientFunds as e:
546 if self.tries < 5:
547 self.market.report.log_error(action, message="Retrying with reduced amount", exception=e)
548 self.amount = self.amount * D("0.99")
549 raise e
550 else:
551 self.market.report.log_error(action, message="Giving up {}".format(self), exception=e)
552 self.status = "error"
553 return
540 except Exception as e: 554 except Exception as e:
541 self.status = "error" 555 self.status = "error"
542 action = "market.ccxt.create_order('{}', 'limit', '{}', {}, price={}, account={})".format(symbol, self.action, amount, self.rate, self.account)
543 self.market.report.log_error(action, exception=e) 556 self.market.report.log_error(action, exception=e)
544 return 557 return
545 self.id = self.results[0]["id"] 558 self.id = self.results[0]["id"]