mfe.multivariate¶
mfe.multivariate ¶
mfe.multivariate — Multivariate volatility models.
All of these are missing from the arch package (as of 2026).
Models
DCC Dynamic Conditional Correlation (Engle 2002); variants: dcc, cdcc, deco CCC Constant Conditional Correlation (Bollerslev 1990) BEKK BEKK model (Engle & Kroner 1995); variants: scalar, diagonal OGARCH Orthogonal GARCH (Alexander 2001) GOGARCH Generalized Orthogonal GARCH (van der Weide 2002); rotations: ica, moments RCC Rotated Conditional Correlation (Noureldin, Shephard & Sheppard 2014)
DCC ¶
DCC-GARCH(1,1) model (Engle 2002).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
variant
|
'dcc'(default) | 'cdcc' | 'deco'
|
|
'dcc'
|
Source code in src/mfe/multivariate/dcc.py
fit ¶
Two-step DCC estimation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
(T, K) return matrix
|
|
required |
starting_values
|
(2,) array [a, b]; if None uses [0.05, 0.90]
|
|
None
|
Source code in src/mfe/multivariate/dcc.py
CCC ¶
CCC-GARCH(1,1) model (Bollerslev 1990).
No free parameters beyond the K univariate GARCH models.
fit ¶
Estimate CCC-GARCH.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
(T, K) return matrix
|
|
required |
Source code in src/mfe/multivariate/ccc.py
BEKK ¶
BEKK-GARCH model (Engle & Kroner 1995).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
variant
|
'scalar' | 'diagonal' | 'full'
|
"full" is not yet implemented. |
SCALAR
|
Source code in src/mfe/multivariate/bekk.py
fit ¶
fit(data: FloatArray, starting_values: FloatArray | None = None, method: str = 'L-BFGS-B', options: dict | None = None) -> MultivariateVolResult
Estimate BEKK parameters via QMLE.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
(T, K) return matrix (demeaned)
|
|
required |
Source code in src/mfe/multivariate/bekk.py
GOGARCH ¶
GO-GARCH (Generalized Orthogonal GARCH) — van der Weide (2002).
Extends O-GARCH by estimating an additional orthogonal rotation U from fourth-order cumulants (ICA), so that the latent factors are as close to independent as possible.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_components
|
PCA components to retain (default: all K)
|
|
None
|
rotation
|
Literal['ica', 'moments']
|
"ica" — FastICA deflationary algorithm, kurtosis contrast "moments" — Boswijk & van der Weide (2011) cumulant minimisation |
'ica'
|
Source code in src/mfe/multivariate/gogarch.py
fit ¶
Estimate GO-GARCH.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
(T, K) demeaned return matrix
|
|
required |
Source code in src/mfe/multivariate/gogarch.py
OGARCH ¶
O-GARCH (Orthogonal GARCH) — Alexander (2001).
Factor loadings are fixed at PCA eigenvectors. Each factor follows an independent GARCH(1,1). No rotation optimisation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_components
|
number of PCA factors to retain (default: all K)
|
|
None
|
Source code in src/mfe/multivariate/gogarch.py
fit ¶
Estimate O-GARCH.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
(T, K) demeaned return matrix
|
|
required |
Source code in src/mfe/multivariate/gogarch.py
GOGARCHResult
dataclass
¶
GOGARCHResult(log_likelihood: float, conditional_covariances: FloatArray, factors: FloatArray, factor_variances: FloatArray, mixing_matrix: FloatArray, rotation_matrix: FloatArray | None, eigenvalues: FloatArray, converged: bool, n_obs: int, n_components: int, model_name: str, garch_results: list = list(), diagnostics: dict = dict())
Extended result for GO-GARCH / O-GARCH models.
factor_correlations ¶
(K, K) unconditional correlation of the K latent factors with the original returns (mixing matrix scaled to unit-variance factors).
Source code in src/mfe/multivariate/gogarch.py
RCC ¶
Rotated Conditional Correlation (RCC) model.
Noureldin, Shephard & Sheppard (2014). Scalar parameterisation only (full RARCH — fully parametric A, B matrices — is left as a future extension).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rotation
|
'symmetric'(default) | 'cholesky'
|
How to compute P^{1/2}: "symmetric" — symmetric (spectral) square root. PSD-preserving, recommended. "cholesky" — lower-triangular Cholesky. Faster but ordering-dependent. |
'symmetric'
|
Source code in src/mfe/multivariate/rcc.py
fit ¶
fit(data: FloatArray, starting_values: FloatArray | None = None, options: dict | None = None) -> RCCResult
Estimate RCC by two-step QML.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
FloatArray
|
|
required |
starting_values
|
FloatArray | None
|
|
None
|
options
|
dict | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
RCCResult
|
|
Source code in src/mfe/multivariate/rcc.py
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | |
RCCResult
dataclass
¶
RCCResult(params: FloatArray, log_likelihood: float, conditional_covariances: FloatArray, G_t: FloatArray, u_t: FloatArray, P: FloatArray, P_half: FloatArray, converged: bool, n_obs: int, n_vars: int, diagnostics: dict = dict())
RCC model estimation result.
conditional_correlations ¶
Extract (T, K, K) conditional correlation matrices from Sigma_t.
Source code in src/mfe/multivariate/rcc.py
base ¶
Abstract base class for multivariate volatility models.
Design principles: - Results are dataclasses, not mutable objects, to avoid state mutation bugs. - Convergence failures surface as ConvergenceWarning, not silent bad params. - Robust VCV (sandwich) is computed by default alongside the Hessian-only VCV.
ConvergenceWarning ¶
Bases: UserWarning
Raised when the optimizer did not fully converge.
MultivariateVolResult
dataclass
¶
MultivariateVolResult(params: FloatArray, log_likelihood: float, conditional_covariances: FloatArray, residuals: FloatArray, vcv: FloatArray, vcv_robust: FloatArray, scores: FloatArray, converged: bool = True, n_obs: int = 0, n_params: int = 0, model_name: str = '', diagnostics: dict = dict())
Container for multivariate volatility estimation results.
MultivariateVolatilityProcess ¶
Bases: ABC
Base class for all multivariate volatility models.
Subclasses must implement: _log_likelihood(params, data) -> float _compute_covariances(params, data) -> (T, K, K) _starting_values(data) -> FloatArray _parameter_bounds(data, K) -> list[tuple[float, float]] _parameter_names(K) -> list[str]
fit ¶
fit(data: FloatArray, starting_values: FloatArray | None = None, method: str = 'L-BFGS-B', options: dict | None = None) -> MultivariateVolResult
Fit the model via quasi-maximum likelihood.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
FloatArray
|
|
required |
starting_values
|
(P,) starting parameter vector; if None, uses heuristic
|
|
None
|
method
|
str
|
|
'L-BFGS-B'
|
options
|
dict | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
MultivariateVolResult
|
|
Source code in src/mfe/multivariate/base.py
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | |
bekk ¶
BEKK-GARCH models (Engle & Kroner 1995).
Three variants: Scalar BEKK: H_t = C'C + a^2 * eps_{t-1} eps_{t-1}' + b^2 * H_{t-1} Diagonal BEKK: H_t = C'C + A' * eps eps' * A + B' * H_{t-1} * B (A,B diagonal) Full BEKK: H_t = C'C + A' * eps eps' * A + B' * H_{t-1} * B (A,B full K×K)
Estimation via QMLE (two-step or direct). We implement the scalar and diagonal variants first; full BEKK is numerically expensive (O(K^4) per recursion step) and relegated to Phase 2.
Key performance note: - Scalar BEKK inner loop: O(K^2 * T) — fast enough in numpy for K <= 20 - Diagonal BEKK: O(K^2 * T) — same - Full BEKK: O(K^4 * T) — needs Cython for K > 5
References
Engle, R.F. & Kroner, K.F. (1995): "Multivariate Simultaneous Generalized ARCH", Econometric Theory.
Noureldin, D., Shephard, N. & Sheppard, K. (2012): "Multivariate High-Frequency-Based Volatility (HEAVY) Models", JoE.
BEKK ¶
BEKK-GARCH model (Engle & Kroner 1995).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
variant
|
'scalar' | 'diagonal' | 'full'
|
"full" is not yet implemented. |
SCALAR
|
Source code in src/mfe/multivariate/bekk.py
fit ¶
fit(data: FloatArray, starting_values: FloatArray | None = None, method: str = 'L-BFGS-B', options: dict | None = None) -> MultivariateVolResult
Estimate BEKK parameters via QMLE.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
(T, K) return matrix (demeaned)
|
|
required |
Source code in src/mfe/multivariate/bekk.py
ccc ¶
CCC-GARCH (Constant Conditional Correlation).
Bollerslev, T. (1990): "Modelling the Coherence in Short-Run Nominal Exchange Rates: A Multivariate Generalized ARCH Model", Review of Economics and Statistics.
H_t = D_t R D_t
Where D_t = diag(sigma_{1,t}, ..., sigma_{K,t}) from K independent GARCH(1,1) and R = unconditional correlation matrix (constant).
Two-step estimation: Step 1: Fit GARCH(1,1) to each series independently. Step 2: Compute R = sample correlation of standardized residuals.
This is just DCC with a=b=0 (zero dynamics in the correlation), but it's worth having as an explicit model for testing (CCC vs DCC likelihood ratio test).
CCC ¶
CCC-GARCH(1,1) model (Bollerslev 1990).
No free parameters beyond the K univariate GARCH models.
fit ¶
Estimate CCC-GARCH.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
(T, K) return matrix
|
|
required |
Source code in src/mfe/multivariate/ccc.py
dcc ¶
DCC-GARCH (Dynamic Conditional Correlation) model.
Engle, R. (2002): "Dynamic Conditional Correlations — A Simple Class of Multivariate Generalized Autoregressive Conditional Heteroskedasticity Models", JBES.
Two-step estimation: Step 1: Fit univariate GARCH(1,1) to each asset. Extract standardized residuals. Step 2: Estimate DCC parameters (a, b) by maximizing the correlation likelihood.
Also implements: - cDCC (Aielli 2013): consistent DCC (avoids bias in Q_bar estimation) - DECO (Engle & Kelly 2012): equicorrelation restricted DCC
Key fix vs. the MATLAB mfe-toolbox: The MATLAB dcc.m computes Q_bar = mean(z_t z_t') once at the start and inside the log-likelihood. For long panels this is fine. We pre-compute it and pass it as a constant to the inner loop to avoid the recomputation on every likelihood call.
DCC ¶
DCC-GARCH(1,1) model (Engle 2002).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
variant
|
'dcc'(default) | 'cdcc' | 'deco'
|
|
'dcc'
|
Source code in src/mfe/multivariate/dcc.py
fit ¶
Two-step DCC estimation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
(T, K) return matrix
|
|
required |
starting_values
|
(2,) array [a, b]; if None uses [0.05, 0.90]
|
|
None
|
Source code in src/mfe/multivariate/dcc.py
gogarch ¶
GO-GARCH: Generalized Orthogonal GARCH.
Two closely related models:
O-GARCH (Alexander 2001): Factors = PCA rotation of returns. Factor loadings fixed at eigenvectors. Each factor follows an independent GARCH(1,1). Sigma_t = W diag(h_{1,t}, ..., h_{K,t}) W' where W = eigenvectors of the unconditional covariance, scaled to unit-variance factors.
GO-GARCH (van der Weide 2002): Extends O-GARCH. The mixing matrix is W = P * U where: P = PCA whitening matrix (from unconditional covariance) U = K×K orthogonal matrix estimated from higher-order cumulants (ICA-style; we use the FastICA / JADE approach) Sigma_t = (PU) diag(h_{1,t}, ..., h_{K,t}) (PU)'
References
Alexander, C. (2001): "Orthogonal GARCH", in Mastering Risk, vol. 2, FT Prentice Hall.
van der Weide, R. (2002): "GO-GARCH: A Multivariate Generalized Orthogonal GARCH Model", Journal of Applied Econometrics, 17(5), 549-564.
Boswijk, H.P. & van der Weide, R. (2011): "Method of Moments Estimation of GO-GARCH Models", Journal of Econometrics, 163(1), 118-126.
Implementation notes
- O-GARCH is exact PCA-GARCH: W is fixed from eigendecomposition, no additional optimisation.
- GO-GARCH adds an orthogonal rotation U estimated via one of: "moments" — Boswijk & van der Weide (2011) GMM on fourth-order cumulants "ica" — FastICA (deflationary, kurtosis contrast) The MATLAB mfe-toolbox gogarch.m uses a direct numerical optimisation over U. That approach has a memory-leak issue (anonymous function closes over volData in a loop). We avoid this entirely by using the closed-form cumulant matching.
- Factor GARCH: each factor uses GARCH(1,1) from the
archpackage. - The full conditional covariance is assembled from factor variances in O(K^2 * T).
MATLAB bugs fixed
- Memory leak: the MATLAB version closes over
volDatain a nested fmincon call inside a loop. We avoid closures entirely — all state is explicit. - No convergence warning: MATLAB silently used non-converged parameters. We raise ConvergenceWarning on any non-converged factor GARCH.
- Inconsistent factor ordering: MATLAB returns factors in eigenvalue order (descending). We follow the same convention but document it explicitly.
GOGARCHResult
dataclass
¶
GOGARCHResult(log_likelihood: float, conditional_covariances: FloatArray, factors: FloatArray, factor_variances: FloatArray, mixing_matrix: FloatArray, rotation_matrix: FloatArray | None, eigenvalues: FloatArray, converged: bool, n_obs: int, n_components: int, model_name: str, garch_results: list = list(), diagnostics: dict = dict())
Extended result for GO-GARCH / O-GARCH models.
factor_correlations ¶
(K, K) unconditional correlation of the K latent factors with the original returns (mixing matrix scaled to unit-variance factors).
Source code in src/mfe/multivariate/gogarch.py
OGARCH ¶
O-GARCH (Orthogonal GARCH) — Alexander (2001).
Factor loadings are fixed at PCA eigenvectors. Each factor follows an independent GARCH(1,1). No rotation optimisation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_components
|
number of PCA factors to retain (default: all K)
|
|
None
|
Source code in src/mfe/multivariate/gogarch.py
fit ¶
Estimate O-GARCH.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
(T, K) demeaned return matrix
|
|
required |
Source code in src/mfe/multivariate/gogarch.py
GOGARCH ¶
GO-GARCH (Generalized Orthogonal GARCH) — van der Weide (2002).
Extends O-GARCH by estimating an additional orthogonal rotation U from fourth-order cumulants (ICA), so that the latent factors are as close to independent as possible.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_components
|
PCA components to retain (default: all K)
|
|
None
|
rotation
|
Literal['ica', 'moments']
|
"ica" — FastICA deflationary algorithm, kurtosis contrast "moments" — Boswijk & van der Weide (2011) cumulant minimisation |
'ica'
|
Source code in src/mfe/multivariate/gogarch.py
fit ¶
Estimate GO-GARCH.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
(T, K) demeaned return matrix
|
|
required |
Source code in src/mfe/multivariate/gogarch.py
rcc ¶
Rotated Conditional Correlation (RCC) model.
Noureldin, D., Shephard, N. & Sheppard, K. (2014): "Multivariate Rotated ARCH Models", Journal of Econometrics, 179(1), 16-30.
Core idea
Standard DCC operates on the correlation structure of standardised returns. RCC instead:
-
Rotates raw returns by the inverse square-root of their unconditional covariance: u_t = P^{-1/2} r_t where P = E[r_t r_t'] Under the true DGP, u_t has unconditional covariance I_K.
-
Fits a BEKK-type process to u_t u_t' in the rotated space: G_t = (I_K - A - B) + A * u_{t-1} u_{t-1}' * A + B * G_{t-1} * B With covariance targeting, the unconditional mean of G_t is I_K by construction, which removes the free intercept.
-
The DCC-type RCC sets A = aI_K, B = bI_K (scalar): G_t = (1 - a - b) I_K + a u_{t-1}u_{t-1}' + b G_{t-1}
-
Reconstructs the conditional covariance of original returns: Sigma_t = P^{1/2} G_t P^{1/2}
Advantages over DCC
- Covariance targeting is exact by construction (no approximate initialisation).
- Estimation is more stable for large K: scalar RCC has only 2 free parameters (a, b) regardless of dimension, compared to DCC which also has 2 but its inner Q-bar computation can be numerically unstable.
- The rotated space has a cleaner likelihood because the rotated residuals u_t have unconditional identity covariance, so the step-2 likelihood simplifies.
Two-step estimation
Step 1: Estimate P = sample covariance of returns. Compute P^{1/2} (Cholesky or spectral decomp). Rotate: u_t = P^{-1/2} r_t. Step 2: Estimate scalar (a, b) by maximising the correlation log-likelihood using the G_t recursion.
This matches the MFE MATLAB rcc.m implementation.
RCCResult
dataclass
¶
RCCResult(params: FloatArray, log_likelihood: float, conditional_covariances: FloatArray, G_t: FloatArray, u_t: FloatArray, P: FloatArray, P_half: FloatArray, converged: bool, n_obs: int, n_vars: int, diagnostics: dict = dict())
RCC model estimation result.
conditional_correlations ¶
Extract (T, K, K) conditional correlation matrices from Sigma_t.
Source code in src/mfe/multivariate/rcc.py
RCC ¶
Rotated Conditional Correlation (RCC) model.
Noureldin, Shephard & Sheppard (2014). Scalar parameterisation only (full RARCH — fully parametric A, B matrices — is left as a future extension).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rotation
|
'symmetric'(default) | 'cholesky'
|
How to compute P^{1/2}: "symmetric" — symmetric (spectral) square root. PSD-preserving, recommended. "cholesky" — lower-triangular Cholesky. Faster but ordering-dependent. |
'symmetric'
|
Source code in src/mfe/multivariate/rcc.py
fit ¶
fit(data: FloatArray, starting_values: FloatArray | None = None, options: dict | None = None) -> RCCResult
Estimate RCC by two-step QML.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
FloatArray
|
|
required |
starting_values
|
FloatArray | None
|
|
None
|
options
|
dict | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
RCCResult
|
|
Source code in src/mfe/multivariate/rcc.py
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | |