Fit a Vector Autoregression (VAR) across every ticker in the Toolkit instance and trace out the Impulse Response Function (IRF) – how a shock to each ticker propagates through the whole system over periods periods ahead. The shock is one standard deviation of the orthogonalized innovation when orthogonalized=True (the default) and a unit shock to the reduced-form residual when orthogonalized=False.

Also known as: IRF.

A natural companion to get_var_forecast: rather than forecasting the levels forward, this traces out each ticker’s dynamic response to a shock in every ticker (including itself) – see time_series_model.get_impulse_response_function for the full formula, the Cholesky-orthogonalization used to identify the shocks, and why the ordering of tickers is an identifying assumption.

The formula is as follows:

\[\text{Ψ₀} = I \;\text{and}\; \text{Ψₙ} = \operatorname{Σ}(l = \operatorname{1..min}(n,\; p)) \text{Phiₗ} \cdot \text{Ψₙ₋ₗ},\;\; \text{the moving-average matrices of the VAR(p) fitted on every ticker's column (Return by default)},\;\; p = \text{lags} (1 \;\text{by default})\] \[\text{Σᵤ} = \text{Û'Û} / (T - k \cdot p - 1) = P \cdot P',\;\; \text{with P the lower-triangular Cholesky factor}\] \[\text{Θₙ} = \text{Ψₙ} \cdot P (\text{orthogonalized} = \text{True},\; a \;\text{one-standard-deviation shock}) \text{or}\; \text{Θₙ} = \text{Ψₙ} (\text{orthogonalized} = \text{False},\; a \;\text{unit reduced-form shock})\] \[\text{Response of ticker i, n periods after a shock to ticker j:}\;\; \text{Θₙ[i, j]},\;\; \text{for} \;\; n = \text{0..periods}\]

Impulse Response Function (IRF) in Python or via the MCP

Install the Finance Toolkit with:

pip install financetoolkit -U

Then call get_impulse_response_function as shown below.

from financetoolkit import Toolkit

toolkit = Toolkit(
    ["^VIX", "^OVX"],
    api_key="FINANCIAL_MODELING_PREP_KEY",
    start_date="2021-01-01",
    end_date="2025-12-31",
)

toolkit.econometrics.get_impulse_response_function(column="Adj Close", periods=20)

Or, after setting up the Finance Toolkit MCP, ask:

How did the VIX and the oil volatility index (OVX) respond to a shock in either of them over 20 days, estimated on their daily levels from 2021 to 2025?

Which returns:

Horizon (‘^VIX’, ‘^VIX’) (‘^VIX’, ‘^OVX’) (‘^OVX’, ‘^VIX’) (‘^OVX’, ‘^OVX’)
0 1.7975 1.1106 0 2.4048
1 1.6806 1.1595 0.022 2.2148
2 1.5725 1.1956 0.0407 2.0416
3 1.4723 1.2207 0.0565 1.8834
4 1.3794 1.2361 0.0698 1.7389
5 1.2933 1.2433 0.0807 1.6069
6 1.2133 1.2434 0.0897 1.4861
7 1.1389 1.2374 0.097 1.3755
8 1.0698 1.2262 0.1027 1.2743
9 1.0054 1.2106 0.1071 1.1814
10 0.9454 1.1914 0.1104 1.0963
11 0.8895 1.1691 0.1126 1.0181
12 0.8374 1.1444 0.114 0.9462
13 0.7887 1.1176 0.1146 0.8801
14 0.7432 1.0893 0.1145 0.8193
15 0.7006 1.0597 0.1139 0.7633
16 0.6608 1.0292 0.1129 0.7117
17 0.6236 0.9981 0.1114 0.664
18 0.5886 0.9667 0.1096 0.6201
19 0.5559 0.9351 0.1075 0.5794
20 0.5252 0.9034 0.1052 0.5418

Using Your Own Data

get_impulse_response_function 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_impulse_response_function()

Parameters

get_impulse_response_function accepts the following parameters.

ParameterTypeDescriptionExample
periodstrThe data frequency (daily, weekly, monthly, quarterly, or yearly). Defaults to “daily”."weekly"
columnstrThe historical data column to model. Defaults to “Return”."Return"
lagsintThe VAR order. Defaults to 1.2
periodsintThe number of periods ahead to trace the response out to. Defaults to 10.20
orthogonalizedboolWhether to orthogonalize the shocks via a Cholesky decomposition of the residual covariance matrix – see time_series_model.get_impulse_response_function. Defaults to True.False
include_benchmarkboolWhether to include “Benchmark” among the tickers modeled jointly. Defaults to False.True
roundingint | NoneThe number of decimals to round the results to. Defaults to None.2
Share