Chow Test
Calculate the Chow test for a structural break at break_date in a regression of dependent_ticker on independent_tickers.
The sample is split at break_date into a “before” and “after” period, a regression is fitted on each part separately and on the full sample, and an F-test checks whether allowing the coefficients to differ between the two periods significantly reduces the residual sum of squares.
The formula is as follows:
\[F = ((\text{RSS\_pooled} - (\text{RSS}_{1} + \text{RSS}_{2})) / k) / ((\text{RSS}_{1} + \text{RSS}_{2}) / (n - 2k))\]- The second sub-period starts at the first date on or after
break_date, andkincludes the constant when add_constant=True
Where RSS_pooled is the residual sum of squares of the full-sample regression, RSS_1 and RSS_2 those of the two sub-periods, k the number of parameters and n the total number of observations. Under the null hypothesis of no structural break (the same coefficients apply throughout), F follows an F(k, n - 2k) distribution. A low p-value means the relationship changed at break_date, for example an asset’s beta shifting after a merger, a regulatory change or a market regime change, so a single regression over the full sample is misspecified. The break date must be chosen in advance; testing many candidate dates and keeping the most significant overstates the evidence.
For more information about the method, see the following paper:
- Chow, G.C. (1960). “Tests of Equality Between Sets of Coefficients in Two Linear Regressions.” Econometrica, 28(3), 591-605.
Also known as: Chow breakpoint test.
Chow Test in Python or via the MCP
Install the Finance Toolkit with:
pip install financetoolkit -U
Then call get_chow_test as shown below.
from financetoolkit import Toolkit
toolkit = Toolkit(
["NVDA"],
api_key="FINANCIAL_MODELING_PREP_KEY",
start_date="2021-01-01",
end_date="2025-12-31",
)
# NVDA is dependent and the Benchmark independent, with a break at the launch of ChatGPT
toolkit.econometrics.get_chow_test(break_date="2022-11-30", include_benchmark=True)
Or, after setting up the Finance Toolkit MCP, ask:
Did the relationship between Nvidia's daily returns and the S&P 500 break on 30 November 2022, the launch of ChatGPT, measured from 2021 to 2025?
Which returns:
| Value | |
|---|---|
| Chow F-Statistic | 0.811 |
| P-Value | 0.4447 |
| Reject No Structural Break (5%) | 0 |
Using Your Own Data
get_chow_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, where each country is a column:
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")
Then call econometrics.get_chow_test with break_date.
Parameters
get_chow_test accepts the following parameters.
| Parameter | Type | Description | Example |
|---|---|---|---|
break_date | str | The date (e.g. “2021-06-30”) at which to split the sample – all periods starting on or after this date form the “after” sub-sample, everything before it forms the “before” sub-sample. | "2022-01-03" |
dependent_ticker | str | None | The dependent (predicted) asset. Defaults to None, meaning the Toolkit instance’s first ticker. | "AAPL" |
independent_tickers | str | list[str] | None | The independent (predictor) asset(s). Defaults to None, meaning every other ticker in the Toolkit instance besides dependent_ticker. | ["MSFT", "Benchmark"] |
include_benchmark | bool | Whether to include “Benchmark” in the default independent ticker(s) (has no effect when independent_tickers is given explicitly). Defaults to False. | True |
period | str | The data frequency (daily, weekly, monthly, quarterly, or yearly). Defaults to “daily”. | "weekly" |
column | str | The historical data column to regress on. Defaults to “Return”. | "Return" |
add_constant | bool | Whether to include an intercept in the underlying regression(s). Defaults to True. | False |
rounding | int | None | The number of decimals to round the results to. Defaults to None. | 2 |