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 sixeyes.Volatility import RollingSTD
model = RollingSTD(window_size=21, days_per_annum=252, annualize=True)
vol = model.compute(returns=returns)
forecast = model.predict(horizon=5, returns=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 sixeyes.Volatility import EWMA
model = EWMA(alpha=0.94, span=20, days_per_annum=252, annualize=True)
vol = model.compute(returns=returns.values)
forecast = model.predict(horizon=5, returns=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 sixeyes.Volatility import Parkinson
model = Parkinson(window=21, annualize=True)
vol = model.compute(high=df["High"].values, low=df["Low"].values)
forecast = model.predict(horizon=5, high=df["High"].values, low=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 sixeyes.Volatility 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,
)
forecast = model.predict(
horizon=5,
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 sixeyes.Volatility import DownSideVolatility
model = DownSideVolatility(window=21, annualize=True)
downside_vol = model.compute(returns.values)
forecast = model.predict(horizon=5, returns=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 sixeyes.Volatility import VolOfVol, EWMA
ewma_vol = EWMA(alpha=0.94, span=20, days_per_annum=252).compute(returns.values)
ewma_forecast = EWMA(alpha=0.94, span=20, days_per_annum=252).predict(horizon=5, returns=returns.values)
model = VolOfVol(window=21)
vov = model.compute(ewma_vol)
vov_forecast = model.predict(horizon=5, vol_series=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 sixeyes.Volatility import Parkinson, GarmanKlass, EWMA
from sixeyes.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 sixeyes.Volatility import RollingSTD, EWMA, GarmanKlass, DownSideVolatility, 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=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.2.0.tar.gz.
File metadata
- Download URL: sixeyes-0.2.0.tar.gz
- Upload date:
- Size: 7.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8daffaeda21fe70c016c5e8eb6adcd49c847038d9e55d3ebe51576a8d7f7a34a
|
|
| MD5 |
31ae04c17946567d1d513cc5cc5075ee
|
|
| BLAKE2b-256 |
946455ccb604ace33af7b6dd1fc559b380e104e61e333be520e6903000267d6f
|
File details
Details for the file sixeyes-0.2.0-py3-none-any.whl.
File metadata
- Download URL: sixeyes-0.2.0-py3-none-any.whl
- Upload date:
- Size: 7.4 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 |
2e40f6048d6b3133e079b85d6185567966870b9d550a959b48bf9a5829fc5a3e
|
|
| MD5 |
8d9b38e7a91981d704efd9ad3d5070ef
|
|
| BLAKE2b-256 |
86fb27834a2bd92ccd8d6fc531a45c2ea7279443e12dc554eab8a80ceb778174
|