from typing import List, Optional from datetime import datetime from pydantic import BaseModel, Field class ArbitrageOpportunityBase(BaseModel): token_address: str token_symbol: str source_dex: str target_dex: str source_price: float target_price: float price_difference: float price_difference_percent: float estimated_profit_usd: float estimated_profit_token: float max_trade_amount_usd: float max_trade_amount_token: float slippage_estimate: float fees_estimate: float is_viable: bool class ArbitrageOpportunityCreate(ArbitrageOpportunityBase): pass class ArbitrageOpportunityUpdate(BaseModel): token_address: Optional[str] = None token_symbol: Optional[str] = None source_dex: Optional[str] = None target_dex: Optional[str] = None source_price: Optional[float] = None target_price: Optional[float] = None price_difference: Optional[float] = None price_difference_percent: Optional[float] = None estimated_profit_usd: Optional[float] = None estimated_profit_token: Optional[float] = None max_trade_amount_usd: Optional[float] = None max_trade_amount_token: Optional[float] = None slippage_estimate: Optional[float] = None fees_estimate: Optional[float] = None is_viable: Optional[bool] = None was_executed: Optional[bool] = None class ArbitrageOpportunity(ArbitrageOpportunityBase): id: int created_at: datetime was_executed: bool class Config: from_attributes = True class TradeBase(BaseModel): token_address: str token_symbol: str source_dex: str target_dex: str input_amount: float input_amount_usd: float output_amount: float output_amount_usd: float profit_amount: float profit_amount_usd: float profit_percent: float class TradeCreate(TradeBase): opportunity_id: int tx_signature: Optional[str] = None tx_status: str tx_error: Optional[str] = None class TradeUpdate(BaseModel): token_address: Optional[str] = None token_symbol: Optional[str] = None source_dex: Optional[str] = None target_dex: Optional[str] = None input_amount: Optional[float] = None input_amount_usd: Optional[float] = None output_amount: Optional[float] = None output_amount_usd: Optional[float] = None profit_amount: Optional[float] = None profit_amount_usd: Optional[float] = None profit_percent: Optional[float] = None opportunity_id: Optional[int] = None tx_signature: Optional[str] = None tx_status: Optional[str] = None tx_error: Optional[str] = None class Trade(TradeBase): id: int created_at: datetime opportunity_id: int tx_signature: Optional[str] = None tx_status: str tx_error: Optional[str] = None class Config: from_attributes = True class SystemEventBase(BaseModel): event_type: str component: str message: str details: Optional[str] = None class SystemEventCreate(SystemEventBase): pass class SystemEventUpdate(BaseModel): event_type: Optional[str] = None component: Optional[str] = None message: Optional[str] = None details: Optional[str] = None class SystemEvent(SystemEventBase): id: int timestamp: datetime class Config: from_attributes = True class StatusResponse(BaseModel): """Response model for the status endpoint""" status: str version: str network: str execution_enabled: bool scan_interval_seconds: int last_scan_time: Optional[datetime] = None monitored_tokens_count: int enabled_dexes: List[str] wallet_connected: bool wallet_balance_sol: Optional[float] = None wallet_balance_usdc: Optional[float] = None active_opportunities_count: int = Field(default=0, description="Number of currently viable arbitrage opportunities") trades_last_24h: int = Field(default=0, description="Number of trades executed in the last 24 hours") profit_last_24h_usd: float = Field(default=0.0, description="Total profit in USD for the last 24 hours") class OpportunitiesList(BaseModel): """Response model for the opportunities endpoint""" opportunities: List[ArbitrageOpportunity] count: int timestamp: datetime = Field(default_factory=datetime.utcnow) class TradesList(BaseModel): """Response model for the trades endpoint""" trades: List[Trade] count: int timestamp: datetime = Field(default_factory=datetime.utcnow) total_profit_usd: float = 0.0