---
id: "US-ML-007"
title: "Ver Historial de Señales"
type: "User Story"
status: "Done"
priority: "Media"
epic: "OQI-006"
project: "trading-platform"
story_points: 3
created_date: "2025-12-05"
updated_date: "2026-01-04"
---

# US-ML-007: Ver Historial de Señales

## Metadata

| Campo | Valor |
|-------|-------|
| **ID** | US-ML-007 |
| **Épica** | OQI-006 - Señales ML y Predicciones |
| **Módulo** | ml-signals |
| **Prioridad** | P1 |
| **Story Points** | 3 |
| **Sprint** | Sprint 7 |
| **Estado** | Pendiente |
| **Asignado a** | Por asignar |

---

## Historia de Usuario

**Como** trader/inversor,
**quiero** ver un historial completo de señales pasadas con su outcome real (TP alcanzado, SL activado, expirada),
**para** evaluar el desempeño histórico del ML y aprender de señales anteriores.

## Descripción Detallada

El usuario debe poder acceder a una tabla/lista de todas las señales generadas históricamente, filtradas por símbolo, horizonte, y rango de fechas. Cada señal debe mostrar si alcanzó TP1/TP2/TP3, si activó SL, o si expiró, junto con la ganancia/pérdida real.

## Mockups/Wireframes

```
┌──────────────────────────────────────────────────────────────────┐
│  SIGNAL HISTORY                                         BTCUSDT  │
├──────────────────────────────────────────────────────────────────┤
│                                                                   │
│  Filters:                                                         │
│  [Symbol: BTCUSDT ▼] [Horizon: All ▼] [Date: Last 30 days ▼]    │
│  [Action: All ▼] [Outcome: All ▼]                   [Export CSV] │
│                                                                   │
│  ══════════════════════════════════════════════════════════════  │
│                                                                   │
│  ┌────────────────────────────────────────────────────────────┐ │
│  │ Date/Time       Action  Horizon   Conf  Outcome   P&L      │ │
│  ├────────────────────────────────────────────────────────────┤ │
│  │ Dec 5, 18:30   🟢 BUY   Scalping  75%  ✅ TP2    +0.42%   │ │
│  │ Entry: $89,400 → Exit: $89,775 (TP2) in 22 min           │ │
│  │ [View Details]                                             │ │
│  ├────────────────────────────────────────────────────────────┤ │
│  │ Dec 5, 17:45   🔴 SELL  Intraday  68%  ✅ TP1    +0.31%   │ │
│  │ Entry: $90,100 → Exit: $89,820 (TP1) in 45 min           │ │
│  │ [View Details]                                             │ │
│  ├────────────────────────────────────────────────────────────┤ │
│  │ Dec 5, 16:20   🟢 BUY   Scalping  62%  ❌ SL     -0.25%   │ │
│  │ Entry: $89,800 → Exit: $89,575 (SL) in 18 min            │ │
│  │ [View Details]                                             │ │
│  ├────────────────────────────────────────────────────────────┤ │
│  │ Dec 5, 15:10   🟢 BUY   Swing     58%  ⏱️ Expired   0%    │ │
│  │ Entry: $89,500 → Expired after 3 hours (no TP/SL hit)    │ │
│  │ [View Details]                                             │ │
│  ├────────────────────────────────────────────────────────────┤ │
│  │ Dec 5, 14:00   🔵 HOLD  Intraday  45%  ⏱️ Expired   0%    │ │
│  │ No action recommended                                      │ │
│  ├────────────────────────────────────────────────────────────┤ │
│  │ Dec 5, 12:35   🟢 BUY   Position  71%  ✅ TP3    +1.12%   │ │
│  │ Entry: $88,900 → Exit: $89,896 (TP3) in 5h 23min         │ │
│  │ [View Details]                                             │ │
│  └────────────────────────────────────────────────────────────┘ │
│                                                                   │
│  Showing 6 of 247 signals                    [Load More]         │
│                                                                   │
│  SUMMARY (Last 30 days):                                         │
│  Win Rate: 69% | Avg Gain: +0.42% | Avg Loss: -0.28%            │
│                                                                   │
└──────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────┐
│  SIGNAL DETAILS - Dec 5, 18:30                          [✕ Close]│
├──────────────────────────────────────────────────────────────────┤
│                                                                   │
│  🟢 BUY Signal - BTCUSDT (Scalping)                              │
│                                                                   │
│  Signal ID: 550e8400-e29b-41d4-a716-446655440000                 │
│  Generated: Dec 5, 2025 18:30:00 UTC                             │
│  Expired: Dec 5, 2025 19:00:00 UTC                               │
│                                                                   │
│  SIGNAL DETAILS                                                  │
│  ══════════════════════════════════════════════════════════════  │
│  Entry Price:        $89,400.00                                  │
│  Exit Price:         $89,775.00 (TP2)                            │
│  Confidence:         75%                                          │
│  Score:              8.5/10                                       │
│  Priority:           HIGH                                         │
│                                                                   │
│  LEVELS                                                          │
│  ══════════════════════════════════════════════════════════════  │
│  TP1: $89,650 (+0.28%)  ✅ Hit at 18:42 (+12 min)               │
│  TP2: $89,775 (+0.42%)  ✅ Hit at 18:52 (+22 min) ← Exit        │
│  TP3: $89,900 (+0.56%)  ⬜ Not reached                          │
│  SL:  $89,150 (-0.28%)  ⬜ Not triggered                        │
│                                                                   │
│  PERFORMANCE                                                     │
│  ══════════════════════════════════════════════════════════════  │
│  Outcome:            TP2 Hit (Success)                           │
│  Duration:           22 minutes                                  │
│  Realized P&L:       +0.42% (+$375.00)                           │
│  Risk/Reward:        1:2.0                                        │
│                                                                   │
│  TECHNICAL CONTEXT (at signal generation)                        │
│  ══════════════════════════════════════════════════════════════  │
│  RSI:                55.3 (Neutral)                              │
│  MACD:               Bullish crossover                           │
│  Volume Ratio:       1.2x (Above average)                        │
│                                                                   │
│  REASONS                                                         │
│  ══════════════════════════════════════════════════════════════  │
│  ✓ Strong upward prediction (0.75 confidence)                   │
│  ✓ Healthy RSI (55.3, not overbought)                           │
│  ✓ Above average volume (1.2x)                                  │
│  ✓ Favorable risk/reward (1:2)                                  │
│                                                                   │
│  [View on Chart]  [Similar Signals]                             │
│                                                                   │
└──────────────────────────────────────────────────────────────────┘
```

---

## Criterios de Aceptación

**Escenario 1: Ver historial de señales**
```gherkin
DADO que el usuario está autenticado
CUANDO navega a "Signal History"
ENTONCES se muestra una tabla con las últimas 20 señales
Y cada fila muestra:
  - Fecha y hora de generación
  - Acción (BUY/SELL/HOLD)
  - Horizonte
  - Confianza
  - Outcome (TP1/TP2/TP3/SL/Expired)
  - P&L real (% y USD si aplica)
Y se muestra resumen al final (win rate, avg gain, avg loss)
```

**Escenario 2: Filtrar por símbolo**
```gherkin
DADO que el usuario está en Signal History
CUANDO selecciona "ETHUSDT" en el filtro de símbolo
ENTONCES se muestran solo señales de ETHUSDT
Y el contador actualiza a "Showing X of Y signals"
Y el resumen se recalcula solo para ETHUSDT
```

**Escenario 3: Filtrar por outcome**
```gherkin
DADO que el usuario está en Signal History
CUANDO selecciona "TP Hit" en el filtro de Outcome
ENTONCES se muestran solo señales que alcanzaron TP1, TP2 o TP3
Y el win rate refleja solo estas señales
```

**Escenario 4: Ver detalles de señal**
```gherkin
DADO que el usuario está viendo el historial
CUANDO hace click en "View Details" de una señal
ENTONCES se abre un modal con:
  - Todos los detalles de la señal original
  - Outcome detallado (qué niveles se alcanzaron y cuándo)
  - P&L real calculado
  - Duración de la señal
  - Contexto técnico al momento de generación
  - Botón para ver la señal en el chart
```

**Escenario 5: Exportar historial a CSV**
```gherkin
DADO que el usuario está viendo el historial filtrado
CUANDO hace click en "Export CSV"
ENTONCES se descarga un archivo CSV con:
  - Todas las señales del filtro actual
  - Columnas: Date, Symbol, Action, Horizon, Confidence, Outcome, P&L
  - Nombre de archivo: "signal-history-BTCUSDT-2025-12-05.csv"
```

**Escenario 6: Paginación**
```gherkin
DADO que existen más de 20 señales
CUANDO el usuario hace scroll hasta el final
ENTONCES se muestra botón "Load More"
Y al hacer click, carga las siguientes 20 señales
Y el contador actualiza "Showing 40 of 247 signals"
```

## Criterios Adicionales

- [ ] El historial debe cargar en menos de 2 segundos
- [ ] Debe soportar hasta 1000 señales por símbolo
- [ ] Los filtros deben ser combinables
- [ ] El modal de detalles debe ser responsive
- [ ] El CSV debe incluir header con metadatos (fecha de export, filtros)

---

## Tareas Técnicas

**Backend:**
- [ ] BE-ML-011: Crear endpoint GET /api/signals/:symbol/history
- [ ] BE-ML-012: Implementar filtros (date_range, horizon, action, outcome)
- [ ] BE-ML-013: Implementar paginación (offset/limit)
- [ ] BE-ML-014: Endpoint GET /api/signals/:id/details
- [ ] BE-ML-015: Implementar generación de CSV

**Frontend:**
- [ ] FE-ML-028: Crear componente `SignalHistory.tsx`
- [ ] FE-ML-029: Crear componente `SignalTable.tsx`
- [ ] FE-ML-030: Crear componente `SignalFilters.tsx`
- [ ] FE-ML-031: Crear componente `SignalDetailsModal.tsx`
- [ ] FE-ML-032: Implementar infinite scroll / paginación
- [ ] FE-ML-033: Implementar export a CSV
- [ ] FE-ML-034: Agregar indicadores visuales de outcome (✅❌⏱️)

**Tests:**
- [ ] TEST-ML-013: Test de filtrado de señales
- [ ] TEST-ML-014: Test de cálculo de P&L
- [ ] TEST-ML-015: Test E2E de historial y detalles

---

## Dependencias

**Depende de:**
- [ ] RF-ML-002: Generación de señales (tracking de outcomes)
- [ ] US-ML-002: Ver señal - Estado: Pendiente

**Bloquea:**
- Ninguna (historia final)

---

## Notas Técnicas

**Endpoints involucrados:**
| Método | Endpoint | Descripción |
|--------|----------|-------------|
| GET | /api/signals/:symbol/history | Obtener historial con filtros |
| GET | /api/signals/:id/details | Detalles de señal específica |
| GET | /api/signals/:symbol/export.csv | Exportar a CSV |

**Query Parameters - History:**
```
GET /api/signals/BTCUSDT/history?
  date_from=2025-11-05&
  date_to=2025-12-05&
  horizon=scalping&
  action=BUY&
  outcome=tp_hit&
  limit=20&
  offset=0
```

**Response esperado:**
```typescript
interface SignalHistoryResponse {
  signals: SignalHistoryItem[];
  total_count: number;
  page_info: {
    limit: number;
    offset: number;
    has_more: boolean;
  };
  summary: {
    total_signals: number;
    win_rate: number;
    avg_gain: number;
    avg_loss: number;
    overall_pnl: number;
  };
}

interface SignalHistoryItem {
  signal_id: string;
  symbol: string;
  timestamp: string;
  action: 'BUY' | 'SELL' | 'HOLD';
  horizon: string;
  confidence: number;
  score: number;
  priority: string;

  entry_price: number;
  exit_price?: number;

  outcome: 'tp1' | 'tp2' | 'tp3' | 'sl' | 'expired';
  outcome_timestamp?: string;
  duration_minutes?: number;

  realized_pnl_pct?: number;
  realized_pnl_usd?: number;
}
```

**Componentes UI:**
- `SignalHistory`: Container principal
- `SignalTable`: Tabla de señales
- `SignalRow`: Fila individual
- `SignalFilters`: Barra de filtros
- `SignalDetailsModal`: Modal de detalles
- `OutcomeBadge`: Badge de outcome (✅/❌/⏱️)
- `SummaryStats`: Resumen de estadísticas

**Estado (Zustand):**
```typescript
interface SignalHistoryStore {
  signals: SignalHistoryItem[];
  filters: SignalFilters;
  summary: SummaryStats;
  isLoading: boolean;
  hasMore: boolean;

  fetchHistory: (symbol: string, filters: SignalFilters) => Promise<void>;
  loadMore: () => Promise<void>;
  updateFilters: (filters: Partial<SignalFilters>) => void;
  exportCSV: () => 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] Sin bloqueadores
- [x] Diseño/mockup disponible

## 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
- [ ] Filtros funcionan correctamente (combinados)
- [ ] Paginación funciona sin memory leaks
- [ ] Export CSV genera archivo válido
- [ ] Modal de detalles responsive
- [ ] Desplegado en producción

---

## Historial de Cambios

| Fecha | Cambio | Autor |
|-------|--------|-------|
| 2025-12-05 | Creación | Requirements-Analyst |

---

**Creada por:** Requirements-Analyst
**Fecha:** 2025-12-05
**Última actualización:** 2025-12-05
