--- id: "ET-LLM-002" title: "Agente de Análisis de Mercado" type: "Technical Specification" status: "Done" priority: "Alta" epic: "OQI-007" project: "trading-platform" version: "1.0.0" created_date: "2025-12-05" updated_date: "2026-01-04" --- # ET-LLM-002: Agente de Análisis de Mercado **Épica:** OQI-007 - LLM Strategy Agent **Versión:** 1.0 **Fecha:** 2025-12-05 **Estado:** Planificado **Prioridad:** P0 - Crítico --- ## Resumen Esta especificación define la arquitectura y prompts del agente especializado en análisis de mercado, incluyendo análisis técnico, fundamental y de sentimiento. --- ## Arquitectura del Agente ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ MARKET ANALYSIS AGENT │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────────────────────────────────────────────────────────┐ │ │ │ System Prompt │ │ │ │ - Rol: Analista de mercados experto │ │ │ │ - Capacidades: Técnico, fundamental, sentiment │ │ │ │ - Restricciones: Disclaimers, no asesoría financiera │ │ │ └──────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Tool: │ │ Tool: │ │ Tool: │ │ Tool: │ │ │ │ get_price │ │ get_ohlcv │ │get_indicators│ │ get_news │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Tool: │ │ Tool: │ │ Tool: │ │ │ │get_ml_signal │ │get_fundament │ │get_sentiment │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────┘ ``` --- ## System Prompt ```markdown # Market Analysis Agent - Trading Platform ## Tu Rol Eres un analista de mercados experto especializado en trading. Tu objetivo es proporcionar análisis objetivos, detallados y accionables basados en datos reales del mercado. ## Capacidades 1. **Análisis Técnico:** Interpretas patrones de precio, indicadores técnicos y formaciones de velas 2. **Análisis Fundamental:** Evalúas métricas financieras, earnings y comparativas sectoriales (solo stocks) 3. **Análisis de Sentimiento:** Analizas noticias, menciones sociales y fear & greed index 4. **Integración ML:** Explicas predicciones del modelo de machine learning ## Herramientas Disponibles - `get_price(symbol)`: Precio actual y cambio 24h - `get_ohlcv(symbol, timeframe, limit)`: Datos de velas históricas - `get_indicators(symbol, indicators[], timeframe)`: Indicadores técnicos calculados - `get_news(symbol, limit)`: Noticias recientes con sentiment - `get_ml_signals(symbol)`: Predicciones del ML Engine (solo Pro/Premium) - `get_fundamentals(symbol)`: Datos fundamentales (solo stocks) - `get_sentiment(symbol)`: Sentiment agregado de múltiples fuentes ## Formato de Respuesta para Análisis Completo ```markdown ## Análisis de [SYMBOL] - [Nombre Completo] ### Resumen Ejecutivo [2-3 oraciones con conclusión principal y sesgo] ### Análisis Técnico - **Tendencia:** [Alcista/Bajista/Lateral] ([justificación]) - **Soportes:** $X, $Y, $Z - **Resistencias:** $X, $Y, $Z - **Indicadores:** - RSI (14): [valor] - [interpretación] - MACD: [estado] - [interpretación] - BB: [posición] - [interpretación] - **Patrones:** [patrones identificados] ### Análisis Fundamental (si aplica) - **P/E:** [valor] vs sector [valor] - **Revenue Growth:** [%] - **Earnings:** [próximo/último] ### Sentimiento - **Noticias:** [positivo/negativo/neutral] - **Principales headlines:** [lista] ### Señales ML (si disponible) - **Predicción:** [dirección] - **Confianza:** [%] - **Horizonte:** [timeframe] ### Oportunidad [Descripción de oportunidad si existe] - Entry: $X - Stop: $X ([%] riesgo) - Target: $X (R:R [ratio]) ⚠️ *Disclaimer: Este análisis es informativo. No constituye asesoría financiera.* ``` ## Reglas 1. SIEMPRE usa herramientas para obtener datos actuales - NUNCA inventes precios 2. SIEMPRE incluye disclaimer en análisis financieros 3. Si el usuario es Free, NO muestres señales ML 4. Para crypto, NO incluyas análisis fundamental 5. Sé objetivo - no exageres oportunidades 6. Indica nivel de confianza en tus análisis 7. Si no tienes datos suficientes, dilo claramente ``` --- ## Tools Definitions ### get_price ```typescript const getPriceTool = { type: 'function', function: { name: 'get_price', description: 'Obtiene el precio actual de un símbolo con cambio 24h', parameters: { type: 'object', properties: { symbol: { type: 'string', description: 'Símbolo del activo (ej: AAPL, BTC/USD)', }, }, required: ['symbol'], }, }, }; // Implementation async function getPrice(symbol: string): Promise { const normalizedSymbol = normalizeSymbol(symbol); const data = await marketDataService.getQuote(normalizedSymbol); return { symbol: normalizedSymbol, price: data.price, change24h: data.change, changePercent: data.changePercent, high24h: data.high, low24h: data.low, volume: data.volume, timestamp: data.timestamp, }; } ``` ### get_ohlcv ```typescript const getOhlcvTool = { type: 'function', function: { name: 'get_ohlcv', description: 'Obtiene datos OHLCV (velas) históricos', parameters: { type: 'object', properties: { symbol: { type: 'string', description: 'Símbolo del activo', }, timeframe: { type: 'string', enum: ['1m', '5m', '15m', '1h', '4h', '1d', '1w'], description: 'Timeframe de las velas', }, limit: { type: 'number', description: 'Número de velas (max 500)', default: 100, }, }, required: ['symbol', 'timeframe'], }, }, }; ``` ### get_indicators ```typescript const getIndicatorsTool = { type: 'function', function: { name: 'get_indicators', description: 'Calcula indicadores técnicos para un símbolo', parameters: { type: 'object', properties: { symbol: { type: 'string', description: 'Símbolo del activo', }, indicators: { type: 'array', items: { type: 'string', enum: ['RSI', 'MACD', 'BB', 'SMA', 'EMA', 'ATR', 'VWAP', 'OBV'], }, description: 'Lista de indicadores a calcular', }, timeframe: { type: 'string', enum: ['1h', '4h', '1d'], default: '1d', }, }, required: ['symbol', 'indicators'], }, }, }; // Implementation async function getIndicators( symbol: string, indicators: string[], timeframe: string, ): Promise { const ohlcv = await marketDataService.getOHLCV(symbol, timeframe, 100); const results: Record = {}; for (const indicator of indicators) { switch (indicator) { case 'RSI': results.RSI = calculateRSI(ohlcv.close, 14); break; case 'MACD': results.MACD = calculateMACD(ohlcv.close); break; case 'BB': results.BB = calculateBollingerBands(ohlcv.close, 20, 2); break; case 'SMA': results.SMA = { sma20: calculateSMA(ohlcv.close, 20), sma50: calculateSMA(ohlcv.close, 50), sma200: calculateSMA(ohlcv.close, 200), }; break; case 'EMA': results.EMA = { ema12: calculateEMA(ohlcv.close, 12), ema26: calculateEMA(ohlcv.close, 26), }; break; case 'ATR': results.ATR = calculateATR(ohlcv, 14); break; // ... más indicadores } } return { symbol, timeframe, indicators: results, timestamp: new Date().toISOString(), }; } ``` ### get_news ```typescript const getNewsTool = { type: 'function', function: { name: 'get_news', description: 'Obtiene noticias recientes con análisis de sentimiento', parameters: { type: 'object', properties: { symbol: { type: 'string', description: 'Símbolo del activo', }, limit: { type: 'number', description: 'Número de noticias (max 10)', default: 5, }, }, required: ['symbol'], }, }, }; // Implementation async function getNews(symbol: string, limit: number): Promise { const news = await newsService.getBySymbol(symbol, limit); return { symbol, news: news.map(article => ({ title: article.title, source: article.source, publishedAt: article.publishedAt, sentiment: article.sentiment, // -1 to 1 sentimentLabel: getSentimentLabel(article.sentiment), summary: article.summary, url: article.url, })), overallSentiment: calculateOverallSentiment(news), timestamp: new Date().toISOString(), }; } ``` ### get_ml_signals ```typescript const getMlSignalsTool = { type: 'function', function: { name: 'get_ml_signals', description: 'Obtiene predicciones del ML Engine (solo Pro/Premium)', parameters: { type: 'object', properties: { symbol: { type: 'string', description: 'Símbolo del activo', }, }, required: ['symbol'], }, }, }; // Implementation (with plan check) async function getMlSignals( symbol: string, userPlan: string, ): Promise { if (userPlan === 'free') { return { error: 'PLAN_REQUIRED', message: 'Las señales ML requieren plan Pro o Premium', upgradeUrl: '/pricing', }; } const signal = await mlService.getPrediction(symbol); return { symbol, prediction: signal.direction, // 'bullish' | 'bearish' | 'neutral' confidence: signal.confidence, // 0-1 horizon: signal.horizon, // '1h', '4h', '1d' features: signal.topFeatures, // Principales features usados historicalAccuracy: signal.modelAccuracy, timestamp: signal.timestamp, }; } ``` ### get_fundamentals ```typescript const getFundamentalsTool = { type: 'function', function: { name: 'get_fundamentals', description: 'Obtiene datos fundamentales de una acción (no disponible para crypto)', parameters: { type: 'object', properties: { symbol: { type: 'string', description: 'Símbolo de la acción', }, }, required: ['symbol'], }, }, }; // Implementation async function getFundamentals(symbol: string): Promise { if (isCrypto(symbol)) { return { error: 'NOT_AVAILABLE', message: 'Datos fundamentales no disponibles para crypto', }; } const data = await fundamentalsService.get(symbol); return { symbol, companyName: data.name, sector: data.sector, industry: data.industry, marketCap: data.marketCap, peRatio: data.peRatio, pbRatio: data.pbRatio, eps: data.eps, epsGrowth: data.epsGrowth, revenue: data.revenue, revenueGrowth: data.revenueGrowth, profitMargin: data.profitMargin, dividendYield: data.dividendYield, nextEarnings: data.nextEarningsDate, analystRating: data.analystRating, // buy/hold/sell priceTarget: data.priceTarget, timestamp: new Date().toISOString(), }; } ``` --- ## Flujo de Análisis Completo ``` ┌─────────────────────────────────────────────────────────────┐ │ Usuario: "Dame un análisis completo de NVDA" │ └──────────────────────────┬──────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 1. Agente determina herramientas necesarias: │ │ - get_price("NVDA") │ │ - get_ohlcv("NVDA", "1d", 100) │ │ - get_indicators("NVDA", ["RSI","MACD","BB"], "1d") │ │ - get_fundamentals("NVDA") │ │ - get_news("NVDA", 5) │ │ - get_ml_signals("NVDA") // si usuario Pro/Premium │ └──────────────────────────┬──────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 2. Ejecutar herramientas en paralelo │ │ (batch de 6 tool calls simultáneos) │ └──────────────────────────┬──────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 3. Agente recibe resultados y sintetiza: │ │ │ │ get_price → $145.23 (+2.3%) │ │ get_indicators → RSI: 58, MACD: bullish, BB: middle │ │ get_fundamentals → P/E: 65, Rev Growth: 122% │ │ get_news → 4 positive, 1 neutral │ │ get_ml_signals → bullish 68% (4h) │ └──────────────────────────┬──────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 4. Generar análisis estructurado con formato definido │ │ (streaming al usuario) │ └─────────────────────────────────────────────────────────────┘ ``` --- ## Tipos de Respuesta ### Interfaz de Response ```typescript interface IndicatorsData { symbol: string; timeframe: string; indicators: { RSI?: { value: number; interpretation: 'oversold' | 'neutral' | 'overbought'; }; MACD?: { value: number; signal: number; histogram: number; interpretation: 'bullish' | 'bearish' | 'neutral'; }; BB?: { upper: number; middle: number; lower: number; percentB: number; interpretation: string; }; SMA?: { sma20: number; sma50: number; sma200: number; }; // ... más indicadores }; timestamp: string; } interface FundamentalsData { symbol: string; companyName: string; sector: string; industry: string; marketCap: number; peRatio: number; pbRatio: number; eps: number; epsGrowth: number; revenue: number; revenueGrowth: number; profitMargin: number; dividendYield: number | null; nextEarnings: string | null; analystRating: 'strong_buy' | 'buy' | 'hold' | 'sell' | 'strong_sell'; priceTarget: number; timestamp: string; } interface MLSignalData { symbol: string; prediction: 'bullish' | 'bearish' | 'neutral'; confidence: number; horizon: string; features: Array<{ name: string; importance: number; }>; historicalAccuracy: number; timestamp: string; } ``` --- ## Dependencias ### Servicios Requeridos - MarketDataService (OQI-003) - MLSignalService (OQI-006) - NewsService (externo) - FundamentalsService (externo) ### APIs Externas - Alpaca Markets (market data) - Alpha Vantage (fundamentals) - News API (noticias) - TradingAgent ML Engine (predicciones) --- ## Referencias - [RF-LLM-002: Análisis de Mercado](../requerimientos/RF-LLM-002-market-analysis.md) - [ET-LLM-003: Integración ML](./ET-LLM-003-integracion-ml.md) --- *Especificación técnica - Sistema NEXUS* *Trading Platform*