""" Cliente principal de OrbiQuant SDK """ import httpx from typing import Optional, Any, Dict from .config import Config, DEFAULT_CONFIG class OrbiQuantClient: """ Cliente principal para OrbiQuant Trading Platform. Ejemplo de uso: ```python from orbiquant_sdk import OrbiQuantClient, Config config = Config.from_env() client = OrbiQuantClient(config) # Obtener predicción prediction = await client.ml.get_prediction("BTCUSDT", "1h") # Enviar señal await client.signals.send_signal(signal_data) ``` """ def __init__(self, config: Optional[Config] = None): self.config = config or DEFAULT_CONFIG self._http_client: Optional[httpx.AsyncClient] = None @property def http(self) -> httpx.AsyncClient: """HTTP client lazy initialization""" if self._http_client is None: self._http_client = httpx.AsyncClient( timeout=self.config.timeout, headers=self._get_headers(), ) return self._http_client def _get_headers(self) -> Dict[str, str]: """Get request headers""" headers = {"Content-Type": "application/json"} if self.config.access_token: headers["Authorization"] = f"Bearer {self.config.access_token}" if self.config.api_key: headers["X-API-Key"] = self.config.api_key return headers async def close(self): """Close HTTP client""" if self._http_client: await self._http_client.aclose() self._http_client = None async def __aenter__(self): return self async def __aexit__(self, exc_type, exc_val, exc_tb): await self.close() # ========================================================================= # ML Engine Methods # ========================================================================= async def get_prediction( self, symbol: str, timeframe: str, lookback: int = 100 ) -> Dict[str, Any]: """Get price prediction from ML Engine""" response = await self.http.post( f"{self.config.ml_engine_url}/api/v1/predict", json={"symbol": symbol, "timeframe": timeframe, "lookback": lookback}, ) response.raise_for_status() return response.json() async def get_signals( self, symbol: Optional[str] = None, active_only: bool = True ) -> list: """Get trading signals""" params = {"active": active_only} if symbol: params["symbol"] = symbol response = await self.http.get( f"{self.config.ml_engine_url}/api/v1/signals", params=params ) response.raise_for_status() return response.json() async def run_backtest( self, symbol: str, timeframe: str, start_date: str, end_date: str, strategy: str, parameters: Optional[Dict] = None, ) -> Dict[str, Any]: """Run backtest""" response = await self.http.post( f"{self.config.ml_engine_url}/api/v1/backtest", json={ "symbol": symbol, "timeframe": timeframe, "start_date": start_date, "end_date": end_date, "strategy": strategy, "parameters": parameters or {}, }, ) response.raise_for_status() return response.json() # ========================================================================= # LLM Agent Methods # ========================================================================= async def chat( self, message: str, conversation_id: Optional[str] = None, context: Optional[Dict] = None, ) -> Dict[str, Any]: """Send message to LLM copilot""" response = await self.http.post( f"{self.config.llm_agent_url}/api/v1/chat", json={ "message": message, "conversation_id": conversation_id, "context": context, }, ) response.raise_for_status() return response.json() async def analyze_market(self, symbol: str, timeframe: str) -> Dict[str, Any]: """Get market analysis from LLM""" response = await self.http.post( f"{self.config.llm_agent_url}/api/v1/analyze", json={"symbol": symbol, "timeframe": timeframe}, ) response.raise_for_status() return response.json() # ========================================================================= # Trading Agents Methods # ========================================================================= async def start_agent(self, agent_id: str) -> Dict[str, Any]: """Start a trading agent""" response = await self.http.post( f"{self.config.trading_agents_url}/api/v1/agents/{agent_id}/start" ) response.raise_for_status() return response.json() async def stop_agent(self, agent_id: str) -> Dict[str, Any]: """Stop a trading agent""" response = await self.http.post( f"{self.config.trading_agents_url}/api/v1/agents/{agent_id}/stop" ) response.raise_for_status() return response.json() async def get_agent_stats(self, agent_id: str) -> Dict[str, Any]: """Get agent statistics""" response = await self.http.get( f"{self.config.trading_agents_url}/api/v1/agents/{agent_id}/stats" ) response.raise_for_status() return response.json() # ========================================================================= # Data Service Methods # ========================================================================= async def get_market_data( self, symbol: str, timeframe: str, limit: int = 100 ) -> list: """Get market data (candles)""" response = await self.http.get( f"{self.config.data_service_url}/api/v1/candles/{symbol}", params={"timeframe": timeframe, "limit": limit}, ) response.raise_for_status() return response.json() async def get_ticker(self, symbol: str) -> Dict[str, Any]: """Get current ticker""" response = await self.http.get( f"{self.config.data_service_url}/api/v1/ticker/{symbol}" ) response.raise_for_status() return response.json() # ========================================================================= # Backend API Methods # ========================================================================= async def get_user_portfolio(self) -> Dict[str, Any]: """Get user portfolio from backend""" response = await self.http.get(f"{self.config.backend_url}/api/v1/portfolio") response.raise_for_status() return response.json() async def get_positions(self) -> list: """Get open positions""" response = await self.http.get( f"{self.config.backend_url}/api/v1/trading/positions" ) response.raise_for_status() return response.json() async def create_order(self, order_data: Dict[str, Any]) -> Dict[str, Any]: """Create a new order""" response = await self.http.post( f"{self.config.backend_url}/api/v1/trading/orders", json=order_data ) response.raise_for_status() return response.json() # ========================================================================= # Health Checks # ========================================================================= async def health_check(self) -> Dict[str, bool]: """Check health of all services""" services = { "backend": self.config.backend_url, "ml_engine": self.config.ml_engine_url, "llm_agent": self.config.llm_agent_url, "trading_agents": self.config.trading_agents_url, "data_service": self.config.data_service_url, } results = {} for name, url in services.items(): try: response = await self.http.get(f"{url}/health", timeout=5) results[name] = response.status_code == 200 except Exception: results[name] = False return results