| Title: | Scale-Ordered Contagion: Spectral Theory and Tests of Heterogeneous Information Adaptation |
|---|---|
| Description: | A spectral theory of financial contagion under heterogeneous information adaptation, with the estimators and falsifiable tests it implies. Modelling both the source and the receiving market as exponential information filters yields a bi-exponential transmission response whose power spectrum is the product of two Lorentzians; the slower market supplies the binding spectral corner. Projected onto a maximal-overlap discrete wavelet basis (Percival and Walden, 2000, ISBN:9780521685085) this gives a closed-form transfer-entropy-by-scale profile and three predictions (Scale-Ordered Contagion): scale ordering by adaptation speed, shape symmetry across direction, and magnitude asymmetry. The package provides the closed-form spectrum and scale power, a profile-matching estimator that recovers adaptation rates and endogenises the fast/slow classification, the wavelet-quantile directional-gain measure built from the transfer-entropy estimator of Schreiber (2000) <doi:10.1103/PhysRevLett.85.461> with quantile conditioning (Koenker and Bassett, 1978) <doi:10.2307/1913643> and the quantile goodness-of-fit of Koenker and Machado (1999) <doi:10.1080/01621459.1999.10473882>, and the three tests with phase-randomised surrogate (Theiler, Eubank, Longtin, Galdrikian and Farmer, 1992) <doi:10.1016/0167-2789(92)90102-S> and stationary block-bootstrap (Politis and Romano, 1994) <doi:10.1080/01621459.1994.10476870> nulls. Bundled G20 equity returns and replication scripts reproduce the headline results; the package is general-purpose and accommodates user-supplied returns. |
| Authors: | Avishek Bhandari [aut, cre] (Indian Institute of Technology Bhubaneswar), Ipsita Parida [aut] (Indian Institute of Technology Bhubaneswar) |
| Maintainer: | Avishek Bhandari <[email protected]> |
| License: | GPL-3 |
| Version: | 0.1.0 |
| Built: | 2026-06-03 08:57:52 UTC |
| Source: | https://github.com/avishekb9/sochcontagion |
Daily log-returns for eighteen G20 equity-market indices from 12 January 2006 through 18 March 2026, used for the empirical tests of the Scale-Ordered Contagion framework. Price levels are integrated of order one and returns are stationary, so all transfer-entropy computation is on returns.
g20_returnsg20_returns
A numeric matrix with 5036 rows (trading days) and 18 columns (markets), the row names being ISO dates. Columns are Argentina, Australia, Brazil, Canada, China, France, Germany, India, Indonesia, Italy, Japan, Mexico, Russia, SouthAfrica, SouthKorea, Turkey, UK, USA.
Compiled from public sources (e.g. Yahoo Finance) for the G20 equity indices.
data(g20_returns) dim(g20_returns) head(colnames(g20_returns))data(g20_returns) dim(g20_returns) head(colnames(g20_returns))
The a-priori advanced/emerging partition of the bundled markets, used to build the slowness proxy and the directional magnitude comparison. Under the Scale-Ordered Contagion theory this partition is a hypothesis to be tested against the data-determined classification, not a maintained assumption.
market_groupsmarket_groups
A list with two character vectors, advanced and
emerging.
data(market_groups) market_groups$advanceddata(market_groups) market_groups$advanced
Returns the brick-walled MODWT detail coefficients of a series at every
scale up to J, using the Daubechies least-asymmetric filter of
length 8 (LA8). The maximal-overlap discrete wavelet transform is
shift-invariant and time-aligned, which suits financial returns; see
Percival and Walden (2000).
modwt_detail(x, J = 5L, filter = "la8")modwt_detail(x, J = 5L, filter = "la8")
x |
Numeric vector (e.g. a return series). |
J |
Integer number of detail levels (default 5). |
filter |
Character wavelet filter (default |
A list of length J; element k is the numeric vector of
scale-k detail coefficients (boundary coefficients removed).
Percival, D. B., & Walden, A. T. (2000). Wavelet Methods for Time Series Analysis. Cambridge University Press.
d <- modwt_detail(rnorm(1024), J = 5) length(d)d <- modwt_detail(rnorm(1024), J = 5) length(d)
Generates a surrogate of a series that preserves its power spectrum (linear autocorrelation) and is real-valued, by randomising the Fourier phases. Used to build the directional-significance null for the wavelet-quantile measure (a source surrogate breaks directed structure while preserving the source's own spectrum); see Theiler et al. (1992).
phase_surrogate(x)phase_surrogate(x)
x |
Numeric vector. |
A numeric vector the same length as x.
Theiler, J., Eubank, S., Longtin, A., Galdrikian, B., & Farmer, J. D. (1992). Testing for nonlinearity in time series: the method of surrogate data. Physica D, 58(1-4), 77-94. doi:10.1016/0167-2789(92)90102-S.
xs <- phase_surrogate(rnorm(256)) length(xs)xs <- phase_surrogate(rnorm(256)) length(xs)
Horizontal bar chart of estimated market adaptation rates with the
cross-sectional median split, as returned by soch_fit_market.
plot_market_rates(rates, col = c("#1f3b73", "#c0392b"))plot_market_rates(rates, col = c("#1f3b73", "#c0392b"))
rates |
A |
col |
Two colours for the fast/slow (or supplied) classes. |
Invisibly NULL; called for its plot.
r <- data.frame(market = c("USA","UK","India","China"), alpha = c(2.4, 2.4, 0.29, 0.08), class = c("fast","fast","slow","slow")) plot_market_rates(r)r <- data.frame(market = c("USA","UK","India","China"), alpha = c(2.4, 2.4, 0.29, 0.08), class = c("fast","fast","slow","slow")) plot_market_rates(r)
Draws one or more directed wavelet-quantile scale profiles against MODWT scale, for visual inspection of the rising/peaked shapes that the SOCH predictions concern.
plot_scale_profiles(profiles, normalise = FALSE, col = NULL)plot_scale_profiles(profiles, normalise = FALSE, col = NULL)
profiles |
A named list of numeric scale profiles ( |
normalise |
Logical; plot profiles normalised to sum one (default
|
col |
Optional vector of line colours (recycled). |
Invisibly NULL; called for its plot.
P <- list("USA|India" = c(0.016,0.043,0.049,0.049,0.057), "India|USA" = c(0.006,0.027,0.045,0.022,0.042)) plot_scale_profiles(P)P <- list("USA|India" = c(0.016,0.043,0.049,0.049,0.057), "India|USA" = c(0.006,0.027,0.045,0.022,0.042)) plot_scale_profiles(P)
Forest plot of each unordered pair's observed cross-direction divergence
against its same-shape bootstrap null, as returned by
soch_test_symmetry. Points inside the null bars do not reject
shape symmetry.
plot_soch_symmetry(test)plot_soch_symmetry(test)
test |
A |
Invisibly NULL; called for its plot.
tt <- data.frame(pair = c("USA-India","Germany-India"), D_obs = c(0.076, 0.010), null_q95 = c(1.48, 1.88), p_value = c(0.92, 1.00), holds = c(TRUE, TRUE)) plot_soch_symmetry(tt)tt <- data.frame(pair = c("USA-India","Germany-India"), D_obs = c(0.076, 0.010), null_q95 = c(1.48, 1.88), p_value = c(0.92, 1.00), holds = c(TRUE, TRUE)) plot_soch_symmetry(tt)
Returns the nominal MODWT detail pass-bands in angular frequency. With unit
sampling and Nyquist frequency , detail level has band
; for daily data, level 1 is the
two-to-four-day band and level 5 the thirty-two-to-sixty-four-day band.
soch_bands(J = 5L)soch_bands(J = 5L)
J |
Integer number of scales (default 5). |
A numeric matrix with J rows and columns wmin,
wmax giving the lower and upper band edges in angular frequency.
soch_bands(5)soch_bands(5)
Classifies markets as fast or slow adapters by a cross-sectional median split of estimated adaptation rates, replacing the exogenous advanced/emerging partition with a data-determined one.
soch_classify(alpha)soch_classify(alpha)
alpha |
Numeric vector of estimated adaptation rates. |
Character vector ("fast" if above the median, else "slow").
soch_classify(c(USA = 2.4, India = 0.29, China = 0.08, UK = 2.4))soch_classify(c(USA = 2.4, India = 0.29, China = 0.08, UK = 2.4))
Estimates one adaptation rate per market by constraining every directed pair to use its two markets' rates, with a per-pair level concentrated out. Sharing each rate across all pairs containing that market resolves the per-pair ordering ambiguity and yields a stable market-level estimate.
soch_fit_market(profiles, markets, bands = NULL, start = NULL)soch_fit_market(profiles, markets, bands = NULL, start = NULL)
profiles |
A list of directed profiles; each element is a list with
|
markets |
Character vector of market names (the rate vector order). |
bands |
Band matrix (default |
start |
Optional numeric vector of log-rate start values
(length |
A data.frame with columns market, alpha
(estimated rate), and class ("fast"/"slow" by the cross-sectional
median).
Bhandari, A., & Parida, I. (2026). Scale-Ordered Contagion. Working paper, IIT Bhubaneswar.
data(g20_returns); data(market_groups) mk <- c(market_groups$advanced[1:2], market_groups$emerging[1:2]) prof <- list() for (a in mk) for (b in mk) if (a != b) prof[[length(prof)+1]] <- list(i = a, j = b, wqte = wqte_profile(g20_returns, a, b, tau = 0.05)) soch_fit_market(prof, mk)data(g20_returns); data(market_groups) mk <- c(market_groups$advanced[1:2], market_groups$emerging[1:2]) prof <- list() for (a in mk) for (b in mk) if (a != b) prof[[length(prof)+1]] <- list(i = a, j = b, wqte = wqte_profile(g20_returns, a, b, tau = 0.05)) soch_fit_market(prof, mk)
Recovers a pair's adaptation rates by fitting an observed wavelet-quantile
profile to the closed-form scale power soch_scale_power by
nonlinear least squares, concentrating out the level. Because the scale
power is symmetric in the two rates, a single directional profile identifies
only the unordered pair ; the
ordered assignment comes from the pooled fit
(soch_fit_market). Rates faster than the Nyquist frequency are
not recoverable from sampled data, so the search is confined to
[LO, HI] with HI = pi.
soch_fit_pair( wqte, bands = soch_bands(length(wqte)), LO = 0.02, HI = pi, starts = NULL )soch_fit_pair( wqte, bands = soch_bands(length(wqte)), LO = 0.02, HI = pi, starts = NULL )
wqte |
Numeric vector: an observed directed WQTE scale profile. |
bands |
Band matrix from |
LO, HI
|
Lower and upper bounds on the searched rates (defaults
|
starts |
Optional matrix of log-rate start values (two columns); a sensible multi-start grid is used by default. |
A list with amin, amax (recovered unordered rates),
theta (level), ssr, fitted, resid, R2,
kstar (peak scale of wqte).
Bhandari, A., & Parida, I. (2026). Scale-Ordered Contagion. Working paper, IIT Bhubaneswar.
truth <- 3 * soch_scale_power(2.0, 0.2) fit <- soch_fit_pair(truth) c(amin = fit$amin, amax = fit$amax)truth <- 3 * soch_scale_power(2.0, 0.2) fit <- soch_fit_pair(truth) c(amin = fit$amin, amax = fit$amax)
The angular frequency at which (the quantity the
octave-band profile tracks) is maximised. It solves
and lies in where
: in the symmetric case it equals
, and in the strongly asymmetric case it approaches the
slower rate.
soch_peak_frequency(alpha_s, alpha_r)soch_peak_frequency(alpha_s, alpha_r)
alpha_s |
Positive source adaptation rate. |
alpha_r |
Positive receiver adaptation rate. |
The peak angular frequency (scalar).
soch_peak_frequency(1, 1) # symmetric: 1/sqrt(3) soch_peak_frequency(2.0, 0.2) # near the slow rate 0.2soch_peak_frequency(1, 1) # symmetric: 1/sqrt(3) soch_peak_frequency(2.0, 0.2) # near the slow rate 0.2
The wavelet scale at which directed transfer entropy is predicted to peak,
, governed by the slower
market's adaptation rate (prediction SOCH-A). Smaller
(a slower market) gives a larger, coarser peak scale.
soch_peak_scale(alpha_s, alpha_r, J = 5L)soch_peak_scale(alpha_s, alpha_r, J = 5L)
alpha_s |
Positive source adaptation rate. |
alpha_r |
Positive receiver adaptation rate. |
J |
Integer number of observed scales used to clip the result (default 5). |
The (continuous) predicted peak scale, clipped to [1, J].
soch_peak_scale(2.0, 0.2)soch_peak_scale(2.0, 0.2)
Runs the complete Scale-Ordered Contagion empirical programme on a returns panel: builds all directed WQTE profiles, runs the three SOCH tests (ordering, magnitude, and—optionally—shape symmetry), and recovers market-level adaptation rates with the pooled profile-matching estimator, classifying each market as a fast or slow adapter.
soch_pipeline( returns, advanced, emerging, tau = 0.05, J = 5L, symmetry = FALSE, B = 200L )soch_pipeline( returns, advanced, emerging, tau = 0.05, J = 5L, symmetry = FALSE, B = 200L )
returns |
Numeric returns matrix (columns named by market). |
advanced, emerging
|
Character vectors partitioning the markets a priori (used only to build the slowness proxy and the magnitude comparison; under the theory the partition is itself a hypothesis tested by the recovered classification). |
tau |
Quantile level (default 0.05). |
J |
Integer scales (default 5). |
symmetry |
Logical; run the (heavier) SOCH-B block-bootstrap test
(default |
B |
Bootstrap replications for the symmetry test (default 200). |
A list with profiles, kstar, aggregate,
test_ordering, test_magnitude, optionally
test_symmetry, and market_rates (a data.frame of recovered
rates and classification).
Bhandari, A., & Parida, I. (2026). Scale-Ordered Contagion. Working paper, IIT Bhubaneswar.
data(g20_returns); data(market_groups) adv <- market_groups$advanced[1:3]; emg <- market_groups$emerging[1:3] res <- soch_pipeline(g20_returns, adv, emg, tau = 0.05) res$test_ordering$p_value res$market_ratesdata(g20_returns); data(market_groups) adv <- market_groups$advanced[1:3]; emg <- market_groups$emerging[1:3] res <- soch_pipeline(g20_returns, adv, emg, tau = 0.05) res$test_ordering$p_value res$market_rates
Computes the wavelet-quantile directional scale profile for every ordered pair among the chosen markets, returning the named list used by the SOCH tests and the pooled estimator.
soch_profiles(returns, markets, tau = 0.05, J = 5L, filter = "la8")soch_profiles(returns, markets, tau = 0.05, J = 5L, filter = "la8")
returns |
Numeric returns matrix (columns named by market). |
markets |
Character vector of markets. |
tau |
Quantile level (default 0.05). |
J |
Integer scales (default 5). |
filter |
Wavelet filter (default |
A named list; element "from|to" is the numeric scale profile.
data(g20_returns) P <- soch_profiles(g20_returns, c("USA","India","Germany"), tau = 0.05) names(P)data(g20_returns) P <- soch_profiles(g20_returns, c("USA","India","Germany"), tau = 0.05) names(P)
Integrates the product-Lorentzian spectrum over each MODWT band to give the
transmitted information power by scale, in closed form (partial fractions
plus the arctangent integral). For the
antiderivative is used; the confluent case is the
removable limit, evaluated by direct numerical integration. The profile is
symmetric in the two rates (the basis of the SOCH shape-symmetry
prediction) and strictly positive.
soch_scale_power(alpha_s, alpha_r, bands = soch_bands(), A = 1)soch_scale_power(alpha_s, alpha_r, bands = soch_bands(), A = 1)
alpha_s |
Positive source adaptation rate. |
alpha_r |
Positive receiver adaptation rate. |
bands |
A two-column matrix of band edges from |
A |
Level constant (default 1). |
Numeric vector of length nrow(bands): the power at
each scale.
Bhandari, A., & Parida, I. (2026). Scale-Ordered Contagion. Working paper, IIT Bhubaneswar.
soch_scale_power(2.0, 0.2) # fast source, slow receiver soch_scale_power(0.2, 2.0) # reverse: identical (symmetry)soch_scale_power(2.0, 0.2) # fast source, slow receiver soch_scale_power(0.2, 2.0) # reverse: identical (symmetry)
The power spectral density of the bi-exponential transmission response
implied by a source filter of rate alpha_s and a receiver filter of
rate alpha_r. It is the product of two Lorentzians and is symmetric
in the two rates; the slower rate sets the binding spectral corner.
soch_spectrum(alpha_s, alpha_r, omega, A = 1)soch_spectrum(alpha_s, alpha_r, omega, A = 1)
alpha_s |
Positive source adaptation rate. |
alpha_r |
Positive receiver adaptation rate. |
omega |
Numeric vector of non-negative angular frequencies. |
A |
Level constant (default 1). |
Numeric vector of spectral density values
.
Bhandari, A., & Parida, I. (2026). Scale-Ordered Contagion. Working paper, IIT Bhubaneswar.
w <- seq(0, pi, length.out = 64) s <- soch_spectrum(2.0, 0.2, w)w <- seq(0, pi, length.out = 64) s <- soch_spectrum(2.0, 0.2, w)
Tests the prediction that advanced-to-emerging flows dominate emerging-to-advanced flows in level. For each advanced-emerging pair the ratio of aggregate WQTE in the two directions is formed and a one-sided sign test assesses whether the ratio exceeds one.
soch_test_magnitude(profiles, advanced, emerging)soch_test_magnitude(profiles, advanced, emerging)
profiles |
A named list of directed WQTE profiles ( |
advanced, emerging
|
Character vectors of market names. |
A list with the per-pair ratios, their median,
mean, the fraction exceeding one (frac_gt1), and the
one-sided sign-test p_value.
Bhandari, A., & Parida, I. (2026). Scale-Ordered Contagion. Working paper, IIT Bhubaneswar.
prof <- list("USA|India" = c(1,2,3,4,5)*1.3, "India|USA" = c(1,2,3,4,5), "UK|China" = c(1,2,3,3,2)*1.1, "China|UK" = c(1,2,3,3,2)) soch_test_magnitude(prof, advanced = c("USA","UK"), emerging = c("India","China"))$frac_gt1prof <- list("USA|India" = c(1,2,3,4,5)*1.3, "India|USA" = c(1,2,3,4,5), "UK|China" = c(1,2,3,3,2)*1.1, "China|UK" = c(1,2,3,3,2)) soch_test_magnitude(prof, advanced = c("USA","UK"), emerging = c("India","China"))$frac_gt1
Tests the prediction that pairs containing slower markets peak at coarser
wavelet scales. For each directed profile the peak scale is
located, and is regressed on a slowness proxy (the number of
emerging markets in the pair). A positive slope supports SOCH-A.
soch_test_ordering(profiles, emerging)soch_test_ordering(profiles, emerging)
profiles |
A named list of directed WQTE profiles; names are
|
emerging |
Character vector of market names treated as the slow group. |
A list with the fitted model (an lm), the
slope, its t statistic and p_value, and the mean
peak scale by slowness level (means).
Bhandari, A., & Parida, I. (2026). Scale-Ordered Contagion. Working paper, IIT Bhubaneswar.
## toy profiles: emerging-inclusive pairs peak coarser set.seed(1) prof <- list("USA|UK" = c(5,4,3,2,1), "UK|USA" = c(5,4,3,2,1), "USA|India" = c(1,2,3,4,5), "India|USA" = c(1,2,3,4,5), "India|China" = c(1,1,2,4,6), "China|India" = c(1,1,2,4,6)) soch_test_ordering(prof, emerging = c("India","China"))$p_value## toy profiles: emerging-inclusive pairs peak coarser set.seed(1) prof <- list("USA|UK" = c(5,4,3,2,1), "UK|USA" = c(5,4,3,2,1), "USA|India" = c(1,2,3,4,5), "India|USA" = c(1,2,3,4,5), "India|China" = c(1,1,2,4,6), "China|India" = c(1,1,2,4,6)) soch_test_ordering(prof, emerging = c("India","China"))$p_value
Tests the prediction—the sharpest of the three—that the shape of
the directional scale profile is the same in both directions for a given
pair. For each unordered pair the cross-direction symmetric KL of the
normalised profiles is compared to a same-shape null built by
stationary-block-bootstrap re-estimation of a single direction (the sampling
variability of one shape). A large means the two directions are
statistically indistinguishable, supporting SOCH-B.
soch_test_symmetry( returns, markets, tau = 0.05, J = 5L, B = 200L, L = 22L, filter = "la8" )soch_test_symmetry( returns, markets, tau = 0.05, J = 5L, B = 200L, L = 22L, filter = "la8" )
returns |
Numeric returns matrix (columns named by market). |
markets |
Character vector of markets; all unordered pairs are tested. |
tau |
Quantile level (default 0.05). |
J |
Integer scales (default 5). |
B |
Integer bootstrap replications per direction (default 200). |
L |
Integer block length for the stationary bootstrap (default 22). |
filter |
Wavelet filter (default |
A data.frame with one row per unordered pair: pair,
D_obs, null_q95, p_value, and holds
(p_value > 0.05).
Politis, D. N., & Romano, J. P. (1994). The Stationary Bootstrap. Journal of the American Statistical Association, 89(428), 1303-1313. doi:10.1080/01621459.1994.10476870.
data(g20_returns) soch_test_symmetry(g20_returns, c("USA","India","Germany"), tau = 0.05, B = 50)data(g20_returns) soch_test_symmetry(g20_returns, c("USA","India","Germany"), tau = 0.05, B = 50)
The symmetrised KL divergence between two non-negative profiles after normalising each to sum to one. Used to compare the shape of two directional scale profiles in the SOCH shape-symmetry test; smaller values indicate more similar shapes. A small additive constant guards against zero entries.
sym_kl(p, q, eps = 1e-09)sym_kl(p, q, eps = 1e-09)
p, q
|
Numeric non-negative vectors of equal length. |
eps |
Small stabiliser added before normalising (default 1e-9). |
A non-negative scalar.
sym_kl(c(1, 2, 3, 2, 1), c(1, 2, 3, 2, 1)) # identical shapes: 0 sym_kl(c(3, 2, 1), c(1, 2, 3)) # reversed shapes: > 0sym_kl(c(1, 2, 3, 2, 1), c(1, 2, 3, 2, 1)) # identical shapes: 0 sym_kl(c(3, 2, 1), c(1, 2, 3)) # reversed shapes: > 0
Measures directed tail dependence from a source coefficient series x
to a target series y as a Koenker-Machado quantile pseudo-:
the proportional reduction in the -quantile check loss when the
source's lagged value is added to a regression of the target's value on its
own lag. A value in ; larger means stronger directed information
flow at quantile . This is the loadable realisation of the
wavelet-quantile transfer-entropy primitive and shares the
conditional-quantile-regression construction of that measure.
wq_gain(x, y, tau = 0.05)wq_gain(x, y, tau = 0.05)
x |
Numeric source series (typically a MODWT detail). |
y |
Numeric target series (typically a MODWT detail). |
tau |
Quantile level in (0,1) (default 0.05, the lower tail). |
A scalar in ; NA if there are too few
observations or the quantile regressions fail.
Koenker, R., & Bassett, G. (1978). Regression Quantiles. Econometrica, 46(1), 33-50. doi:10.2307/1913643.
Koenker, R., & Machado, J. A. F. (1999). Goodness of Fit and Related Inference Processes for Quantile Regression. Journal of the American Statistical Association, 94(448), 1296-1310. doi:10.1080/01621459.1999.10473882.
Schreiber, T. (2000). Measuring Information Transfer. Physical Review Letters, 85(2), 461-464. doi:10.1103/PhysRevLett.85.461.
x <- rnorm(500); y <- 0.4 * c(0, x[-500]) + rnorm(500) wq_gain(x, y, tau = 0.5) # source improves the target's quantile fitx <- rnorm(500); y <- 0.4 * c(0, x[-500]) + rnorm(500) wq_gain(x, y, tau = 0.5) # source improves the target's quantile fit
Computes the per-scale wavelet-quantile directional gain from one market to
another: the directed WQTE profile across the
wavelet scales, whose shape, ordering, and level the SOCH theory
predicts.
wqte_profile(returns, from, to, tau = 0.05, J = 5L, filter = "la8")wqte_profile(returns, from, to, tau = 0.05, J = 5L, filter = "la8")
returns |
Numeric matrix of returns (rows = time, columns = markets,
with column names); or an object coercible by |
from, to
|
Market names (columns of |
tau |
Quantile level (default 0.05). |
J |
Integer number of scales (default 5). |
filter |
Wavelet filter (default |
Numeric vector of length J: the directed WQTE by scale.
data(g20_returns) p <- wqte_profile(g20_returns, "USA", "India", tau = 0.05) round(p, 4)data(g20_returns) p <- wqte_profile(g20_returns, "USA", "India", tau = 0.05) round(p, 4)