You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何计算时间序列中多股票间的滚动相关系数矩阵?

计算多只股票滚动相关系数矩阵的解决方案

问题背景

我正在进行股票组合分析,需要计算多只股票间的滚动相关系数矩阵,动态监控它们的相关性变化。

具体需求

针对每个交易日,使用当日及前59天(共60个交易日)的收益数据,计算所有股票对的相关系数。

样本数据

// Generate simulated return data for 4 stocks over 90 days
n_days = 90
n_stocks = 4
stock_list = `stock_A`stock_B`stock_C`stock_D

// Generate dates and stock symbols (90 days for each stock)
trade_date = (2023.10.01 + 0..(n_days-1)) join (2023.10.01 + 0..(n_days-1)) join (2023.10.01 + 0..(n_days-1)) join (2023.10.01 + 0..(n_days-1))
symbol = take(`stock_A, n_days) join take(`stock_B, n_days) join take(`stock_C, n_days) join take(`stock_D, n_days)

// Generate return data
return_A = norm(0.001, 0.02, n_days)
return_B = return_A * 0.7 + norm(0, 0.015, n_days)  // Correlated with A
return_C = norm(0.0012, 0.018, n_days)
return_D = norm(0.0005, 0.015, n_days)

daily_return = return_A join return_B join return_C join return_D

returns = table(trade_date, symbol, daily_return)

// View data structure
select top 20 * from returns order by trade_date, symbol

已尝试方案

直接使用corr()函数

// Attempting to calculate correlation in a 60-day rolling window
result = select corr(daily_return) as correlation
from returns
context by symbol

// Error: corr requires two parameters, cannot pass only one column
// Syntax Error: [line #24] The function [corr] expects 2 argument(s), but the actual number of arguments is: 1

corr()函数需要两个变量作为参数,但数据中不同股票的收益都在daily_return列中,不知道如何配对不同股票来计算相关系数。

核心问题

如何针对这种格式的时间序列数据,计算所有股票对的滚动相关系数?

解决方案

要解决这个问题,需要先将长格式的数据转换为宽格式(每只股票的收益作为单独列),再通过滚动窗口计算相关系数矩阵。以下是完整的Q语言实现步骤:

步骤1:转换数据格式为宽表

首先把长表转换为宽表,每一列对应一只股票的日收益:

// 转换为宽格式:trade_date 作为行索引,每只股票对应一列
wide_returns = pivot(returns, `trade_date, `symbol, `daily_return)

步骤2:定义滚动窗口相关系数计算函数

编写一个函数,输入指定窗口内的收益数据,输出所有股票对的相关系数表:

// 计算相关系数矩阵并转换为长表格式
corrPairs:{[df]
    // 计算相关系数矩阵
    corr_mat = corr each flip df;
    // 获取股票列表
    syms = cols df;
    // 生成所有股票对(排除自身配对)
    pairs = syms cross syms where not syms cross syms like each syms;
    // 提取对应相关系数值
    corr_vals = raze corr_mat where not iota[count syms] cross iota[count syms] like each iota[count syms];
    // 返回结果表
    table(symbol1: first each pairs, symbol2: last each pairs, correlation: corr_vals)
}

步骤3:滚动窗口计算

使用rolling函数对宽表应用滚动窗口,结合上述函数计算每个窗口的相关系数:

// 设置滚动窗口大小为60
window_size = 60

// 对每一行,取当前行及前59行的数据计算相关系数
rolling_corr = select trade_date, ungroup corrPairs(wide_returns[window_start::window_end;])
from wide_returns
where window_end = iota[count wide_returns], window_start = max(0; window_end - window_size + 1)
// 过滤掉窗口数据不足60天的行
where window_end >= window_size - 1

步骤4:结果说明

最终结果表rolling_corr包含以下字段:

  • trade_date:当前交易日(窗口结束日)
  • symbol1:股票对中的第一只股票
  • symbol2:股票对中的第二只股票
  • correlation:两只股票在过去60个交易日的相关系数

这样就能得到每个交易日对应的所有股票对滚动相关系数,满足动态监控的需求。


内容的提问来源于stack exchange,提问作者xinyu zhang

火山引擎 最新活动