Changes include: - Updated architecture documentation - Enhanced module definitions (OQI-001 to OQI-008) - ML integration documentation updates - Trading strategies documentation - Orchestration and inventory updates - Docker configuration updates 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
489 lines
13 KiB
Markdown
489 lines
13 KiB
Markdown
---
|
||
id: "RF-TRD-007"
|
||
title: "Historial y Trades"
|
||
type: "Requirement"
|
||
status: "Done"
|
||
priority: "Alta"
|
||
module: "trading"
|
||
epic: "OQI-003"
|
||
version: "1.0"
|
||
created_date: "2025-12-05"
|
||
updated_date: "2026-01-04"
|
||
---
|
||
|
||
# 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
|