SpilloverResult#
- class cultivars.multivariate.large_dim.spillover.SpilloverResult(*, names, horizon, table, total, to_others, from_others, net, net_pairwise)[source]
Bases:
_SummaryMixinA connectedness table and the directional readings it implies.
All quantities are percentages of forecast-error variance from the row-normalized generalized decomposition,
\[\theta_{ij}(H) = \frac{\sigma_{jj}^{-1} \sum_{h=0}^{H} (e_i' \Psi_h \Sigma_u e_j)^2} {\sum_{h=0}^{H} e_i' \Psi_h \Sigma_u \Psi_h' e_i}, \qquad \tilde\theta_{ij}(H) = 100\,\frac{\theta_{ij}(H)}{\sum_j \theta_{ij}(H)},\]with \(\Psi_h\) the moving-average matrices of the fitted system and \(\Sigma_u\) its innovation covariance. The table is \(\tilde\theta\); its off-diagonal mass is connectedness, column sums are what each variable’s shocks contribute to the others, row sums what each variable receives, and the difference ranks transmitters against receivers.
Note
horizonis the largest moving-average lead in the sum, so the shares cumulate \(\Psi_0, \ldots, \Psi_H\) – \(H + 1\) terms – and equal100 * result.generalized_fevd(horizon)[-1]on any result that offers that method. Rows oftablesum to 100 by construction; columns do not.netsums to zero across variables, andtotalequals the mean offrom_othersand ofto_others. Because generalized shocks are correlated the raw shares \(\theta_{ij}\) do not sum to one, which is why the rows are normalized and why the table is a relative attribution rather than an additive decomposition.- Variables:
names – Variable labels, indexing every axis below.
horizon – The forecast horizon the decomposition was read at.
table –
(k, k)connectedness table; entry[i, j]is the share ofi’s forecast-error variance associated with shocks toj. Rows sum to 100.total – The total spillover index – average off-diagonal mass, in
[0, 100].to_others –
(k,)directional spillover to others: what shocks to each variable contribute to everyone else’s variance.from_others –
(k,)directional spillover from others: how much of each variable’s variance arrives from elsewhere.net –
to_others - from_others; positive ranks a variable as a net transmitter.net_pairwise –
(k, k)antisymmetric net pairwise spillovers,table[j, i] - table[i, j]read asi’s net transmission toj.
See also
References
Diebold, F. X., & Yilmaz, K. (2012). Better to give than to receive: Predictive directional measurement of volatility spillovers. International Journal of Forecasting, 28(1), 57-66.
Pesaran, M. H., & Shin, Y. (1998). Generalized impulse response analysis in linear multivariate models. Economics Letters, 58(1), 17-29.
Example
A three-variable VAR(1) in which only
y2drivesy1; the table namesy2the transmitter andy1the receiver, and the accounting identities hold:>>> import numpy as np >>> from cultivars.multivariate.reduced_form.vector_autoregression import VAR >>> rng = np.random.default_rng(0) >>> y = np.zeros((300, 3)) >>> a = np.array([[0.5, 0.3, 0.0], [0.0, 0.5, 0.0], [0.0, 0.0, 0.5]]) >>> for t in range(1, 300): ... y[t] = a @ y[t - 1] + rng.standard_normal(3) >>> spill = Spillover(VAR(y, order=1).fit(), horizon=10).compute() >>> spill.names, spill.horizon, spill.k_endog, spill.table.shape (('y1', 'y2', 'y3'), 10, 3, (3, 3)) >>> bool(np.allclose(spill.table.sum(axis=1), 100.0)), bool(abs(spill.net.sum()) < 1e-9) (True, True) >>> bool(spill.table[0, 1] > 5.0), bool(spill.table[1, 0] < 2.0) (True, True) >>> int(np.argmax(spill.net)), int(np.argmin(spill.net)) (1, 0) >>> bool(abs(spill.total - spill.from_others.mean()) < 1e-9) True
Private methods#
Build the structured summary. |