cross_corr

Defined in fynance.features.roll_functions

cross_corr(x, y, max_lag=20)[source]

Full-sample lead-lag cross-correlation profile of two series.

\[cross\_corr_{lag}(x, y) = corr(x_t, y_{t - lag}), \quad lag \in \{-max\_lag, \dots, max\_lag\}\]

where the correlation is computed over the full overlapping sample (all valid t, i.e. T - |lag| pairs), not a trailing window.

Lag convention. Entry lag correlates x[t] with y[t - lag]. A positive lag therefore pairs x at time t with y earlier in the series (at t - lag): if that pairing is where the correlation peaks, y’s past values line up with x’s current values, i.e. y leads x by lag bars. Conversely a negative lag that maximizes the correlation means y lags x (x leads y) by |lag| bars. For example, if y[t] = x[t - 3] (y is x delayed by 3 bars, so x leads y by 3), the profile peaks at lag = -3, since y[t - (-3)] = y[t + 3] = x[t].

Parameters:
xnp.ndarray[float64, ndim=1]

First series. Cast to float64 if needed; must not contain NaN.

ynp.ndarray[float64, ndim=1]

Second series, same length as x. Cast to float64 if needed; must not contain NaN.

max_lagint, optional

Maximum absolute lag to scan, must be a non-negative integer and strictly less than len(x). Default is 20.

Returns:
np.ndarray[float64, ndim=1]

Cross-correlation profile of length 2 * max_lag + 1, ordered from lag=-max_lag to lag=max_lag. Entries where either side has zero variance over the overlap are np.nan (checked explicitly before dividing — no RuntimeWarning is raised).

See also

roll_corr

Examples

y is x delayed by 3 bars (x leads y by 3): the profile peaks at lag = -3.

>>> rng = np.random.default_rng(0)
>>> x = rng.normal(size=200)
>>> y = np.roll(x, 3)
>>> y[:3] = rng.normal(size=3)  # avoid a spurious wrap-around match
>>> profile = cross_corr(x, y, max_lag=5)
>>> profile.shape
(11,)
>>> int(np.arange(-5, 6)[np.argmax(profile)])
-3