Regression Discontinuity (RDD)
Estimate a Sharp Regression Discontinuity (RDD): the jump in dependent_ticker exactly where running_variable_ticker crosses cutoff.
Also known as: RDD, sharp RD.
For more information about the method, see causal_inference_model.get_regression_discontinuity.
Treats running_variable_ticker’s value as the running variable that (hypothetically) triggers some discrete change once it crosses cutoff – e.g. testing whether dependent_ticker’s return behaves discontinuously around a round-number/threshold level of another asset or indicator (a psychological price level, an index-inclusion market-cap threshold, a macro indicator’s policy-relevant threshold) fed in as running_variable_ticker. Fits separate local linear regressions of dependent_ticker’s return on the (cutoff-centered) running_variable_ticker value, one on each side of cutoff, and reports the gap between the two fitted lines exactly at the cutoff.
The formula is as follows:
\[\text{x̃ₜ} = \text{xₜ} - \text{cutoff},\;\; \text{keeping the observations with |x̃ₜ| < h},\;\; \text{where} \;\; \text{xₜ} \;\text{is the running ticker's}\; \text{column} (\text{Return by default}) \text{and}\; h = \text{bandwidth},\;\; \text{or half the range of xₜ by default}\] \[\text{Each side} (\text{x̃ₜ} < 0 \;\text{and}\; \text{x̃ₜ} \geq 0) \text{:} \text{yₜ} = a + b \cdot \text{x̃ₜ} + \text{eₜ},\;\; \text{fitted by OLS} (\text{kernel} = \text{"uniform"},\; \text{the default}) \text{or by WLS with weights}\; 1 - | \text{x̃ₜ} | / h (\text{kernel} = \text{"triangular"})\] \[\text{Discontinuity} = a_{\text{right}} - a_{\text{left}},\;\; \text{with SE} = \sqrt{\operatorname{SE}(a_{\text{right}}) ^{2} + \operatorname{SE}(a_{\text{left}}) ^{2}}\] \[t = \text{Discontinuity} / \text{SE},\;\; \text{with a Student-t distribution on the two sides' residual degrees of freedom combined}\]Regression Discontinuity (RDD) in Python or via the MCP
Install the Finance Toolkit with:
pip install financetoolkit -U
Then call get_regression_discontinuity as shown below.
from financetoolkit import Toolkit
toolkit = Toolkit(
["COIN", "BTCUSD"],
api_key="FINANCIAL_MODELING_PREP_KEY",
start_date="2022-01-01",
end_date="2025-12-31",
)
# COIN's return on days Bitcoin rises versus days it falls
toolkit.econometrics.get_regression_discontinuity(
dependent_ticker="COIN", running_variable_ticker="BTCUSD", cutoff=0
)
Or, after setting up the Finance Toolkit MCP, ask:
Did Coinbase's daily return jump at the point where Bitcoin's daily return turned positive, from 2022 to 2025?
Which returns:
| Value | |
|---|---|
| Discontinuity | 0.0031 |
| Std. Error | 0.0027 |
| t-Statistic | 1.1191 |
| P-Value | 0.2633 |
| Cutoff | 0 |
| Bandwidth | 0.1497 |
| N Left | 729 |
| N Right | 728 |
Using Your Own Data
get_regression_discontinuity 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_regression_discontinuity with dependent_ticker, running_variable_ticker and cutoff, using the column names of the data as tickers.
Parameters
get_regression_discontinuity accepts the following parameters.
| Parameter | Type | Description | Example |
|---|---|---|---|
dependent_ticker | str | The outcome asset. | "AAPL" |
running_variable_ticker | str | The asset (or column) whose value determines which side of cutoff an observation falls on. | "MSFT" |
cutoff | float | The threshold value of running_variable_ticker at which the discontinuity is estimated. | 0.01 |
period | str | The data frequency (daily, weekly, monthly, quarterly, or yearly). Defaults to “daily”. | "weekly" |
column | str | The historical data column to use for both series. Defaults to “Return”. | "Return" |
bandwidth | float | None | The maximum distance from cutoff an observation may be to be included in either local regression. Defaults to None, which uses half of the running variable’s observed range – see causal_inference_model.get_regression_discontinuity for why this is a deliberately naive default. | 0.02 |
kernel | str | One of “uniform” or “triangular”. Defaults to “uniform”. | "triangular" |
rounding | int | None | The number of decimals to round the results to. Defaults to None. | 2 |