Files
xnessomGitHubxnessomgoogle-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
e52b45ab6d ⚙️ Jules02: Performance and runtime analysis — [high-throughput optimizations] (#1214)
* feat: ⚙️ Jules02: Performance and runtime analysis — high-throughput optimizations

This PR implements several key performance improvements across the trading system:

1. **Backtesting Speedup**: Replaced per-bar `profile` context managers in `BacktestEngine` with lightweight `time.perf_counter()` accumulators. This reduces loop overhead by ~40% for typical backtests while providing a more detailed execution breakdown.
2. **Database Efficiency**: Optimized the trade closure sequence in `main.py` and `TradeLogger` to eliminate redundant database queries by passing and returning ORM objects directly.
3. **Live Loop Consolidation**: Redundant technical indicators (ATR, Volatility) in the live trading loop are now extracted from already-computed feature dataframes or regime info, avoiding expensive rolling window calculations.
4. **Log Processing Optimization**: Hardened `SecretMaskingProcessor` with a primitive fast-path and in-place recursion support, significantly reducing overhead for high-frequency logging events.
5. **Hygiene**: Organized performance benchmarks into a dedicated `benchmarks/` directory.

Verified with `pytest` and custom benchmark scripts.
- Backtest (2000 bars): 0.19s -> 0.11s
- Masking primitive fast-path: ~0.3us
- All 15 relevant tests passed.

Co-authored-by: xnessom <255288032+xnessom@users.noreply.github.com>

* feat: ⚙️ Jules02: Performance and runtime analysis — high-throughput optimizations

This PR implements several key performance improvements across the trading system:

1. **Backtesting Speedup**: Replaced per-bar `profile` context managers in `BacktestEngine` with lightweight `time.perf_counter()` accumulators. This reduces loop overhead by ~40% for typical backtests while providing a more detailed execution breakdown.
2. **Database Efficiency**: Optimized the trade closure sequence in `main.py` and `TradeLogger` to eliminate redundant database queries by passing and returning ORM objects directly.
3. **Live Loop Consolidation**: Redundant technical indicators (ATR, Volatility) in the live trading loop are now extracted from already-computed feature dataframes or regime info, avoiding expensive rolling window calculations.
4. **Log Processing Optimization**: Hardened `SecretMaskingProcessor` with a primitive fast-path and correct in-place recursion support, significantly reducing overhead for high-frequency logging events.
5. **Dependency Harmony**: Resolved a version conflict between `python-socketio` and `metaapi-cloud-sdk` by pinning a compatible version.

Verified with `pytest` and custom benchmark scripts.
- Backtest (2000 bars): 0.19s -> 0.11s
- All 15 relevant tests passed.
- Linting and dependency checks pass.

Co-authored-by: xnessom <255288032+xnessom@users.noreply.github.com>

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: xnessom <255288032+xnessom@users.noreply.github.com>
2026-05-15 05:31:57 +00:00

12 KiB

Performance Tuning Guide: MT5 AI/ML XAUUSD Trading Bot

Executive Summary

Systematic approach to identifying and eliminating performance bottlenecks, achieving sub-100ms execution latency and handling 1000+ market ticks per second while maintaining prediction accuracy.

1. Profiling & Bottleneck Identification

1.1 CPU Profiling

  • Tool: cProfile, py-spy for runtime profiling
  • Instrumentation: High-resolution profile context manager in src/core/profiler.py
    • DEBUG Level: All performance metrics are logged at DEBUG level by default to minimize I/O overhead.
    • Slow Threshold: Supports an optional slow_threshold_ms parameter. If duration exceeds this threshold, the event is escalated to INFO level for visibility of latency hotspots.
  • Granular Blocks:
    • compute_features_total: Entire feature engineering pipeline.
    • fe_base_technical, fe_candle_patterns, fe_price_action, fe_volume: Specific base-timeframe feature blocks.
    • fe_mtf_all: All multi-timeframe feature generation.
    • fe_mtf_[TF]: Latency for a specific timeframe (e.g., fe_mtf_H1).
    • inference_ppo, inference_lstm: Latency for individual model predictions within the ensemble.
  • Target: Identify functions consuming >10% CPU time
  • Analysis: Continuous monitoring of main loop latency (data_fetch, inference, risk_check, execution)
  • Output: Structured logs with duration_ms AND Prometheus Histogram metrics (trading_block_duration_seconds)
  • Action: Optimize top 3 CPU consumers

1.2 Memory Profiling

  • Tool: memory_profiler, objgraph
  • Target: Identify memory leaks and bloat
  • Monitoring: Track memory growth over time
  • Limits: Keep memory <500MB for model inference
  • Optimization: Use generators for large datasets

1.3 I/O Profiling

  • Tool: strace, py-spy with I/O mode
  • Target: Identify slow disk/network I/O
  • Analysis: Monitor open file descriptors
  • Target: <10ms for database queries
  • Optimization: Connection pooling, caching, conditional persistence (only save metrics on trade close)

2. Data Pipeline Optimization

2.1 Data Ingestion

  • Batch Processing: Process 100+ ticks in batches
  • Buffering: 1-second rolling buffer
  • Async I/O: Non-blocking network reads
  • Compression: Compress historical data on disk
  • Target: <5ms ingestion latency per batch

2.2 Feature Engineering

  • Incremental Calculation: Update features incrementally
  • Caching: Cache expensive feature calculations
  • Vectorization: Use NumPy/Pandas for bulk operations
  • Multiprocessing: Parallel feature calculation
  • Target: <10ms for 50+ features per tick

2.3 Data Storage

  • Format: Protocol Buffers for serialization
  • Compression: LZ4 for data at rest
  • Indexing: Database indexes on frequently queried columns
  • Partitioning: Time-series partitioning by date
  • Archival: Move old data to cold storage

3. Model Inference Optimization

3.1 Model Serving

  • Framework: TensorFlow Serving or ONNX Runtime
  • Quantization: 8-bit integer quantization
  • Pruning: Remove 30%+ of low-importance weights
  • Batching: Batch 100 predictions for GPU
  • Target: <10ms latency per prediction

3.2 Hardware Acceleration

  • GPU: NVIDIA GPU for batched inference
  • TensorRT: NVIDIA TensorRT for optimization
  • ONNX: Model-agnostic inference optimization
  • CPU: Intel MKL for CPU optimization
  • Speedup: 10-100x improvement with GPU

3.3 Caching Strategy

  • Output Cache: Cache recent predictions
  • TTL: 100ms cache lifetime
  • Size: 10,000 entry cache
  • Hit Rate: Target 30%+ cache hit rate
  • Measurement: Monitor cache effectiveness

4. Database Optimization

4.1 Query Optimization

  • Analysis: EXPLAIN ANALYZE for slow queries
  • Scalar Selects: Use scalars().all() to fetch specific columns (e.g., P&L) instead of full ORM objects.
  • Indexing: Add indexes on ticket, status, and is_deleted.
  • Denormalization: Pre-aggregate time-series data
  • Partitioning: Partition by date for faster queries
  • Target: <10ms for most queries

4.2 Connection Pooling

  • Pool Size: 20-50 connections
  • Reuse: Reuse connections to avoid handshake overhead
  • Timeout: 5-minute idle timeout
  • Overflow: Queue requests during peak load
  • Monitoring: Track pool utilization

4.3 Caching Layer

  • Tool: Redis for caching
  • Strategy: Cache hot data (recent trades, positions)
  • TTL: 1-minute cache for market data
  • Size: 100MB+ cache for efficient hit rates
  • Eviction: LRU eviction policy

5. Network Optimization

5.1 Connection Management

  • Persistent Connections: Keep MT5 connection open
  • Connection Pooling: Reuse connections
  • Heartbeat: Send keep-alive every 30 seconds
  • Reconnection: Automatic reconnection on timeout
  • Target: <5ms round-trip time

5.2 Protocol Optimization

  • Format: Binary format over JSON for efficiency
  • Compression: Gzip for large messages
  • Batching: Send/receive in batches
  • Async: Non-blocking I/O for all network operations
  • Reduction: Minimize data transferred

5.3 Bandwidth Management

  • Streaming: Stream data instead of batch loading
  • Sampling: Sample non-critical data
  • Delta Updates: Send only changes
  • Throttling: Rate limit to 1000 ticks/second
  • Monitoring: Track bandwidth utilization

6. Algorithm Optimization

6.1 Order Execution

  • Algorithm: TWAP/VWAP for large orders
  • Splits: Break large orders into smaller pieces
  • Timing: Execute during high liquidity windows
  • Validation: Pre-validate all orders before submission
  • Target: <100ms from signal to execution

6.2 Risk Calculations

  • Incremental: Update risk incrementally
  • Approximation: Use approximate calculations for speed
  • Caching: Cache risk metrics with 10-second TTL
  • Vectorization: Batch calculate multiple risk metrics
  • Target: <1ms for all risk calculations

6.3 Decision Making

  • Early Exit: Exit early on clear signals
  • Threshold: Use confidence threshold to skip low-signal trades
  • Batching: Batch process multiple decisions
  • Async: Process decisions asynchronously
  • Target: <50ms for decision making

7. Code-Level Optimizations

7.1 Python Optimization

  • Bypass Redundant Rendering: In DecisionSupportSystem.format_for_operator, we bypass rich.Console.capture() when a console is already provided for direct printing. This eliminates expensive string rendering in the main loop.
  • Vectorized Backtest Loops: In BacktestEngine.run_walk_forward, we pre-calculate all execution filter metrics (ATR, EMA, RSI, and slopes) outside the main walk-forward loop. Complexity is reduced from O(N^2) to O(N) by eliminating redundant slicing and rolling calculations.
  • TradeLogger Caching: Implemented an intelligent cache for performance reports in TradeLogger that invalidates only on trade closure. This prevents redundant database I/O and O(N) P&L recalculations on every tick evaluation in live mode.
  • Precomputed Execution Filters: ExecutionFilter.validate now supports a precomputed_metrics parameter, enabling it to bypass all internal DataFrame processing when metrics are supplied by an optimized loop (like the backtester).
  • Optional MTF Patterns: FeatureEngineer now defaults to include_mtf_patterns=False. Disabling expensive candle pattern recognition on higher timeframes provides a ~60% speedup for large datasets (e.g., 50,000 bars) and reduces feature matrix dimensionality.
  • Optional Volume Profile: FeatureEngineer supports include_volume_profile=False to skip expensive rolling quantile calculations (POC, VAH, VAL). This provides an additional ~40% latency reduction in the feature engineering pipeline. Schema stability is maintained by padding disabled columns with NaNs.
  • Resilient NaN Handling: FeatureEngineer now only drops rows missing base features and uses forward-filling for MTF gaps, significantly increasing data utilization for short historical windows.
  • Granular Performance Metrics: TradeLogger.read_performance_report and the BacktestEngine loop are instrumented with high-resolution profile markers.
  • ORM Object Reuse: TradeLogger.update_trade and the live trading loop in main.py are optimized to reuse Trade ORM objects, eliminating redundant database lookups during position closure.
  • Lightweight Backtest Timing: The hot loop in BacktestEngine now uses manual time.perf_counter() accumulators instead of the higher-overhead profile context manager, reducing backtest loop latency by ~40%.
  • Log Masking Fast-Path: SecretMaskingProcessor implements a primitive fast-path and in-place recursion, significantly reducing instrumentation overhead for high-frequency logging.
  • Indicator Calculation Consolidation: The live loop in main.py avoids redundant rolling window calculations by extracting ATR and volatility metrics directly from already-computed feature dataframes.
# Bad: List comprehension with function call
results = [calculate_result(x) for x in data]

# Good: Vectorized NumPy operation
results = np.vectorize(calculate_result)(data)

# Better: Built-in NumPy function
results = np.array(data) * 2  # If that's what calculate_result does

7.2 Memory Optimization

# Bad: Create large intermediate lists
data = [expensive_calculation(x) for x in range(1000000)]
results = [process(x) for x in data]

# Good: Use generators
def data_gen():
    for x in range(1000000):
        yield expensive_calculation(x)

results = [process(x) for x in data_gen()]

7.3 Async I/O

# Bad: Blocking I/O
for trade in trades:
    result = broker_api.submit_order(trade)  # Blocks
    print(result)

# Good: Async I/O
async def submit_orders_async(trades):
    tasks = [broker_api.submit_order_async(t) for t in trades]
    results = await asyncio.gather(*tasks)
    return results

8. System-Level Optimization

8.1 CPU Affinity

  • Pinning: Pin processes to specific CPU cores
  • NUMA: Optimize for NUMA architecture
  • Hyperthreading: Disable for consistent performance
  • Frequency: Set CPU governor to performance mode
  • Isolation: Isolate trading bot CPU cores

8.2 Operating System

  • Kernel: Low-latency kernel for trading systems
  • Scheduler: Use FIFO scheduler for critical threads
  • Memory: Pre-allocate memory to avoid page faults
  • Swap: Disable swap for predictable latency
  • Limits: Increase file descriptor limits

8.3 Container Optimization

  • CPU Limits: Set appropriate CPU limits
  • Memory Limits: 1GB+ for trading bot
  • Affinity: Bind to specific CPU cores
  • Priority: Set high priority for trading thread
  • Resource: Monitor resource usage

9. Benchmarking & Testing

9.1 Load Testing

  • Scenario: 1000 ticks/second sustained load
  • Duration: 1-hour sustained test
  • Metrics: Track latency, throughput, errors
  • Target: p95 latency <500ms, p99 <1s
  • Frequency: Weekly load testing

9.2 Stress Testing

  • Spike: 10x normal load sudden spike
  • Recovery: Verify recovery to baseline
  • Failure Points: Identify where system breaks
  • Mitigation: Implement circuit breakers
  • Testing: Monthly stress test

9.3 Regression Testing

  • Baseline: Establish performance baseline
  • Changes: Test performance after code changes
  • Comparison: Compare to baseline
  • Alert: Automatic alert on >5% regression
  • Tracking: Track performance metrics over time

10. Monitoring & Continuous Optimization

10.1 Performance Metrics

  • Latency: p50, p95, p99 percentiles
  • Throughput: Requests/predictions per second
  • CPU/Memory: Resource utilization
  • Network: Bandwidth and connection count
  • Cache: Hit rate and eviction rate

10.2 Alerting

  • Latency Alert: p95 > 500ms
  • Throughput Alert: < 50% expected
  • Error Rate: > 0.5%
  • Resource Alert: CPU > 80%, Memory > 85%
  • Response: Auto-scaling on alert

10.3 Optimization Roadmap

  • Week 1-2: Profile and identify top bottlenecks
  • Week 3-4: Optimize data pipeline
  • Week 5-6: Optimize model inference
  • Week 7-8: Database and caching optimization
  • Week 9+: Continuous monitoring and tuning

Conclusion

Performance is critical for trading bot success. Systematic profiling, optimization, and continuous monitoring ensure sub-100ms execution latency and 99.5% uptime.