mirror of
https://github.com/freqtrade/freqtrade.git
synced 2025-12-03 18:43:04 +00:00
feat: implement order replacement for backtesting
This commit is contained in:
@@ -831,6 +831,10 @@ class Backtesting:
|
||||
amount = amount_to_contract_precision(
|
||||
amount or trade.amount, trade.amount_precision, self.precision_mode, trade.contract_size
|
||||
)
|
||||
|
||||
if self.handle_similar_order(trade, close_rate, amount, trade.exit_side, exit_candle_time):
|
||||
return None
|
||||
|
||||
order = Order(
|
||||
id=self.order_id_counter,
|
||||
ft_trade_id=trade.id,
|
||||
@@ -1116,6 +1120,10 @@ class Backtesting:
|
||||
orders=[],
|
||||
)
|
||||
LocalTrade.add_bt_trade(trade)
|
||||
elif self.handle_similar_order(
|
||||
trade, propose_rate, amount, trade.entry_side, current_time
|
||||
):
|
||||
return None
|
||||
|
||||
trade.adjust_stop_loss(trade.open_rate, self.strategy.stoploss, initial=True)
|
||||
|
||||
@@ -1214,6 +1222,37 @@ class Backtesting:
|
||||
# default maintain trade
|
||||
return False
|
||||
|
||||
def cancel_open_orders(self, trade: LocalTrade, current_time: datetime):
|
||||
"""
|
||||
Cancel all open orders for the given trade.
|
||||
"""
|
||||
for order in [o for o in trade.orders if o.ft_is_open]:
|
||||
if order.side == trade.entry_side:
|
||||
self.canceled_entry_orders += 1
|
||||
elif order.side == trade.exit_side:
|
||||
self.canceled_exit_orders += 1
|
||||
# canceled orders are removed from the trade
|
||||
del trade.orders[trade.orders.index(order)]
|
||||
|
||||
def handle_similar_order(
|
||||
self, trade: LocalTrade, price: float, amount: float, side: str, current_time: datetime
|
||||
) -> bool:
|
||||
"""
|
||||
Handle similar order for the given trade.
|
||||
"""
|
||||
if trade.has_open_orders:
|
||||
oo = trade.select_order(side, True)
|
||||
if oo:
|
||||
if (price == oo.price) and (side == oo.side) and (amount == oo.amount):
|
||||
logger.info(
|
||||
f"A similar open order was found for {trade.pair}. "
|
||||
f"Keeping existing {trade.exit_side} order. {price=}, {amount=}"
|
||||
)
|
||||
return True
|
||||
self.cancel_open_orders(trade, current_time)
|
||||
|
||||
return False
|
||||
|
||||
def check_order_cancel(
|
||||
self, trade: LocalTrade, order: Order, current_time: datetime
|
||||
) -> bool | None:
|
||||
@@ -1399,7 +1438,7 @@ class Backtesting:
|
||||
self.wallets.update()
|
||||
|
||||
# 4. Create exit orders (if any)
|
||||
if trade.has_open_position or trade.has_open_orders:
|
||||
if trade.has_open_position:
|
||||
self._check_trade_exit(trade, row, current_time) # Place exit order if necessary
|
||||
|
||||
# 5. Process exit orders.
|
||||
|
||||
Reference in New Issue
Block a user