Skip to content

Commit 8e8d5f5

Browse files
committed
add volatility metrics
1 parent 004673f commit 8e8d5f5

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"""
2+
Volatility is a statistical measure of the dispersion of returns for a
3+
given portfolio. In finance, it is commonly used as a proxy for risk.
4+
This function calculates the standard deviation of daily log returns and
5+
annualizes it, giving an estimate of how much the portfolio's value
6+
fluctuates on a yearly basis.
7+
"""
8+
9+
import pandas as pd
10+
import numpy as np
11+
from investing_algorithm_framework import BacktestReport
12+
13+
14+
def get_volatility(backtest_report: BacktestReport) -> float:
15+
"""
16+
Calculate the annualized volatility of portfolio net values.
17+
18+
Args:
19+
backtest_report: BacktestReport object with snapshots and
20+
number_of_days
21+
22+
Returns:
23+
Float: Annualized volatility as a float
24+
"""
25+
snapshots = backtest_report.get_snapshots()
26+
27+
if len(snapshots) < 2:
28+
return 0.0 # Not enough data to calculate volatility
29+
30+
# Build DataFrame from snapshots
31+
records = [
32+
(snapshot.total_value, snapshot.created_at) for snapshot in snapshots
33+
]
34+
df = pd.DataFrame(records, columns=['total_value', 'created_at'])
35+
df['created_at'] = pd.to_datetime(df['created_at'])
36+
df = df.sort_values('created_at').drop_duplicates('created_at').copy()
37+
38+
# Calculate log returns
39+
df['log_return'] = np.log(df['total_value'] / df['total_value'].shift(1))
40+
df = df.dropna()
41+
42+
if df.empty:
43+
return 0.0
44+
45+
daily_volatility = df['log_return'].std()
46+
47+
# Estimate trading days per year based on snapshot frequency
48+
total_days = backtest_report.number_of_days
49+
num_observations = len(df)
50+
51+
if total_days > 0:
52+
trading_days_per_year = (num_observations / total_days) * 365
53+
else:
54+
trading_days_per_year = 252 # Default fallback
55+
56+
return daily_volatility * np.sqrt(trading_days_per_year)

tests/metrics/test_volatility.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
# Mock snapshot class
99
class Snapshot:
10-
def __init__(self, net_size, created_at):
11-
self.net_size = net_size
10+
def __init__(self, total_value, created_at):
11+
self.total_value = total_value
1212
self.created_at = created_at
1313

1414
class TestGetVolatility(unittest.TestCase):

0 commit comments

Comments
 (0)