Time-Varying Beta
Estimate the alpha and beta of every asset as they change over time, with the Kalman filter. The regression y_t = α_t + β_t x_t + ε_t lets both coefficients take a random step every period; how large those steps are, and how much noise surrounds the regression, is estimated by maximum likelihood. A beta that drifts, such as a stock becoming more sensitive to the market, shows up without choosing the window of a rolling regression, while a beta that is constant stays flat.
Every alpha and beta is the filtered estimate, updated with the observations up to its date only. The three variances that set how fast the estimates adapt are estimated on the whole sample, however, so the path is not entirely what would have been known at the time. The filter starts without prior knowledge of the coefficients, so the first date (or the first few, when the independent series starts with zeros) cannot separate the alpha from the beta and is NaN.
By default every asset is regressed on the Benchmark of the Toolkit (or, with standalone data, on the second series).
The formula is as follows:
\[\text{yₜ} = \text{alphaₜ} + \text{betaₜ} \cdot \text{xₜ} + \text{epsilonₜ},\;\; \text{epsilonₜ} \sim N(0,\; \sigma ^{\text{2\_epsilon}}),\;\; \text{with yₜ the asset's and xₜ the independent asset's column series (Return by default)},\;\; \text{on the dates both have}\] \[\text{alphaₜ} = \text{alphaₜ₋₁} + \text{ηₜ} \;\text{and}\; \text{betaₜ} = \text{betaₜ₋₁} + \text{ζₜ},\;\; \text{ηₜ} \sim N(0,\; \sigma ^{\text{2\_alpha}}) \text{and}\; \text{ζₜ} \sim N(0,\; \sigma ^{\text{2\_beta}}) \text{:} \;\text{random walks}\]-
σ²_ε, σ²_α and σ²_β are fitted by Maximum Likelihood with the Kalman filter (diffusely initialized) on the series divided by their standard deviations, and scaled back
-
Alpha and Beta are the filtered states E[αₜ, βₜ | y₁..yₜ]; the Beta Standard Error is the square root of the filtered variance of βₜ
For more information, see the following book:
- Durbin, J. and Koopman, S.J. (2012). “Time Series Analysis by State Space Methods.” Oxford University Press, 2nd edition.
Also known as: Kalman filter beta, rolling beta, dynamic beta, state space regression.
Time-Varying Beta in Python or via the MCP
Install the Finance Toolkit with:
pip install financetoolkit -U
Then call get_time_varying_beta as shown below.
from financetoolkit import Toolkit
toolkit = Toolkit(
["AAPL", "MSFT"],
api_key="FINANCIAL_MODELING_PREP_KEY",
start_date="2015-01-01",
end_date="2025-12-31",
)
beta = toolkit.econometrics.get_time_varying_beta(period="monthly")
beta.xs("Beta", axis=1, level=1).iloc[12::24]
Or, after setting up the Finance Toolkit MCP, ask:
How did the beta of Apple and Microsoft against the S&P 500 change over time, estimated on monthly returns from 2015 to 2025?
Which returns:
| Date | AAPL | MSFT |
|---|---|---|
| 2016-02 | 1.2708 | 1.5813 |
| 2018-02 | 1.1427 | 1.3183 |
| 2020-02 | 1.3197 | 1.1153 |
| 2022-02 | 1.2496 | 0.9853 |
| 2024-02 | 1.2526 | 0.9525 |
Using Your Own Data
get_time_varying_beta 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_time_varying_beta()
Parameters
get_time_varying_beta accepts the following parameters.
| Parameter | Type | Description | Example |
|---|---|---|---|
dependent_tickers | str | list[str] | None | The assets whose beta is estimated. Defaults to None, which uses every asset except the independent one. | ["AAPL", "MSFT", "GOOGL"] |
independent_ticker | str | None | The asset the beta is measured against. Defaults to None, which uses the Benchmark or the second series. | None, which uses the Benchmark or the second series |
period | str | The data frequency (daily, weekly, monthly, quarterly, or yearly). Defaults to “daily”. | "weekly" |
column | str | The historical data column to use. Defaults to “Return”. | "Return" |
rounding | int | None | The number of decimals to round the results to. Defaults to None. | 2 |