@@ -831,6 +831,10 @@ def _exit_trade(
831831 amount = amount_to_contract_precision (
832832 amount or trade .amount , trade .amount_precision , self .precision_mode , trade .contract_size
833833 )
834+
835+ if self .handle_similar_order (trade , close_rate , amount , trade .exit_side , exit_candle_time ):
836+ return None
837+
834838 order = Order (
835839 id = self .order_id_counter ,
836840 ft_trade_id = trade .id ,
@@ -1116,6 +1120,10 @@ def _enter_trade(
11161120 orders = [],
11171121 )
11181122 LocalTrade .add_bt_trade (trade )
1123+ elif self .handle_similar_order (
1124+ trade , propose_rate , amount , trade .entry_side , current_time
1125+ ):
1126+ return None
11191127
11201128 trade .adjust_stop_loss (trade .open_rate , self .strategy .stoploss , initial = True )
11211129
@@ -1214,6 +1222,37 @@ def manage_open_orders(self, trade: LocalTrade, current_time: datetime, row: tup
12141222 # default maintain trade
12151223 return False
12161224
1225+ def cancel_open_orders (self , trade : LocalTrade , current_time : datetime ):
1226+ """
1227+ Cancel all open orders for the given trade.
1228+ """
1229+ for order in [o for o in trade .orders if o .ft_is_open ]:
1230+ if order .side == trade .entry_side :
1231+ self .canceled_entry_orders += 1
1232+ elif order .side == trade .exit_side :
1233+ self .canceled_exit_orders += 1
1234+ # canceled orders are removed from the trade
1235+ del trade .orders [trade .orders .index (order )]
1236+
1237+ def handle_similar_order (
1238+ self , trade : LocalTrade , price : float , amount : float , side : str , current_time : datetime
1239+ ) -> bool :
1240+ """
1241+ Handle similar order for the given trade.
1242+ """
1243+ if trade .has_open_orders :
1244+ oo = trade .select_order (side , True )
1245+ if oo :
1246+ if (price == oo .price ) and (side == oo .side ) and (amount == oo .amount ):
1247+ logger .info (
1248+ f"A similar open order was found for { trade .pair } . "
1249+ f"Keeping existing { trade .exit_side } order. { price = } , { amount = } "
1250+ )
1251+ return True
1252+ self .cancel_open_orders (trade , current_time )
1253+
1254+ return False
1255+
12171256 def check_order_cancel (
12181257 self , trade : LocalTrade , order : Order , current_time : datetime
12191258 ) -> bool | None :
@@ -1399,7 +1438,7 @@ def backtest_loop_inner(
13991438 self .wallets .update ()
14001439
14011440 # 4. Create exit orders (if any)
1402- if trade .has_open_position or trade . has_open_orders :
1441+ if trade .has_open_position :
14031442 self ._check_trade_exit (trade , row , current_time ) # Place exit order if necessary
14041443
14051444 # 5. Process exit orders.
0 commit comments