# Trading Agent Service Design **Version**: 1.0 **Date**: 2025-10-16 **Author**: Agent 11.10 **Status**: Design Phase --- ## Executive Summary The **Trading Agent Service** is a new microservice that orchestrates trading decisions by managing universe selection, asset selection, portfolio allocation, and strategy coordination. It **drives** the Trading Service by generating and submitting orders based on ML predictions, market conditions, and risk constraints. **Key Principle**: The Trading Agent Service is the **decision-making brain** while the Trading Service remains the **execution engine**. --- ## Architecture Overview ### Current State ``` API Gateway (50051) ↓ Trading Service (50052) ← monolithic decision + execution Backtesting Service (50053) ML Training Service (50054) ``` ### Target State ``` API Gateway (50051) ↓ Trading Agent Service (50055) ← NEW: decision-making orchestration ↓ (drives via gRPC calls) Trading Service (50052) ← execution only ↓ ML Training Service (50054) ← provides ML predictions Backtesting Service (50053) ← simulates Trading Agent behavior ``` --- ## Service Responsibilities ### Trading Agent Service (NEW - Port 50055) **Core Responsibilities**: 1. **Universe Selection**: Determine which markets/exchanges to trade (ES.FUT, NQ.FUT, etc.) 2. **Asset Selection**: Choose specific instruments within universe based on ML signals 3. **Portfolio Allocation**: Optimize capital allocation across selected assets 4. **Risk Management Coordination**: Enforce portfolio-level risk limits 5. **Strategy Orchestration**: Coordinate multiple trading strategies (ML ensemble, mean reversion, etc.) 6. **Order Generation**: Create orders based on allocation decisions 7. **ML Integration**: Query ML Training Service for predictions 8. **Performance Monitoring**: Track agent performance vs. benchmarks **What it DOES**: - ✅ Decides WHAT to trade and WHEN - ✅ Calculates position sizes and allocations - ✅ Generates order instructions - ✅ Monitors overall portfolio health - ✅ Adapts to market regimes **What it DOES NOT do**: - ❌ Execute orders (Trading Service responsibility) - ❌ Manage individual order lifecycle (Trading Service) - ❌ Track fills and positions (Trading Service) - ❌ Stream market data (Trading Service) - ❌ Train ML models (ML Training Service) ### Trading Service (Port 50052) **Responsibilities (UNCHANGED)**: - Order execution and lifecycle management - Position tracking and PnL calculation - Market data streaming - Execution quality monitoring - Paper trading simulation - ML order submission (enhanced with agent integration) **New Integration**: - Receives order instructions from Trading Agent Service - Reports execution status back to Trading Agent Service - Provides position snapshots for allocation decisions --- ## gRPC API Design ### Proto Definition **File**: `services/trading_agent_service/proto/trading_agent.proto` ```protobuf syntax = "proto3"; package trading_agent; // Trading Agent Service orchestrates trading decisions across universe selection, // asset selection, portfolio allocation, and strategy coordination. service TradingAgentService { // Universe Management // Select tradable universe based on liquidity, volatility, and ML signals rpc SelectUniverse(SelectUniverseRequest) returns (SelectUniverseResponse); // Get current trading universe configuration rpc GetUniverse(GetUniverseRequest) returns (GetUniverseResponse); // Update universe selection criteria rpc UpdateUniverseCriteria(UpdateUniverseCriteriaRequest) returns (UpdateUniverseCriteriaResponse); // Asset Selection // Select specific assets to trade within universe rpc SelectAssets(SelectAssetsRequest) returns (SelectAssetsResponse); // Get current asset selection with scores rpc GetSelectedAssets(GetSelectedAssetsRequest) returns (GetSelectedAssetsResponse); // Portfolio Allocation // Allocate capital across selected assets rpc AllocatePortfolio(AllocatePortfolioRequest) returns (AllocatePortfolioResponse); // Get current portfolio allocation rpc GetAllocation(GetAllocationRequest) returns (GetAllocationResponse); // Rebalance portfolio based on target allocation rpc RebalancePortfolio(RebalancePortfolioRequest) returns (RebalancePortfolioResponse); // Order Generation // Generate orders based on allocation and ML signals rpc GenerateOrders(GenerateOrdersRequest) returns (GenerateOrdersResponse); // Submit generated orders to Trading Service rpc SubmitAgentOrders(SubmitAgentOrdersRequest) returns (SubmitAgentOrdersResponse); // Strategy Coordination // Register a trading strategy with the agent rpc RegisterStrategy(RegisterStrategyRequest) returns (RegisterStrategyResponse); // Get list of active strategies rpc ListStrategies(ListStrategiesRequest) returns (ListStrategiesResponse); // Enable/disable a strategy rpc UpdateStrategyStatus(UpdateStrategyStatusRequest) returns (UpdateStrategyStatusResponse); // Agent Monitoring // Get comprehensive agent status and performance rpc GetAgentStatus(GetAgentStatusRequest) returns (GetAgentStatusResponse); // Stream real-time agent decisions and actions rpc StreamAgentActivity(StreamAgentActivityRequest) returns (stream AgentActivityEvent); // Get agent performance metrics rpc GetAgentPerformance(GetAgentPerformanceRequest) returns (GetAgentPerformanceResponse); // Service Health rpc HealthCheck(HealthCheckRequest) returns (HealthCheckResponse); } // Universe Selection Messages message SelectUniverseRequest { UniverseCriteria criteria = 1; // Selection criteria optional uint32 max_instruments = 2; // Maximum instruments in universe bool force_refresh = 3; // Force recalculation } message SelectUniverseResponse { repeated Instrument instruments = 1; // Selected instruments UniverseMetrics metrics = 2; // Universe quality metrics int64 timestamp = 3; // Selection timestamp (nanoseconds) string universe_id = 4; // Unique universe identifier } message GetUniverseRequest { optional string universe_id = 1; // Get specific universe, or current if not specified } message GetUniverseResponse { string universe_id = 1; repeated Instrument instruments = 2; UniverseCriteria criteria = 3; UniverseMetrics metrics = 4; int64 created_at = 5; // Unix timestamp (nanoseconds) int64 updated_at = 6; } message UpdateUniverseCriteriaRequest { UniverseCriteria criteria = 1; } message UpdateUniverseCriteriaResponse { bool success = 1; string message = 2; string universe_id = 3; // New universe ID after update } // Asset Selection Messages message SelectAssetsRequest { string universe_id = 1; // Universe to select from AssetSelectionCriteria criteria = 2; // Selection criteria uint32 max_assets = 3; // Maximum assets to select } message SelectAssetsResponse { repeated AssetScore assets = 1; // Selected assets with scores SelectionMetrics metrics = 2; // Selection quality metrics int64 timestamp = 3; } message GetSelectedAssetsRequest { optional string universe_id = 1; } message GetSelectedAssetsResponse { repeated AssetScore assets = 1; SelectionMetrics metrics = 2; int64 timestamp = 3; } // Portfolio Allocation Messages message AllocatePortfolioRequest { repeated AssetScore assets = 1; // Assets to allocate across AllocationStrategy strategy = 2; // Allocation algorithm RiskConstraints risk_constraints = 3; // Risk limits double total_capital = 4; // Total capital to allocate } message AllocatePortfolioResponse { repeated AssetAllocation allocations = 1; // Allocation per asset AllocationMetrics metrics = 2; // Allocation quality metrics int64 timestamp = 3; string allocation_id = 4; } message GetAllocationRequest { optional string allocation_id = 1; // Get specific allocation, or current if not specified } message GetAllocationResponse { string allocation_id = 1; repeated AssetAllocation allocations = 2; AllocationMetrics metrics = 3; int64 created_at = 4; double total_capital = 5; } message RebalancePortfolioRequest { string allocation_id = 1; // Target allocation double rebalance_threshold = 2; // Min deviation to trigger rebalance (%) bool force_rebalance = 3; // Force rebalance regardless of threshold } message RebalancePortfolioResponse { repeated RebalanceAction actions = 1; // Required rebalancing actions RebalanceMetrics metrics = 2; bool rebalance_required = 3; int64 timestamp = 4; } // Order Generation Messages message GenerateOrdersRequest { string allocation_id = 1; // Target allocation repeated MLSignal ml_signals = 2; // ML predictions for timing OrderGenerationStrategy strategy = 3; // Order generation algorithm } message GenerateOrdersResponse { repeated GeneratedOrder orders = 1; // Generated order instructions OrderGenerationMetrics metrics = 2; int64 timestamp = 3; string order_batch_id = 4; } message SubmitAgentOrdersRequest { string order_batch_id = 1; // Batch ID from GenerateOrders repeated GeneratedOrder orders = 2; // Orders to submit bool dry_run = 3; // Test without actual submission } message SubmitAgentOrdersResponse { repeated OrderSubmissionResult results = 1; // Submission results per order OrderSubmissionMetrics metrics = 2; int64 timestamp = 3; } // Strategy Coordination Messages message RegisterStrategyRequest { string strategy_name = 1; // Unique strategy name StrategyType strategy_type = 2; // Strategy category StrategyConfig config = 3; // Strategy configuration bool auto_enable = 4; // Enable immediately after registration } message RegisterStrategyResponse { bool success = 1; string strategy_id = 2; string message = 3; } message ListStrategiesRequest { optional StrategyStatus status_filter = 1; // Filter by status } message ListStrategiesResponse { repeated Strategy strategies = 1; } message UpdateStrategyStatusRequest { string strategy_id = 1; StrategyStatus new_status = 2; optional string reason = 3; } message UpdateStrategyStatusResponse { bool success = 1; string message = 2; Strategy updated_strategy = 3; } // Agent Monitoring Messages message GetAgentStatusRequest { bool include_performance = 1; // Include performance metrics bool include_positions = 2; // Include current positions } message GetAgentStatusResponse { AgentStatus status = 1; optional AgentPerformanceMetrics performance = 2; optional PositionSummary positions = 3; int64 timestamp = 4; } message StreamAgentActivityRequest { repeated ActivityType activity_types = 1; // Filter by activity type } message AgentActivityEvent { ActivityType activity_type = 1; oneof event { UniverseSelectionEvent universe_event = 2; AssetSelectionEvent asset_event = 3; AllocationEvent allocation_event = 4; OrderGenerationEvent order_event = 5; StrategyEvent strategy_event = 6; } int64 timestamp = 7; } message GetAgentPerformanceRequest { optional int64 start_time = 1; // Performance window start (nanoseconds) optional int64 end_time = 2; // Performance window end (nanoseconds) bool include_strategy_breakdown = 3; // Include per-strategy performance } message GetAgentPerformanceResponse { AgentPerformanceMetrics metrics = 1; repeated StrategyPerformance strategy_performance = 2; int64 timestamp = 3; } message HealthCheckRequest {} message HealthCheckResponse { bool healthy = 1; string message = 2; map details = 3; } // Data Structures message Instrument { string symbol = 1; // Trading symbol (ES.FUT, NQ.FUT) string exchange = 2; // Exchange identifier InstrumentType instrument_type = 3; // Futures, equity, FX, etc. double liquidity_score = 4; // Liquidity rating (0.0-1.0) double volatility = 5; // Annualized volatility double ml_signal_strength = 6; // ML prediction confidence map metadata = 7; } message UniverseCriteria { double min_liquidity_score = 1; // Minimum liquidity threshold double min_volatility = 2; // Minimum volatility double max_volatility = 3; // Maximum volatility repeated InstrumentType allowed_types = 4; repeated string exchanges = 5; // Allowed exchanges double min_ml_confidence = 6; // Minimum ML signal confidence } message UniverseMetrics { uint32 total_instruments = 1; double avg_liquidity_score = 2; double avg_volatility = 3; double portfolio_diversification = 4; // 0.0-1.0 } message AssetSelectionCriteria { double min_ml_signal_strength = 1; // Minimum ML confidence double min_sharpe_ratio = 2; // Minimum risk-adjusted return SelectionMode mode = 3; // Top-N, threshold-based, etc. } message AssetScore { string symbol = 1; double ml_score = 2; // ML model prediction score double momentum_score = 3; // Momentum factor score double value_score = 4; // Value factor score double quality_score = 5; // Quality factor score double composite_score = 6; // Final weighted score map model_scores = 7; // Per-model scores (DQN, MAMBA2, etc.) } message SelectionMetrics { uint32 assets_evaluated = 1; uint32 assets_selected = 2; double avg_composite_score = 3; double min_score = 4; double max_score = 5; } message AllocationStrategy { AllocationType allocation_type = 1; // Equal-weight, risk-parity, etc. map parameters = 2; // Strategy-specific parameters } message RiskConstraints { double max_position_size_pct = 1; // Max % of portfolio per position double max_sector_exposure_pct = 2; // Max % per sector double max_volatility = 3; // Portfolio volatility limit double max_var_95 = 4; // Value at Risk (95%) double max_leverage = 5; // Maximum leverage ratio } message AssetAllocation { string symbol = 1; double target_weight = 2; // Target allocation weight (0.0-1.0) double target_capital = 3; // Target capital in USD double target_quantity = 4; // Target position size double current_weight = 5; // Current allocation weight double current_quantity = 6; // Current position size double rebalance_delta = 7; // Required change } message AllocationMetrics { double total_weight = 1; // Should be ~1.0 double portfolio_volatility = 2; // Expected portfolio volatility double portfolio_sharpe = 3; // Expected Sharpe ratio double var_95 = 4; // Portfolio VaR (95%) double max_drawdown_estimate = 5; // Expected max drawdown } message RebalanceAction { string symbol = 1; double current_quantity = 2; double target_quantity = 3; double delta_quantity = 4; // Positive = buy, negative = sell RebalanceReason reason = 5; } message RebalanceMetrics { uint32 total_rebalance_actions = 1; double total_turnover = 2; // Total capital moved (USD) double estimated_cost = 3; // Estimated transaction costs } message MLSignal { string symbol = 1; string model_name = 2; // DQN, MAMBA2, PPO, TFT double signal_strength = 3; // -1.0 to 1.0 (short to long) double confidence = 4; // 0.0 to 1.0 string predicted_action = 5; // BUY, SELL, HOLD int64 timestamp = 6; } message OrderGenerationStrategy { OrderGenerationMode mode = 1; double slippage_tolerance = 2; // Max acceptable slippage (%) bool use_limit_orders = 3; // Use limit orders vs market double limit_price_offset = 4; // Offset from mid price (%) } message GeneratedOrder { string symbol = 1; OrderSide side = 2; // BUY or SELL double quantity = 3; OrderType order_type = 4; // MARKET, LIMIT, etc. optional double price = 5; // Limit price if applicable string rationale = 6; // Why this order was generated map metadata = 7; } message OrderGenerationMetrics { uint32 orders_generated = 1; double total_notional = 2; // Total order value (USD) double avg_order_size = 3; } message OrderSubmissionResult { string symbol = 1; bool success = 2; optional string order_id = 3; // From Trading Service optional string error_message = 4; } message OrderSubmissionMetrics { uint32 orders_submitted = 1; uint32 orders_accepted = 2; uint32 orders_rejected = 3; double acceptance_rate = 4; } message Strategy { string strategy_id = 1; string strategy_name = 2; StrategyType strategy_type = 3; StrategyStatus status = 4; StrategyConfig config = 5; StrategyPerformance performance = 6; int64 created_at = 7; int64 updated_at = 8; } message StrategyConfig { map parameters = 1; // Strategy-specific parameters repeated string target_symbols = 2; // Symbols this strategy trades double max_capital_pct = 3; // Max % of portfolio for this strategy } message StrategyPerformance { string strategy_id = 1; double total_pnl = 2; double sharpe_ratio = 3; double win_rate = 4; uint32 total_trades = 5; int64 period_start = 6; int64 period_end = 7; } message AgentStatus { AgentState state = 1; string current_universe_id = 2; uint32 active_strategies = 3; uint32 selected_assets = 4; double portfolio_utilization = 5; // % of capital deployed int64 last_action_timestamp = 6; } message AgentPerformanceMetrics { double total_pnl = 1; double sharpe_ratio = 2; double max_drawdown = 3; double win_rate = 4; uint32 total_trades = 5; double avg_trade_pnl = 6; double portfolio_turnover = 7; // Annualized int64 period_start = 8; int64 period_end = 9; } message PositionSummary { repeated Position positions = 1; double total_equity = 2; double total_exposure = 3; double leverage_ratio = 4; } message Position { string symbol = 1; double quantity = 2; double average_price = 3; double market_value = 4; double unrealized_pnl = 5; double weight = 6; // % of portfolio } message UniverseSelectionEvent { string universe_id = 1; repeated string added_symbols = 2; repeated string removed_symbols = 3; UniverseMetrics metrics = 4; } message AssetSelectionEvent { repeated AssetScore selected_assets = 1; SelectionMetrics metrics = 2; } message AllocationEvent { string allocation_id = 1; repeated AssetAllocation allocations = 2; AllocationMetrics metrics = 3; } message OrderGenerationEvent { string order_batch_id = 1; repeated GeneratedOrder orders = 2; OrderGenerationMetrics metrics = 3; } message StrategyEvent { string strategy_id = 1; StrategyEventType event_type = 2; string message = 3; } // Enums enum InstrumentType { INSTRUMENT_TYPE_UNSPECIFIED = 0; INSTRUMENT_TYPE_EQUITY = 1; INSTRUMENT_TYPE_FUTURES = 2; INSTRUMENT_TYPE_FX = 3; INSTRUMENT_TYPE_OPTIONS = 4; INSTRUMENT_TYPE_CRYPTO = 5; } enum SelectionMode { SELECTION_MODE_UNSPECIFIED = 0; SELECTION_MODE_TOP_N = 1; // Select top N by score SELECTION_MODE_THRESHOLD = 2; // Select all above threshold SELECTION_MODE_QUANTILE = 3; // Select top quantile (e.g., top 20%) } enum AllocationType { ALLOCATION_TYPE_UNSPECIFIED = 0; ALLOCATION_TYPE_EQUAL_WEIGHT = 1; // 1/N allocation ALLOCATION_TYPE_RISK_PARITY = 2; // Equal risk contribution ALLOCATION_TYPE_ML_OPTIMIZED = 3; // ML-based optimization ALLOCATION_TYPE_KELLY = 4; // Kelly criterion ALLOCATION_TYPE_MEAN_VARIANCE = 5; // Mean-variance optimization } enum RebalanceReason { REBALANCE_REASON_UNSPECIFIED = 0; REBALANCE_REASON_DRIFT = 1; // Allocation drifted from target REBALANCE_REASON_UNIVERSE_CHANGE = 2; // Universe updated REBALANCE_REASON_RISK_LIMIT = 3; // Risk limit violation REBALANCE_REASON_MANUAL = 4; // Manual rebalance request } enum OrderGenerationMode { ORDER_GENERATION_MODE_UNSPECIFIED = 0; ORDER_GENERATION_MODE_AGGRESSIVE = 1; // Market orders, immediate execution ORDER_GENERATION_MODE_PASSIVE = 2; // Limit orders, minimize slippage ORDER_GENERATION_MODE_ADAPTIVE = 3; // Adapt based on market conditions } enum OrderSide { ORDER_SIDE_UNSPECIFIED = 0; ORDER_SIDE_BUY = 1; ORDER_SIDE_SELL = 2; } enum OrderType { ORDER_TYPE_UNSPECIFIED = 0; ORDER_TYPE_MARKET = 1; ORDER_TYPE_LIMIT = 2; ORDER_TYPE_STOP = 3; ORDER_TYPE_STOP_LIMIT = 4; } enum StrategyType { STRATEGY_TYPE_UNSPECIFIED = 0; STRATEGY_TYPE_ML_ENSEMBLE = 1; // Ensemble ML predictions STRATEGY_TYPE_MEAN_REVERSION = 2; // Mean reversion STRATEGY_TYPE_MOMENTUM = 3; // Momentum/trend following STRATEGY_TYPE_ARBITRAGE = 4; // Statistical arbitrage STRATEGY_TYPE_MARKET_MAKING = 5; // Market making } enum StrategyStatus { STRATEGY_STATUS_UNSPECIFIED = 0; STRATEGY_STATUS_ENABLED = 1; STRATEGY_STATUS_DISABLED = 2; STRATEGY_STATUS_PAUSED = 3; STRATEGY_STATUS_ERROR = 4; } enum AgentState { AGENT_STATE_UNSPECIFIED = 0; AGENT_STATE_INITIALIZING = 1; AGENT_STATE_ACTIVE = 2; AGENT_STATE_PAUSED = 3; AGENT_STATE_ERROR = 4; AGENT_STATE_SHUTDOWN = 5; } enum ActivityType { ACTIVITY_TYPE_UNSPECIFIED = 0; ACTIVITY_TYPE_UNIVERSE_SELECTION = 1; ACTIVITY_TYPE_ASSET_SELECTION = 2; ACTIVITY_TYPE_ALLOCATION = 3; ACTIVITY_TYPE_ORDER_GENERATION = 4; ACTIVITY_TYPE_STRATEGY = 5; } enum StrategyEventType { STRATEGY_EVENT_TYPE_UNSPECIFIED = 0; STRATEGY_EVENT_TYPE_REGISTERED = 1; STRATEGY_EVENT_TYPE_ENABLED = 2; STRATEGY_EVENT_TYPE_DISABLED = 3; STRATEGY_EVENT_TYPE_ERROR = 4; } ``` --- ## Data Flow Diagrams ### 1. Universe Selection Flow ``` User/Scheduler → Trading Agent Service ↓ SelectUniverse(criteria) ↓ ┌─────────────────┴─────────────────┐ │ 1. Query market data (liquidity) │ │ 2. Calculate volatility metrics │ │ 3. Fetch ML signal strengths │ │ 4. Apply selection criteria │ │ 5. Rank and filter instruments │ └─────────────────┬─────────────────┘ ↓ Universe (ES.FUT, NQ.FUT, ZN.FUT, etc.) ↓ Store in PostgreSQL ``` ### 2. Asset Selection & Allocation Flow ``` Trading Agent Service (scheduled job, e.g., every 5 minutes) ↓ SelectAssets(universe_id, criteria) ↓ ┌─────────────────┴─────────────────┐ │ 1. Get instruments from universe │ │ 2. Query ML Training Service │ │ → GetMLPredictions(symbols) │ │ 3. Calculate factor scores │ │ 4. Compute composite scores │ │ 5. Rank and select top N assets │ └─────────────────┬─────────────────┘ ↓ Selected Assets (ES.FUT, NQ.FUT) ↓ AllocatePortfolio(assets, strategy, risk) ↓ ┌─────────────────┴─────────────────┐ │ 1. Get current positions from │ │ Trading Service │ │ 2. Calculate target weights │ │ 3. Apply risk constraints │ │ 4. Compute target quantities │ └─────────────────┬─────────────────┘ ↓ Allocation (ES.FUT: 40%, NQ.FUT: 60%) ``` ### 3. Order Generation & Submission Flow ``` Trading Agent Service (allocation + ML signals) ↓ GenerateOrders(allocation_id, ml_signals) ↓ ┌─────────────────┴─────────────────┐ │ 1. Calculate delta from current │ │ 2. Determine order side (buy/sell) │ │ 3. Set order type (market/limit) │ │ 4. Apply price offsets │ │ 5. Add order metadata │ └─────────────────┬─────────────────┘ ↓ Generated Orders (BUY ES.FUT 10 @ MARKET) ↓ SubmitAgentOrders(orders) ↓ ┌─────────────────┴─────────────────┐ │ Trading Agent → Trading Service │ │ SubmitMLOrder(symbol, features) │ └─────────────────┬─────────────────┘ ↓ Trading Service executes orders ↓ Returns order IDs and status ↓ Trading Agent logs execution results ``` ### 4. Strategy Coordination Flow ``` User → TLI → API Gateway → Trading Agent Service ↓ RegisterStrategy(name, type, config) ↓ Store strategy in PostgreSQL ↓ ┌───────────────────────────┐ │ Strategy 1: ML Ensemble │ ← ENABLED │ Strategy 2: Mean Reversion│ ← DISABLED │ Strategy 3: Momentum │ ← ENABLED └───────────────────────────┘ ↓ Periodic execution (every 5 min): ↓ ┌─────────────────────────────────┐ │ For each ENABLED strategy: │ │ 1. Run strategy logic │ │ 2. Generate allocation │ │ 3. Submit orders │ │ 4. Track performance │ └─────────────────────────────────┘ ``` --- ## Integration Points ### 1. Trading Agent ↔ Trading Service **Trading Agent calls Trading Service** (Client → Server): ```rust // Get current positions for allocation decisions let positions = trading_service_client .get_positions(GetPositionsRequest { account_id: Some(agent_account_id), symbol: None }) .await?; // Submit generated orders let ml_order_result = trading_service_client .submit_ml_order(MLOrderRequest { symbol: "ES.FUT".to_string(), account_id: agent_account_id, use_ensemble: true, features: feature_vector, ..Default::default() }) .await?; ``` **Trading Service reports to Trading Agent** (via callback or stream): - Order fill notifications - Position updates - Execution quality metrics ### 2. Trading Agent ↔ ML Training Service **Trading Agent queries ML predictions**: ```rust // Get ML predictions for asset selection let predictions = ml_training_client .get_ml_predictions(GetMLPredictionsRequest { symbols: vec!["ES.FUT", "NQ.FUT", "ZN.FUT"], models: vec!["DQN", "MAMBA2", "PPO", "TFT"], timestamp: current_time, }) .await?; // Use predictions to score assets for prediction in predictions { let score = calculate_composite_score(&prediction); asset_scores.push(AssetScore { symbol: prediction.symbol, ml_score: score, model_scores: prediction.model_scores, ..Default::default() }); } ``` ### 3. TLI ↔ Trading Agent Service **TLI commands** (via API Gateway): ```bash # Select trading universe tli agent universe select --min-liquidity 0.7 --max-volatility 0.5 # View current universe tli agent universe show # Select assets tli agent assets select --top-n 5 --min-ml-score 0.6 # Allocate portfolio tli agent allocate --strategy risk-parity --capital 1000000 # Generate and submit orders tli agent orders generate --allocation-id abc123 tli agent orders submit --batch-id xyz789 # Register strategy tli agent strategy register \ --name "ml_ensemble_v1" \ --type ML_ENSEMBLE \ --config config.yaml # Monitor agent tli agent status tli agent performance --window 24h tli agent activity stream ``` ### 4. Backtesting Service ↔ Trading Agent **Backtesting simulates Trading Agent**: ```rust // Backtesting Service simulates Trading Agent decisions struct BacktestingAgent { agent_service_client: TradingAgentServiceClient, simulated_time: DateTime, } impl BacktestingAgent { async fn run_backtest(&self, historical_data: Vec) -> BacktestResult { for bar in historical_data { // Simulate universe selection let universe = self.agent_service_client .select_universe(SelectUniverseRequest { criteria: default_criteria(), ..Default::default() }) .await?; // Simulate asset selection let assets = self.agent_service_client .select_assets(SelectAssetsRequest { universe_id: universe.universe_id, ..Default::default() }) .await?; // Simulate allocation let allocation = self.agent_service_client .allocate_portfolio(AllocatePortfolioRequest { assets: assets.assets, ..Default::default() }) .await?; // Simulate order generation let orders = self.agent_service_client .generate_orders(GenerateOrdersRequest { allocation_id: allocation.allocation_id, ..Default::default() }) .await?; // Track simulated results self.apply_orders_to_simulation(orders); } Ok(self.calculate_backtest_metrics()) } } ``` --- ## Service Configuration ### Port Allocation | Service | gRPC Port | Health Port | Metrics Port | |---------|-----------|-------------|--------------| | API Gateway | 50051 | 8080 | 9091 | | Trading Service | 50052 | 8081 | 9092 | | Backtesting Service | 50053 | 8082 | 9093 | | ML Training Service | 50054 | 8095 | 9094 | | **Trading Agent Service** | **50055** | **8083** | **9095** | ### Environment Variables ```bash # Trading Agent Service Configuration TRADING_AGENT_SERVICE_HOST=0.0.0.0 TRADING_AGENT_SERVICE_PORT=50055 TRADING_AGENT_HEALTH_PORT=8083 TRADING_AGENT_METRICS_PORT=9095 # Integration Configuration TRADING_SERVICE_URL=http://trading_service:50052 ML_TRAINING_SERVICE_URL=http://ml_training_service:50054 # Agent Configuration AGENT_UNIVERSE_REFRESH_INTERVAL=3600 # seconds (1 hour) AGENT_ASSET_SELECTION_INTERVAL=300 # seconds (5 minutes) AGENT_REBALANCE_THRESHOLD=0.05 # 5% drift triggers rebalance AGENT_DEFAULT_CAPITAL=1000000 # $1M default capital # Risk Configuration AGENT_MAX_POSITION_SIZE_PCT=0.20 # 20% max per position AGENT_MAX_LEVERAGE=2.0 # 2x max leverage AGENT_MAX_PORTFOLIO_VAR_95=0.05 # 5% max VaR (95%) # Database DATABASE_URL=postgresql://foxhunt:foxhunt_dev_password@postgres:5432/foxhunt # Monitoring RUST_LOG=info PROMETHEUS_ENABLED=true ``` ### Docker Compose Entry ```yaml trading_agent_service: build: context: . dockerfile: services/trading_agent_service/Dockerfile ports: - "50055:50055" # gRPC - "8083:8083" # Health - "9095:9095" # Metrics environment: - TRADING_AGENT_SERVICE_PORT=50055 - TRADING_SERVICE_URL=http://trading_service:50052 - ML_TRAINING_SERVICE_URL=http://ml_training_service:50054 - DATABASE_URL=postgresql://foxhunt:foxhunt_dev_password@postgres:5432/foxhunt - RUST_LOG=info depends_on: - postgres - trading_service - ml_training_service networks: - foxhunt_network healthcheck: test: ["CMD", "grpc_health_probe", "-addr=:50055"] interval: 10s timeout: 5s retries: 3 ``` --- ## Database Schema ### Tables ```sql -- Universe history CREATE TABLE trading_universes ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), universe_id TEXT NOT NULL UNIQUE, criteria JSONB NOT NULL, instruments JSONB NOT NULL, -- Array of Instrument objects metrics JSONB NOT NULL, -- UniverseMetrics created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_universes_created_at ON trading_universes(created_at DESC); -- Asset selection history CREATE TABLE asset_selections ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), universe_id TEXT REFERENCES trading_universes(universe_id), criteria JSONB NOT NULL, asset_scores JSONB NOT NULL, -- Array of AssetScore objects metrics JSONB NOT NULL, selected_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_asset_selections_universe ON asset_selections(universe_id); CREATE INDEX idx_asset_selections_selected_at ON asset_selections(selected_at DESC); -- Portfolio allocations CREATE TABLE portfolio_allocations ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), allocation_id TEXT NOT NULL UNIQUE, strategy JSONB NOT NULL, -- AllocationStrategy risk_constraints JSONB NOT NULL, allocations JSONB NOT NULL, -- Array of AssetAllocation objects metrics JSONB NOT NULL, total_capital NUMERIC(20, 2), created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_allocations_created_at ON portfolio_allocations(created_at DESC); -- Order batches CREATE TABLE order_batches ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), order_batch_id TEXT NOT NULL UNIQUE, allocation_id TEXT REFERENCES portfolio_allocations(allocation_id), orders JSONB NOT NULL, -- Array of GeneratedOrder objects metrics JSONB NOT NULL, submission_results JSONB, -- Array of OrderSubmissionResult objects created_at TIMESTAMPTZ DEFAULT NOW(), submitted_at TIMESTAMPTZ ); CREATE INDEX idx_order_batches_created_at ON order_batches(created_at DESC); CREATE INDEX idx_order_batches_allocation ON order_batches(allocation_id); -- Registered strategies CREATE TABLE agent_strategies ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), strategy_id TEXT NOT NULL UNIQUE, strategy_name TEXT NOT NULL, strategy_type TEXT NOT NULL, status TEXT NOT NULL, -- ENABLED, DISABLED, PAUSED, ERROR config JSONB NOT NULL, performance JSONB, -- StrategyPerformance created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_strategies_status ON agent_strategies(status); CREATE INDEX idx_strategies_name ON agent_strategies(strategy_name); -- Agent activity log CREATE TABLE agent_activity_log ( id BIGSERIAL PRIMARY KEY, activity_type TEXT NOT NULL, -- UNIVERSE_SELECTION, ASSET_SELECTION, etc. event_data JSONB NOT NULL, timestamp TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_activity_log_timestamp ON agent_activity_log(timestamp DESC); CREATE INDEX idx_activity_log_type ON agent_activity_log(activity_type); -- Agent performance metrics (time-series) CREATE TABLE agent_performance_metrics ( id BIGSERIAL PRIMARY KEY, metrics JSONB NOT NULL, -- AgentPerformanceMetrics period_start TIMESTAMPTZ NOT NULL, period_end TIMESTAMPTZ NOT NULL, recorded_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_performance_metrics_period ON agent_performance_metrics(period_start, period_end); ``` --- ## Implementation Plan ### Phase 1: Core Service Setup (Week 1) 1. **Create Service Skeleton**: - Initialize `services/trading_agent_service/` directory structure - Setup `Cargo.toml` with dependencies - Create `proto/trading_agent.proto` - Generate gRPC stubs 2. **Implement Basic gRPC Server**: - `main.rs` with gRPC server setup - Health check endpoint - Prometheus metrics integration 3. **Database Setup**: - Create migration for Trading Agent tables - Implement repository traits - Setup connection pooling 4. **Docker Integration**: - Create `Dockerfile` - Add to `docker-compose.yml` - Configure networking ### Phase 2: Universe & Asset Selection (Week 2) 1. **Universe Selection**: - Implement `SelectUniverse` logic - Market data integration - Volatility calculation - Liquidity scoring - Store universe in database 2. **Asset Selection**: - Implement `SelectAssets` logic - ML signal integration (call ML Training Service) - Factor score calculation - Composite scoring algorithm 3. **Testing**: - Unit tests for selection logic - Integration tests with mock ML service ### Phase 3: Portfolio Allocation (Week 3) 1. **Allocation Strategies**: - Equal-weight allocation - Risk-parity allocation - ML-optimized allocation - Kelly criterion 2. **Risk Constraint Engine**: - Position size limits - Sector exposure limits - VaR calculation - Leverage checks 3. **Rebalancing Logic**: - Drift detection - Rebalance action generation - Cost estimation ### Phase 4: Order Generation & Execution (Week 4) 1. **Order Generation**: - Delta calculation (target - current) - Order type selection (market/limit) - Price determination - Order metadata tagging 2. **Trading Service Integration**: - gRPC client for Trading Service - Order submission logic - Result handling and logging 3. **Testing**: - End-to-end tests with Trading Service - Paper trading simulation ### Phase 5: Strategy Coordination (Week 5) 1. **Strategy Framework**: - Strategy registration - Strategy lifecycle management - Performance tracking per strategy 2. **Built-in Strategies**: - ML Ensemble strategy - Mean reversion strategy - Momentum strategy 3. **Strategy Execution Engine**: - Periodic execution scheduler - Strategy isolation - Error handling ### Phase 6: Monitoring & API Gateway Integration (Week 6) 1. **Agent Monitoring**: - Real-time status API - Activity streaming - Performance metrics calculation 2. **API Gateway Integration**: - Add Trading Agent proxy to API Gateway - Update TLI with agent commands - Documentation 3. **Observability**: - Grafana dashboard for agent metrics - Prometheus alerts for agent errors - Structured logging ### Phase 7: Backtesting Integration (Week 7) 1. **Backtesting Simulation**: - Backtest adapter for Trading Agent - Historical replay logic - Performance comparison 2. **Testing & Validation**: - End-to-end tests across all services - Load testing - Chaos testing (service failures) ### Phase 8: Production Hardening (Week 8) 1. **Error Handling**: - Graceful degradation - Circuit breakers - Retry logic 2. **Performance Optimization**: - Database query optimization - Caching strategies - Connection pooling tuning 3. **Documentation**: - API documentation - Deployment guide - Operational runbook --- ## Success Criteria ### Functional Requirements - ✅ Universe selection completes in <1 second - ✅ Asset selection completes in <2 seconds (including ML query) - ✅ Portfolio allocation completes in <500ms - ✅ Order generation completes in <200ms - ✅ End-to-end (universe → orders) completes in <5 seconds - ✅ Strategies execute on schedule with <100ms jitter - ✅ All APIs return in <100ms (excluding long-running operations) ### Non-Functional Requirements - ✅ Service uptime >99.9% - ✅ No data loss (all decisions logged to database) - ✅ Prometheus metrics exported - ✅ Health checks respond in <10ms - ✅ Graceful shutdown (drain in-flight requests) - ✅ Docker container restart recovery ### Integration Requirements - ✅ Trading Service integration (order submission) - ✅ ML Training Service integration (prediction queries) - ✅ API Gateway proxy configured - ✅ TLI commands functional - ✅ Backtesting simulation working ### Testing Requirements - ✅ Unit test coverage >80% - ✅ Integration tests for all gRPC methods - ✅ End-to-end tests across services - ✅ Load tests (100 req/s sustained) - ✅ Chaos tests (service failure recovery) --- ## Risk Analysis ### Technical Risks | Risk | Impact | Probability | Mitigation | |------|--------|-------------|------------| | ML service latency | High | Medium | Cache predictions, use stale data if needed | | Trading service downtime | Critical | Low | Queue orders, retry with exponential backoff | | Database bottleneck | High | Medium | Index optimization, read replicas, caching | | Strategy logic errors | Critical | Medium | Extensive testing, paper trading validation | | Order submission failures | High | Medium | Idempotent retry, comprehensive error handling | ### Operational Risks | Risk | Impact | Probability | Mitigation | |------|--------|-------------|------------| | Configuration errors | High | Medium | Schema validation, default values, dry-run mode | | Resource exhaustion | High | Low | Resource limits, monitoring alerts | | Data corruption | Critical | Low | Database transactions, audit logging | | Version incompatibility | Medium | Low | API versioning, backward compatibility | --- ## Alternatives Considered ### Alternative 1: Embed Agent Logic in Trading Service **Pros**: Simpler architecture, lower latency **Cons**: Violates SRP, harder to test, couples decision-making with execution **Decision**: ❌ Rejected - doesn't scale, poor separation of concerns ### Alternative 2: Use Message Queue Instead of gRPC **Pros**: Decoupling, buffering, retry semantics **Cons**: Added complexity, harder to debug, eventual consistency **Decision**: ❌ Rejected for MVP - can add later if needed ### Alternative 3: Agent as Library, Not Service **Pros**: No network overhead, simpler deployment **Cons**: Can't reuse across services, harder to version independently **Decision**: ❌ Rejected - limits reusability (backtesting needs it) --- ## Future Enhancements ### Phase 2 (Post-MVP) 1. **Advanced Allocation Strategies**: - Black-Litterman allocation - Hierarchical risk parity - Reinforcement learning-based allocation 2. **Multi-Account Support**: - Manage multiple trading accounts - Cross-account risk aggregation 3. **Regime Detection**: - Automatic strategy switching based on market regime - Volatility regime detection 4. **Advanced Rebalancing**: - Tax-aware rebalancing - Transaction cost optimization 5. **Strategy Marketplace**: - User-defined strategies - Strategy backtesting UI - Strategy performance leaderboard --- ## Appendix A: Example Workflow **Scenario**: Daily portfolio rebalancing at market open ``` 1. 08:30 AM: Universe selection job triggers → SelectUniverse(criteria: {min_liquidity: 0.7, max_volatility: 0.5}) → Returns: [ES.FUT, NQ.FUT, ZN.FUT, 6E.FUT] 2. 08:31 AM: Asset selection job triggers → SelectAssets(universe_id: "univ-123", max_assets: 3) → Queries ML Training Service for predictions → Returns: [ES.FUT (score: 0.85), NQ.FUT (score: 0.78), ZN.FUT (score: 0.72)] 3. 08:32 AM: Portfolio allocation job triggers → AllocatePortfolio(assets: [...], strategy: RISK_PARITY, capital: $1M) → Returns: {ES.FUT: 35%, NQ.FUT: 40%, ZN.FUT: 25%} 4. 08:33 AM: Order generation job triggers → GenerateOrders(allocation_id: "alloc-456", ml_signals: [...]) → Returns: [BUY ES.FUT 15 @ MARKET, BUY NQ.FUT 20 @ MARKET, SELL ZN.FUT 5 @ MARKET] 5. 08:33 AM: Order submission → SubmitAgentOrders(order_batch_id: "batch-789", orders: [...]) → Calls Trading Service.SubmitMLOrder() for each order → Returns: {accepted: 3, rejected: 0, acceptance_rate: 1.0} 6. 08:34 AM: Monitor execution → StreamAgentActivity() streams order fill events → Logs execution results to database → Updates performance metrics 7. 08:35 AM: Performance tracking → GetAgentPerformance(window: 24h) → Returns: {total_pnl: $12,500, sharpe_ratio: 1.8, win_rate: 0.65} ``` --- ## Appendix B: Key Metrics ### Trading Agent Metrics (Prometheus) ```prometheus # Universe selection trading_agent_universe_size{universe_id} gauge trading_agent_universe_refresh_duration_seconds histogram trading_agent_universe_liquidity_score{universe_id} gauge # Asset selection trading_agent_selected_assets{universe_id} gauge trading_agent_asset_selection_duration_seconds histogram trading_agent_asset_composite_score{symbol} gauge # Portfolio allocation trading_agent_portfolio_utilization gauge # % capital deployed trading_agent_portfolio_volatility gauge trading_agent_portfolio_sharpe gauge trading_agent_allocation_duration_seconds histogram # Order generation trading_agent_orders_generated counter trading_agent_orders_submitted counter trading_agent_orders_accepted counter trading_agent_orders_rejected counter trading_agent_order_acceptance_rate gauge # Strategy performance trading_agent_strategy_pnl{strategy_id} gauge trading_agent_strategy_sharpe{strategy_id} gauge trading_agent_strategy_trades{strategy_id} counter # Agent health trading_agent_active_strategies gauge trading_agent_errors_total{error_type} counter trading_agent_api_request_duration_seconds{method} histogram ``` --- ## Conclusion The **Trading Agent Service** is a critical component that separates trading decision-making from execution. By following this design, we achieve: 1. **Separation of Concerns**: Decision-making (Agent) vs. execution (Trading Service) 2. **Reusability**: Backtesting can reuse agent logic 3. **Testability**: Agent logic can be tested independently 4. **Scalability**: Agent can be scaled independently of Trading Service 5. **Maintainability**: Clear boundaries between components **Next Steps**: 1. Review and approve this design 2. Create GitHub issues for each implementation phase 3. Start with Phase 1: Core Service Setup 4. Iterative development with weekly demos --- **Document Status**: ✅ **READY FOR REVIEW** **Estimated Implementation Time**: 8 weeks (1 developer) **Dependencies**: Trading Service, ML Training Service, API Gateway **Risk Level**: Medium (new service, but clear interfaces)