ML Engine Updates: - Updated BTCUSD with Polygon API data (2024-2025): 215,699 new records - Re-trained all ML models: Attention (R²: 0.223), Base, Metamodel (87.3% confidence) - Backtest results: +176.71R profit with aggressive_filter strategy Documentation Consolidation: - Created docs/99-analisis/_MAP.md index with 13 new analysis documents - Consolidated inventories: removed duplicates from orchestration/inventarios/ - Updated ML_INVENTORY.yml with BTCUSD metrics and training results - Added execution reports: FASE11-BTCUSD, correction issues, alignment validation Architecture & Integration: - Updated all module documentation with NEXUS v3.4 frontmatter - Fixed _MAP.md indexes across all folders - Updated orchestration plans and traces Files: 229 changed, 5064 insertions(+), 1872 deletions(-) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
18 KiB
18 KiB
| id | title | type | status | priority | epic | project | version | created_date | updated_date |
|---|---|---|---|---|---|---|---|---|---|
| ET-LLM-002 | Agente de Análisis de Mercado | Technical Specification | Done | Alta | OQI-007 | trading-platform | 1.0.0 | 2025-12-05 | 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
# 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
- SIEMPRE usa herramientas para obtener datos actuales - NUNCA inventes precios
- SIEMPRE incluye disclaimer en análisis financieros
- Si el usuario es Free, NO muestres señales ML
- Para crypto, NO incluyas análisis fundamental
- Sé objetivo - no exageres oportunidades
- Indica nivel de confianza en tus análisis
- 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<PriceData> {
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
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
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<IndicatorsData> {
const ohlcv = await marketDataService.getOHLCV(symbol, timeframe, 100);
const results: Record<string, any> = {};
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
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<NewsData> {
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
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<MLSignalData | PermissionError> {
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
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<FundamentalsData> {
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
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
Especificación técnica - Sistema NEXUS Trading Platform