@@ -385,8 +385,9 @@ def _fill_order(self, order: Order, price: float, h: float, l: float):
385385 # Commission summ
386386 self .open_commission -= closed_trade .commission
387387
388- # We realize later if it is cash per order
389- if commission_type == _commission .cash_per_contract :
388+ # We realize later if it is cash per order or cash per contract
389+ if (commission_type == _commission .cash_per_contract or
390+ commission_type == _commission .cash_per_order ):
390391 closed_trade_size += abs (size )
391392 else :
392393 commission = abs (size ) * commission_value
@@ -458,7 +459,8 @@ def _fill_order(self, order: Order, price: float, h: float, l: float):
458459 self .open_trades = open_trades
459460 if delete :
460461 if order .exit_id is not None :
461- self .orders .pop (order .exit_id , None )
462+ # Exit orders are stored with "exit_" prefix
463+ self .orders .pop ("exit_" + order .exit_id , None )
462464
463465 if commission_type == _commission .cash_per_order :
464466 # Realize commission
@@ -521,7 +523,13 @@ def _fill_order(self, order: Order, price: float, h: float, l: float):
521523 # Commission summ
522524 self .open_commission += commission
523525
524- del self .orders [order .order_id ]
526+ # Remove the order using the actual key (which includes the prefix)
527+ # The order_id in the Order object doesn't have the prefix,
528+ # so we need to find and delete by iterating
529+ for key , stored_order in list (self .orders .items ()):
530+ if stored_order is order :
531+ del self .orders [key ]
532+ break
525533
526534 # If position has just closed
527535 if not self .open_trades :
@@ -562,7 +570,11 @@ def fill_order(self, order: Order, price: float, h: float, l: float) -> bool:
562570 # Modify the original order to open a position in the new direction
563571 order .size = new_size
564572 assert order .order_id is not None
565- self .orders [order .order_id ] = order
573+ # Store with appropriate prefix based on order type
574+ if order .order_type == _order_type_entry :
575+ self .orders ["entry_" + order .order_id ] = order
576+ else :
577+ self .orders ["exit_" + order .order_id ] = order
566578 self ._fill_order (order , price , h , l )
567579 return True
568580
@@ -811,10 +823,17 @@ def cancel(id: str):
811823 if lib ._lib_semaphore :
812824 return
813825
826+ assert lib ._script is not None and lib ._script .position is not None
827+ # Try to cancel both entry and exit orders with the given ID
828+ # since we don't know which type it is
829+ # noinspection PyProtectedMember
830+ try :
831+ del lib ._script .position .orders ["entry_" + id ]
832+ except KeyError :
833+ pass
834+ # noinspection PyProtectedMember
814835 try :
815- assert lib ._script is not None and lib ._script .position is not None
816- # noinspection PyProtectedMember
817- del lib ._script .position .orders [id ]
836+ del lib ._script .position .orders ["exit_" + id ]
818837 except KeyError :
819838 pass
820839
@@ -873,7 +892,8 @@ def close(id: str, comment: str | NA[str] = NA(str), qty: float | NA[float] = NA
873892 comment = None if isinstance (comment , NA ) else comment ,
874893 alert_message = None if isinstance (alert_message , NA ) else alert_message )
875894
876- position .orders [exit_id ] = order
895+ # Use "exit_" prefix to avoid ID collision with entry orders
896+ position .orders ["exit_" + exit_id ] = order
877897 if immediately :
878898 round_to_mintick = lib .math .round_to_mintick
879899 position .fill_order (order ,
@@ -904,7 +924,8 @@ def close_all(comment: str | NA[str] = NA(str), alert_message: str | NA[str] = N
904924 order = Order (None , - position .size , exit_id = exit_id , order_type = _order_type_close ,
905925 comment = comment , alert_message = alert_message )
906926
907- position .orders [exit_id ] = order
927+ # Use "exit_" prefix to avoid ID collision with entry orders
928+ position .orders ["exit_" + exit_id ] = order
908929 if immediately :
909930 round_to_mintick = lib .math .round_to_mintick
910931 position .fill_order (order ,
@@ -1050,7 +1071,8 @@ def entry(id: str, direction: direction.Direction, qty: int | float | NA[float]
10501071
10511072 order = Order (id , size , order_type = _order_type_entry , limit = limit , stop = stop , oca_name = oca_name ,
10521073 oca_type = oca_type , comment = comment , alert_message = alert_message )
1053- script .position .orders [id ] = order
1074+ # Use "entry_" prefix to avoid ID collision with exit orders
1075+ script .position .orders ["entry_" + id ] = order
10541076
10551077
10561078# noinspection PyShadowingBuiltins,PyProtectedMember,PyShadowingNames,PyUnusedLocal
@@ -1134,14 +1156,18 @@ def _exit():
11341156 if not isinstance (trail_price , NA ):
11351157 trail_price = _price_round (trail_price , direction )
11361158
1137- position .orders [id ] = Order (from_entry , size , exit_id = id , order_type = _order_type_close ,
1138- limit = limit , stop = stop ,
1139- trail_price = trail_price , trail_offset = trail_offset ,
1140- oca_name = oca_name , comment = comment , alert_message = alert_message )
1159+ # Use "exit_" prefix to avoid ID collision with entry orders
1160+ position .orders ["exit_" + id ] = Order (
1161+ from_entry , size , exit_id = id , order_type = _order_type_close ,
1162+ limit = limit , stop = stop ,
1163+ trail_price = trail_price , trail_offset = trail_offset ,
1164+ oca_name = oca_name , comment = comment , alert_message = alert_message
1165+ )
11411166
11421167 # Find direction and size
11431168 if from_entry :
1144- entry_order = position .orders .get (from_entry , None )
1169+ # Entry orders are stored with "entry_" prefix
1170+ entry_order = position .orders .get ("entry_" + from_entry , None )
11451171
11461172 # Find open trade if no entry order found
11471173 if not entry_order :
0 commit comments