Merge pull request #2523 from freqtrade/timeout_handling

Improve timedout handling
This commit is contained in:
hroff-1902 2019-11-13 22:25:58 +03:00 committed by GitHub
commit f4d18034d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -139,7 +139,6 @@ class FreqtradeBot:
if len(trades) < self.config['max_open_trades']: if len(trades) < self.config['max_open_trades']:
self.process_maybe_execute_buys() self.process_maybe_execute_buys()
if 'unfilledtimeout' in self.config:
# Check and handle any timed out open orders # Check and handle any timed out open orders
self.check_handle_timedout() self.check_handle_timedout()
Trade.session.flush() Trade.session.flush()
@ -756,23 +755,28 @@ class FreqtradeBot:
return True return True
return False return False
def _check_timed_out(self, side: str, order: dict) -> bool:
"""
Check if timeout is active, and if the order is still open and timed out
"""
timeout = self.config.get('unfilledtimeout', {}).get(side)
ordertime = arrow.get(order['datetime']).datetime
if timeout is not None:
timeout_threshold = arrow.utcnow().shift(minutes=-timeout).datetime
return (order['status'] == 'open' and order['side'] == side
and ordertime < timeout_threshold)
return False
def check_handle_timedout(self) -> None: def check_handle_timedout(self) -> None:
""" """
Check if any orders are timed out and cancel if neccessary Check if any orders are timed out and cancel if neccessary
:param timeoutvalue: Number of minutes until order is considered timed out :param timeoutvalue: Number of minutes until order is considered timed out
:return: None :return: None
""" """
buy_timeout = self.config['unfilledtimeout']['buy']
sell_timeout = self.config['unfilledtimeout']['sell']
buy_timeout_threshold = arrow.utcnow().shift(minutes=-buy_timeout).datetime
sell_timeout_threshold = arrow.utcnow().shift(minutes=-sell_timeout).datetime
for trade in Trade.get_open_order_trades(): for trade in Trade.get_open_order_trades():
try: try:
# FIXME: Somehow the query above returns results
# where the open_order_id is in fact None.
# This is probably because the record got
# updated via /forcesell in a different thread.
if not trade.open_order_id: if not trade.open_order_id:
continue continue
order = self.exchange.get_order(trade.open_order_id, trade.pair) order = self.exchange.get_order(trade.open_order_id, trade.pair)
@ -782,7 +786,6 @@ class FreqtradeBot:
trade, trade,
traceback.format_exc()) traceback.format_exc())
continue continue
ordertime = arrow.get(order['datetime']).datetime
# Check if trade is still actually open # Check if trade is still actually open
if float(order['remaining']) == 0.0: if float(order['remaining']) == 0.0:
@ -790,15 +793,13 @@ class FreqtradeBot:
continue continue
if ((order['side'] == 'buy' and order['status'] == 'canceled') if ((order['side'] == 'buy' and order['status'] == 'canceled')
or (order['status'] == 'open' or (self._check_timed_out('buy', order))):
and order['side'] == 'buy' and ordertime < buy_timeout_threshold)):
self.handle_timedout_limit_buy(trade, order) self.handle_timedout_limit_buy(trade, order)
self.wallets.update() self.wallets.update()
elif ((order['side'] == 'sell' and order['status'] == 'canceled') elif ((order['side'] == 'sell' and order['status'] == 'canceled')
or (order['status'] == 'open' or (self._check_timed_out('sell', order))):
and order['side'] == 'sell' and ordertime < sell_timeout_threshold)):
self.handle_timedout_limit_sell(trade, order) self.handle_timedout_limit_sell(trade, order)
self.wallets.update() self.wallets.update()