CCF
This function estimates the cross-correlation function (CCF) between two univariate time series, reporting how strongly one series is linearly related to lagged values of another.
For lag k, the cross-correlation compares x_{t+k} with y_t after normalization by series variability.
Optional confidence intervals can be returned to assess whether cross-correlations differ materially from zero.
Excel Usage
=CCF(x, y, adjusted, fft, nlags, alpha)
x(list[list], required): First time series as a 2D range.y(list[list], required): Second time series as a 2D range.adjusted(bool, optional, default: true): Use denominator n-k instead of n for normalization.fft(bool, optional, default: true): Use FFT-based convolution.nlags(int, optional, default: null): Number of lags to compute; null uses statsmodels default.alpha(float, optional, default: null): Significance level for confidence intervals; null disables intervals.
Returns (list[list]): 2D table with columns lag, ccf, conf_low, and conf_high.
Example 1: Cross-correlation with default options
Inputs:
| x | y | adjusted | fft | nlags | alpha | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 1 | 1 | 2 | 3 | 5 | 8 | true | true | 5 |
Excel formula:
=CCF({1,2,3,4,5,6}, {1,1,2,3,5,8}, TRUE, TRUE, 5, )
Expected output:
| Result | |||
|---|---|---|---|
| 0 | 0.938953 | ||
| 1 | 0.359932 | ||
| 2 | -0.166273 | ||
| 3 | -0.625969 | ||
| 4 | -1.09545 |
Example 2: Cross-correlation with confidence intervals
Inputs:
| x | y | adjusted | fft | nlags | alpha | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2 | 1 | 2 | 1 | 2 | 1 | 2 | 1 | 1 | 2 | 1 | 2 | 1 | 2 | 1 | 2 | true | true | 6 | 0.05 |
Excel formula:
=CCF({2,1,2,1,2,1,2,1}, {1,2,1,2,1,2,1,2}, TRUE, TRUE, 6, 0.05)
Expected output:
| Result | |||
|---|---|---|---|
| 0 | -1 | -1.69295 | -0.307048 |
| 1 | 1 | 0.307048 | 1.69295 |
| 2 | -1 | -1.69295 | -0.307048 |
| 3 | 1 | 0.307048 | 1.69295 |
| 4 | -1 | -1.69295 | -0.307048 |
| 5 | 1 | 0.307048 | 1.69295 |
Example 3: Cross-correlation without FFT
Inputs:
| x | y | adjusted | fft | nlags | alpha | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 3 | 5 | 4 | 6 | 5 | 7 | 6 | 2 | 4 | 3 | 5 | 4 | 6 | 5 | false | false | 5 |
Excel formula:
=CCF({3,5,4,6,5,7,6}, {2,4,3,5,4,6,5}, FALSE, FALSE, 5, )
Expected output:
| Result | |||
|---|---|---|---|
| 0 | 1 | ||
| 1 | 0.0639098 | ||
| 2 | 0.364662 | ||
| 3 | -0.295113 | ||
| 4 | -0.0864662 |
Example 4: Cross-correlation using a small lag count
Inputs:
| x | y | adjusted | fft | nlags | alpha | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 3 | 2 | 4 | 3 | 5 | 4 | 2 | 1 | 3 | 2 | 4 | 3 | 5 | true | true | 3 |
Excel formula:
=CCF({1,3,2,4,3,5,4}, {2,1,3,2,4,3,5}, TRUE, TRUE, 3, )
Expected output:
| Result | |||
|---|---|---|---|
| 0 | 0.289474 | ||
| 1 | 0.508772 | ||
| 2 | -0.160526 |
Python Code
import numpy as np
from statsmodels.tsa.stattools import ccf as sm_ccf
def ccf(x, y, adjusted=True, fft=True, nlags=None, alpha=None):
"""
Compute cross-correlation between two time series across nonnegative lags.
See: https://www.statsmodels.org/stable/generated/statsmodels.tsa.stattools.ccf.html
This example function is provided as-is without any representation of accuracy.
Args:
x (list[list]): First time series as a 2D range.
y (list[list]): Second time series as a 2D range.
adjusted (bool, optional): Use denominator n-k instead of n for normalization. Default is True.
fft (bool, optional): Use FFT-based convolution. Default is True.
nlags (int, optional): Number of lags to compute; null uses statsmodels default. Default is None.
alpha (float, optional): Significance level for confidence intervals; null disables intervals. Default is None.
Returns:
list[list]: 2D table with columns lag, ccf, conf_low, and conf_high.
"""
try:
def to1d(values):
if isinstance(values, list):
if all(isinstance(row, list) for row in values):
raw = [item for row in values for item in row]
else:
raw = values
else:
raw = [values]
out = []
for item in raw:
try:
out.append(float(item))
except (TypeError, ValueError):
continue
return out
x_vals = to1d(x)
y_vals = to1d(y)
if len(x_vals) < 2 or len(y_vals) < 2:
return "Error: x and y must each contain at least two numeric values"
if len(x_vals) != len(y_vals):
return "Error: x and y must have the same number of numeric values"
result = sm_ccf(
np.asarray(x_vals, dtype=float),
np.asarray(y_vals, dtype=float),
adjusted=adjusted,
fft=fft,
nlags=nlags,
alpha=alpha,
)
if isinstance(result, tuple):
ccf_vals, confint = result
else:
ccf_vals = result
confint = None
ccf_arr = np.asarray(ccf_vals, dtype=float)
conf_arr = np.asarray(confint, dtype=float) if confint is not None else None
table = []
for lag in range(len(ccf_arr)):
low = ""
high = ""
if conf_arr is not None and lag < len(conf_arr):
low = float(conf_arr[lag][0])
high = float(conf_arr[lag][1])
table.append([lag, float(ccf_arr[lag]), low, high])
return table
except Exception as e:
return f"Error: {str(e)}"Online Calculator
First time series as a 2D range.
Second time series as a 2D range.
Use denominator n-k instead of n for normalization.
Use FFT-based convolution.
Number of lags to compute; null uses statsmodels default.
Significance level for confidence intervals; null disables intervals.