Ljung-Box Test
Calculate the Ljung-Box test for autocorrelation.
The test aggregates the squared Autocorrelation Function up to lag h into a single statistic that is chi-squared distributed with h degrees of freedom under the null hypothesis that the series exhibits no autocorrelation up to that lag. A significant result (low p-value) indicates that the series is autocorrelated, which is relevant both as a standalone diagnostic (e.g. to check whether a return series follows a random walk) and as a residual diagnostic after fitting a model (e.g. checking that GARCH residuals are no longer autocorrelated).
The formula is as follows:
\[Q = n \cdot (n + 2) \cdot \operatorname{Σ}(k = 1..h) \text{rhoₖ} ^{2} / (n - k),\;\; \text{chi-squared with h degrees of freedom},\;\; h = \text{lags} (10 \;\text{by default})\] \[\text{rhoₖ} = \operatorname{Σ}(t = k + 1..n) (\text{rₜ} - \operatorname{mean}(r)) \cdot (\text{rₜ₋ₖ} - \operatorname{mean}(r)) / \operatorname{Σ}(t = 1..n) (\text{rₜ} - \operatorname{mean}(r)) ^{2},\;\; \text{the sample autocorrelation of the returns of period at lag k}\]For more information about the method, see the following paper:
- Ljung, G.M., & Box, G.E.P. (1978). “On a Measure of Lack of Fit in Time Series Models.” Biometrika, 65(2), 297-303.
Also known as: Ljung-Box Q test, portmanteau test.
Ljung-Box Test in Python or via the MCP
Install the Finance Toolkit with:
pip install financetoolkit -U
Then call get_ljung_box_test as shown below.
from financetoolkit import Toolkit
toolkit = Toolkit(
["WMT", "COST", "TGT"],
api_key="FINANCIAL_MODELING_PREP_KEY",
start_date="2021-01-01",
end_date="2025-12-31",
)
toolkit.econometrics.get_ljung_box_test()
Or, after setting up the Finance Toolkit MCP, ask:
Were the daily returns of Walmart, Costco and Target autocorrelated up to ten lags from 2021 to 2025, according to the Ljung-Box test?
Which returns:
| WMT | COST | TGT | |
|---|---|---|---|
| Ljung-Box Statistic | 12.8794 | 10.9863 | 11.9887 |
| P-Value | 0.2305 | 0.3586 | 0.2858 |
Using Your Own Data
get_ljung_box_test runs on any data, not only prices: ratios, economic indicators, yield curves or your own dataset. Pass a DataFrame, a Series or a dictionary of them to Econometrics as data, with the dates in the rows or the columns, and set changes to how its changes are calculated: "percentage", "log", "difference" for rates and ratios, or None when the data are changes already. For example, for the monthly unemployment rates of the United States and Germany:
from financetoolkit import Economics, Econometrics
economics = Economics(start_date="2000-01-01")
unemployment = economics.get_unemployment_rate(
countries=["United States", "Germany"], period="monthly"
)
econometrics = Econometrics(data=unemployment, changes="difference")
econometrics.get_ljung_box_test()
Parameters
get_ljung_box_test accepts the following parameters.
| Parameter | Type | Description | Example |
|---|---|---|---|
period | str | The data frequency for returns (daily, weekly, monthly, quarterly, or yearly). Defaults to “daily”. | "weekly" |
within_period | bool | Whether to calculate the test within the specified period or for the entire period. Thus whether to look at the test within a specific year (if period = ‘yearly’) or look at the entirety of all years. Defaults to False. Note that this requires intraday data when period = ‘daily’, since a single day only nests observations when intraday data was fetched. | True |
lags | int | The number of lags to test for autocorrelation up to. Defaults to 10. | 20 |
include_benchmark | bool | Whether to include “Benchmark” among the assets tested. Defaults to False. | True |
rounding | int | None | The number of decimals to round the results to. Defaults to None. | 2 |