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, and k includes 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.

ParameterTypeDescriptionExample
break_datestrThe 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_tickerstr | NoneThe dependent (predicted) asset. Defaults to None, meaning the Toolkit instance’s first ticker."AAPL"
independent_tickersstr | list[str] | NoneThe independent (predictor) asset(s). Defaults to None, meaning every other ticker in the Toolkit instance besides dependent_ticker.["MSFT", "Benchmark"]
include_benchmarkboolWhether to include “Benchmark” in the default independent ticker(s) (has no effect when independent_tickers is given explicitly). Defaults to False.True
periodstrThe data frequency (daily, weekly, monthly, quarterly, or yearly). Defaults to “daily”."weekly"
columnstrThe historical data column to regress on. Defaults to “Return”."Return"
add_constantboolWhether to include an intercept in the underlying regression(s). Defaults to True.False
roundingint | NoneThe number of decimals to round the results to. Defaults to None.2
Share