Diebold-Yilmaz (2012) connectedness — generalized FEVD + total/directional/net spillover indices. Pure numpy+scipy.
Project description
diebold-yilmaz
Diebold-Yilmaz (2012) connectedness via generalized forecast-error variance decomposition. Pure numpy + scipy, no C++ deps.
What and why
statsmodels provides VAR fitting and a FEVD method — but only the Cholesky-orthogonalized FEVD, which depends on the (arbitrary) ordering of your variables. The Diebold-Yilmaz (2012, 2014) connectedness framework requires the generalized FEVD of Pesaran & Shin (1998), which is invariant to reordering. This library fills that gap.
Given VAR-MA coefficients Ψ and residual covariance Σ, it produces:
- the full connectedness table
C(row-normalized N × N percent matrix) - the Total Spillover Index
S = mean of off-diagonal C × 100 % - per-variable directional spillovers:
from_others,to_others,net = to − from - the net pairwise matrix
C − Cᵀ
…all in one call.
Install
pip install diebold-yilmaz
Python ≥ 3.9, numpy ≥ 1.23, scipy ≥ 1.10. statsmodels is optional (only needed if you use the fit_var convenience).
Quickstart
import numpy as np
from diebold_yilmaz import connectedness, ma_coefficients
# VAR(1) with variable 0 shocking 1 and 2
A1 = np.array(
[[0.20, 0.00, 0.00],
[0.50, 0.20, 0.00],
[0.40, 0.00, 0.20]]
)
sigma = np.eye(3)
psi = ma_coefficients([A1], horizon=12)
result = connectedness(psi, sigma, variable_names=["SENDER", "RECV_1", "RECV_2"])
print(f"Total spillover index: {result.total_index:.2f}%")
print(f"Net per variable: {dict(zip(result.variable_names, result.net.round(2)))}")
# Total spillover index: 12.43%
# Net per variable: {'SENDER': 37.3, 'RECV_1': -22.0, 'RECV_2': -15.29}
With statsmodels (optional)
pip install diebold-yilmaz[statsmodels]
from diebold_yilmaz import fit_var, connectedness
psi, sigma, p_used = fit_var(returns_TN, p=None, ic="aic", horizon=10)
result = connectedness(psi, sigma)
If you already have VAR outputs (from R, custom code, or statsmodels.tsa.vector_ar.var_model.VARResults.ma_rep), feed them directly to connectedness — statsmodels is never imported unless you call fit_var.
The math (1-minute version)
Start with a stable VAR(p): y_t = Σ_k A_k y_{t−k} + ε_t, ε ~ N(0, Σ). Its moving-average form is
y_t = Σ_h Ψ_h ε_{t−h}, Ψ_0 = I, Ψ_h = Σ_{j=1..min(h,p)} A_j Ψ_{h−j}
Pesaran-Shin (1998) generalized FEVD at horizon H:
θ^g_{ij}(H) = σ_{jj}^{−1} · Σ_{h=0..H−1} (e_i' Ψ_h Σ e_j)²
/ Σ_{h=0..H−1} (e_i' Ψ_h Σ Ψ_h' e_i)
This is invariant to the ordering of the variables — unlike the Cholesky FEVD — because it uses generalized impulse responses instead of orthogonalized ones. Row-normalize θ so rows sum to 1 and you get the Diebold-Yilmaz connectedness table.
From there: Total = mean off-diagonal; from_i = row_i off-diagonal sum; to_j = col_j off-diagonal sum; net = to − from.
Correctness
14 unit tests cover:
- Ψ_0 = I identity, hand-checked MA recursion on a 2-step VAR(2)
- Row-sums equal 1.0 after normalization
- All entries non-negative (FEVD invariant)
- Ordering invariance (the whole point of generalized FEVD): reorder variables, FEVD permutes accordingly
- Scale invariance: rescale a variable by diag(D), connectedness table is unchanged
- Antisymmetry of net pairwise:
C − Cᵀ = −(Cᵀ − C) - Total spillover index lies in [0, 100] %
- Degenerate case: diagonal VAR + diagonal Σ ⇒ zero spillover
- Sender/receiver case: hand-constructed lead-lag VAR produces correctly signed
net - Input validation: shape mismatches, non-positive
σ_{jj}, badhorizon
Roadmap
v0.2 (planned):
- Rolling-window connectedness helper (Diebold-Yilmaz 2014 style, for time-varying spillover series)
- Block-bootstrap confidence intervals on
total_indexandnet - Community-/cluster-level aggregation on
net_pairwise
Authors
- Pierre Samson (@darw007d) — idea, use-case, design decisions
- Claude Opus (Anthropic) — implementation and tests
Originally motivated by the OMEGA Swarm project, Phase 19 Tier B #7. Sister package to phawkes (Hawkes), fisherrao (information geometry), and tailcor (tail-contagion decomposition). Same "small, tested, publishable" pattern.
Citations
- Diebold, F.X. & Yilmaz, K. (2012). Better to give than to receive: Predictive directional measurement of volatility spillovers. Int. J. Forecasting 28(1), 57-66.
- Diebold, F.X. & Yilmaz, K. (2014). On the network topology of variance decompositions: Measuring the connectedness of financial firms. J. Econometrics 182(1), 119-134.
- Pesaran, M.H. & Shin, Y. (1998). Generalized impulse response analysis in linear multivariate models. Economics Letters 58(1), 17-29.
License
MIT — see LICENSE.
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 diebold_yilmaz-0.1.0.tar.gz.
File metadata
- Download URL: diebold_yilmaz-0.1.0.tar.gz
- Upload date:
- Size: 11.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e8e740c60059ecd86e7ebf3c3ebfedf7963b47576dc34244d847e880b5c8706
|
|
| MD5 |
571e9db1c886746fac561ab251a46871
|
|
| BLAKE2b-256 |
aa7a198a89a623851f4b49c5225aa652483859ed08ace9a7354f6957689142e7
|
File details
Details for the file diebold_yilmaz-0.1.0-py3-none-any.whl.
File metadata
- Download URL: diebold_yilmaz-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a5775b703b8e427b47b970b236e4fe2eba155c34fe92a9ab7fcc8055a6cef832
|
|
| MD5 |
76023e718b64eb8e4a895c459121d4ea
|
|
| BLAKE2b-256 |
1b9d87e6ae71195e260d668e9ebfef541fc0bd62f71b22fdf7b70882ba37d09b
|