forked from OPCODE-Open-Spring-Fest/QuantResearch
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbenchmark_factors.py
More file actions
67 lines (52 loc) · 1.69 KB
/
benchmark_factors.py
File metadata and controls
67 lines (52 loc) · 1.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
"""
Benchmark script to compare performance of factor computations.
Usage:
python examples/benchmarks/benchmark_factors.py
"""
import time
import numpy as np
import pandas as pd
from quant_research_starter.factors import (
BollingerBandsFactor,
IdiosyncraticVolatility,
MomentumFactor,
SizeFactor,
ValueFactor,
VolatilityFactor,
)
def generate_synthetic_prices(
n_assets: int = 500, n_days: int = 252 * 3
) -> pd.DataFrame:
"""Generate synthetic random walk price data for testing."""
np.random.seed(42)
returns = np.random.normal(0, 0.01, size=(n_days, n_assets))
prices = 100 * np.exp(np.cumsum(returns, axis=0))
dates = pd.date_range(end=pd.Timestamp.today(), periods=n_days, freq="B")
tickers = [f"Stock_{i:03d}" for i in range(n_assets)]
return pd.DataFrame(prices, index=dates, columns=tickers)
def benchmark_factor(factor, prices: pd.DataFrame):
"""Benchmark runtime of a given factor."""
start = time.time()
_ = factor.compute(prices)
end = time.time()
elapsed = end - start
print(
f"{factor.name:<25} | Lookback: {factor.lookback:<5} | Time: {elapsed:.3f} sec"
)
def main():
print("Generating synthetic data...")
prices = generate_synthetic_prices(n_assets=500, n_days=252 * 3)
print(f"Data shape: {prices.shape}")
print("\nRunning factor benchmarks...\n")
factors = [
MomentumFactor(lookback=63),
ValueFactor(),
SizeFactor(),
VolatilityFactor(lookback=21),
IdiosyncraticVolatility(lookback=63),
BollingerBandsFactor(lookback=20),
]
for factor in factors:
benchmark_factor(factor, prices)
if __name__ == "__main__":
main()