- Add 5 frontend specification documents (ET-*-frontend.md): - ET-AUTH-006: Authentication module frontend spec - ET-ML-008: ML Signals module frontend spec - ET-LLM-007: LLM Agent module frontend spec - ET-PFM-008: Portfolio Manager frontend spec (design) - ET-MKT-003: Marketplace frontend spec (design) - Add 8 new user stories: - US-AUTH-013: Global logout - US-AUTH-014: Device management - US-ML-008: Ensemble signal view - US-ML-009: ICT analysis view - US-ML-010: Multi-symbol scan - US-LLM-011: Execute trade from chat - US-PFM-013: Rebalance alerts - US-PFM-014: PDF report generation - Update task index with completed analysis Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
443 lines
20 KiB
Markdown
443 lines
20 KiB
Markdown
---
|
|
id: "US-ML-008"
|
|
title: "Ver Señal Ensemble"
|
|
type: "User Story"
|
|
status: "Pending"
|
|
priority: "Alta"
|
|
epic: "OQI-006"
|
|
project: "trading-platform"
|
|
story_points: 5
|
|
created_date: "2026-01-25"
|
|
updated_date: "2026-01-25"
|
|
---
|
|
|
|
# US-ML-008: Ver Señal Ensemble
|
|
|
|
## Metadata
|
|
|
|
| Campo | Valor |
|
|
|-------|-------|
|
|
| **ID** | US-ML-008 |
|
|
| **Épica** | OQI-006 - Señales ML y Predicciones |
|
|
| **Módulo** | ml-signals |
|
|
| **Prioridad** | P0 (Alta) |
|
|
| **Story Points** | 5 |
|
|
| **Sprint** | Sprint 8 |
|
|
| **Estado** | Pendiente |
|
|
| **Asignado a** | Por asignar |
|
|
|
|
---
|
|
|
|
## Historia de Usuario
|
|
|
|
**Como** trader/inversor,
|
|
**quiero** ver la señal combinada (ensemble) de múltiples modelos ML con sus contribuciones individuales,
|
|
**para** tomar decisiones más informadas y confiar en predicciones robustas de múltiples fuentes.
|
|
|
|
## Descripción Detallada
|
|
|
|
El usuario debe poder ver una vista integrada que combina las predicciones de múltiples modelos ML (LSTM, RandomForest, SVM, etc.) en una señal consolidada (ensemble). La vista debe mostrar:
|
|
|
|
1. **Señal Ensemble Principal:** La decisión combinada (BUY/SELL/HOLD) con confianza agregada
|
|
2. **Confianza Combinada:** Porcentaje agregado considerando pesos de cada modelo
|
|
3. **Contribuciones Individuales:** Lista de modelos participantes con sus predicciones y pesos
|
|
4. **Scoring Detallado:** Score de cada modelo, peso asignado, contribución a la decisión final
|
|
5. **Votación de Modelos:** Cuántos modelos votaron por cada acción
|
|
6. **Consenso:** Nivel de acuerdo entre modelos
|
|
|
|
---
|
|
|
|
## Mockups/Wireframes
|
|
|
|
```
|
|
┌──────────────────────────────────────────────────────────────────┐
|
|
│ ENSEMBLE SIGNAL BTCUSDT │
|
|
├──────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌────────────────────────────────────────────────────────────┐ │
|
|
│ │ ENSEMBLE DECISION │ │
|
|
│ ├────────────────────────────────────────────────────────────┤ │
|
|
│ │ │ │
|
|
│ │ Signal: 🟢 BUY │ │
|
|
│ │ Confidence: ████████░ 82% │ │
|
|
│ │ Score: 8.2/10 │ │
|
|
│ │ Consensus: STRONG (4/5 models agree) │ │
|
|
│ │ │ │
|
|
│ │ Entry Price Avg: $89,450.00 │ │
|
|
│ │ TP1: $89,650 (+0.22%) | TP2: $89,850 (+0.45%) │ │
|
|
│ │ TP3: $90,050 (+0.67%) | SL: $89,150 (-0.33%) │ │
|
|
│ │ │ │
|
|
│ │ Generated: 2026-01-25 10:30:15 UTC │ │
|
|
│ │ Expires: 2026-01-25 14:30:15 UTC (4h horizon) │ │
|
|
│ │ │ │
|
|
│ └────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌────────────────────────────────────────────────────────────┐ │
|
|
│ │ MODEL CONTRIBUTIONS │ │
|
|
│ ├────────────────────────────────────────────────────────────┤ │
|
|
│ │ │ │
|
|
│ │ [Model Distribution] │ │
|
|
│ │ │ │
|
|
│ │ 🟢 BUY: 4 models (80%) ████████░░ │ │
|
|
│ │ 🔴 SELL: 1 model (20%) ██░░░░░░░░ │ │
|
|
│ │ 🔵 HOLD: 0 models (0%) ░░░░░░░░░░ │ │
|
|
│ │ │ │
|
|
│ └────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌────────────────────────────────────────────────────────────┐ │
|
|
│ │ DETAILED MODEL VOTING │ │
|
|
│ ├────────────────────────────────────────────────────────────┤ │
|
|
│ │ │ │
|
|
│ │ Model Name Prediction Score Weight Contribution│ │
|
|
│ │ ─────────────────────────────────────────────────────────│ │
|
|
│ │ ✓ LSTM 🟢 BUY 87% 25% 21.75% │ │
|
|
│ │ ✓ RandomForest 🟢 BUY 85% 30% 25.50% │ │
|
|
│ │ ✓ SVM 🟢 BUY 78% 20% 15.60% │ │
|
|
│ │ ✓ Transformer 🟢 BUY 81% 15% 12.15% │ │
|
|
│ │ ✗ GradientBoosting 🔴 SELL 72% 10% -7.20%* │ │
|
|
│ │ │ │
|
|
│ │ *Negative contribution indicates minority prediction │ │
|
|
│ │ │ │
|
|
│ │ CONSENSUS ANALYSIS: │ │
|
|
│ │ • 4 out of 5 models predict BUY (strong agreement) │ │
|
|
│ │ • Confidence scores range from 72% to 87% (tight) │ │
|
|
│ │ • 1 outlier (GradientBoosting) predicts SELL │ │
|
|
│ │ • Overall consensus strength: 80% (STRONG) │ │
|
|
│ │ │ │
|
|
│ └────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌────────────────────────────────────────────────────────────┐ │
|
|
│ │ HISTORICAL MODEL PERFORMANCE │ │
|
|
│ ├────────────────────────────────────────────────────────────┤ │
|
|
│ │ │ │
|
|
│ │ Model Name Accuracy Win Rate Last 7d Trend │ │
|
|
│ │ ─────────────────────────────────────────────────────────│ │
|
|
│ │ LSTM 84.2% 71.5% 72% ↑ Good │ │
|
|
│ │ RandomForest 82.1% 68.9% 69% ↑ Good │ │
|
|
│ │ SVM 79.8% 65.3% 66% → Stable │ │
|
|
│ │ Transformer 81.5% 70.2% 71% ↑ Good │ │
|
|
│ │ GradientBoosting 76.2% 61.4% 62% ↓ Declining│ │
|
|
│ │ │ │
|
|
│ │ Ensemble (Combined) 85.6% 75.1% 76% ↑ Excellent│ │
|
|
│ │ │ │
|
|
│ └────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ [View Technical Context] [Compare Models] [View Signal History] │
|
|
│ │
|
|
└──────────────────────────────────────────────────────────────────┘
|
|
|
|
┌──────────────────────────────────────────────────────────────────┐
|
|
│ MODEL COMPARISON CHART │
|
|
├──────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ Prediction Heatmap: │
|
|
│ │
|
|
│ LSTM RF SVM TRF GB ENS │
|
|
│ BTCUSDT [87%] [85%][78%][81%][72%][82%] 🟢 BUY │
|
|
│ ETHUSDT [84%] [86%][75%][80%][70%][81%] 🟢 BUY │
|
|
│ XRPUSDT [81%] [79%][72%][76%][68%][77%] 🟢 BUY │
|
|
│ SOLUSDT [76%] [74%][69%][71%][65%][72%] 🟡 HOLD (Weak) │
|
|
│ │
|
|
│ Legend: ENS = Ensemble Vote │
|
|
│ │
|
|
│ Consensus Strength Graph: │
|
|
│ │
|
|
│ 100% │ │
|
|
│ │ ╱─╲ │
|
|
│ 80% │ ╱─ ╲╱╲ │
|
|
│ │ ╱─ ╲─╲ │
|
|
│ 60% │╱─ ╲─── │
|
|
│ │────────────────────► time │
|
|
│ 40% │ │
|
|
│ └────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
└──────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Criterios de Aceptación
|
|
|
|
**Escenario 1: Ver señal ensemble**
|
|
```gherkin
|
|
DADO que el usuario está autenticado en Trading Platform
|
|
CUANDO navega a "ML Signals > Ensemble" para un símbolo (ej: BTCUSDT)
|
|
ENTONCES ve la señal ensemble con:
|
|
- Decisión principal (BUY/SELL/HOLD)
|
|
- Confianza combinada (%)
|
|
- Score de 0 a 10
|
|
- Nivel de consenso (STRONG/MODERATE/WEAK)
|
|
- Número de modelos votando por cada acción
|
|
Y se muestra el timestamp de generación y expiración
|
|
```
|
|
|
|
**Escenario 2: Ver contribuciones de modelos**
|
|
```gherkin
|
|
DADO que el usuario está viendo una señal ensemble
|
|
CUANDO expande la sección "Model Contributions"
|
|
ENTONCES ve una tabla con:
|
|
- Nombre de cada modelo
|
|
- Predicción individual (BUY/SELL/HOLD)
|
|
- Score/confianza de cada modelo (%)
|
|
- Peso asignado a cada modelo (%)
|
|
- Contribución calculada al resultado final
|
|
Y las filas están ordenadas por peso (mayor a menor)
|
|
```
|
|
|
|
**Escenario 3: Ver votación de modelos**
|
|
```gherkin
|
|
DADO que existen 5 modelos en el ensemble
|
|
CUANDO veo la distribución de votos
|
|
ENTONCES se muestra:
|
|
- Gráfico de barras: cuántos modelos votaron por cada acción
|
|
- Porcentaje: 80% BUY, 20% SELL, 0% HOLD
|
|
- Indicador visual de consenso (fuerte/moderado/débil)
|
|
- Descripción: "4 out of 5 models agree on BUY"
|
|
```
|
|
|
|
**Escenario 4: Ver performance histórico de modelos**
|
|
```gherkin
|
|
DADO que el usuario quiere evaluar fiabilidad de cada modelo
|
|
CUANDO expande "Historical Model Performance"
|
|
ENTONCES ve para cada modelo:
|
|
- Accuracy (%)
|
|
- Win Rate en los últimos 7 días (%)
|
|
- Tendencia (↑/→/↓)
|
|
- Comparación con ensemble
|
|
```
|
|
|
|
**Escenario 5: Detectar outliers**
|
|
```gherkin
|
|
DADO que 1 modelo predice diferente al ensemble (ej: SELL vs BUY)
|
|
CUANDO veo la tabla de contribuciones
|
|
ENTONCES:
|
|
- Se destaca visualmente con icono ✗ (en lugar de ✓)
|
|
- Se muestra con color diferente (rojo vs verde)
|
|
- Se incluye nota: "Minority prediction"
|
|
- Contribución se resta del total (negativa)
|
|
```
|
|
|
|
**Escenario 6: Comparar modelos lado a lado**
|
|
```gherkin
|
|
DADO que quiero evaluar predicciones de todos los modelos
|
|
CUANDO hago click en "Compare Models"
|
|
ENTONCES se abre una vista con:
|
|
- Heatmap de predicciones por símbolo
|
|
- Scores de cada modelo lado a lado
|
|
- Tendencia de consenso en tiempo (gráfico)
|
|
- Botón para exportar comparación
|
|
```
|
|
|
|
## Criterios Adicionales
|
|
|
|
- [ ] Debe cargar en menos de 1.5 segundos
|
|
- [ ] Soportar 5-10 modelos simultáneamente
|
|
- [ ] Actualizar automáticamente cada 30 segundos (si hay nuevas señales)
|
|
- [ ] Ser responsive en mobile
|
|
- [ ] Mostrar claramente cuál es el modelo más confiable
|
|
- [ ] Detectar y resaltar predicciones outliers
|
|
- [ ] Permitir ponderar dinámicamente los modelos (admin)
|
|
|
|
---
|
|
|
|
## Tareas Técnicas
|
|
|
|
**Backend:**
|
|
- [ ] BE-ML-016: Crear endpoint GET /api/ml/ensemble/:symbol
|
|
- [ ] BE-ML-017: Implementar cálculo de confianza combinada (weighted average)
|
|
- [ ] BE-ML-018: Implementar votación y consenso de modelos
|
|
- [ ] BE-ML-019: Obtener scores individuales de cada modelo
|
|
- [ ] BE-ML-020: Calcular performance histórico de modelos
|
|
- [ ] BE-ML-021: Endpoint GET /api/ml/ensemble/:symbol/models (detalle)
|
|
- [ ] BE-ML-022: Endpoint GET /api/ml/ensemble/comparison (heatmap)
|
|
|
|
**Frontend:**
|
|
- [ ] FE-ML-035: Crear componente `EnsembleSignal.tsx`
|
|
- [ ] FE-ML-036: Crear componente `ModelVoting.tsx`
|
|
- [ ] FE-ML-037: Crear componente `ModelContributions.tsx` (tabla)
|
|
- [ ] FE-ML-038: Crear componente `ConsensusIndicator.tsx`
|
|
- [ ] FE-ML-039: Crear componente `ModelPerformance.tsx`
|
|
- [ ] FE-ML-040: Crear componente `ModelComparison.tsx` (heatmap)
|
|
- [ ] FE-ML-041: Implementar auto-refresh cada 30 segundos
|
|
- [ ] FE-ML-042: Agregar indicadores visuales para outliers
|
|
|
|
**Tests:**
|
|
- [ ] TEST-ML-016: Test de cálculo de confianza combinada
|
|
- [ ] TEST-ML-017: Test de votación de modelos
|
|
- [ ] TEST-ML-018: Test E2E de vista ensemble
|
|
- [ ] TEST-ML-019: Test de detección de outliers
|
|
|
|
---
|
|
|
|
## Dependencias
|
|
|
|
**Depende de:**
|
|
- [ ] RF-ML-003: Múltiples modelos ML entrenados (LSTM, RF, SVM, Transformer, GB)
|
|
- [ ] RF-ML-004: Sistema de pesos y scoring de modelos
|
|
- [ ] US-ML-001: Ver señal básica - Estado: Completado
|
|
|
|
**Bloquea:**
|
|
- [ ] US-ML-009: Configurar ensemble (admin puede cambiar pesos)
|
|
- [ ] US-ML-010: Histórico de ensemble signals
|
|
|
|
---
|
|
|
|
## Notas Técnicas
|
|
|
|
**Endpoints involucrados:**
|
|
| Método | Endpoint | Descripción |
|
|
|--------|----------|-------------|
|
|
| GET | /api/ml/ensemble/:symbol | Obtener señal ensemble actual |
|
|
| GET | /api/ml/ensemble/:symbol/models | Detalle de cada modelo |
|
|
| GET | /api/ml/ensemble/comparison | Heatmap de predicciones |
|
|
| GET | /api/ml/ensemble/:symbol/performance | Performance histórico |
|
|
|
|
**Query Parameters - Ensemble Signal:**
|
|
```
|
|
GET /api/ml/ensemble/BTCUSDT?
|
|
include_performance=true&
|
|
include_comparison=false
|
|
```
|
|
|
|
**Response esperado:**
|
|
```typescript
|
|
interface EnsembleSignalResponse {
|
|
ensemble: {
|
|
symbol: string;
|
|
action: 'BUY' | 'SELL' | 'HOLD';
|
|
confidence: number; // weighted average, 0-100
|
|
score: number; // 0-10
|
|
consensus_strength: 'STRONG' | 'MODERATE' | 'WEAK';
|
|
timestamp: string;
|
|
expires_at: string;
|
|
|
|
entry_price: number;
|
|
tp1: number;
|
|
tp2: number;
|
|
tp3: number;
|
|
sl: number;
|
|
};
|
|
|
|
model_votes: {
|
|
buy_count: number;
|
|
sell_count: number;
|
|
hold_count: number;
|
|
total_models: number;
|
|
buy_percentage: number;
|
|
sell_percentage: number;
|
|
hold_percentage: number;
|
|
};
|
|
|
|
models: ModelContribution[];
|
|
|
|
consensus_analysis: {
|
|
all_agree: boolean;
|
|
minority_models: string[];
|
|
agreement_percentage: number;
|
|
description: string;
|
|
};
|
|
}
|
|
|
|
interface ModelContribution {
|
|
model_id: string;
|
|
model_name: string;
|
|
prediction: 'BUY' | 'SELL' | 'HOLD';
|
|
score: number; // 0-100
|
|
confidence: number; // 0-100
|
|
weight: number; // 0-100, suma con otros = 100
|
|
contribution: number; // score * weight
|
|
is_outlier: boolean;
|
|
|
|
performance?: ModelPerformance;
|
|
}
|
|
|
|
interface ModelPerformance {
|
|
accuracy: number; // last 100 predictions
|
|
win_rate: number; // last 7 days
|
|
total_signals: number;
|
|
correct_signals: number;
|
|
trend: 'UP' | 'STABLE' | 'DOWN';
|
|
last_updated: string;
|
|
}
|
|
```
|
|
|
|
**Cálculos:**
|
|
```typescript
|
|
// Confianza combinada (weighted average)
|
|
ensemble_confidence = sum(model.score * model.weight) / 100
|
|
|
|
// Votación
|
|
buy_percentage = (buy_count / total_models) * 100
|
|
|
|
// Contribución de cada modelo
|
|
contribution = model.score * model.weight / 100
|
|
|
|
// Consenso
|
|
consensus_strength = all_models_agree ? 'STRONG' :
|
|
buy_percentage > 60 ? 'MODERATE' : 'WEAK'
|
|
```
|
|
|
|
**Componentes UI:**
|
|
- `EnsembleSignal`: Container principal
|
|
- `EnsembleHeader`: Decisión + confianza + consenso
|
|
- `ModelVoting`: Distribución de votos (barras)
|
|
- `ModelContributions`: Tabla detallada
|
|
- `ConsensusIndicator`: Visual de acuerdo
|
|
- `ModelPerformance`: Stats históricos
|
|
- `ModelComparison`: Heatmap
|
|
- `OutlierBadge`: Indicador de predicción minoritaria
|
|
|
|
**Estado (Zustand):**
|
|
```typescript
|
|
interface EnsembleStore {
|
|
ensemble: EnsembleSignalResponse | null;
|
|
selectedSymbol: string;
|
|
isLoading: boolean;
|
|
lastUpdated: string;
|
|
autoRefreshInterval: number; // 30000 ms
|
|
|
|
fetchEnsemble: (symbol: string) => Promise<void>;
|
|
setAutoRefresh: (enabled: boolean) => void;
|
|
compareModels: () => void;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Definition of Ready (DoR)
|
|
|
|
- [x] Historia claramente escrita (quién, qué, por qué)
|
|
- [x] Criterios de aceptación definidos
|
|
- [x] Story points estimados
|
|
- [x] Dependencias identificadas
|
|
- [x] Modelos ML disponibles (LSTM, RF, SVM, Transformer, GB)
|
|
- [x] Diseño/mockup disponible
|
|
|
|
## Definition of Done (DoD)
|
|
|
|
- [ ] Código implementado según criterios
|
|
- [ ] Tests unitarios escritos y pasando (>80% coverage)
|
|
- [ ] Tests E2E pasando
|
|
- [ ] Code review aprobado
|
|
- [ ] Documentación actualizada
|
|
- [ ] QA aprobado en staging
|
|
- [ ] Auto-refresh funciona sin memory leaks
|
|
- [ ] Performance: carga < 1.5s
|
|
- [ ] Mobile responsive
|
|
- [ ] Outliers detectados y resaltados correctamente
|
|
- [ ] Desplegado en producción
|
|
|
|
---
|
|
|
|
## Historial de Cambios
|
|
|
|
| Fecha | Cambio | Autor |
|
|
|-------|--------|-------|
|
|
| 2026-01-25 | Creación | Requirements-Analyst |
|
|
|
|
---
|
|
|
|
**Creada por:** Requirements-Analyst
|
|
**Fecha:** 2026-01-25
|
|
**Última actualización:** 2026-01-25
|