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);

  // Server-streaming: polls GetAgentStatus at gateway level
  rpc StreamAgentStatus(StreamAgentStatusRequest) returns (stream GetAgentStatusResponse);
}

// Streaming request messages

message StreamAgentStatusRequest {
  uint32 interval_seconds = 1; // 0 = server default (3s)
}

// 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<string, string> 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<string, string> 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<string, double> 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<string, double> 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<string, string> 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<string, string> 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;
}
