quant-statistics
This Claude Code skill provides quantitative statistical methods for algorithmic trading, including ADF unit-root tests to check time-series stationarity, cointegration tests for identifying mean-reverting pairs, GARCH models for volatility forecasting, regression diagnostics for heteroskedasticity and autocorrelation detection, bootstrap resampling for confidence intervals, and hypothesis testing frameworks. Use this when developing quantitative strategies, conducting factor research, validating trading signals, or ensuring statistical validity before backtesting regression-based models.
git clone --depth 1 https://github.com/HKUDS/Vibe-Trading /tmp/quant-statistics && cp -r /tmp/quant-statistics/agent/src/skills/quant-statistics ~/.claude/skills/quant-statisticsSKILL.md
# Quantitative Statistical Methods
## Overview
Common statistical methodology used in quantitative investing, covering time-series testing, volatility modeling, regression diagnostics, and statistical inference. Provides the statistical foundation for strategy development and factor research.
## Implementation
Every test below is already implemented and unit-tested in `src.quantlib.timeseries`. **Import and call it — do not retype these formulas into throwaway code**, which is how sign errors and double-sqrt bugs get into results.
```python
from src.quantlib.timeseries import (
adf_test, cointegration_test, find_hedge_ratio, compute_half_life,
granger_test, fit_garch, heteroscedasticity_test, autocorrelation_test,
vif_test, bootstrap_statistic, bootstrap_sharpe,
)
```
**Optional backends**: `statsmodels` powers everything except the two bootstrap helpers (which are pure numpy); `arch` powers `fit_garch` only. Neither is declared as a dependency of `vibe-trading-ai`, so both are imported lazily inside the functions. Importing the module always works; calling a function whose backend is missing raises an `ImportError` naming the package and the install command (`pip install "statsmodels>=0.14"` / `pip install "arch>=6.0"`). If you hit that error, report it to the user rather than silently substituting a different method.
## Time-Series Tests
### 1. ADF Unit-Root Test (Stationarity Test)
**Why it matters**: regressing non-stationary series directly can produce spurious regression, making conclusions unreliable.
```python
from src.quantlib.timeseries import adf_test
result = adf_test(prices['close'], significance=0.05)
# {'adf_statistic': -1.23, 'p_value': 0.65, 'lags_used': 4,
# 'is_stationary': False,
# 'critical_values': {'1%': -3.44, '5%': -2.87, '10%': -2.57}}
if not result['is_stationary']:
returns = np.log(prices['close']).diff().dropna()
adf_test(returns) # log returns are normally stationary
```
**Decision rules**:
| p-value | Conclusion | Action |
|-----|------|------|
| < 0.01 | Strongly stationary | Can be used directly for regression / modeling |
| 0.01-0.05 | Stationary | Usable |
| 0.05-0.10 | Weak evidence | Difference the series and retest |
| > 0.10 | Non-stationary | Must difference or handle with cointegration |
**Stationarity of common financial series**:
| Series | Typical Result | Treatment |
|------|---------|---------|
| Price series | Non-stationary (unit root) | Use log returns |
| Log returns | Stationary | Can be used directly |
| PE / PB series | Usually non-stationary | Use changes or logs |
| Volatility series | Usually stationary | Can be used directly |
| Volume | May be non-stationary | Use logs or standardization |
### 2. Cointegration Test
**Purpose**: determine whether two non-stationary series share a long-run equilibrium relationship (the foundation of pair trading / statistical arbitrage).
```python
from src.quantlib.timeseries import cointegration_test
result = cointegration_test(prices_a, prices_b, significance=0.05)
# {'test_statistic': -4.52, 'p_value': 0.002, 'is_cointegrated': True,
# 'critical_values': {'1%': -3.90, '5%': -3.34, '10%': -3.05}}
```
Both legs must be individually non-stationary (check with `adf_test` first) — cointegration on two already-stationary series is meaningless.
Both legs must also share one index. Two same-length series on *different* indices raise `ValueError` rather than being zipped positionally, because a positional join of, say, an A-share calendar against a US one reports cointegration between days that never coexisted. Reindex or inner-join the two legs yourself before calling.
**Application in pair trading**:
```python
from src.quantlib.timeseries import find_hedge_ratio, compute_half_life
result = find_hedge_ratio(prices_a, prices_b)
# {'hedge_ratio': 2.49, 'intercept': 0.40,
# 'spread_mean': 0.40, 'spread_std': 1.73, 'half_life': 16.7}
spread = prices_a - result['hedge_ratio'] * prices_b
z_score = (spread - result['spread_mean']) / result['spread_std']
# half_life is in observation periods (days for daily bars) and is `inf`
# when the spread does not mean-revert. Sanity-check it before trading:
# a half-life longer than your holding horizon means the spread will not
# close in time, however good the cointegration p-value looks.
compute_half_life(spread)
```
A perfectly flat leg (a name halted for the whole window) makes the regression
degenerate, so `find_hedge_ratio` and `compute_half_life` raise `ValueError`
rather than return a meaningless β. Treat that as "this pair has no usable data
in this window", not as something to work around.
**Pair-trading signal**:
```
z_score = (spread - mean) / std
| z_score | Signal |
|---------|------|
| > 2.0 | Short spread (sell y, buy x) |
| > 1.5 | Small short spread |
| < -1.5 | Small long spread |
| < -2.0 | Long spread (buy y, sell x) |
| Back near 0 | Close position |
```
### 3. Granger Causality Test
```python
from src.quantlib.timeseries import granger_test
p_by_lag = granger_test(df, x_col='volume', y_col='return', max_lag=5)
# {1: 0.003, 2: 0.011, 3: 0.08, 4: 0.21, 5: 0.33}
# small p at lag k -> past x at that lag helps predict y
```
Granger causality is **predictive, not structural**: it says past `x` improves the forecast of `y`, never that `x` causes `y`. A common confounder is that both respond to a third variable. Note also that testing 5 lags is 5 hypothesis tests — one small p-value among them is weak evidence.
## GARCH Volatility Modeling
### GARCH(1,1) Model
```
Returns: r_t = μ + ε_t
Volatility: σ²_t = ω + α×ε²_{t-1} + β×σ²_{t-1}
Parameter meanings:
- ω (omega): long-run variance baseline
- α (alpha): impact of yesterday's shock on today's volatility
- β (beta): persistence of yesterday's volatility into today
- α + β: volatility persistence (usually 0.95-0.99)
- Long-run volatility = sqrt(ω / (1 - α - β))
```
```python
from src.quantlib.timeseries import fit_garch
# `returns` are FRACTIOProfessional finance research toolkit — backtesting (10 engines + benchmark comparison panel), factor analysis, Alpha Zoo (462 pre-built alphas across qlib158/alpha101/gtja191/academic/fundamental), options pricing, 90 finance skills, 30 multi-agent swarm teams, Trade Journal analyzer, and Shadow Account (extract → backtest → render) across 25 market-data sources (tushare, yfinance, okx, binance, akshare, baostock, tencent, mootdx, ccxt, futu, mt5, tickerall, local, eastmoney, sina, stooq, yahoo, pykrx, india_broker, qveris, longbridge, plus optional-key finnhub/alphavantage/tiingo/fmp).
ADR/H-share/A-share cross-listing premium analysis — track pricing gaps between US-listed ADRs, HK-listed H-shares, and A-shares for arbitrage signals, dual-listing valuation, and delisting risk assessment.
AKShare financial data aggregator (18k+ stars). Free, no API key. Covers A-shares, US, HK, futures, macro, forex. Primary fallback for tushare and yfinance.
Browse and bench the bundled alpha zoos — prebuilt cross-sectional factor libraries (Kakushadze 101, GTJA 191, Qlib 158, Fama-French / Carhart). Use when the user asks "which alphas exist", wants metadata on a named alpha, or wants to run IC/IR on a whole zoo over a universe.
A 股 ST/*ST 风险预测框架 — 基于最新中报/三季报或业绩预告/快报,预测下一财年是否会因营收、利润、净资产、分红不达标而被风险警示,并将新浪监管处罚记录作为独立证据面纳入风险等级。仅适用于 A 股,不预测财务造假。
Asset allocation theory and optimizer usage — MPT / Black-Litterman / risk budgeting / all-weather strategy, including guides for 5 optimizers and rebalancing rules.
Diagnose failed or underperforming backtests, locate the root cause, and fix the issue
Behavioral finance applications: theories of overreaction and underreaction, behavioral explanations for momentum and reversal, investor sentiment cycles, cognitive-bias checklists, and debiasing quantitative strategies.