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>
126 lines
2.8 KiB
Markdown
126 lines
2.8 KiB
Markdown
---
|
|
id: "ET-PFM-002"
|
|
title: "Cálculo de Métricas de Portfolio"
|
|
type: "Technical Specification"
|
|
status: "Done"
|
|
priority: "Alta"
|
|
epic: "OQI-008"
|
|
project: "trading-platform"
|
|
version: "1.0.0"
|
|
created_date: "2025-12-05"
|
|
updated_date: "2026-01-04"
|
|
---
|
|
|
|
# ET-PFM-002: Cálculo de Métricas de Portfolio
|
|
|
|
**Épica:** OQI-008 - Portfolio Manager
|
|
**Versión:** 1.0
|
|
**Fecha:** 2025-12-05
|
|
**Estado:** Planificado
|
|
|
|
---
|
|
|
|
## Métricas Implementadas
|
|
|
|
### Métricas Básicas (Todos los planes)
|
|
- Total Value
|
|
- Total P&L
|
|
- Day P&L
|
|
- Position Weights
|
|
|
|
### Métricas de Riesgo (Pro/Premium)
|
|
- Volatilidad (std dev anualizada)
|
|
- Beta vs S&P 500
|
|
- Maximum Drawdown
|
|
- Value at Risk (VaR) 95%
|
|
|
|
### Métricas Avanzadas (Premium)
|
|
- Sharpe Ratio
|
|
- Sortino Ratio
|
|
- Information Ratio
|
|
- Calmar Ratio
|
|
- VaR 99%
|
|
|
|
---
|
|
|
|
## Fórmulas de Cálculo
|
|
|
|
```typescript
|
|
// src/modules/portfolio/services/metrics.service.ts
|
|
|
|
@Injectable()
|
|
export class MetricsService {
|
|
|
|
// Volatilidad anualizada
|
|
calculateVolatility(returns: number[]): number {
|
|
const mean = returns.reduce((a, b) => a + b, 0) / returns.length;
|
|
const variance = returns.reduce((sum, r) =>
|
|
sum + Math.pow(r - mean, 2), 0) / (returns.length - 1);
|
|
const stdDev = Math.sqrt(variance);
|
|
return stdDev * Math.sqrt(252); // Anualizar
|
|
}
|
|
|
|
// Sharpe Ratio
|
|
calculateSharpe(returns: number[], riskFreeRate = 0.05): number {
|
|
const annualReturn = this.calculateAnnualizedReturn(returns);
|
|
const volatility = this.calculateVolatility(returns);
|
|
return (annualReturn - riskFreeRate) / volatility;
|
|
}
|
|
|
|
// Value at Risk (método histórico)
|
|
calculateVaR(returns: number[], confidence = 0.95): number {
|
|
const sorted = [...returns].sort((a, b) => a - b);
|
|
const index = Math.floor((1 - confidence) * sorted.length);
|
|
return sorted[index];
|
|
}
|
|
|
|
// Maximum Drawdown
|
|
calculateMaxDrawdown(values: number[]): number {
|
|
let peak = values[0];
|
|
let maxDD = 0;
|
|
|
|
for (const value of values) {
|
|
if (value > peak) peak = value;
|
|
const drawdown = (peak - value) / peak;
|
|
if (drawdown > maxDD) maxDD = drawdown;
|
|
}
|
|
|
|
return maxDD;
|
|
}
|
|
|
|
// Beta vs Benchmark
|
|
calculateBeta(
|
|
portfolioReturns: number[],
|
|
benchmarkReturns: number[]
|
|
): number {
|
|
const covariance = this.calculateCovariance(
|
|
portfolioReturns,
|
|
benchmarkReturns
|
|
);
|
|
const benchmarkVariance = this.calculateVariance(benchmarkReturns);
|
|
return covariance / benchmarkVariance;
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Cache Strategy
|
|
|
|
| Métrica | TTL | Trigger Update |
|
|
|---------|-----|----------------|
|
|
| Básicas | 15s | Price change |
|
|
| Volatilidad | 1h | New trade |
|
|
| Sharpe/Sortino | 1d | End of day |
|
|
| VaR | 1h | New trade |
|
|
|
|
---
|
|
|
|
## Referencias
|
|
|
|
- [RF-PFM-002: Análisis de Riesgo](../requerimientos/RF-PFM-002-analisis-riesgo.md)
|
|
|
|
---
|
|
|
|
*Especificación técnica - Sistema NEXUS*
|