🚀 AI 一键生成 joinquant 策略代码
立即体验
👉 AI 生成代码 👈

如何在 JoinQuant 平台实现 DCC-GARCH 动态相关性分析策略?

joinquant | 发布时间: 2026/6/24
以下内容由 EasyQuant 生成。

问题描述

关于策略相关性研究

请问各位大神能不能实现DCC-GARCH分析?希望基于相关性分析构建策略。
请问如何编程构建股票收益率的动态条件相关系数(Dynamic conditional correlation)模型,目前我只知道Python有一般garch模型的函数garch。

解决方案

DCC-GARCH 模型在量化交易中的应用

在量化投资中,资产之间的相关性往往不是恒定不变的。DCC-GARCH(Dynamic Conditional Correlation GARCH,动态条件相关系数模型) 能够有效地捕捉资产收益率之间随时间波动的相关性,这对于统计套利(如配对交易)投资组合优化风险管理具有极大的价值。

在 JoinQuant(聚宽)平台上,虽然 Python 的标准库中没有像 R 语言 rmgarch 那样完善的多元 GARCH 现成包,但我们完全可以通过结合 arch 库(用于单变量 GARCH 拟合)和 scipy.optimize(用于极大似然估计)来自己构建 DCC-GARCH 模型。


在 JoinQuant 中实现 DCC-GARCH 的步骤

实现 DCC-GARCH 通常分为两步(Engle 的两步估计法):

  1. 第一步:对每个资产的收益率序列分别拟合单变量 GARCH 模型,提取出条件方差标准化残差
  2. 第二步:利用第一步得到的标准化残差,通过极大似然估计(MLE)拟合 DCC 模型的参数($\alpha$ 和 $\beta$),从而计算出动态相关系数矩阵。

1. 数据获取与预处理

首先,我们需要使用 JoinQuant 的 API 获取目标股票的历史价格数据并计算对数收益率。

import jqdata
import pandas as pd
import numpy as np
from arch import arch_model
import scipy.optimize as opt

# 获取两只股票的数据(例如:平安银行和万科A)
stock1 = '000001.XSHE'
stock2 = '000002.XSHE'
start_date = '2020-01-01'
end_date = '2023-01-01'

df1 = get_price(stock1, start_date=start_date, end_date=end_date, frequency='daily', fields=['close'])
df2 = get_price(stock2, start_date=start_date, end_date=end_date, frequency='daily', fields=['close'])

# 计算对数收益率
ret1 = np.log(df1['close'] / df1['close'].shift(1)).dropna() * 100
ret2 = np.log(df2['close'] / df2['close'].shift(1)).dropna() * 100

returns = pd.concat([ret1, ret2], axis=1)
returns.columns = [stock1, stock2]

2. 第一步:单变量 GARCH 拟合

使用 Python 的 arch 库对每个序列拟合 GARCH(1,1) 模型。

# 存储标准化残差和条件方差
std_resid = pd.DataFrame(index=returns.index, columns=returns.columns)
cond_vol = pd.DataFrame(index=returns.index, columns=returns.columns)

for col in returns.columns:
    # 构建 GARCH(1,1) 模型,假设均值为常数
    am = arch_model(returns[col], mean='Constant', vol='GARCH', p=1, q=1)
    res = am.fit(disp='off')
    cond_vol[col] = res.conditional_volatility
    std_resid[col] = res.resid / res.conditional_volatility

3. 第二步:DCC 参数估计与动态相关系数计算

这一步需要自定义似然函数并使用 scipy.optimize 求解。为了简化,以下提供 DCC 核心逻辑的伪代码框架:

# 计算标准化残差的无条件相关系数矩阵 Q_bar
Q_bar = np.cov(std_resid.T)

# 定义 DCC 似然函数 (简化版框架)
def dcc_loss(params, std_resid, Q_bar):
    a, b = params[0], params[1]
    T, N = std_resid.shape
    
    # 约束条件:a > 0, b > 0, a + b < 1
    if a <= 0 or b <= 0 or a + b >= 1:
        return 1e10
    
    Q_t = np.zeros((T, N, N))
    Q_t[0] = Q_bar
    loglik = 0.0
    
    for t in range(1, T):
        eps_t_1 = std_resid.iloc[t-1].values.reshape(-1, 1)
        # DCC 演化方程
        Q_t[t] = (1 - a - b) * Q_bar + a * (eps_t_1 @ eps_t_1.T) + b * Q_t[t-1]
        
        # 计算相关系数矩阵 R_t
        D_t_inv = np.diag(1 / np.sqrt(np.diag(Q_t[t])))
        R_t = D_t_inv @ Q_t[t] @ D_t_inv
        
        # 累加对数似然值 (此处省略具体的多元正态似然公式)
        # loglik += ... 
        
    return -loglik

# 使用 scipy.optimize.minimize 求解最优的 a 和 b
# initial_guess = [0.05, 0.90]
# bounds = ((0.0001, 0.9999), (0.0001, 0.9999))
# result = opt.minimize(dcc_loss, initial_guess, args=(std_resid, Q_bar), bounds=bounds)

注:完整的 DCC 似然函数较为复杂,建议在 JoinQuant 研究环境中引入开源的 Python DCC-GARCH 实现脚本(如 GitHub 上的 mgarch 库)作为自定义模块调用。


基于 DCC-GARCH 的策略构建思路

一旦你计算出了两只股票(或资产)每天的动态条件相关系数 $\rho_t$,就可以构建以下类型的量化策略:

1. 动态配对交易策略 (Pairs Trading)

传统的配对交易依赖于协整关系的长期稳定性。结合 DCC-GARCH:

  • 信号生成:当两只股票的动态相关系数 $\rho_t$ 处于历史高位(例如 > 0.8),但它们的价格比值(或价差)偏离了历史均值超过 2 个标准差时,说明出现了暂时的定价错误。
  • 交易动作:做空相对高估的股票,做多相对低估的股票。
  • 平仓信号:当价差回归均值,或者动态相关系数 $\rho_t$ 突然大幅下降(说明联动逻辑破裂)时平仓止损。

2. 动态风险平价组合 (Risk Parity)

在构建投资组合时,传统的马科维茨均值-方差模型使用静态协方差矩阵。使用 DCC-GARCH:

  • 每天根据 GARCH 预测的波动率和 DCC 预测的相关系数,重构动态协方差矩阵
  • 将该矩阵输入到 JoinQuant 的 portfolio_optimizer(投资组合优化器)中,选择 MinVariance(最小化方差)或 RiskParity(风险平价)目标函数,实现每日或每周的动态调仓,从而更敏锐地应对市场系统性风险的变化。

总结

在 JoinQuant 平台上实现 DCC-GARCH 需要一定的统计编程基础。建议先在**研究环境(Jupyter Notebook)**中利用历史数据跑通两步估计法,将计算出的动态相关系数序列保存下来,观察其与资产价差的关系。验证有效后,再将其封装为函数,引入到 handle_data 或定时运行函数中进行回测。