trading-platform/docs/02-definicion-modulos/OQI-003-trading-charts/historias-usuario/US-TRD-011-ver-estadisticas.md
rckrdmrd a7cca885f0 feat: Major platform documentation and architecture updates
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>
2026-01-07 05:33:35 -06:00

400 lines
15 KiB
Markdown

---
id: "US-TRD-011"
title: "Ver Estadisticas de Rendimiento"
type: "User Story"
status: "Done"
priority: "Alta"
epic: "OQI-003"
story_points: 3
created_date: "2025-12-05"
updated_date: "2026-01-04"
---
# US-TRD-011: Ver Estadísticas de Rendimiento
## Metadata
| Campo | Valor |
|-------|-------|
| **ID** | US-TRD-011 |
| **Épica** | OQI-003 - Trading y Charts |
| **Módulo** | trading |
| **Prioridad** | P1 |
| **Story Points** | 3 |
| **Sprint** | Sprint 5 |
| **Estado** | Pendiente |
| **Asignado a** | Por asignar |
---
## Historia de Usuario
**Como** trader practicante,
**quiero** ver estadísticas detalladas de mi rendimiento (win rate, profit factor, drawdown, etc.),
**para** evaluar objetivamente mi progreso y identificar áreas de mejora en mi trading.
## Descripción Detallada
El usuario debe tener acceso a un dashboard de estadísticas que muestre métricas clave de rendimiento: win rate, profit factor, average win/loss, maximum drawdown, sharpe ratio, gráficos de equity curve, distribución de P&L, y análisis por símbolo y timeframe.
## Mockups/Wireframes
```
┌─────────────────────────────────────────────────────────────────────────┐
│ TRADING STATISTICS │
├─────────────────────────────────────────────────────────────────────────┤
│ Period: [Last 30 days ▼] [Custom Range] │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Win Rate │ │ Profit │ │ Net P&L │ │ Total Trades│ │
│ │ │ │ Factor │ │ │ │ │ │
│ │ 62.5% │ │ 2.45 │ │ +$1,234.56 │ │ 45 │ │
│ │ ████░░ │ │ Excellent │ │ (+12.3%) │ │ 27W / 18L │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ EQUITY CURVE │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ $12,000 ┤ ████ │ │
│ │ $11,500 ┤ ████████ │ │
│ │ $11,000 ┤ ████████ │ │
│ │ $10,500 ┤ ████████ │ │
│ │ $10,000 ┤────────────────────████████ │ │
│ │ $9,500 ┤ ████████ │ │
│ │ └──────────────────────────────────────────────────────── │ │
│ │ Nov 5 Nov 15 Nov 25 Dec 5 │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────┐ ┌──────────────────────────────────┐ │
│ │ PERFORMANCE METRICS │ │ P&L DISTRIBUTION │ │
│ ├──────────────────────────┤ ├──────────────────────────────────┤ │
│ │ Average Win: $45.72 │ │ $200+ ░░░░░░ 3 │ │
│ │ Average Loss: -$25.38 │ │ $100 ████████████ 8 │ │
│ │ Largest Win: $150.00 │ │ $50 ████████████████ 12 │ │
│ │ Largest Loss: -$80.00 │ │ $0 ██████ 4 │ │
│ │ │ │ -$50 ████████ 6 │ │
│ │ Avg Duration: 4h 20m │ │ -$100 ████ 3 │ │
│ │ Max Drawdown: -$345.00 │ │ -$200 ░░░ 2 │ │
│ │ (-3.45%) │ │ │ │
│ │ │ └──────────────────────────────────┘ │
│ │ Sharpe Ratio: 1.85 │ │
│ │ Recovery Factor: 3.58 │ ┌──────────────────────────────────┐ │
│ └──────────────────────────┘ │ BY SYMBOL │ │
│ ├──────────────────────────────────┤ │
│ │ BTCUSDT 15 trades +$567.89 │ │
│ │ ETHUSDT 20 trades +$456.12 │ │
│ │ SOLUSDT 10 trades +$210.55 │ │
│ └──────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
```
---
## Criterios de Aceptación
**Escenario 1: Ver dashboard de estadísticas**
```gherkin
DADO que el usuario ha completado 45 trades
CUANDO accede a "Statistics"
ENTONCES se muestra dashboard con:
- Win rate con barra de progreso
- Profit factor con indicador
- Net P&L con porcentaje
- Total de trades (wins/losses)
Y todos los valores corresponden al periodo seleccionado
```
**Escenario 2: Ver equity curve**
```gherkin
DADO que el usuario selecciona "Last 30 days"
CUANDO el dashboard carga
ENTONCES se muestra gráfico de línea con equity curve
Y el eje X muestra fechas
Y el eje Y muestra balance
Y el punto inicial es $10,000
Y el punto actual refleja el balance actual
Y se resaltan periodos de drawdown en rojo
```
**Escenario 3: Ver métricas de performance**
```gherkin
DADO que el usuario está en Statistics
ENTONCES se muestran métricas calculadas:
- Average Win: Promedio de trades ganadores
- Average Loss: Promedio de trades perdedores
- Largest Win: Mayor ganancia en un trade
- Largest Loss: Mayor pérdida en un trade
- Avg Duration: Duración promedio de trades
- Max Drawdown: Mayor caída desde peak
- Sharpe Ratio: Ratio riesgo/retorno
- Recovery Factor: NetPnL / MaxDrawdown
```
**Escenario 4: Ver distribución de P&L**
```gherkin
DADO que el usuario tiene trades con diferentes P&L
CUANDO ve el histograma de distribución
ENTONCES muestra barras agrupadas por rangos de P&L
Y cada barra indica cantidad de trades en ese rango
Y la altura de la barra es proporcional a la cantidad
```
**Escenario 5: Filtrar por periodo**
```gherkin
DADO que el usuario está en Statistics
CUANDO selecciona "Last 7 days"
ENTONCES todas las métricas se recalculan
Y el equity curve muestra solo últimos 7 días
Y la distribución P&L se actualiza
```
**Escenario 6: Ver estadísticas por símbolo**
```gherkin
DADO que el usuario tradea múltiples símbolos
CUANDO ve la sección "By Symbol"
ENTONCES muestra lista de símbolos con:
- Cantidad de trades
- P&L total del símbolo
- Win rate del símbolo
Y están ordenados por P&L descendente
```
## Criterios Adicionales
- [ ] Comparación con periodo anterior
- [ ] Indicadores de mejora/empeoración con flechas
- [ ] Exportar reporte en PDF
- [ ] Gráficos de trades por día de semana
- [ ] Análisis de mejor/peor hora del día
---
## Tareas Técnicas
**Database:**
- [ ] DB-TRD-017: Crear tabla trading.daily_snapshots (balance diario)
- [ ] DB-TRD-018: Crear funciones de cálculo de métricas
**Backend:**
- [ ] BE-TRD-056: Crear endpoint GET /trading/paper/statistics
- [ ] BE-TRD-057: Implementar StatisticsService.calculateMetrics()
- [ ] BE-TRD-058: Implementar cálculo de win rate
- [ ] BE-TRD-059: Implementar cálculo de profit factor
- [ ] BE-TRD-060: Implementar cálculo de drawdown
- [ ] BE-TRD-061: Implementar cálculo de Sharpe ratio
- [ ] BE-TRD-062: Crear endpoint GET /trading/paper/statistics/equity-curve
- [ ] BE-TRD-063: Implementar cálculo por símbolo
**Frontend:**
- [ ] FE-TRD-057: Crear componente StatisticsPanel.tsx
- [ ] FE-TRD-058: Crear componente MetricCard.tsx
- [ ] FE-TRD-059: Crear componente EquityCurveChart.tsx (Recharts)
- [ ] FE-TRD-060: Crear componente PnLDistribution.tsx
- [ ] FE-TRD-061: Crear componente SymbolBreakdown.tsx
- [ ] FE-TRD-062: Implementar hook useStatistics
- [ ] FE-TRD-063: Implementar selector de periodo
**Tests:**
- [ ] TEST-TRD-028: Test unitario cálculos de métricas
- [ ] TEST-TRD-029: Test integración endpoint statistics
- [ ] TEST-TRD-030: Test E2E dashboard completo
---
## Dependencias
**Depende de:**
- [ ] US-TRD-010: Ver historial - Estado: Pendiente (necesita datos de trades)
**Bloquea:**
- Ninguna
---
## Notas Técnicas
**Endpoints involucrados:**
| Método | Endpoint | Descripción |
|--------|----------|-------------|
| GET | /trading/paper/statistics | Métricas generales |
| GET | /trading/paper/statistics/equity-curve | Datos equity curve |
| GET | /trading/paper/statistics/by-symbol | Breakdown por símbolo |
| GET | /trading/paper/statistics/distribution | Distribución P&L |
**Entidades/Tablas:**
```sql
CREATE TABLE trading.daily_snapshots (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES auth.users(id),
date DATE NOT NULL,
balance DECIMAL(20, 8) NOT NULL,
equity DECIMAL(20, 8) NOT NULL,
total_pnl DECIMAL(20, 8) NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
CONSTRAINT unique_user_date UNIQUE(user_id, date)
);
CREATE INDEX idx_daily_snapshots_user_date
ON trading.daily_snapshots(user_id, date DESC);
```
**Componentes UI:**
- `StatisticsPanel`: Panel principal
- `MetricCard`: Card de métrica individual
- `EquityCurveChart`: Gráfico de equity
- `PnLDistribution`: Histograma de P&L
- `SymbolBreakdown`: Tabla por símbolo
- `PeriodSelector`: Selector de periodo
**Response (Statistics):**
```typescript
{
period: {
from: "2025-11-05",
to: "2025-12-05"
},
overview: {
totalTrades: 45,
wins: 27,
losses: 18,
winRate: 60.0,
profitFactor: 2.45,
netPnl: 1234.56,
netPnlPercentage: 12.35
},
performance: {
averageWin: 45.72,
averageLoss: -25.38,
largestWin: 150.00,
largestLoss: -80.00,
averageDuration: 15600, // segundos
maxDrawdown: -345.00,
maxDrawdownPercentage: -3.45,
sharpeRatio: 1.85,
recoveryFactor: 3.58
},
bySymbol: [
{
symbol: "BTCUSDT",
trades: 15,
wins: 10,
losses: 5,
winRate: 66.67,
netPnl: 567.89
},
// ... más símbolos
]
}
```
**Response (Equity Curve):**
```typescript
{
data: [
{
date: "2025-11-05",
balance: 10000.00,
equity: 10000.00,
drawdown: 0.00
},
{
date: "2025-11-06",
balance: 10050.00,
equity: 10075.50,
drawdown: 0.00
},
// ... más puntos
]
}
```
**Response (Distribution):**
```typescript
{
ranges: [
{ min: -200, max: -100, count: 2 },
{ min: -100, max: -50, count: 3 },
{ min: -50, max: 0, count: 6 },
{ min: 0, max: 50, count: 4 },
{ min: 50, max: 100, count: 12 },
{ min: 100, max: 200, count: 8 },
{ min: 200, max: Infinity, count: 3 }
]
}
```
**Fórmulas de cálculo:**
```typescript
// Win Rate
const winRate = (wins / totalTrades) * 100;
// Profit Factor
const profitFactor = grossProfit / Math.abs(grossLoss);
// Sharpe Ratio (anualizado)
const returns = trades.map(t => t.pnlPercentage);
const avgReturn = mean(returns);
const stdDev = standardDeviation(returns);
const sharpeRatio = (avgReturn / stdDev) * Math.sqrt(252); // 252 trading days
// Maximum Drawdown
let peak = initialBalance;
let maxDD = 0;
equityCurve.forEach(point => {
if (point.equity > peak) peak = point.equity;
const drawdown = peak - point.equity;
if (drawdown > maxDD) maxDD = drawdown;
});
const maxDrawdownPercentage = (maxDD / peak) * 100;
// Recovery Factor
const recoveryFactor = netPnl / Math.abs(maxDrawdown);
// Average Duration (en segundos)
const avgDuration = sum(trades.map(t => t.durationSeconds)) / totalTrades;
```
**Periodos disponibles:**
- Last 7 days
- Last 30 days
- Last 90 days
- Year to date
- All time
- Custom range
---
## Definition of Ready (DoR)
- [x] Historia claramente escrita
- [x] Criterios de aceptación definidos
- [x] Story points estimados
- [x] Dependencias identificadas
- [x] Sin bloqueadores
- [ ] Diseño/mockup disponible
- [ ] API spec disponible
## Definition of Done (DoD)
- [ ] Código implementado según criterios
- [ ] Tests unitarios escritos y pasando
- [ ] Tests de integración pasando
- [ ] Code review aprobado
- [ ] Documentación actualizada
- [ ] QA aprobado
- [ ] Desplegado en ambiente de pruebas
---
## 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