--- 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