# Integración con OrbiQuant Trading Platform Guía de integración del servicio Trading Agents con otros módulos de la plataforma. ## 1. Integración con Backend (NestJS) ### 1.1 Investment Service Integration El backend debe comunicarse con el servicio de Trading Agents para: 1. **Asignar agente a cuenta de inversión** 2. **Notificar depósitos/retiros** 3. **Obtener métricas de rendimiento** 4. **Gestionar estado del agente** ### 1.2 Ejemplo de Cliente TypeScript ```typescript // backend/src/services/trading-agents.client.ts import axios, { AxiosInstance } from 'axios'; export class TradingAgentsClient { private client: AxiosInstance; constructor() { this.client = axios.create({ baseURL: process.env.TRADING_AGENTS_URL || 'http://trading-agents:8003', timeout: 30000, headers: { 'Content-Type': 'application/json', }, }); } /** * Iniciar agente para una cuenta de inversión */ async startAgent(accountId: string, agentType: string, initialEquity: number) { const response = await this.client.post(`/agents/${agentType}/start`, { agent_name: agentType, initial_equity: initialEquity, }); return response.data; } /** * Obtener estado del agente */ async getAgentStatus(agentType: string) { const response = await this.client.get(`/agents/${agentType}/status`); return response.data; } /** * Obtener métricas del agente */ async getAgentMetrics(agentType: string) { const response = await this.client.get(`/agents/${agentType}/metrics`); return response.data; } /** * Pausar agente */ async pauseAgent(agentType: string) { const response = await this.client.post(`/agents/${agentType}/pause`); return response.data; } /** * Reanudar agente */ async resumeAgent(agentType: string) { const response = await this.client.post(`/agents/${agentType}/resume`); return response.data; } /** * Detener agente */ async stopAgent(agentType: string) { const response = await this.client.post(`/agents/${agentType}/stop`); return response.data; } /** * Obtener posiciones abiertas */ async getPositions(agentType: string) { const response = await this.client.get(`/agents/${agentType}/positions`); return response.data; } } ``` ### 1.3 Investment Account Service ```typescript // backend/src/modules/investment/services/account.service.ts import { Injectable } from '@nestjs/common'; import { TradingAgentsClient } from '../../../services/trading-agents.client'; @Injectable() export class AccountService { constructor( private tradingAgentsClient: TradingAgentsClient, ) {} async openAccount(userId: string, productId: string, initialDeposit: number) { // 1. Crear cuenta en DB const account = await this.createAccountRecord(userId, productId, initialDeposit); // 2. Determinar tipo de agente según producto const agentType = this.getAgentTypeByProduct(productId); // 3. Iniciar agente await this.tradingAgentsClient.startAgent( account.id, agentType, initialDeposit ); return account; } async getAccountPerformance(accountId: string) { const account = await this.findAccountById(accountId); const agentType = this.getAgentTypeByProduct(account.product_id); // Obtener métricas del agente const metrics = await this.tradingAgentsClient.getAgentMetrics(agentType); return { account_id: accountId, current_balance: account.current_balance, total_return: metrics.total_profit - metrics.total_loss, win_rate: metrics.win_rate, total_trades: metrics.total_trades, current_drawdown: metrics.current_drawdown, }; } private getAgentTypeByProduct(productId: string): string { // Mapear producto a agente // Atlas: productos conservadores // Orion: productos moderados // Nova: productos agresivos // Implementar lógica según tu DB return 'atlas'; // placeholder } } ``` ## 2. Integración con ML Engine ### 2.1 Flujo de Señales ``` ML Engine → Trading Agents → Execute Trade ``` El ML Engine debe exponer endpoints para: 1. **POST /api/v1/signals/batch** - Señales en batch 2. **GET /api/v1/signals/latest/{symbol}** - Última señal por símbolo 3. **GET /api/v1/signals/account/{account_id}** - Señales para cuenta ### 2.2 Ejemplo de Integración ```python # ml-engine/api/signals.py from fastapi import APIRouter, Depends from typing import List router = APIRouter(prefix="/signals", tags=["signals"]) @router.post("/batch") async def get_signals_batch(symbols: List[str]): """ Obtener señales para múltiples símbolos Usado por MLSignalConsumer del Trading Agents """ signals = {} for symbol in symbols: # Generar señal usando tu modelo ML signal = generate_signal(symbol) signals[symbol] = signal return {"signals": signals} @router.get("/latest/{symbol}") async def get_latest_signal(symbol: str): """ Obtener última señal para un símbolo """ signal = generate_signal(symbol) return { "signal": { "symbol": symbol, "action": signal.action, # buy, sell, hold "confidence": signal.confidence, # 0-1 "price": signal.price, "timestamp": signal.timestamp } } def generate_signal(symbol: str): # Tu lógica ML aquí pass ``` ## 3. Integración con Database ### 3.1 Guardar Trades en DB ```python # trading-agents/src/journal/trade_journal.py import asyncpg from datetime import datetime class TradeJournal: """ Guarda trades en la base de datos investment.account_transactions """ def __init__(self, db_url: str): self.db_url = db_url self.pool = None async def connect(self): self.pool = await asyncpg.create_pool(self.db_url) async def record_trade( self, account_id: str, symbol: str, side: str, quantity: float, entry_price: float, exit_price: float, profit_loss: float ): """Guardar trade en DB""" async with self.pool.acquire() as conn: # Insertar en account_transactions await conn.execute(""" INSERT INTO investment.account_transactions ( account_id, transaction_type, amount, balance_before, balance_after, description, reference_type, reference_id ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) """, account_id, 'profit' if profit_loss > 0 else 'loss', abs(profit_loss), 0, # balance_before (obtener de agente) 0, # balance_after f"{side.upper()} {symbol} {quantity} @ {entry_price}", 'agent_trade', None # ID del trade ) async def update_daily_performance( self, account_id: str, date: str, opening_balance: float, closing_balance: float, trades_count: int, winning_trades: int ): """Actualizar performance diaria""" async with self.pool.acquire() as conn: await conn.execute(""" INSERT INTO investment.performance_snapshots ( account_id, snapshot_date, period_type, opening_balance, closing_balance, profit_loss, total_trades, winning_trades ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) ON CONFLICT (account_id, snapshot_date, period_type) DO UPDATE SET closing_balance = EXCLUDED.closing_balance, profit_loss = EXCLUDED.profit_loss, total_trades = EXCLUDED.total_trades, winning_trades = EXCLUDED.winning_trades """, account_id, date, 'daily', opening_balance, closing_balance, closing_balance - opening_balance, trades_count, winning_trades ) ``` ### 3.2 Uso en Agentes ```python # Modificar agentes para usar TradeJournal class AtlasAgent(BaseAgent): def __init__(self, equity: float, db_url: str, account_id: str): super().__init__(...) self.account_id = account_id self.journal = TradeJournal(db_url) async def on_start(self): await self.journal.connect() # ... async def _execute_close(self, symbol: str): position = self.get_position(symbol) # ... cerrar posición # Guardar en DB await self.journal.record_trade( account_id=self.account_id, symbol=position.symbol, side=position.side, quantity=position.quantity, entry_price=position.entry_price, exit_price=position.current_price, profit_loss=position.pnl ) ``` ## 4. Variables de Entorno ### 4.1 Actualizar docker-compose.yml principal ```yaml # /trading-platform/docker-compose.yml services: trading-agents: build: ./apps/trading-agents environment: - DATABASE_URL=postgresql+asyncpg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@database:5432/${POSTGRES_DB} - ML_ENGINE_URL=http://ml-engine:8000 - BINANCE_API_KEY=${BINANCE_API_KEY} - BINANCE_API_SECRET=${BINANCE_API_SECRET} - BINANCE_TESTNET=true depends_on: - database - ml-engine networks: - orbiquant-network ``` ### 4.2 Variables Requeridas ```bash # .env principal del proyecto # Trading Agents BINANCE_API_KEY=your_testnet_key BINANCE_API_SECRET=your_testnet_secret BINANCE_TESTNET=true TRADING_AGENTS_URL=http://trading-agents:8003 ``` ## 5. Cron Jobs para Sincronización ### 5.1 Daily Performance Sync ```typescript // backend/src/jobs/sync-trading-performance.job.ts import { Injectable } from '@nestjs/common'; import { Cron } from '@nestjs/schedule'; import { TradingAgentsClient } from '../services/trading-agents.client'; @Injectable() export class SyncTradingPerformanceJob { constructor( private tradingAgentsClient: TradingAgentsClient, ) {} @Cron('0 0 * * *') // Diariamente a medianoche async syncPerformance() { // Obtener todas las cuentas activas con agentes const accounts = await this.getActiveAccounts(); for (const account of accounts) { const agentType = this.getAgentType(account.product_id); // Obtener métricas del agente const metrics = await this.tradingAgentsClient.getAgentMetrics(agentType); // Actualizar en DB await this.updateAccountMetrics(account.id, metrics); } } } ``` ## 6. Webhooks del ML Engine ### 6.1 Configurar Webhook en Trading Agents ```python # trading-agents/src/api/webhooks.py from fastapi import APIRouter, Request, HTTPException import hmac import hashlib router = APIRouter(prefix="/webhooks", tags=["webhooks"]) WEBHOOK_SECRET = "your_webhook_secret" @router.post("/ml-signals") async def receive_ml_signal(request: Request): """ Recibir señal del ML Engine vía webhook """ # Verificar firma signature = request.headers.get("X-ML-Signature") payload = await request.body() expected_signature = hmac.new( WEBHOOK_SECRET.encode(), payload, hashlib.sha256 ).hexdigest() if signature != expected_signature: raise HTTPException(status_code=401, detail="Invalid signature") # Procesar señal data = await request.json() # Despachar a agente correspondiente agent_name = data.get('agent_name', 'atlas') if agent_name in agents: await agents[agent_name].on_signal(data['signal']) return {"status": "received"} ``` ## 7. Monitoreo y Alertas ### 7.1 Health Check Endpoint El backend debe monitorear el servicio: ```typescript // backend/src/health/trading-agents.health.ts import { Injectable } from '@nestjs/common'; import { HealthIndicator, HealthIndicatorResult } from '@nestjs/terminus'; import { TradingAgentsClient } from '../services/trading-agents.client'; @Injectable() export class TradingAgentsHealthIndicator extends HealthIndicator { constructor( private tradingAgentsClient: TradingAgentsClient, ) { super(); } async isHealthy(key: string): Promise { try { const response = await this.tradingAgentsClient.healthCheck(); return this.getStatus(key, true, { status: 'up', agents_running: response.agents_running }); } catch (error) { return this.getStatus(key, false, { status: 'down', message: error.message }); } } } ``` ## 8. Testing de Integración ### 8.1 Test End-to-End ```typescript // backend/test/e2e/trading-agents.e2e-spec.ts describe('Trading Agents Integration', () => { it('should create account and start agent', async () => { // 1. Crear cuenta de inversión const account = await request(app.getHttpServer()) .post('/investment/accounts') .send({ user_id: userId, product_id: 'atlas-conservative', initial_deposit: 1000.0 }) .expect(201); // 2. Verificar que agente se inició const agentStatus = await tradingAgentsClient.getAgentStatus('atlas'); expect(agentStatus.status).toBe('running'); // 3. Simular señal ML await tradingAgentsClient.sendSignal('atlas', { symbol: 'BTCUSDT', action: 'buy', confidence: 0.85, price: 45000.0 }); // 4. Verificar posición abierta const positions = await tradingAgentsClient.getPositions('atlas'); expect(positions.total_positions).toBeGreaterThan(0); }); }); ``` ## 9. Diagrama de Flujo Completo ``` ┌─────────────┐ │ Usuario │ └──────┬──────┘ │ 1. Abre cuenta ▼ ┌─────────────────┐ │ Backend API │ │ (NestJS) │ └──────┬──────────┘ │ 2. Start agent ▼ ┌─────────────────┐ │ Trading Agents │◄──── 3. Poll signals ────┐ │ (Python) │ │ └──────┬──────────┘ ┌──────┴──────┐ │ 4. Execute trade │ ML Engine │ ▼ │ (Python) │ ┌─────────────────┐ └─────────────┘ │ Binance │ │ Testnet │ └──────┬──────────┘ │ 5. Order filled ▼ ┌─────────────────┐ │ PostgreSQL │◄──── 6. Save trade │ Database │ └─────────────────┘ ``` ## 10. Checklist de Integración - [ ] Configurar variables de entorno en docker-compose - [ ] Implementar TradingAgentsClient en backend - [ ] Integrar con Investment Account Service - [ ] Configurar webhooks del ML Engine - [ ] Implementar TradeJournal para guardar en DB - [ ] Agregar health checks - [ ] Configurar cron jobs de sincronización - [ ] Testing end-to-end - [ ] Monitoreo y alertas - [ ] Documentación API --- Para más información, consultar: - `README.md` - Documentación principal - `PAPER_TRADING_GUIDE.md` - Guía de paper trading - `IMPLEMENTATION_REPORT.md` - Reporte de implementación