A Python library for quantitative analysis of volatility patterns and regime dynamics.
Project description
SixEyes
A Python library for volatility estimation, regime analysis, and hidden state modeling in financial time series.
SixEyes is designed for quantitative teams and research groups that require transparent, modular, and production-aligned volatility forecasting infrastructure.
Modules
| Module | Status | Description |
|---|---|---|
Volatility |
Available | Rolling, EWMA, range-based, asymmetric, and vol-of-vol estimators |
RegimeModel |
In development | Regime-switching models for structural break detection |
Installation
pip install sixeyes
Setup & Testing
All examples below use S&P 500 daily OHLC data pulled from Yahoo Finance.
import yfinance as yf
import numpy as np
df = yf.download("^GSPC", start="2020-01-01", end="2024-12-31")
returns = np.log(df["Close"] / df["Close"].shift(1)).dropna()
Volatility
Rolling Standard Deviation
Close-to-close log return vol over a fixed 21-day window.
from Volatility.realized import RollingSTD
model = RollingSTD(window_size=21, days_per_annum=252, annualize=True)
vol = model.compute(returns)
EWMA
Same as rolling std but decays older observations — a spike in March weights less by April. RiskMetrics standard is alpha=0.94 for daily data.
from Volatility.realized import EWMA
model = EWMA(alpha=0.94, span=20, days_per_annum=252, annualize=True)
vol = model.compute(returns.values)
Parkinson
Replaces close-to-close returns with the daily high-low range — more efficient for FX or futures where overnight gaps are small.
from Volatility.range_based import Parkinson
model = Parkinson(window=21, annualize=True)
vol = model.compute(df["High"].values, df["Low"].values)
Garman-Klass
Uses all four OHLC prices — the most efficient classical daily estimator for equities where the open-close drift matters.
from Volatility.range_based import GarmanKlass
model = GarmanKlass(window=21, annualize=True)
vol = model.compute(
open_=df["Open"].values,
high=df["High"].values,
low=df["Low"].values,
close=df["Close"].values,
)
Downside Volatility
Computes vol using only negative return days — separates loss dispersion from gain dispersion, which rolling std conflates.
from Volatility.assymetric import DownSideVolatility
model = DownSideVolatility(window=21, annualize=True)
downside_vol = model.compute(returns.values)
# Sortino ratio
ann_return = returns.mean() * 252
sortino = (ann_return - 0.05) / downside_vol[-1]
Vol of Vol
Rolling standard deviation of a vol series — measures how much volatility is itself moving day to day.
from Volatility.vol_of_vol import VolOfVol
from Volatility.realized import EWMA
ewma_vol = EWMA(alpha=0.94, span=20, days_per_annum=252).compute(returns.values)
model = VolOfVol(window=21)
vov = model.compute(ewma_vol)
Forecasting and Evaluation
Each estimator's predict(horizon) shifts the vol series forward to produce a persistence forecast. evaluate() scores it against future realized vol using RMSE — useful for choosing the right estimator per instrument.
from Volatility.range_based import Parkinson, GarmanKlass
from Volatility.realized import EWMA
from Volatility.evaluation import evaluate
high, low = df["High"].values, df["Low"].values
r = returns.values
results = {
"Parkinson": evaluate(Parkinson(21, annualize=False), r, {"high": high, "low": low}, horizon=5),
"GarmanKlass": evaluate(GarmanKlass(21, annualize=False), r, {"open_": df["Open"].values, "high": high, "low": low, "close": df["Close"].values}, horizon=5),
"EWMA": evaluate(EWMA(0.94, 252, 20, annualize=False), r, {"returns": r}, horizon=5),
}
for name, rmse in results.items():
print(f"{name:12s} RMSE: {rmse:.6f}")
Putting It Together
import pandas as pd
import numpy as np
import yfinance as yf
from Volatility.realized import RollingSTD, EWMA
from Volatility.range_based import GarmanKlass
from Volatility.assymetric import DownSideVolatility
from Volatility.vol_of_vol import VolOfVol
df = yf.download("^GSPC", start="2020-01-01", end="2024-12-31")
returns = np.log(df["Close"] / df["Close"].shift(1)).dropna()
r = returns.values
ev = EWMA(alpha=0.94, span=20, days_per_annum=252).compute(r)
summary = pd.DataFrame({
"rolling": RollingSTD(21, 252).compute(returns),
"ewma": ev,
"gk": GarmanKlass(21).compute(df.Open.values, df.High.values, df.Low.values, df.Close.values),
"downside": DownSideVolatility(21, annualize=True).compute(r),
"vol_of_vol": VolOfVol(21).compute(ev),
}, index=returns.index)
print(summary.tail(3))
RegimeModel (coming soon)
The RegimeModel module will provide regime-switching models for identifying structural breaks and latent market states. Planned:
- Hidden Markov Model state estimation
- Regime-conditional vol and return statistics
- Transition probability matrices
- State sequence visualization
License
MIT License © Umer Farooq
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sixeyes-0.1.2.tar.gz.
File metadata
- Download URL: sixeyes-0.1.2.tar.gz
- Upload date:
- Size: 4.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
88cd22844fddb8d357f53848a95a99fff0816ff96912cbd11e5f07e792d9cb2d
|
|
| MD5 |
8741ea570115b9e9487cb9138d5c27bd
|
|
| BLAKE2b-256 |
98455170d3f539fbcec5d8282ea2378895c9bd92a9f02b12e55e91efdd20339e
|
File details
Details for the file sixeyes-0.1.2-py3-none-any.whl.
File metadata
- Download URL: sixeyes-0.1.2-py3-none-any.whl
- Upload date:
- Size: 4.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef8b7c654d488fb42e9c91a0b1e0bcfe34847d1dc0a21f1eae0771255c8f0741
|
|
| MD5 |
9eb3935c18e0a07b3c33c8112ef9ad80
|
|
| BLAKE2b-256 |
8d8e5ca327e88815426153c1b02ee143307476060342c80d5e35c86a6fb048c4
|