@@ -425,41 +425,77 @@ def get_should_cancel_loaded_orders(cls) -> bool:
425425 """
426426 raise NotImplementedError ("get_should_cancel_loaded_orders not implemented" )
427427
428+ def _get_to_cancel_orders (
429+ self , symbol = None , side = None , tag = None , active = None , exchange_order_ids = None
430+ ) -> list :
431+ cancel_loaded_orders = self .get_should_cancel_loaded_orders ()
432+ return [
433+ order
434+ for order in self .exchange_manager .exchange_personal_data .orders_manager .get_open_orders (
435+ symbol = symbol , tag = tag , active = active
436+ )
437+ if (
438+ not (order .is_cancelled () or order .is_closed ())
439+ and (cancel_loaded_orders or order .is_from_this_octobot )
440+ and (side is None or (side is order .side ))
441+ and (exchange_order_ids is None or (order .exchange_order_id in exchange_order_ids ))
442+ )
443+ ]
444+
445+ async def _cancel_orders (
446+ self , orders : list ,
447+ dependencies : typing .Optional [commons_signals .SignalDependencies ] = None
448+ ) -> tuple [bool , typing .Optional [commons_signals .SignalDependencies ]]:
449+ cancelled = False
450+ failed_to_cancel = False
451+ cancelled_dependencies = commons_signals .SignalDependencies ()
452+ for order in orders :
453+ try :
454+ is_cancelled , new_dependencies = await self .trading_mode .cancel_order (
455+ order , dependencies = dependencies
456+ )
457+ if is_cancelled :
458+ cancelled = True
459+ cancelled_dependencies .extend (new_dependencies )
460+ else :
461+ failed_to_cancel = True
462+ except errors .OctoBotExchangeError as err :
463+ # do not propagate exchange error when canceling order
464+ self .logger .exception (err , True , f"Error when cancelling order [{ order } ]: { err } " )
465+ failed_to_cancel = True
466+ return (cancelled and not failed_to_cancel ), cancelled_dependencies or None
467+
428468 async def cancel_symbol_open_orders (
429- self , symbol , side = None , tag = None , exchange_order_ids = None ,
469+ self , symbol , side = None , tag = None , active = None , exchange_order_ids = None ,
430470 dependencies : typing .Optional [commons_signals .SignalDependencies ] = None
431- ) -> tuple [bool , commons_signals .SignalDependencies ]:
471+ ) -> tuple [bool , typing . Optional [ commons_signals .SignalDependencies ] ]:
432472 """
433473 Cancel all symbol open orders
434474 """
435- cancel_loaded_orders = self .get_should_cancel_loaded_orders ()
436- cancelled = False
437- failed_to_cancel = False
438- cancelled_dependencies = commons_signals .SignalDependencies ()
439475 if self .exchange_manager .trader .is_enabled :
440- for order in self .exchange_manager .exchange_personal_data .orders_manager .get_open_orders (
441- symbol = symbol , tag = tag
476+ return await self ._cancel_orders (
477+ self ._get_to_cancel_orders (
478+ symbol = symbol , side = side , tag = tag , active = active , exchange_order_ids = exchange_order_ids
479+ ), dependencies
480+ )
481+ return False , None
482+
483+ async def apply_cancel_policies (
484+ self , symbol = None , side = None , tag = None , exchange_order_ids = None , active = None ,
485+ dependencies : typing .Optional [commons_signals .SignalDependencies ] = None
486+ ) -> tuple [bool , typing .Optional [commons_signals .SignalDependencies ]]:
487+ """
488+ Cancel all orders that should be according to their cancel policies
489+ """
490+ if self .exchange_manager .trader .is_enabled :
491+ if to_cancel_orders := self .exchange_manager .exchange_personal_data .orders_manager .get_orders_to_cancel_from_policies (
492+ self ._get_to_cancel_orders (
493+ symbol = symbol , side = side , tag = tag , active = active , exchange_order_ids = exchange_order_ids
494+ )
442495 ):
443- if (
444- not (order .is_cancelled () or order .is_closed ())
445- and (cancel_loaded_orders or order .is_from_this_octobot )
446- and (side is None or (side is order .side ))
447- and (exchange_order_ids is None or (order .exchange_order_id in exchange_order_ids ))
448- ):
449- try :
450- is_cancelled , new_dependencies = await self .trading_mode .cancel_order (
451- order , dependencies = dependencies
452- )
453- if is_cancelled :
454- cancelled = True
455- cancelled_dependencies .extend (new_dependencies )
456- else :
457- failed_to_cancel = True
458- except errors .OctoBotExchangeError as err :
459- # do not propagate exchange error when canceling order
460- self .logger .exception (err , True , f"Error when cancelling order [{ order } ]: { err } " )
461- failed_to_cancel = True
462- return (cancelled and not failed_to_cancel ), cancelled_dependencies or None
496+ self .logger .info (f"Cancelling { len (to_cancel_orders )} orders from cancel policies" )
497+ return await self ._cancel_orders (to_cancel_orders , dependencies )
498+ return False , None
463499
464500 def all_databases (self ):
465501 provider = databases .RunDatabasesProvider .instance ()
0 commit comments