Estimate the correlation between every pair of assets as it changes over time, with the dynamic conditional correlation (DCC) GARCH(1,1) model of Engle (2002). Every asset gets its own GARCH(1,1) volatility, and the correlation of the standardized returns follows a GARCH-like recursion around their long-run correlation. Correlations between assets tend to rise in crises, exactly when diversification is needed most. A rolling correlation sees that late and depends on its window; the DCC model updates the correlation every period, with a (how strongly it reacts to news) and b (how persistent it is) estimated by maximum likelihood.

The formula is as follows:

\[\text{zᵢ},\;\; \text{ₜ} = (\text{rᵢ},\; \text{ₜ} - \operatorname{mean}(\text{rᵢ})) / \text{sigmaᵢ},\;\; \text{ₜ},\;\; \text{with rᵢ},\;\; \text{ₜ} \;\text{the}\; \text{column} \;\text{series} (\text{Return by default}) \text{on the dates all assets have and}\; \sigma ^{\text{2ᵢ}},\;\; \text{ₜ} = \text{ω} + \alpha \cdot \text{uᵢ},\;\; \text{ₜ₋₁} ^{2} + \beta \cdot \sigma ^{\text{2ᵢ}},\;\; \text{ₜ₋₁} \;\text{each asset's GARCH} (1,\; 1) \text{variance of the demeaned returns}\; u (\text{GARCH Persistence} = \alpha + \beta)\] \[\text{Qₜ} = (1 - a - b) \cdot \text{Q̄} + a \cdot \text{zₜ₋₁} \cdot \text{zₜ₋₁'} + b \cdot \text{Qₜ₋₁},\;\; \text{with}\; \text{Q̄} \;\text{the sample correlation of}\; z \;\text{and}\; \text{Q₀} = \text{Q̄}\] \[\text{Rₜ} = \operatorname{diag}(\text{Qₜ}) ^{- 1 / 2} \cdot \text{Qₜ} \cdot \operatorname{diag}(\text{Qₜ}) ^{- 1 / 2},\;\; \text{the conditional correlations}\]
  • a and b maximize the correlation log-likelihood -½·Σₜ (ln|Rₜ| + zₜ’·Rₜ⁻¹·zₜ), with a, b ≥ 0 and a + b < 1

For more information, see the following paper:

  • Engle, R. (2002). “Dynamic Conditional Correlation: A Simple Class of Multivariate Generalized Autoregressive Conditional Heteroskedasticity Models.” Journal of Business & Economic Statistics, 20(3), 339-350.

Also known as: DCC-GARCH, dynamic conditional correlation, time-varying correlation, multivariate GARCH.

DCC-GARCH in Python or via the MCP

Install the Finance Toolkit with:

pip install financetoolkit -U

Then call get_dcc_garch as shown below.

from financetoolkit import Toolkit

toolkit = Toolkit(
    ["AAPL", "MSFT", "XOM"],
    api_key="FINANCIAL_MODELING_PREP_KEY",
    start_date="2018-01-01",
    end_date="2025-12-31",
)

correlations = toolkit.econometrics.get_dcc_garch()

correlations.resample("Y").mean().round(4)

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

How did the DCC-GARCH correlation between Apple, Microsoft and ExxonMobil develop from 2018 to 2025?

Which returns:

Date AAPL / MSFT AAPL / XOM MSFT / XOM
2018 0.6047 0.2794 0.2729
2019 0.578 0.2982 0.2641
2020 0.6665 0.2879 0.226
2021 0.6199 0.1384 0.0786
2022 0.7084 0.2283 0.1692
2023 0.5802 0.1706 0.0386
2024 0.5378 0.1018 0.0237
2025 0.4636 0.1991 0.114

Using Your Own Data

get_dcc_garch 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_dcc_garch()

Parameters

get_dcc_garch accepts the following parameters.

ParameterTypeDescriptionExample
periodstrThe data frequency (daily, weekly, monthly, quarterly, or yearly). Defaults to “daily”."weekly"
columnstrThe historical data column to use. Defaults to “Return”."Return"
parametersboolWhether to return the estimated parameters (a, b and the GARCH persistence of every asset) instead of the correlations. Defaults to False.False
include_benchmarkboolWhether to include “Benchmark” among the assets. Defaults to False.True
roundingint | NoneThe number of decimals to round the results to. Defaults to None.2
Share