- 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>
449 lines
19 KiB
Markdown
449 lines
19 KiB
Markdown
---
|
|
id: "US-ML-010"
|
|
title: "Scan Multi-Símbolo"
|
|
type: "User Story"
|
|
status: "Pending"
|
|
priority: "Media"
|
|
epic: "OQI-006"
|
|
project: "trading-platform"
|
|
story_points: 5
|
|
created_date: "2026-01-25"
|
|
updated_date: "2026-01-25"
|
|
---
|
|
|
|
# US-ML-010: Scan Multi-Símbolo
|
|
|
|
## Metadata
|
|
|
|
| Campo | Valor |
|
|
|-------|-------|
|
|
| **ID** | US-ML-010 |
|
|
| **Épica** | OQI-006 - Señales ML y Predicciones |
|
|
| **Módulo** | ml-signals |
|
|
| **Prioridad** | P2 (Media) |
|
|
| **Story Points** | 5 |
|
|
| **Sprint** | Por asignar |
|
|
| **Estado** | Pendiente |
|
|
| **Asignado a** | Por asignar |
|
|
|
|
---
|
|
|
|
## Historia de Usuario
|
|
|
|
**Como** trader/inversor,
|
|
**quiero** escanear múltiples símbolos simultáneamente en busca de señales de trading,
|
|
**para** encontrar las mejores oportunidades disponibles en el mercado de forma eficiente.
|
|
|
|
## Descripción Detallada
|
|
|
|
El usuario debe poder seleccionar una lista de símbolos (desde una lista predefinida, watchlist personal, o subir lista personalizada), ejecutar un escaneo que genere señales ML para todos ellos en paralelo, y visualizar los resultados filtrados y ordenados por confianza. El escaneo debe completarse en menos de 10 segundos para máximo 50 símbolos.
|
|
|
|
## Mockups/Wireframes
|
|
|
|
```
|
|
┌──────────────────────────────────────────────────────────────────┐
|
|
│ MULTI-SYMBOL SCAN │
|
|
├──────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ Symbol Selection: │
|
|
│ ┌────────────────────────────────────────────────────────────┐ │
|
|
│ │ ▼ Select from: [Popular ▼] [My Watchlist ▼] [Custom ▼] │ │
|
|
│ │ │ │
|
|
│ │ ☑ BTCUSDT ☑ ETHUSDT ☑ BNBUSDT │ │
|
|
│ │ ☑ ADAUSDT ☑ XRPUSDT ☑ DOGEUSDT │ │
|
|
│ │ ☑ MATICUSDT ☑ SOLUSDT ☑ LINKUSDT │ │
|
|
│ │ │ │
|
|
│ │ [Clear All] [Select All] [Select: 9 symbols] │ │
|
|
│ │ │ │
|
|
│ │ Or upload CSV: [Choose File] upload-symbols.csv │ │
|
|
│ └────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ Filter & Sort: │
|
|
│ ┌────────────────────────────────────────────────────────────┐ │
|
|
│ │ Signal Type: [All ▼] Action: [BUY ▼] Horizon: [All ▼] │ │
|
|
│ │ Min Confidence: [50% ▼] Sort by: [Confidence ▼] │ │
|
|
│ │ │ │
|
|
│ │ [🔄 Scan Now] [⏸️ Cancel] Scanning: 7/9 │ │
|
|
│ └────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ══════════════════════════════════════════════════════════════ │
|
|
│ │
|
|
│ SCAN RESULTS - 9 Symbols, 12 Signals Found │
|
|
│ │
|
|
│ ┌────────────────────────────────────────────────────────────┐ │
|
|
│ │ Symbol Action Horizon Conf. Score Entry Status │ │
|
|
│ ├────────────────────────────────────────────────────────────┤ │
|
|
│ │ BTCUSDT 🟢 BUY Scalping 85% 9.2/10 $89,400 ✅ Ready│ │
|
|
│ │ ETHUSDT 🟢 BUY Intraday 78% 8.8/10 $3,240 ✅ Ready│ │
|
|
│ │ BNBUSDT 🟢 BUY Swing 72% 8.1/10 $620 ✅ Ready│ │
|
|
│ │ ADAUSDT 🔴 SELL Intraday 68% 7.6/10 $1.05 ✅ Ready│ │
|
|
│ │ LINKUSDT 🟢 BUY Swing 65% 7.3/10 $28.50 ✅ Ready│ │
|
|
│ │ SOLUSDT 🔵 HOLD Position 58% 6.9/10 $190.50 ⚠️ Weak │ │
|
|
│ │ XRPUSDT 🔴 SELL Scalping 55% 6.2/10 $2.45 ⚠️ Weak │ │
|
|
│ │ MATICUSDT - - - - - - ❌ NoSig│ │
|
|
│ │ DOGEUSDT - - - - - - ❌ NoSig│ │
|
|
│ └────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ [View Details] [Add to Watchlist] [Export Results] │
|
|
│ │
|
|
│ SUMMARY │
|
|
│ ══════════════════════════════════════════════════════════════ │
|
|
│ Total Symbols Scanned: 9 │
|
|
│ Signals Found: 7 (77.8%) │
|
|
│ Strong Signals (>70%): 4 │
|
|
│ Weak Signals (50-70%): 3 │
|
|
│ Avg Confidence: 68.3% │
|
|
│ │
|
|
│ [Create Portfolio from BUY Signals] [Refresh Scan] │
|
|
│ │
|
|
└──────────────────────────────────────────────────────────────────┘
|
|
|
|
┌──────────────────────────────────────────────────────────────────┐
|
|
│ SCAN PROGRESS [✕ Cancel] │
|
|
├──────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ Scanning 9 symbols in parallel... │
|
|
│ │
|
|
│ ✅ BTCUSDT (2.1s) │
|
|
│ ✅ ETHUSDT (1.8s) │
|
|
│ ✅ BNBUSDT (1.5s) │
|
|
│ ⏳ ADAUSDT (Generating signal...) │
|
|
│ ⏳ XRPUSDT (Generating signal...) │
|
|
│ ⏳ LINKUSDT (Analyzing indicators...) │
|
|
│ ⏳ SOLUSDT (Analyzing indicators...) │
|
|
│ ⏳ MATICUSDT (Analyzing indicators...) │
|
|
│ ⏳ DOGEUSDT (Analyzing indicators...) │
|
|
│ │
|
|
│ Completed: 3/9 • Elapsed: 5.2s • Est. time: ~7.8s │
|
|
│ ████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 33% │
|
|
│ │
|
|
│ [View Real-time Feed] [Pause] [Cancel] │
|
|
│ │
|
|
└──────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Criterios de Aceptación
|
|
|
|
**Escenario 1: Seleccionar símbolos desde lista predefinida**
|
|
```gherkin
|
|
DADO que el usuario está en la pantalla Multi-Symbol Scan
|
|
CUANDO hace click en "Popular"
|
|
ENTONCES se muestran los 50 símbolos más populares/líquidos
|
|
Y puede seleccionar hasta 50 símbolos con checkboxes
|
|
Y se muestra el contador "Select: X symbols"
|
|
```
|
|
|
|
**Escenario 2: Usar watchlist personal**
|
|
```gherkin
|
|
DADO que el usuario tiene una watchlist guardada
|
|
CUANDO selecciona "My Watchlist"
|
|
ENTONCES se cargan automáticamente los símbolos de la watchlist
|
|
Y puede desseleccionar símbolos si lo desea
|
|
Y se mantiene la selección al cambiar de filtro
|
|
```
|
|
|
|
**Escenario 3: Subir lista personalizada en CSV**
|
|
```gherkin
|
|
DADO que el usuario está en Symbol Selection
|
|
CUANDO hace click en "Choose File" y selecciona un CSV
|
|
ENTONCES el sistema parsea el archivo (formato: 1 símbolo por línea)
|
|
Y agrega los símbolos a la selección
|
|
Y muestra cantidad de símbolos cargados (validando que sean correctos)
|
|
Y permite deseleccionar los que no desea
|
|
```
|
|
|
|
**Escenario 4: Ejecutar escaneo multi-símbolo**
|
|
```gherkin
|
|
DADO que el usuario ha seleccionado 9 símbolos
|
|
Y ha configurado filtros (tipo de señal, confianza mínima)
|
|
CUANDO hace click en "Scan Now"
|
|
ENTONCES inicia escaneo paralelo en todos los símbolos
|
|
Y muestra progreso en tiempo real (símbolos completados)
|
|
Y el escaneo completa en menos de 10 segundos para 50 símbolos
|
|
Y muestra "Scanning: 3/9" mientras se ejecuta
|
|
```
|
|
|
|
**Escenario 5: Ver resultados en tabla**
|
|
```gherkin
|
|
DADO que el escaneo se ha completado
|
|
CUANDO se muestran los resultados
|
|
ENTONCES se visualiza tabla con columnas:
|
|
- Símbolo
|
|
- Acción (BUY/SELL/HOLD)
|
|
- Horizonte
|
|
- Confianza %
|
|
- Score (0-10)
|
|
- Precio de entrada
|
|
- Estado (✅ Ready / ⚠️ Weak / ❌ No Signal)
|
|
Y cada fila es clickeable para ver detalles completos
|
|
```
|
|
|
|
**Escenario 6: Filtrar resultados por confianza**
|
|
```gherkin
|
|
DADO que se muestran los resultados del escaneo
|
|
CUANDO selecciona "Min Confidence: 70%"
|
|
ENTONCES se muestran solo señales con confianza >= 70%
|
|
Y se actualiza el contador "7 of 12 signals"
|
|
Y el resumen se recalcula solo para señales filtradas
|
|
```
|
|
|
|
**Escenario 7: Filtrar por tipo de señal**
|
|
```gherkin
|
|
DADO que se muestran los resultados
|
|
CUANDO selecciona "Action: BUY"
|
|
ENTONCES muestra solo señales de compra
|
|
Y se pueden combinar filtros (ej: Action=BUY AND Horizon=Scalping)
|
|
```
|
|
|
|
**Escenario 8: Ordenar por confianza**
|
|
```gherkin
|
|
DADO que se muestran resultados
|
|
CUANDO hace click en "Sort by: Confidence" (descendente)
|
|
ENTONCES la tabla se ordena con señales más confiables primero
|
|
Y se puede invertir el orden (ascendente/descendente)
|
|
Y se pueden ordenar también por Score, Símbolo, etc.
|
|
```
|
|
|
|
**Escenario 9: Exportar resultados**
|
|
```gherkin
|
|
DADO que se muestran los resultados del escaneo
|
|
CUANDO hace click en "Export Results"
|
|
ENTONCES descarga archivo CSV con:
|
|
- Symbol, Action, Horizon, Confidence, Score, Entry Price
|
|
- Nombre: "scan-results-2026-01-25-09-30.csv"
|
|
```
|
|
|
|
**Escenario 10: Crear portfolio desde resultados**
|
|
```gherkin
|
|
DADO que se muestran resultados del escaneo
|
|
CUANDO hace click en "Create Portfolio from BUY Signals"
|
|
ENTONCES se abre modal para crear nuevo portfolio
|
|
Y se preseleccionan automáticamente todos los BUY signals
|
|
Y el usuario puede ajustar pesos y confirmar creación
|
|
```
|
|
|
|
## Criterios Adicionales
|
|
|
|
- [ ] El escaneo debe soportar máximo 50 símbolos simultáneamente
|
|
- [ ] El tiempo máximo debe ser menor a 10 segundos
|
|
- [ ] Los resultados deben mostrarse ordenados por confianza descendente
|
|
- [ ] El CSV debe ser válido y con header
|
|
- [ ] Debe mostrar progreso en tiempo real durante el escaneo
|
|
- [ ] Debe manejar símbolos inválidos (ignorarlos o marcar con error)
|
|
- [ ] La tabla debe ser responsive en móvil
|
|
- [ ] Los filtros deben ser combinables
|
|
|
|
---
|
|
|
|
## Tareas Técnicas
|
|
|
|
**Backend:**
|
|
- [ ] BE-ML-020: Crear endpoint POST /api/ml/scan
|
|
- [ ] BE-ML-021: Implementar worker para escaneo paralelo (queue-based)
|
|
- [ ] BE-ML-022: Validar símbolos de entrada
|
|
- [ ] BE-ML-023: Parsear CSV de símbolos
|
|
- [ ] BE-ML-024: Implementar filtros (action, horizon, confidence_min)
|
|
- [ ] BE-ML-025: Generar respuesta con resultados ordenados
|
|
- [ ] BE-ML-026: Implementar export a CSV
|
|
|
|
**Frontend:**
|
|
- [ ] FE-ML-040: Crear componente `MultiSymbolScan.tsx`
|
|
- [ ] FE-ML-041: Crear componente `SymbolSelector.tsx`
|
|
- [ ] FE-ML-042: Crear componente `ScanFilters.tsx`
|
|
- [ ] FE-ML-043: Crear componente `ScanResults.tsx`
|
|
- [ ] FE-ML-044: Crear componente `ScanProgress.tsx`
|
|
- [ ] FE-ML-045: Implementar upload de CSV
|
|
- [ ] FE-ML-046: Implementar tabla con sorting y filtros
|
|
- [ ] FE-ML-047: Implementar export a CSV
|
|
- [ ] FE-ML-048: Integración con TanStack Query (react-query)
|
|
- [ ] FE-ML-049: Real-time progress updates (WebSocket/SSE)
|
|
|
|
**ML Engine:**
|
|
- [ ] ML-020: Optimizar generación de señales para múltiples símbolos
|
|
- [ ] ML-021: Implementar ejecución paralela de análisis
|
|
- [ ] ML-022: Cachear indicadores técnicos por símbolo
|
|
|
|
**Tests:**
|
|
- [ ] TEST-ML-020: Test de validación de símbolos
|
|
- [ ] TEST-ML-021: Test de parseo CSV
|
|
- [ ] TEST-ML-022: Test de escaneo paralelo (timeout, errores)
|
|
- [ ] TEST-ML-023: Test de filtrado y ordenamiento
|
|
- [ ] TEST-ML-024: Test E2E completo del multi-scan
|
|
|
|
---
|
|
|
|
## Dependencias
|
|
|
|
**Depende de:**
|
|
- [ ] US-ML-002: Ver señal - Estado: Pendiente
|
|
- [ ] RF-ML-001: Generación de señales ML
|
|
- [ ] Infrastructure: Worker queue (Bull/RabbitMQ)
|
|
|
|
**Bloquea:**
|
|
- [ ] US-ML-011: Alertas de señales (requiere resultados del scan)
|
|
- [ ] US-ML-012: Portfolio builder (requiere scan multi-símbolo)
|
|
|
|
---
|
|
|
|
## Notas Técnicas
|
|
|
|
**Endpoints involucrados:**
|
|
| Método | Endpoint | Descripción |
|
|
|--------|----------|-------------|
|
|
| POST | /api/ml/scan | Ejecutar escaneo multi-símbolo |
|
|
| GET | /api/ml/scan/:scanId/progress | Obtener progreso en tiempo real |
|
|
| GET | /api/ml/scan/:scanId/results | Obtener resultados del escaneo |
|
|
| GET | /api/ml/scan/:scanId/export.csv | Exportar resultados a CSV |
|
|
| GET | /api/symbols/popular | Lista de símbolos populares |
|
|
| GET | /api/watchlists/:id/symbols | Símbolos de watchlist |
|
|
|
|
**Request esperado:**
|
|
```typescript
|
|
interface MultiSymbolScanRequest {
|
|
symbols: string[]; // Array de símbolos (ej: ['BTCUSDT', 'ETHUSDT'])
|
|
filters: {
|
|
signal_type?: 'BUY' | 'SELL' | 'HOLD' | 'ALL';
|
|
horizon?: string;
|
|
confidence_min?: number; // 0-100
|
|
action?: 'BUY' | 'SELL';
|
|
};
|
|
sort_by?: 'confidence' | 'score' | 'symbol';
|
|
sort_order?: 'asc' | 'desc';
|
|
}
|
|
```
|
|
|
|
**Response esperado:**
|
|
```typescript
|
|
interface MultiSymbolScanResponse {
|
|
scan_id: string;
|
|
status: 'completed' | 'in_progress' | 'failed';
|
|
timestamp: string;
|
|
symbols_scanned: number;
|
|
signals_found: number;
|
|
results: SignalResult[];
|
|
summary: {
|
|
total_symbols: number;
|
|
signals_found: number;
|
|
strong_signals: number; // confidence >= 70%
|
|
weak_signals: number; // 50% <= confidence < 70%
|
|
avg_confidence: number;
|
|
};
|
|
execution_time_ms: number;
|
|
}
|
|
|
|
interface SignalResult {
|
|
symbol: string;
|
|
action: 'BUY' | 'SELL' | 'HOLD' | null;
|
|
horizon?: string;
|
|
confidence?: number;
|
|
score?: number;
|
|
entry_price?: number;
|
|
status: 'ready' | 'weak' | 'no_signal' | 'error';
|
|
error_message?: string;
|
|
}
|
|
```
|
|
|
|
**CSV Upload Parser:**
|
|
```typescript
|
|
// Soporta formatos:
|
|
// 1. Un símbolo por línea (simple)
|
|
BTCUSDT
|
|
ETHUSDT
|
|
BNBUSDT
|
|
|
|
// 2. CSV con header
|
|
Symbol,Exchange,Type
|
|
BTCUSDT,BINANCE,SPOT
|
|
ETHUSDT,BINANCE,SPOT
|
|
```
|
|
|
|
**Componentes UI:**
|
|
- `MultiSymbolScan`: Container principal
|
|
- `SymbolSelector`: Selector de símbolos con pestañas
|
|
- `SymbolListPicker`: Selector desde lista predefinida
|
|
- `WatchlistPicker`: Selector desde watchlist personal
|
|
- `CSVUploader`: Componente de upload de CSV
|
|
- `ScanFilters`: Filtros de escaneo
|
|
- `ScanResults`: Tabla de resultados
|
|
- `ScanProgress`: Modal de progreso en tiempo real
|
|
- `ResultsActions`: Acciones sobre resultados (export, create portfolio)
|
|
|
|
**Estado (Zustand):**
|
|
```typescript
|
|
interface MultiSymbolScanStore {
|
|
selectedSymbols: string[];
|
|
scanResults: SignalResult[];
|
|
scanProgress: {
|
|
total: number;
|
|
completed: number;
|
|
currentSymbol: string;
|
|
};
|
|
filters: ScanFilters;
|
|
isScanning: boolean;
|
|
sortBy: 'confidence' | 'score' | 'symbol';
|
|
sortOrder: 'asc' | 'desc';
|
|
|
|
setSelectedSymbols: (symbols: string[]) => void;
|
|
startScan: () => Promise<void>;
|
|
updateProgress: (progress: ScanProgress) => void;
|
|
updateFilters: (filters: Partial<ScanFilters>) => void;
|
|
setSortBy: (field: string, order: 'asc' | 'desc') => void;
|
|
exportToCSV: () => void;
|
|
}
|
|
```
|
|
|
|
**Real-time Progress:**
|
|
- Usar WebSocket o SSE para enviar actualizaciones de progreso
|
|
- Endpoint: `/api/ml/scan/:scanId/progress` con streaming
|
|
- O usar polling cada 500ms si WebSocket no disponible
|
|
|
|
**Performance Targets:**
|
|
- 50 símbolos scanned: < 10 segundos
|
|
- 20 símbolos scanned: < 5 segundos
|
|
- 10 símbolos scanned: < 3 segundos
|
|
|
|
---
|
|
|
|
## 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] Diseño/mockup disponible
|
|
- [x] Targets de performance definidos
|
|
- [x] Formatos de datos especificados
|
|
|
|
## Definition of Done (DoD)
|
|
|
|
- [ ] Código implementado según criterios
|
|
- [ ] Tests unitarios escritos y pasando
|
|
- [ ] Tests E2E pasando
|
|
- [ ] Code review aprobado
|
|
- [ ] Documentación actualizada
|
|
- [ ] QA aprobado en staging
|
|
- [ ] Escaneo paralelo funciona correctamente
|
|
- [ ] Real-time progress updates funcionan
|
|
- [ ] CSV upload y export validan correctamente
|
|
- [ ] Filtros y ordenamiento funcionan
|
|
- [ ] Performance meets targets (< 10s para 50 símbolos)
|
|
- [ ] Manejo de errores robusto (símbolos inválidos, timeouts)
|
|
- [ ] Responsive en móvil
|
|
- [ ] 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
|