Skip to content

Risk Analytics

1. Calculation Name

Volatility, Tracking Error, Information Ratio, and Drawdown Summary

2. Description and Mathematical Formula

The risk plugin produces rolling risk statistics from periodic returns:

  • Portfolio volatility: \( \sigma_P = \mathrm{stdev}(r^P_t) \)
  • Tracking error: \( \mathrm{TE} = \mathrm{stdev}(r^P_t - r^B_t) \)
  • Information ratio: \( \mathrm{IR} = \frac{\overline{r^P_t - r^B_t}}{\mathrm{TE}} \)
  • Maximum drawdown: \( \min_t \left(\frac{V_t}{\max_{s \leq t} V_s} - 1\right) \) where \( V_t = \prod_{k \leq t} (1 + r^P_k) \)

3. Input Sample Data

Month Portfolio Return Benchmark Return Active Return
Jan 2.00% 1.80% 0.20%
Feb 1.50% 1.20% 0.30%
Mar -0.50% -0.60% 0.10%
Apr 1.20% 1.00% 0.20%
May 0.80% 0.70% 0.10%
Jun -1.00% -0.90% -0.10%

4. Mathematical Solution

  • Portfolio standard deviation: \( \sigma_P = 1.18\% \)
  • Tracking error: \( \mathrm{TE} = 0.14\% \)
  • Mean active return: \( \overline{r^P - r^B} = 0.13\% \)
  • Information ratio: \( \mathrm{IR} = 0.13\% / 0.14\% = 0.98 \)
  • Cumulative portfolio path: \( V_t = \prod (1 + r^P_t) \) peaks at 1.037 → max drawdown = -1.00%

5. Sample Python and R Code

import statistics
from functools import reduce

portfolio = [0.020, 0.015, -0.005, 0.012, 0.008, -0.010]
benchmark = [0.018, 0.012, -0.006, 0.010, 0.007, -0.009]
active = [p - b for p, b in zip(portfolio, benchmark)]

sigma_port = statistics.stdev(portfolio)
tracking_error = statistics.stdev(active)
info_ratio = (sum(active) / len(active)) / tracking_error

cum_values = []
value = 1.0
for r in portfolio:
    value *= (1 + r)
    cum_values.append(value)
peak = []
max_v = 0.0
for v in cum_values:
    max_v = max(max_v, v)
    peak.append(max_v)
drawdowns = [c / p - 1 for c, p in zip(cum_values, peak)]

print(f"Volatility: {sigma_port:.4%}")
print(f"Tracking error: {tracking_error:.4%}")
print(f"Information ratio: {info_ratio:.2f}")
print(f"Max drawdown: {min(drawdowns):.4%}")
portfolio <- c(0.020, 0.015, -0.005, 0.012, 0.008, -0.010)
benchmark <- c(0.018, 0.012, -0.006, 0.010, 0.007, -0.009)
active <- portfolio - benchmark

sigma_port <- sd(portfolio)
tracking_error <- sd(active)
info_ratio <- mean(active) / tracking_error

cum_values <- cumprod(1 + portfolio)
peak <- cummax(cum_values)
drawdowns <- cum_values / peak - 1

list(
  volatility = scales::percent(sigma_port, accuracy = 0.01),
  tracking_error = scales::percent(tracking_error, accuracy = 0.01),
  information_ratio = round(info_ratio, 2),
  max_drawdown = scales::percent(min(drawdowns), accuracy = 0.01)
)

6. Output Table

Metric Value
Portfolio Volatility (monthly) 1.18%
Tracking Error 0.14%
Information Ratio 0.98
Maximum Drawdown -1.00%

7. Conclusion

Use this template to explain how FinFacts calculates key risk statistics from simple return streams. It doubles as a regression harness for the risk plugin and as supporting material for investor factsheets.