handle pre existing open order cancelation on trade exit

This commit is contained in:
Axel-CH 2024-09-11 21:11:20 -04:00
parent 1fccdd8cda
commit 2811a470aa
2 changed files with 43 additions and 16 deletions

View File

@ -1683,6 +1683,34 @@ class FreqtradeBot(LoggingMixin):
logger.warning(f"Unable to replace order for {trade.pair}: {exception}")
self.replace_order_failed(trade, f"Could not replace order for {trade}.")
def cancel_open_orders_of_trade(self, trade: Trade, reason: str, sides: List[str]) -> None:
"""
Cancel trade orders of specified sides that are currently open
:param trade: Trade object of the trade we're analyzing
:param reason: The reason for that cancelation
:param sides: The sides where cancellation should take place
:return: None
"""
for open_order in trade.open_orders:
try:
order = self.exchange.fetch_order(open_order.order_id, trade.pair)
except ExchangeError:
logger.info("Can't query order for %s due to %s", trade, traceback.format_exc())
continue
for side in sides:
if (order["side"] == side):
if order["side"] == trade.entry_side:
self.handle_cancel_enter(
trade, order, open_order, reason
)
elif order["side"] == trade.exit_side:
self.handle_cancel_exit(
trade, order, open_order, reason
)
def cancel_all_open_orders(self) -> None:
"""
Cancel all orders that are currently open
@ -1690,22 +1718,11 @@ class FreqtradeBot(LoggingMixin):
"""
for trade in Trade.get_open_trades():
for open_order in trade.open_orders:
try:
order = self.exchange.fetch_order(open_order.order_id, trade.pair)
except ExchangeError:
logger.info("Can't query order for %s due to %s", trade, traceback.format_exc())
continue
self.cancel_open_orders_of_trade(
trade, constants.CANCEL_REASON["ALL_CANCELLED"],
[trade.entry_side, trade.exit_side]
)
if order["side"] == trade.entry_side:
self.handle_cancel_enter(
trade, order, open_order, constants.CANCEL_REASON["ALL_CANCELLED"]
)
elif order["side"] == trade.exit_side:
self.handle_cancel_exit(
trade, order, open_order, constants.CANCEL_REASON["ALL_CANCELLED"]
)
Trade.commit()
def handle_cancel_enter(
@ -1951,6 +1968,14 @@ class FreqtradeBot(LoggingMixin):
limit = self.get_valid_price(custom_exit_price, proposed_limit_rate)
if trade.has_open_orders:
# cancel any open order of this trade
self.cancel_open_orders_of_trade(
trade, constants.CANCEL_REASON["REPLACE"],
[trade.exit_side]
)
Trade.commit()
# First cancelling stoploss on exchange ...
trade = self.cancel_stoploss_on_exchange(trade)

View File

@ -497,7 +497,9 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker,
print("AFTER Process trade.orders")
print(trade.orders)
assert len(trade.orders) == 5
assert trade.orders[-2].status == "canceled"
assert len(trade.orders) == 6
assert trade.orders[-1].side == trade.exit_side
assert trade.orders[-1].status == "open"
assert trade.orders[-1].price == 2.02
# Adjust entry price cannot be called - this is an exit order