@@ -63,11 +63,11 @@ async def main():
6363
6464from project_x_py .exceptions import ProjectXOrderError
6565from project_x_py .models import Order , OrderPlaceResponse
66+ from project_x_py .statistics import BaseStatisticsTracker
6667from project_x_py .types .config_types import OrderManagerConfig
6768from project_x_py .types .stats_types import OrderManagerStats
6869from project_x_py .types .trading import OrderStatus
6970from project_x_py .utils import (
70- EnhancedStatsTrackingMixin ,
7171 ErrorMessages ,
7272 LogContext ,
7373 LogMessages ,
@@ -95,7 +95,7 @@ class OrderManager(
9595 OrderTypesMixin ,
9696 BracketOrderMixin ,
9797 PositionOrderMixin ,
98- EnhancedStatsTrackingMixin ,
98+ BaseStatisticsTracker ,
9999):
100100 """
101101 Async comprehensive order management system for ProjectX trading operations.
@@ -167,14 +167,10 @@ def __init__(
167167 config: Optional configuration for order management behavior. If not provided,
168168 default values will be used for all configuration options.
169169 """
170- # Initialize mixins
170+ # Initialize mixins and statistics
171171 OrderTrackingMixin .__init__ (self )
172- EnhancedStatsTrackingMixin ._init_enhanced_stats (
173- self ,
174- max_errors = 100 ,
175- max_timings = 1000 ,
176- retention_hours = 24 ,
177- enable_profiling = False ,
172+ BaseStatisticsTracker .__init__ (
173+ self , component_name = "order_manager" , max_errors = 100 , cache_ttl = 5.0
178174 )
179175
180176 self .project_x = project_x_client
@@ -460,7 +456,7 @@ async def place_order(
460456 await self .track_error (
461457 error , "place_order" , {"contract_id" : contract_id , "side" : side }
462458 )
463- await self .track_operation ("place_order" , duration_ms , success = False )
459+ await self .record_timing ("place_order" , duration_ms )
464460 raise error
465461
466462 if not response .get ("success" , False ):
@@ -470,7 +466,7 @@ async def place_order(
470466 await self .track_error (
471467 error , "place_order" , {"contract_id" : contract_id , "side" : side }
472468 )
473- await self .track_operation ("place_order" , duration_ms , success = False )
469+ await self .record_timing ("place_order" , duration_ms )
474470 raise error
475471
476472 result = OrderPlaceResponse (
@@ -481,23 +477,28 @@ async def place_order(
481477 )
482478
483479 # Track successful operation without holding locks
484- await self .track_operation (
485- "place_order" ,
486- duration_ms ,
487- success = True ,
488- metadata = {"size" : size , "order_type" : order_type },
489- )
480+ await self .record_timing ("place_order" , duration_ms )
481+ await self .increment ("successful_operations" )
482+ await self .set_gauge ("last_order_size" , size )
483+ await self .set_gauge ("last_order_type" , order_type )
490484
491485 # Update statistics with order_lock
492486 async with self .order_lock :
487+ # Update legacy stats dict for backward compatibility
493488 self .stats ["orders_placed" ] += 1
494489 self .stats ["last_order_time" ] = datetime .now ()
495490 self .stats ["total_volume" ] += size
496491 if size > self .stats ["largest_order" ]:
497492 self .stats ["largest_order" ] = size
498- self ._last_activity = (
499- datetime .now ()
500- ) # Update activity timestamp directly
493+
494+ # Update new statistics system
495+ await self .increment ("orders_placed" )
496+ await self .increment ("total_volume" , size )
497+ await self .set_gauge ("last_order_timestamp" , time .time ())
498+
499+ # Check if this is the largest order
500+ if size > self .stats .get ("largest_order" , 0 ):
501+ await self .set_gauge ("largest_order" , size )
501502
502503 self .logger .info (
503504 LogMessages .ORDER_PLACED ,
@@ -697,6 +698,8 @@ async def cancel_order(self, order_id: int, account_id: int | None = None) -> bo
697698 self .tracked_orders [str (order_id )]["status" ] = OrderStatus .CANCELLED
698699 self .order_status_cache [str (order_id )] = OrderStatus .CANCELLED
699700
701+ # Update statistics
702+ await self .increment ("orders_cancelled" )
700703 self .stats ["orders_cancelled" ] += 1
701704 self .logger .info (
702705 LogMessages .ORDER_CANCELLED , extra = {"order_id" : order_id }
@@ -793,6 +796,7 @@ async def modify_order(
793796
794797 if response and response .get ("success" , False ):
795798 # Update statistics
799+ await self .increment ("orders_modified" )
796800 async with self .order_lock :
797801 self .stats ["orders_modified" ] += 1
798802
@@ -882,6 +886,121 @@ async def cancel_all_orders(
882886
883887 return results
884888
889+ async def get_order_statistics_async (self ) -> dict [str , Any ]:
890+ """
891+ Get comprehensive async order management statistics using the new statistics system.
892+
893+ Returns:
894+ OrderManagerStats with complete metrics
895+ """
896+ # Get base statistics from the new system
897+ base_stats = await self .get_stats ()
898+
899+ # Get performance metrics
900+ health_score = await self .get_health_score ()
901+
902+ # Get error information
903+ error_count = await self .get_error_count ()
904+ recent_errors = await self .get_recent_errors (5 )
905+
906+ # Make quick copies of legacy stats for backward compatibility
907+ stats_copy = dict (self .stats )
908+ _tracked_orders_count = len (self .tracked_orders )
909+
910+ # Count position-order relationships
911+ total_position_orders = 0
912+ position_summary = {}
913+ for contract_id , orders in self .position_orders .items ():
914+ entry_count = len (orders ["entry_orders" ])
915+ stop_count = len (orders ["stop_orders" ])
916+ target_count = len (orders ["target_orders" ])
917+ total_count = entry_count + stop_count + target_count
918+
919+ if total_count > 0 :
920+ total_position_orders += total_count
921+ position_summary [contract_id ] = {
922+ "entry" : entry_count ,
923+ "stop" : stop_count ,
924+ "target" : target_count ,
925+ "total" : total_count ,
926+ }
927+
928+ # Calculate performance metrics
929+ fill_rate = (
930+ stats_copy ["orders_filled" ] / stats_copy ["orders_placed" ]
931+ if stats_copy ["orders_placed" ] > 0
932+ else 0.0
933+ )
934+
935+ rejection_rate = (
936+ stats_copy ["orders_rejected" ] / stats_copy ["orders_placed" ]
937+ if stats_copy ["orders_placed" ] > 0
938+ else 0.0
939+ )
940+
941+ # Calculate basic timing metrics
942+ avg_order_response_time_ms = (
943+ sum (stats_copy ["order_response_times_ms" ])
944+ / len (stats_copy ["order_response_times_ms" ])
945+ if stats_copy ["order_response_times_ms" ]
946+ else 0.0
947+ )
948+
949+ avg_fill_time_ms = (
950+ sum (stats_copy ["fill_times_ms" ]) / len (stats_copy ["fill_times_ms" ])
951+ if stats_copy ["fill_times_ms" ]
952+ else 0.0
953+ )
954+ fastest_fill_ms = (
955+ min (stats_copy ["fill_times_ms" ]) if stats_copy ["fill_times_ms" ] else 0.0
956+ )
957+ slowest_fill_ms = (
958+ max (stats_copy ["fill_times_ms" ]) if stats_copy ["fill_times_ms" ] else 0.0
959+ )
960+
961+ avg_order_size = (
962+ stats_copy ["total_volume" ] / stats_copy ["orders_placed" ]
963+ if stats_copy ["orders_placed" ] > 0
964+ else 0.0
965+ )
966+
967+ return {
968+ "orders_placed" : stats_copy ["orders_placed" ],
969+ "orders_filled" : stats_copy ["orders_filled" ],
970+ "orders_cancelled" : stats_copy ["orders_cancelled" ],
971+ "orders_rejected" : stats_copy ["orders_rejected" ],
972+ "orders_modified" : stats_copy ["orders_modified" ],
973+ # Performance metrics
974+ "fill_rate" : fill_rate ,
975+ "avg_fill_time_ms" : avg_fill_time_ms ,
976+ "rejection_rate" : rejection_rate ,
977+ # Order types
978+ "market_orders" : stats_copy ["market_orders" ],
979+ "limit_orders" : stats_copy ["limit_orders" ],
980+ "stop_orders" : stats_copy ["stop_orders" ],
981+ "bracket_orders" : stats_copy ["bracket_orders" ],
982+ # Timing statistics
983+ "last_order_time" : stats_copy ["last_order_time" ].isoformat ()
984+ if stats_copy ["last_order_time" ]
985+ else None ,
986+ "avg_order_response_time_ms" : avg_order_response_time_ms ,
987+ "fastest_fill_ms" : fastest_fill_ms ,
988+ "slowest_fill_ms" : slowest_fill_ms ,
989+ # Volume and value
990+ "total_volume" : stats_copy ["total_volume" ],
991+ "total_value" : stats_copy ["total_value" ],
992+ "avg_order_size" : avg_order_size ,
993+ "largest_order" : stats_copy ["largest_order" ],
994+ # Risk metrics
995+ "risk_violations" : stats_copy ["risk_violations" ],
996+ "order_validation_failures" : stats_copy ["order_validation_failures" ],
997+ # New metrics from v3.3.0 statistics system
998+ "health_score" : health_score ,
999+ "error_count" : error_count ,
1000+ "recent_errors" : recent_errors ,
1001+ "component_stats" : base_stats ,
1002+ }
1003+
8851004 def get_order_statistics (self ) -> OrderManagerStats :
8861005 """
8871006 Get comprehensive order management statistics and system health information.
0 commit comments