# RF-TRD-007: Historial y Trades

**Versión:** 1.0.0
**Fecha:** 2025-12-05
**Épica:** OQI-003 - Trading y Charts
**Prioridad:** P1
**Story Points:** 8

---

## Descripción

El sistema debe mantener un historial completo y detallado de todas las operaciones de trading ejecutadas por el usuario, permitiendo análisis retrospectivo, aprendizaje de errores y evaluación del rendimiento a lo largo del tiempo.

---

## Requisitos Funcionales

### RF-TRD-007.1: Registro de Trades

El sistema debe registrar automáticamente:
- Cada orden ejecutada (filled)
- Cada posición cerrada (total o parcial)
- Activaciones de Stop Loss / Take Profit
- Liquidaciones forzadas
- Ajustes y correcciones manuales

**Información capturada por trade:**
- Símbolo y par de trading
- Tipo de operación (buy/sell)
- Tipo de orden (market/limit/stop)
- Cantidad ejecutada
- Precio de entrada
- Precio de salida (para cierres)
- PnL realizado
- Fees pagados (futuro, $0 en MVP)
- Duración de la posición
- Motivo de cierre (manual, SL, TP, liquidación)
- Timestamps completos
- Condiciones de mercado (volatilidad, volumen)

### RF-TRD-007.2: Vista de Historial

El sistema debe proporcionar tabla con columnas:

| Columna | Descripción | Formato |
|---------|-------------|---------|
| Date/Time | Fecha de cierre | DD/MM/YYYY HH:mm |
| Symbol | Par de trading | BTCUSDT |
| Type | Buy/Sell | Badge coloreado |
| Entry Price | Precio de entrada | $50,234.56 |
| Exit Price | Precio de salida | $51,500.00 |
| Quantity | Cantidad operada | 0.5 BTC |
| PnL | Ganancia/Pérdida | +$632.50 |
| PnL % | Porcentaje | +2.5% |
| Duration | Tiempo abierto | 2h 34m |
| Close Reason | Motivo de cierre | Manual/SL/TP |

### RF-TRD-007.3: Filtros y Búsqueda

El sistema debe permitir filtrar por:

**Temporalidad:**
- Hoy
- Últimos 7 días
- Últimos 30 días
- Últimos 3 meses
- Rango personalizado
- Todo el historial

**Símbolo:**
- Todos los símbolos
- Símbolo específico
- Múltiples símbolos seleccionados

**Resultado:**
- Todos los trades
- Solo ganadores (PnL > 0)
- Solo perdedores (PnL < 0)
- Breakeven (PnL ≈ 0)

**Tipo:**
- Todos los tipos
- Solo long
- Solo short (futuro)

**Motivo de cierre:**
- Manual
- Stop Loss
- Take Profit
- Liquidación

### RF-TRD-007.4: Ordenamiento

El sistema debe permitir ordenar por:
- Fecha (más reciente / más antiguo)
- PnL (mayor ganancia / mayor pérdida)
- Duración (más largo / más corto)
- Volumen (mayor / menor)

### RF-TRD-007.5: Detalle de Trade

Al hacer click en un trade, mostrar modal con:

**Información completa:**
- Timeline del trade (apertura → eventos → cierre)
- Gráfico del precio durante el trade
- Marcadores de entrada y salida
- Eventos de modificación (SL/TP ajustados)
- Condiciones de mercado en ese momento
- Notas del usuario (editable)
- Tags/etiquetas (ej: "estrategia momentum", "error")

**Métricas adicionales:**
- MAE (Maximum Adverse Excursion): Máxima pérdida durante el trade
- MFE (Maximum Favorable Excursion): Máxima ganancia durante el trade
- Efficiency: PnL / MFE
- Precio de mejor momento de salida

### RF-TRD-007.6: Exportación

El sistema debe permitir exportar historial en:
- CSV (compatible con Excel)
- JSON (para análisis programático)
- PDF (reporte formateado)

**Filtros aplicables:**
- Exportar solo trades filtrados
- Exportar rango de fechas
- Incluir/excluir métricas avanzadas

### RF-TRD-007.7: Estadísticas Resumidas

En el header del historial mostrar:

```
┌─────────────────────────────────────────────────┐
│  Total Trades: 145                              │
│  Win Rate: 58.6% (85W / 60L)                   │
│  Total PnL: +$3,456.78 (+34.6%)                │
│  Avg Win: +$89.23  │  Avg Loss: -$45.67        │
│  Best Trade: +$456.78  │  Worst: -$234.56      │
│  Avg Duration: 4h 23m                           │
└─────────────────────────────────────────────────┘
```

### RF-TRD-007.8: Journal de Trading

El sistema debe permitir:
- Añadir notas a cada trade
- Etiquetar trades (ej: "setup perfecto", "error emocional")
- Subir screenshots del setup
- Marcar trades como favoritos para revisión
- Crear sesiones de trading (agrupar trades del día)

---

## Datos de Entrada

### Registrar Trade

```typescript
interface CreateTradeDto {
  userId: string;
  symbol: string;
  side: 'buy' | 'sell';
  type: 'market' | 'limit' | 'stop_limit';

  // Ejecución
  entryPrice: number;
  exitPrice: number;
  quantity: number;

  // PnL
  realizedPnl: number;
  realizedPnlPercent: number;
  fees: number;

  // Tiempos
  openedAt: string;
  closedAt: string;
  duration: number;  // Segundos

  // Contexto
  closeReason: 'manual' | 'stop_loss' | 'take_profit' | 'liquidation' | 'partial_close';
  stopLossPrice?: number;
  takeProfitPrice?: number;

  // Análisis
  mae?: number;  // Maximum Adverse Excursion
  mfe?: number;  // Maximum Favorable Excursion

  // Metadatos
  orderId: string;
  positionId: string;
}
```

### Añadir Nota a Trade

```typescript
interface AddTradeNoteDto {
  tradeId: string;
  note: string;
  tags?: string[];
  isFavorite?: boolean;
}
```

---

## Datos de Salida

### Trade Histórico

```typescript
interface Trade {
  id: string;
  userId: string;
  symbol: string;
  side: 'buy' | 'sell';
  type: OrderType;

  // Precios
  entryPrice: number;
  exitPrice: number;
  quantity: number;

  // Resultados
  realizedPnl: number;
  realizedPnlPercent: number;
  fees: number;
  netProfit: number;  // PnL - fees

  // Tiempos
  openedAt: string;
  closedAt: string;
  duration: number;
  durationFormatted: string;  // "2h 34m"

  // Contexto
  closeReason: CloseReason;
  stopLossPrice: number | null;
  takeProfitPrice: number | null;

  // Análisis
  mae: number | null;
  mfe: number | null;
  efficiency: number | null;  // PnL / MFE

  // Journal
  notes: string | null;
  tags: string[];
  isFavorite: boolean;
  screenshots: string[];

  // Metadatos
  orderId: string;
  positionId: string;
}

enum CloseReason {
  MANUAL = 'manual',
  STOP_LOSS = 'stop_loss',
  TAKE_PROFIT = 'take_profit',
  LIQUIDATION = 'liquidation',
  PARTIAL_CLOSE = 'partial_close'
}
```

### Estadísticas de Historial

```typescript
interface TradeHistoryStats {
  // Básicas
  totalTrades: number;
  winningTrades: number;
  losingTrades: number;
  breakEvenTrades: number;

  // Win Rate
  winRate: number;  // Porcentaje

  // PnL
  totalPnl: number;
  totalPnlPercent: number;
  grossProfit: number;
  grossLoss: number;

  // Promedios
  avgWin: number;
  avgLoss: number;
  avgTrade: number;
  avgDuration: number;  // Segundos

  // Extremos
  bestTrade: Trade | null;
  worstTrade: Trade | null;
  longestTrade: Trade | null;
  shortestTrade: Trade | null;

  // Ratios
  profitFactor: number;  // grossProfit / grossLoss
  avgWinLossRatio: number;  // avgWin / avgLoss

  // Por período
  tradesThisWeek: number;
  tradesThisMonth: number;
  pnlThisWeek: number;
  pnlThisMonth: number;
}
```

---

## Reglas de Negocio

1. **Registro automático:**
   - Todo trade cerrado debe registrarse
   - No se pueden eliminar trades del historial
   - Solo se pueden añadir notas/tags

2. **Cálculos:**
   - PnL incluye slippage pero no fees (MVP)
   - Duration se calcula desde apertura hasta cierre
   - MAE/MFE se calculan durante vida de posición

3. **Retención:**
   - Historial completo se mantiene indefinidamente
   - Acceso rápido últimos 90 días
   - Historial antiguo puede tener latencia mayor

4. **Exportación:**
   - Máximo 1000 trades por exportación
   - Formato CSV compatible con TradingView/MetaTrader

5. **Privacy:**
   - Solo el usuario puede ver su historial
   - Admin puede ver para soporte (con registro de auditoría)

---

## Criterios de Aceptación

```gherkin
Escenario: Trade se registra automáticamente al cerrar posición
  DADO que el usuario tiene posición abierta de BTCUSDT
  CUANDO cierra la posición con ganancia de +5%
  ENTONCES aparece nuevo trade en historial
  Y muestra entry price, exit price y PnL
  Y calcula duration correctamente

Escenario: Usuario filtra trades ganadores
  DADO que el usuario tiene 100 trades en historial
  Y 60 son ganadores
  CUANDO activa filtro "Solo ganadores"
  ENTONCES se muestran solo 60 trades
  Y todos tienen PnL > 0
  Y se actualiza estadística "Win Rate"

Escenario: Usuario añade nota a trade
  DADO que el usuario ve detalle de un trade
  CUANDO añade nota "Setup perfecto, seguir esta estrategia"
  Y añade tag "momentum-strategy"
  ENTONCES la nota se guarda
  Y el tag aparece en lista de tags
  Y se puede filtrar por este tag

Escenario: Usuario exporta historial a CSV
  DADO que el usuario tiene 50 trades filtrados
  CUANDO hace click en "Exportar CSV"
  ENTONCES se descarga archivo trades.csv
  Y contiene 50 filas (+ header)
  Y es compatible con Excel

Escenario: Usuario ve detalle de trade con gráfico
  DADO que el usuario hace click en un trade
  CUANDO se abre el modal de detalle
  ENTONCES se muestra gráfico del precio durante el trade
  Y marca punto de entrada con flecha verde
  Y marca punto de salida con flecha roja
  Y muestra líneas de SL/TP si existieron

Escenario: Estadísticas se calculan correctamente
  DADO que el usuario tiene 10 trades
  Y 6 son ganadores (+$600 total)
  Y 4 son perdedores (-$200 total)
  ENTONCES Win Rate muestra 60%
  Y Total PnL muestra +$400
  Y Profit Factor muestra 3.0
```

---

## Interfaz de Usuario

```
┌─────────────────────────────────────────────────────────┐
│                   TRADE HISTORY                         │
├─────────────────────────────────────────────────────────┤
│  Total: 145  │  Win Rate: 58.6%  │  PnL: +$3,456 ▲    │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  Filters: [Last 30 days ▼] [All Symbols ▼] [Export ▼] │
│                                                         │
│  Date        │Symbol   │Entry  │Exit   │PnL      │... │
│──────────────┼─────────┼───────┼───────┼─────────┼────│
│  05/12 14:23 │BTCUSDT  │50,000 │51,500 │+$750 ▲  │ 📝 │
│  05/12 12:10 │ETHUSDT  │ 3,200 │ 3,150 │-$100 ▼  │ 📝 │
│  04/12 18:45 │BTCUSDT  │49,500 │50,200 │+$350 ▲  │ 📝 │
│  04/12 09:30 │BNBUSDT  │  450  │  425  │-$250 ▼  │ 📝 │
│  ...         │...      │...    │...    │...      │    │
│                                                         │
│              [Load More]                                │
└─────────────────────────────────────────────────────────┘
```

---

## Dependencias

- RF-TRD-006: Gestión de Posiciones (cerrar posiciones)
- RF-TRD-008: Métricas y Estadísticas (análisis agregado)
- Base de datos con índices en userId, closedAt
- Storage para screenshots (S3, local en MVP)

---

## Notas Técnicas

- Usar paginación para listas grandes (50 trades por página)
- Indexar por userId, symbol, closedAt para queries rápidas
- Cachear estadísticas agregadas (recalcular al nuevo trade)
- Implementar soft-delete para auditoría
- Guardar snapshot del mercado en momento del trade
- Usar transacciones para asegurar consistencia
- Implementar rate limiting en exportaciones
- Comprimir archivos CSV grandes antes de descarga

---

## Cálculos Importantes

### Win Rate
```
Win Rate = (Winning Trades / Total Trades) × 100
```

### Profit Factor
```
Profit Factor = Gross Profit / Gross Loss
```

### Expectancy
```
Expectancy = (Win Rate × Avg Win) - (Loss Rate × Avg Loss)
```

### Efficiency
```
Efficiency = Realized PnL / MFE
```

---

## Métricas a Trackear

- Trades ejecutados por día/semana/mes
- Distribución de PnL (histograma)
- Win rate tendencia (mejorando/empeorando)
- Símbolos más operados
- Horarios de mayor actividad
- Duración promedio por símbolo
- Mejores y peores días
- Rachas de victorias/derrotas
