
    i[              	       ^   d Z ddlZddlZddlmZ ddlmZmZmZ ddl	m
Z
 ddlmZmZmZ ddlmZmZ erddlmZ  ej(                  e      Z ed	d
dd       G d d             Z edd
dd       G d d             Z G d de      Z edd
dd      	 ddddeeeef   dz  defd       Zy)a  
Order lifecycle tracking and management for ProjectX SDK v3.0.0.

DEPRECATED: This module is deprecated as of v3.1.14 and will be removed in v4.0.0.
            Use TradingSuite.track_order() and TradingSuite.order_chain() instead.

Author: SDK v3.0.0
Date: 2025-08-04

Overview:
    Provides a context manager for comprehensive order lifecycle tracking with
    automatic state management, async waiting mechanisms, and simplified error
    handling. Eliminates the need for manual order state tracking in strategies.

Key Features:
    - Context manager for automatic cleanup
    - Async waiting for order fills/status changes
    - Automatic timeout handling
    - Order modification and cancellation helpers
    - Order chain builder for complex orders
    - Common order templates
    - Integration with EventBus for real-time updates

Example Usage:
    ```python
    # Simple order tracking
    async with suite.track_order() as tracker:
        order = await suite.orders.place_limit_order(
            contract_id=instrument.id,
            side=OrderSide.BUY,
            size=1,
            price=current_price - 10,
        )

        try:
            filled_order = await tracker.wait_for_fill(timeout=60)
            print(f"Order filled at {filled_order.filledPrice}")
        except TimeoutError:
            await tracker.modify_or_cancel(new_price=current_price - 5)

    # Order chain builder
    order_chain = (
        suite.orders.market_order(size=1)
        .with_stop_loss(offset=50)
        .with_take_profit(offset=100)
        .with_trail_stop(offset=25, trigger_offset=50)
    )

    result = await order_chain.execute()
    ```

See Also:
    - `order_manager.core.OrderManager`
    - `event_bus.EventBus`
    - `models.Order`
    N)TracebackType)TYPE_CHECKINGAnyUnion)	EventType)BracketOrderResponseOrderOrderPlaceResponse)
deprecateddeprecated_class)TradingSuitez<Use TradingSuite.track_order() for integrated order trackingz3.1.14z4.0.0zTradingSuite.track_order())reasonversionremoval_versionreplacementc                   ,   e Zd ZdZddddedz  fdZddZd	ee   dz  d
edz  de	dz  ddfdZ
ddZddZdeeeef   dd fdZddedefdZddededefdZ	 ddedz  dedz  defdZdedz  fdZedefd       Zedefd       Zedefd       Zy) OrderTrackera  
    Context manager for comprehensive order lifecycle tracking.

    DEPRECATED: Use TradingSuite.track_order() instead. Will be removed in v4.0.0.

    Provides automatic order state management with async waiting capabilities,
    eliminating the need for manual order status polling and complex state
    tracking in trading strategies.

    Features:
        - Automatic order status tracking via EventBus
        - Async waiting for specific order states
        - Timeout handling with automatic cleanup
        - Order modification and cancellation helpers
        - Fill detection and reporting
        - Thread-safe operation
    Ntrading_suiter   orderc                 "   || _         |j                  | _        |j                  | _        || _        |r|j                  nd| _        t        j                         | _
        i | _        |r|j                  nd| _        d| _        d| _        g | _        y)z
        Initialize OrderTracker.

        Args:
            trading_suite: TradingSuite instance for access to components
            order: Optional order to track immediately
        N)suiteordersorder_managerevents	event_busr   idorder_idasyncioEvent_fill_event_status_eventsstatus_current_status_filled_order_error_event_handlers)selfr   r   s      S/home/work/apex_v16/venv/lib/python3.12/site-packages/project_x_py/order_tracker.py__init__zOrderTracker.__init__b   s}     #
*11&--
05EHH4 #==?8:;@5<<d+/(, =?    returnc                 B   K   | j                          d{    | S 7 w)z.Enter the context manager and set up tracking.N)_setup_event_handlersr'   s    r(   
__aenter__zOrderTracker.__aenter__z   s$      ((*** 	+s   exc_typeexc_valexc_tbc                 @   K   | j                          d{    y7 w)z&Exit the context manager and clean up.N)cleanup)r'   r0   r1   r2   s       r(   	__aexit__zOrderTracker.__aexit__   s      llns   c                    K   dt         t        t        f   ddf fd}dt         t        t        f   ddf fd}t        j                  |ft        j
                  |ft        j                  |ft        j                  |fg _         j                  D ])  \  }} j                  j                  ||       d{    + y7 w)z,Set up EventBus handlers for order tracking.datar+   Nc                    K   | j                  d      }|rC|j                  j                  k(  r)|_        d_        j
                  j                          y y y w)Nr      )getr   r   r$   r#   r    set)r7   r   r'   s     r(   on_fillz3OrderTracker._setup_event_handlers.<locals>.on_fill   sP     HHW%ET]]2%*"'($  $$& 3us   AAc                 0  K   | j                  d      }|r~|j                  j                  k(  rd|j                  }|_        |j
                  v rj
                  |   j                          |dv r!t        dj                   d|       _        y y y y w)Nr   )         Order z reached terminal state: )	r:   r   r   r"   r#   r!   r;   OrderLifecycleErrorr%   )r7   r   
new_statusr'   s      r(   on_status_changez<OrderTracker._setup_event_handlers.<locals>.on_status_change   s     HHW%ET]]2"\\
'1$ !4!44''
3779 *"5 /HU#DK + 3us   BB)dictstrr   r   ORDER_FILLEDORDER_CANCELLEDORDER_REJECTEDORDER_EXPIREDr&   r   on)r'   r<   rD   
event_typehandlers   `    r(   r-   z"OrderTracker._setup_event_handlers   s     	'S#X 	'4 	'	c3h 	D 	$ ##W-&&(89%%'78$$&67	 
 $(#7#7 	9J..##J888	98s   B3C 6B>7C c                    K   | j                   D ])  \  }}| j                  j                  ||       d{    + | j                   j                          y7 !w)z&Clean up event handlers and resources.N)r&   r   offclear)r'   rL   rM   s      r(   r4   zOrderTracker.cleanup   sU      $(#7#7 	:J..$$Z999	: 	""$ :s   2AA"Ac                     t        |t              r+|| _        |j                  | _        |j
                  | _        | S t        |t              r|j                  | _        d| _        | S || _        d| _        | S )z
        Start tracking a specific order.

        Args:
            order: Order object, OrderPlaceResponse, or order ID to track

        Returns:
            Self for method chaining
           N)	
isinstancer	   r   r   r   r"   r#   r
   orderId)r'   r   s     r(   trackzOrderTracker.track   sp     eU#DJ!HHDM#(<<D   12!MMDM#$D 
  "DM#'D r*   timeoutc                   K   | j                   st        d      	 t        j                  | j                  j                         |       d{    | j                  r| j                  | j                  r| j                  S | j                  j                  | j                          d{   }|r|j                  dk(  r|S t        d      7 7 $# t        $ r t        d| j                    d| d      dw xY ww)	aE  
        Wait for the order to be filled.

        Args:
            timeout: Maximum time to wait in seconds

        Returns:
            Filled Order object

        Raises:
            TimeoutError: If order is not filled within timeout
            OrderLifecycleError: If order reaches terminal non-filled state
        No order is being trackedrV   Nr9   z.Order fill event received but order not filledrA   z not filled within  seconds)r   
ValueErrorr   wait_forr    waitr%   r$   r   get_order_by_idr"   rB   TimeoutError)r'   rV   r   s      r(   wait_for_fillzOrderTracker.wait_for_fill   s      }}899	""4#3#3#8#8#:GLLL{{kk!!!))) #00@@OOU\\Q. L-H  M P  	':7)8L	sL   C;2C C3C C;(C *C+C C;C C 'C88C;r"   c           
        K   | j                   st        d      || j                  vr!t        j                         | j                  |<   | j
                  |k(  r@| j                  j                  | j                          d{   }|r|j                  |k(  r|S 	 t        j                  | j                  |   j                         |       d{    | j                  r|| j
                  k7  r| j                  | j                  j                  | j                          d{   }|r|j                  |k(  r|S t        d| d	|r|j                         d
       7 7 # t        $ rd | j                  j                  | j                          d{  7  }|r|j                  |k(  r|cY S t        d| j                    d| d| d      dw xY w7 w)a  
        Wait for the order to reach a specific status.

        Args:
            status: Target order status to wait for
            timeout: Maximum time to wait in seconds

        Returns:
            Order object with the target status

        Raises:
            TimeoutError: If status is not reached within timeout
            OrderLifecycleError: If order reaches incompatible terminal state
        rX   NrY   rA   z did not reach status z within rZ   z6Status event received but order not in expected state z. Current state: z	not found)r   r[   r!   r   r   r#   r   r^   r"   r\   r]   r_   r%   rB   )r'   r"   rV   r   s       r(   wait_for_statuszOrderTracker.wait_for_status   s     }}899 ,,,*1--/D' 6),,<<T]]KKE/		""4#6#6v#>#C#C#EwWWW ;;6T%9%99++((88GGU\\V+L &HParwbgbnbn  bJ  K  ~I  bJ  K 5 L X 	,,<<T]]KKKE/'=fXXgYV^_	 Hsa   A>G EG5E# E!E# AG"G#=G!E# #1GFG-G/!GG	new_pricenew_sizec                 ~  K   | j                   st        d      	 ||V| j                  j                  | j                   ||       d{   }|r$t        j                  d| j                    d       y	 | j                  j                  | j                          d{    t        j                  d| j                    d	       y
7 |# t        $ r/}t        j                  d| j                    d|        Y d}~d}~ww xY w7 e# t        $ r+}t        j                  d| j                    d|         d}~ww xY ww)a  
        Attempt to modify the order, or cancel if modification fails.

        Args:
            new_price: New limit price for the order
            new_size: New size for the order

        Returns:
            True if modification succeeded, False if order was cancelled
        rX   N)limit_pricesizerA   z modified successfullyTzFailed to modify order z: z
 cancelledFzFailed to cancel order )
r   r[   r   modify_orderloggerinfo	Exceptionwarningcancel_ordererror)r'   rc   rd   successes        r(   modify_or_cancelzOrderTracker.modify_or_cancel-  s+     }}899	K$(< $ 2 2 ? ?MMyx !@ !  KK&7M NO	$$11$--@@@KK&z:;  	KNN4T]]O2aSIJJ	K
 A  	LL24==/A3GH	sv   D=/C	 
C)C	 4D=6(D D'D D=C	 		D%C<7D=<DD=D 	D:&D55D::D=c                    K   | j                   sy| j                  j                  | j                          d{   S 7 w)zw
        Get the current order status.

        Returns:
            Current Order object or None if not found
        N)r   r   r^   r.   s    r(   get_current_statuszOrderTracker.get_current_statusT  s3      }}''77FFFFs   6?=?c                      | j                   dk(  S )z#Check if the order has been filled.r9   r#   r.   s    r(   	is_filledzOrderTracker.is_filled`  s     ##q((r*   c                     | j                   dv S )z6Check if the order is still working (open or pending).)rR      ru   r.   s    r(   
is_workingzOrderTracker.is_workinge  s     ##v--r*   c                     | j                   dv S )z*Check if the order is in a terminal state.)r9   r>   r?   r@   ru   r.   s    r(   is_terminalzOrderTracker.is_terminalj  s     ## (
 
 	
r*   N)r+   r   )r+   N)g      >@NN)__name__
__module____qualname____doc__r	   r)   r/   typeBaseExceptionr   r5   r-   r4   r   r
   intrU   floatr`   rb   boolrq   rs   propertyrv   ry   r{    r*   r(   r   r   I   sL   $?n ?UT\ ?0}%, % $	
 
%9N%5(:C!?@ ^ .&5 &E &P4C 4% 45 4n FJ%%8;d
%	%N
G%$, 
G )4 ) ) .D . . 
T 
 
r*   r   zBUse TradingSuite.order_chain() for integrated order chain buildingzTradingSuite.order_chain()c            	           e Zd ZdZddZddededd fdZ	 ddedededd fdZddedededd fd	Z	d
e
dd fdZ	 ddedz  dedz  dd fdZ	 	 ddedz  dedz  dd fdZ	 ddededz  dd fdZdefdZy)OrderChainBuildera`  
    Fluent API for building complex order chains.

    DEPRECATED: Use TradingSuite.order_chain() instead. Will be removed in v4.0.0.

    Allows creating multi-part orders (entry + stops + targets) with a
    clean, chainable syntax that's easy to read and maintain.

    Example:
        ```python
        order_chain = (
            OrderChainBuilder(suite)
            .market_order(size=2)
            .with_stop_loss(offset=50)
            .with_take_profit(offset=100)
            .with_trail_stop(offset=25, trigger_offset=50)
        )

        result = await order_chain.execute()
        ```
    c                     || _         |j                  | _        d| _        d| _        d| _        d| _        d| _        d| _        d| _	        d| _
        y)z#Initialize the order chain builder.marketN)r   r   r   
entry_typesiderg   entry_pricecontract_id	stop_losstake_profit
trail_stop)r'   r   s     r(   r)   zOrderChainBuilder.__init__  sV    "
*11 # $	 $	)-'+ 152615r*   rg   r   r+   c                 0    d| _         || _        || _        | S )z"Configure a market order as entry.r   )r   rg   r   )r'   rg   r   s      r(   market_orderzOrderChainBuilder.market_order  s    "		r*   pricec                 >    d| _         || _        || _        || _        | S )z!Configure a limit order as entry.limitr   rg   r   r   r'   rg   r   r   s       r(   limit_orderzOrderChainBuilder.limit_order  s&     "	 	r*   c                 >    d| _         || _        || _        || _        | S )z Configure a stop order as entry.stopr   r   s       r(   
stop_orderzOrderChainBuilder.stop_order  s$     	 	r*   r   c                     || _         | S )z'Set the instrument for the order chain.)r   )r'   r   s     r(   for_instrumentz OrderChainBuilder.for_instrument  s    &r*   Noffsetc                     ||d| _         | S )z#Add a stop loss to the order chain.r   r   )r   r'   r   r   s      r(   with_stop_lossz OrderChainBuilder.with_stop_loss  s     %+U;r*   c                     ||d| _         | S )z%Add a take profit to the order chain.r   )r   r   s      r(   with_take_profitz"OrderChainBuilder.with_take_profit  s     '-u=r*   trigger_offsetc                     ||d| _         | S )z'Add a trailing stop to the order chain.)r   r   )r   )r'   r   r   s      r(   with_trail_stopz!OrderChainBuilder.with_trail_stop  s     &,~Nr*   c                 
  K   | j                   t        d      | j                  t        d      | j                  s!| j                  j
                  st        d      | j                  xs | j                  j
                  }|st        d      | j                  j                  j                          d{   }|st        d      | j                  dk(  r|}n| j                  xs |}d}| j                  rb| j                  d   r| j                  d   }nC| j                  d   r4| j                  d	k(  r|| j                  d   z
  }n|| j                  d   z   }d}| j                  rb| j                  d   r| j                  d   }nC| j                  d   r4| j                  d	k(  r|| j                  d   z   }n|| j                  d   z
  }|s|r| j                  dk7  r|n|}| j                  J | j                   J | j                  j                  || j                  | j                   ||xs d
|xs d
| j                         d{   }| j                  r|j                  r|j                   rt"        j%                  d|j                    d       	 | j                  j'                  |j                          d{    | j                  d   }| j                  d	k(  rdnd	}	| j                  j)                  ||	| j                   |       d{   }
|
j                  r$t"        j%                  d|
j*                          |S t"        j-                  d|
j.                          	 |S |S | j                  dk(  r;| j                  j3                  || j                  | j                          d{   }n| j                  dk(  r]| j                  t        d      | j                  j5                  || j                  | j                   | j                         d{   }n\| j                  t        d      | j                  j7                  || j                  | j                   | j                         d{   }t9        |j                  |j                  r|j*                  nddd||xs d
|xs d
|dd|j.                        S 7 7 7 7 # t0        $ r#}t"        j-                  d|        Y d}~|S d}~ww xY w7 S7 7 w)z
        Execute the order chain.

        Returns:
            BracketOrderResponse with all order IDs

        Raises:
            ValueError: If required parameters are missing
            OrderLifecycleError: If order placement fails
        NzOrder size is requiredzOrder side is requiredzContract ID is requiredz.Cannot get current price for risk calculationsr   r   r   r   g        )r   r   rg   r   stop_loss_pricetake_profit_pricer   zReplacing stop order z with trailing stop.rR   )r   r   rg   trail_pricezTrailing stop order placed: zFailed to place trailing stop: z)Error replacing stop with trailing stop: )r   r   rg   r   z(Entry price is required for limit orders)r   r   rg   rf   z'Entry price is required for stop orders)r   r   rg   
stop_price)ro   entry_order_idstop_order_idtarget_order_idr   r   r   entry_responsestop_responsetarget_responseerror_message)rg   r[   r   r   r   instrument_idr7   get_current_pricer   r   r   r   r   place_bracket_orderr   ro   r   ri   rj   rm   place_trailing_stop_orderrT   rn   errorMessagerk   place_market_orderplace_limit_orderplace_stop_orderr   )r'   r   current_pricer   r   r   bracket_entry_priceresulttrail_offset	stop_sidetrail_responserp   responses                r(   executezOrderChainBuilder.execute  s     9956699566

(@(@677&&B$***B*B677 #jjoo??AAMNN ??h&'K**;mK >>~~g&"&.."9)99>&1DNN84L&LO&1DNN84L&LO !($($4$4W$=!!!(+99>(3d6F6Fx6P(P%(3d6F6Fx6P(P% /  $(:   99(((99(((--AA'YYYY/ / 63"3":s?? B  F 6>>f6J6J+F,@,@+AAUVR,,99&:N:NOOO#'??8#<L%)YY!^I+/+=+=+W+W$/&!YY$0	 ,X , &N &--:>;Q;Q:RS M =n>Y>Y=Z[ M6M (*!%!3!3!F!F +$))$)) "G "  G+##+$%OPP!%!3!3!E!E + $ 0 0	 "F "  ##+$%NOO!%!3!3!D!D +#//	 "E "  ( ((3;3C3Cx//" $' / 63"3":s'" $&33 [ BT  P&  ! RLL#LQC!PQQMRs   B4T6S7FT	S
AT(S  SAS S2S T"S +AT3T4A+TT	 AT<T=ATTS S 	T S>8T>TT	TT)r   r   )r   r}   r|   )r~   r   r   r   r)   r   r   r   r   r   rF   r   r   r   r   r   r   r   r*   r(   r   r   u  s   ,6" C 8K  45 %-0	s 5  DW # 2E  BFdl27$,	  $" t| 
	 =A-2T\	Q3 Qr*   r   c                       e Zd ZdZy)rB   z:Exception raised when order lifecycle encounters an error.N)r~   r   r   r   r   r*   r(   rB   rB   l  s    Dr*   rB   z6Use TradingSuite.track_order() for integrated trackingr   r   r   r+   c                     t        |       }|r1t        |t        t        z        r|j	                  |       |S ||_        |S )a  
    Create an OrderTracker instance.

    Args:
        trading_suite: TradingSuite instance
        order: Optional order to track immediately

    Returns:
        OrderTracker instance

    Example:
        ```python
        async with track_order(suite) as tracker:
            order = await suite.orders.place_limit_order(...)
            tracker.track(order)
            filled = await tracker.wait_for_fill()
        ```
    )r   rS   r	   r
   rU   r   )r   r   trackers      r(   track_orderr   q  sC    : =)GeU%778MM%  N  %GNr*   r|   )r   r   loggingtypesr   typingr   r   r   project_x_py.event_busr   project_x_py.modelsr   r	   r
   project_x_py.utils.deprecationr   r   project_x_py.trading_suiter   	getLoggerr~   ri   r   r   rk   rB   r   r   r   r*   r(   <module>r      s   7r    , , , O O G7			8	$ I,	c
 c
c
L	 O,	n nnbE) E
 C,	 ;?!*C/047 r*   