diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 1a24009b3..1b414b77f 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -457,30 +457,41 @@ class FreqtradeBot(LoggingMixin): """ try: orders = self.exchange.fetch_orders(trade.pair, trade.open_date_utc) + prev_exit_reason = trade.exit_reason + prev_trade_state = trade.is_open for order in orders: trade_order = [o for o in trade.orders if o.order_id == order['id']] - if trade_order: - continue - logger.info(f"Found previously unknown order {order['id']} for {trade.pair}.") - order_obj = Order.parse_from_ccxt_object(order, trade.pair, order['side']) - order_obj.order_filled_date = datetime.fromtimestamp( - safe_value_fallback(order, 'lastTradeTimestamp', 'timestamp') // 1000, - tz=timezone.utc) - trade.orders.append(order_obj) - prev_exit_reason = trade.exit_reason - trade.exit_reason = ExitType.SOLD_ON_EXCHANGE.value - self.update_trade_state(trade, order['id'], order) + if trade_order: + # We knew this order, but didn't have it updated properly + order_obj = trade_order[0] + else: + logger.info(f"Found previously unknown order {order['id']} for {trade.pair}.") + + order_obj = Order.parse_from_ccxt_object(order, trade.pair, order['side']) + order_obj.order_filled_date = datetime.fromtimestamp( + safe_value_fallback(order, 'lastTradeTimestamp', 'timestamp') // 1000, + tz=timezone.utc) + trade.orders.append(order_obj) + Trade.commit() + trade.exit_reason = ExitType.SOLD_ON_EXCHANGE.value + + self.update_trade_state(trade, order['id'], order, send_msg=False) logger.info(f"handled order {order['id']}") - if not trade.is_open: - # Trade was just closed - trade.close_date = order_obj.order_filled_date - Trade.commit() - break - else: - trade.exit_reason = prev_exit_reason - Trade.commit() + + # Refresh trade from database + Trade.session.refresh(trade) + if not trade.is_open: + # Trade was just closed + trade.close_date = max([o.order_filled_date for o in trade.orders + if o.order_filled_date]) + self.order_close_notify(trade, order_obj, + order_obj.ft_order_side == 'stoploss', + send_msg=prev_trade_state != trade.is_open) + else: + trade.exit_reason = prev_exit_reason + Trade.commit() except ExchangeError: logger.warning("Error finding onexchange order.") diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 886012535..2f3a9a1cf 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -5687,7 +5687,8 @@ def test_handle_onexchange_order(mocker, default_conf_usdt, limit_order, is_shor Trade.session.add(trade) freqtrade.handle_onexchange_order(trade) assert log_has_re(r"Found previously unknown order .*", caplog) - assert mock_uts.call_count == 1 + # Update trade state is called twice, once for the known and once for the unknown order. + assert mock_uts.call_count == 2 assert mock_fo.call_count == 1 trade = Trade.session.scalars(select(Trade)).first()