如何在DolphinDB中按ticker计算股票与指数收益的滚动相关性
需求:开发量化对冲策略时,需按ticker分组,计算每只股票收益与指数收益的60日滚动相关性。数据按交易日逐行存储,包含stock_ret(股票收益)和index_ret(指数收益)两列。
示例数据(5日窗口验证用)
以下是用于验证的5日窗口示例代码(实际场景替换为60日):
dates = take(2024.01.02 + 0..19, 60) tickers = sort(take(`AAPL`MSFT`GOOG, 60)) index_ret = take([0.006, -0.0004, 0.0075, 0.0162, -0.0013, 0.008, -0.002, 0.005, 0.011, -0.006, 0.003, 0.007, -0.004, 0.009, 0.002, -0.005, 0.004, 0.008, -0.003, 0.006], 60) stock_ret = index_ret * 1.1 + take([0.001, -0.002, 0.003, -0.001, 0.002, -0.001, 0.002, -0.003, 0.001, -0.002, 0.002, -0.001, 0.001, 0.003, -0.004, 0.001, -0.002, 0.003, -0.001, 0.002], 60) t = table(dates as date, tickers as ticker, stock_ret as stock_ret, index_ret as index_ret)
预期输出
每只股票每日一行数据,窗口未满的前N-1行(5日窗口为前4行,60日窗口为前59行)显示NULL,从第N行开始返回计算值:
| date | ticker | rolling_corr |
|---|---|---|
| 2024-01-02 | AAPL | NULL |
| ... | ... | ... |
| 2024-01-08 | AAPL | 0.897 |
| 2024-01-09 | AAPL | 0.898 |
问题重现
尝试直接将两列打包为列表传入rolling函数:
select date, ticker, rolling(corr, [stock_ret, index_ret], 5) as rolling_corr from t context by ticker
抛出错误:
The length of the vector returned by the UDF specified in SELECT must be the same as the length of the CONTEXT BY column. RefId: S02027
该错误是因为rolling函数无法直接识别多列列表的传入方式,导致内部处理时出现长度不匹配。
解决方案
在DolphinDB中,有两种常用方法处理多列输入的滚动窗口计算:
方法1:使用匿名函数包装corr计算
通过匿名函数接收窗口内的多列数据,再调用corr计算相关性:
select date, ticker, rolling(5, x -> corr(x[0], x[1]), [stock_ret, index_ret]) as rolling_corr from t context by ticker
这里rolling函数的第一个参数是窗口大小,第二个参数是匿名函数,接收窗口内的多列数组(x[0]对应stock_ret窗口数据,x[1]对应index_ret窗口数据),最后传入要处理的多列列表。
方法2:使用mvRoll函数(专门处理多变量滚动计算)
mvRoll是DolphinDB专为多变量滚动计算设计的函数,可直接传入多列和计算函数:
select date, ticker, mvRoll([stock_ret, index_ret], 5, corr) as rolling_corr from t context by ticker
该函数会自动将窗口内的多列数据传入corr函数,无需额外包装,写法更简洁。
两种方法均能实现需求,窗口未满时自动返回NULL,满窗口后输出计算得到的滚动相关性。
内容的提问来源于stack exchange,提问作者Allan

