
Risk & Control
risk-metrics-calculation
The Risk Metrics Calculation skill provides a comprehensive toolkit for measuring and managing portfolio risk, offering essential metrics such as Value at Risk (VaR), Conditional Value at Risk (CVaR), and drawdown analysis.
Resumen
The Risk Metrics Calculation skill provides a comprehensive toolkit for measuring and managing portfolio risk, offering essential metrics such as Value at Risk (VaR), Conditional Value at Risk (CVaR), and drawdown analysis.
The Risk Metrics Calculation skill provides a comprehensive toolkit for measuring and managing portfolio risk, offering essential metrics such as Value at Risk (VaR), Conditional Value at Risk (CVaR), and drawdown analysis. This skill is invaluable for portfolio managers aiming to assess risk exposure, implement risk limits, and optimize investment strategies. It supports various use cases, including regulatory reporting, constructing risk dashboards, and calculating risk-adjusted returns based on different time horizons, from intraday to annual evaluations. By utilizing this skill, users can enhance their decision-making process, ensuring effective risk management and capital preservation.
Skill.md
Cómo funciona esta Skill
The Risk Metrics Calculation skill provides a comprehensive toolkit for measuring and managing portfolio risk, offering essential metrics such as Value at Risk (VaR), Conditional Value at Risk (CVaR), and drawdown analysis.
Risk Metrics Calculation
Comprehensive risk measurement toolkit for portfolio management, including Value at Risk, Expected Shortfall, and drawdown analysis.
When to Use This Skill
- Measuring portfolio risk
- Implementing risk limits
- Building risk dashboards
- Calculating risk-adjusted returns
- Setting position sizes
- Regulatory reporting
Core Concepts
1. Risk Metric Categories
| Category | Metrics | Use Case |
|---|---|---|
| Volatility | Std Dev, Beta | General risk |
| Tail Risk | VaR, CVaR | Extreme losses |
| Drawdown | Max DD, Calmar | Capital preservation |
| Risk-Adjusted | Sharpe, Sortino | Performance |
2. Time Horizons
Intraday: Minute/hourly VaR for day traders
Daily: Standard risk reporting
Weekly: Rebalancing decisions
Monthly: Performance attribution
Annual: Strategic allocation
Implementation
Pattern 1: Core Risk Metrics
import numpy as np
import pandas as pd
from scipy import stats
from typing import Dict, Optional, Tuple
class RiskMetrics:
"""Core risk metric calculations."""
def __init__(self, returns: pd.Series, rf_rate: float = 0.02):
"""
Args:
returns: Series of periodic returns
rf_rate: Annual risk-free rate
"""
self.returns = returns
self.rf_rate = rf_rate
self.ann_factor = 252 # Trading days per year
# Volatility Metrics
def volatility(self, annualized: bool = True) -> float:
"""Standard deviation of returns."""
vol = self.returns.std()
if annualized:
vol *= np.sqrt(self.ann_factor)
return vol
def downside_deviation(self, threshold: float = 0, annualized: bool = True) -> float:
"""Standard deviation of returns below threshold."""
downside = self.returns[self.returns < threshold]
if len(downside) == 0:
return 0.0
dd = downside.std()
if annualized:
dd *= np.sqrt(self.ann_factor)
return dd
def beta(self, market_returns: pd.Series) -> float:
"""Beta relative to market."""
aligned = pd.concat([self.returns, market_returns], axis=1).dropna()
if len(aligned) < 2:
return np.nan
cov = np.cov(aligned.iloc[:, 0], aligned.iloc[:, 1])
return cov[0, 1] / cov[1, 1] if cov[1, 1] != 0 else 0
# Value at Risk
def var_historical(self, confidence: float = 0.95) -> float:
"""Historical VaR at confidence level."""
return -np.percentile(self.returns, (1 - confidence) * 100)
def var_parametric(self, confidence: float = 0.95) -> float:
"""Parametric VaR assuming normal distribution."""
z_score = stats.norm.ppf(confidence)
return self.returns.mean() - z_score * self.returns.std()
def var_cornish_fisher(self, confidence: float = 0.95) -> float:
"""VaR with Cornish-Fisher expansion for non-normality."""
z = stats.norm.ppf(confidence)
s = stats.skew(self.returns) # Skewness
k = stats.kurtosis(self.returns) # Excess kurtosis
# Cornish-Fisher expansion
z_cf = (z + (z**2 - 1) * s / 6 +
(z**3 - 3*z) * k / 24 -
(2*z**3 - 5*z) * s**2 / 36)
return -(self.returns.mean() + z_cf * self.returns.std())
# Conditional VaR (Expected Shortfall)
def cvar(self, confidence: float = 0.95) -> float:
"""Expected Shortfall / CVaR / Average VaR."""
var = self.var_historical(confidence)
return -self.returns[self.returns <= -var].mean()
# Drawdown Analysis
def drawdowns(self) -> pd.Series:
"""Calculate drawdown series."""
cumulative = (1 + self.returns).cumprod()
running_max = cumulative.cummax()
return (cumulative - running_max) / running_max
def max_drawdown(self) -> float:
"""Maximum drawdown."""
return self.drawdowns().min()
def avg_drawdown(self) -> float:
"""Average drawdown."""
dd = self.drawdowns()
return dd[dd < 0].mean() if (dd < 0).any() else 0
def drawdown_duration(self) -> Dict[str, int]:
"""Drawdown duration statistics."""
dd = self.drawdowns()
in_drawdown = dd < 0
# Find drawdown periods
drawdown_starts = in_drawdown & ~in_drawdown.shift(1).fillna(False)
drawdown_ends = ~in_drawdown & in_drawdown.shift(1).fillna(False)
durations = []
current_duration = 0
for i in range(len(dd)):
if in_drawdown.iloc[i]:
current_duration += 1
elif current_duration > 0:
durations.append(current_duration)
current_duration = 0
if current_duration > 0:
durations.append(current_duration)
return {
"max_duration": max(durations) if durations else 0,
"avg_duration": np.mean(durations) if durations else 0,
"current_duration": current_duration
}
# Risk-Adjusted Returns
def sharpe_ratio(self) -> float:
"""Annualized Sharpe ratio."""
excess_return = self.returns.mean() * self.ann_factor - self.rf_rate
vol = self.volatility(annualized=True)
return excess_return / vol if vol > 0 else 0
def sortino_ratio(self) -> float:
"""Sortino ratio using downside deviation."""
excess_return = self.returns.mean() * self.ann_factor - self.rf_rate
dd = self.downside_deviation(threshold=0, annualized=True)
return excess_return / dd if dd > 0 else 0
def calmar_ratio(self) -> float:
"""Calmar ratio (return / max drawdown)."""
annual_return = (1 + self.returns).prod() ** (self.ann_factor / len(self.returns)) - 1
max_dd = abs(self.max_drawdown())
return annual_return / max_dd if max_dd > 0 else 0
def omega_ratio(self, threshold: float = 0) -> float:
"""Omega ratio."""
returns_above = self.returns[self.returns > threshold] - threshold
returns_below = threshold - self.returns[self.returns <= threshold]
if returns_below.sum() == 0:
return np.inf
return returns_above.sum() / returns_below.sum()
# Information Ratio
def information_ratio(self, benchmark_returns: pd.Series) -> float:
"""Information ratio vs benchmark."""
active_returns = self.returns - benchmark_returns
tracking_error = active_returns.std() * np.sqrt(self.ann_factor)
active_return = active_returns.mean() * self.ann_factor
return active_return / tracking_error if tracking_error > 0 else 0
# Summary
def summary(self) -> Dict[str, float]:
"""Generate comprehensive risk summary."""
dd_stats = self.drawdown_duration()
return {
# Returns
"total_return": (1 + self.returns).prod() - 1,
"annual_return": (1 + self.returns).prod() ** (self.ann_factor / len(self.returns)) - 1,
# Volatility
"annual_volatility": self.volatility(),
"downside_deviation": self.downside_deviation(),
# VaR & CVaR
"var_95_historical": self.var_historical(0.95),
"var_99_historical": self.var_historical(0.99),
"cvar_95": self.cvar(0.95),
# Drawdowns
"max_drawdown": self.max_drawdown(),
"avg_drawdown": self.avg_drawdown(),
"max_drawdown_duration": dd_stats["max_duration"],
# Risk-Adjusted
"sharpe_ratio": self.sharpe_ratio(),
"sortino_ratio": self.sortino_ratio(),
"calmar_ratio": self.calmar_ratio(),
"omega_ratio": self.omega_ratio(),
Ideal para
Cuándo usarla
The Risk Metrics Calculation skill provides a comprehensive toolkit for measuring and managing portfolio risk, offering essential metrics such as Value at Risk (VaR), Conditional Value at Risk (CVaR), and drawdown analysis.

01 · ANTES DE LA REUNIÓN
Prepara un informe de decisión
Convierte evidencia dispersa en un caso estructurado antes del comité de inversión.

02 · FLUJO DE EQUIPO
Estandariza los traspasos
Genera resultados de research consistentes entre analistas, gestores de cartera y agents.

03 · ACTUALIZACIÓN EN VIVO
Refresca la tesis
Actualiza los escenarios tras un nuevo catalizador, la publicación de un KPI o un resultado trimestral.
Notas de la comunidad
Mejora a medida que se usa.
Los comentarios aparecerán aquí a medida que esta Skill se use y se revise.
Descubre más
Skills relacionadas
Ver todasStock Compensation Economic Cost
Treat stock-based compensation as a real economic cost, benchmark dilution, and assess the impact on cash flow, ownership, and true profitability. Use when evaluating software or growth companies…
Capitalization Policy Consistency
Compare capitalization policy against accounting norms and peer practice to expose aggressive capitalization, expense deferral, or earnings smoothing. Use when analyzing software, R&D, content, or…
Goodwill Impairment Risk Indicators
Assess goodwill impairment risk using acquisition history, segment underperformance, valuation compression, and accounting warning signs. Use when evaluating acquisitive companies or balance sheets…