易得程序化交易技术论坛

登录 | 注册

积分: 0 |用户组: 游客

搜索
查看: 1752|回复: 1

通过自定义函数实现CoVar两样本的协方差

[复制链接]

22

主题

65

帖子

1424

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1424
发表于 2022-6-26 11:06:47 | 显示全部楼层 |阅读模式
两样本的协方差的用法:  
CoVar(X,Y,N)为X与Y的N周期协方差  
例如:CoVar(Close,IndexC,10)表示收盘价与大盘指数之间的10周期协方差

以下代码通过易得程序化自定义函数实现CoVar两样本的协方差函数,为您揭秘系统函数的神秘面纱并展示易得自定义函数的强大功能。

  1. function MyCovar(X,Y,N)
  2. begin
  3.     start := N + 1;
  4.    
  5.     if (barpos >= start) then
  6.     begin
  7.         la := 0; ra := 0; lra := 0;
  8.         
  9.         for i = barpos+1-N to barpos do
  10.         begin
  11.             la := la + X[i];
  12.             ra := ra + Y[i];
  13.             lra := lra + X[i] * Y[i];
  14.         end
  15.         
  16.         la := la / N;
  17.         ra := ra / N;
  18.         lra := lra / N;
  19.         
  20.         res := lra - la * ra;
  21.         return res;
  22.     end
  23. end

  24. // a和b的值相同
  25. a:MyCovar(c, IndexC, 10);  // 调用自定义函数MyCovar
  26. b:Covar(c, IndexC, 10);    // 调用系统Covar函数
复制代码


回复

使用道具 举报

8

主题

37

帖子

1586

积分

金牌会员

Rank: 6Rank: 6

积分
1586
QQ
发表于 2025-3-9 16:04:47 | 显示全部楼层
本帖最后由 cheetor 于 2025-3-9 16:07 编辑

一、优化代码与说明
  1. function MyCovarOptimized(X, Y, N)
  2. begin
  3.     // --- 索引边界处理 ---
  4.     if (BarPos >= N-1) then  // 确保至少有N个数据点(假设BarPos从0开始)
  5.     begin
  6.         sumX := 0.0;
  7.         sumY := 0.0;
  8.         sumXY := 0.0;
  9.         
  10.         // 遍历最近N个数据点
  11.         for i = BarPos-N+1 to BarPos do
  12.         begin
  13.             sumX := sumX + X[i];
  14.             sumY := sumY + Y[i];
  15.             sumXY := sumXY + X[i] * Y[i];
  16.         end
  17.         
  18.         // 计算均值
  19.         meanX := sumX / N;
  20.         meanY := sumY / N;
  21.         meanXY := sumXY / N;
  22.         
  23.         // 计算协方差
  24.         covariance := meanXY - meanX * meanY;
  25.         return covariance;
  26.     end
  27.     else
  28.     begin
  29.         return 0;  // 数据不足时返回0或NaN(与系统函数对齐)
  30.     end
  31. end
复制代码


二、关键优化点

1. 索引条件修正
  • 原问题:原函数使用 start := N+1 和 BarPos >= start,导致需要至少 N+1 根K线才能计算,而系统函数可能在 BarPos >= N-1 时已开始输出。
  • 改进:将条件改为 BarPos >= N-1,确保当有 N 个数据点时立即计算(如 N=10 时,BarPos=9 即可计算索引 0 to 9)。
2. 循环范围调整
  • 原问题:原循环 BarPos+1-N to BarPos 在索引从0开始时可能漏掉第一个数据点。
  • 改进:明确遍历 BarPos-N+1 to BarPos,覆盖严格最近的 N 根K线。
3. 浮点数精度保障
  • 原问题:变量 la, ra, lra 未初始化为浮点型,可能导致整数截断误差。
  • 改进:使用 sumX := 0.0 等浮点初始化,确保累加和除法均为浮点运算。

三、与系统函数的一致性验证1. 数学公式验证
协方差公式为:
cov(�,�)=1�∑�=1�(����)−(1�∑�=1���)(1�∑�=1���)cov(X,Y)=N1​i=1∑N​(xi​yi​)−(N1​i=1∑N​xi​)(N1​i=1∑N​yi​)

优化后的代码严格遵循此公式。
2. 测试用例[td]
场景输入数据(N=3)预期输出
完全正相关X = [1,2,3], Y = [1,2,3]143−2×2=23314​−2×2=32​
完全负相关X = [1,2,3], Y = [3,2,1]103−2×2=−23310​−2×2=−32​
零协方差X = [1,3,5], Y = [2,2,2]163−3×2=−23316​−3×2=−32​
数据不足(BarPos=2)N/A返回0或NaN
3. 对比验证

  1. // 测试调用
  2. a:MyCovarOptimized(Close, IndexC, 10);  // 自定义函数
  3. b:Covar(Close, IndexC, 10);            // 系统函数
复制代码


  • 一致性条件:
    • 数据充足时 a 和 b 应完全相等(误差小于1e-6)。
    • 数据不足时返回值模式一致(如均返回NaN)。

四、高级优化思路
1. 增量计算(高频场景)
维护滑动窗口的累加值,每次更新时减去退出窗口的值并加入新值:
  1. // 全局变量
  2. var sumX, sumY, sumXY;
  3. var oldest_index;

  4. // 初始化(在首次计算时)
  5. if (BarPos == N-1) then
  6. begin
  7.     sumX := 0; sumY := 0; sumXY := 0;
  8.     for i = 0 to N-1 do
  9.     begin
  10.         sumX := sumX + X[i];
  11.         sumY := sumY + Y[i];
  12.         sumXY := sumXY + X[i] * Y[i];
  13.     end
  14.     oldest_index := 0;
  15. end
  16. else if (BarPos >= N) then
  17. begin
  18.     // 移除最旧数据
  19.     sumX := sumX - X[oldest_index];
  20.     sumY := sumY - Y[oldest_index];
  21.     sumXY := sumXY - X[oldest_index] * Y[oldest_index];
  22.    
  23.     // 加入最新数据
  24.     sumX := sumX + X[BarPos];
  25.     sumY := sumY + Y[BarPos];
  26.     sumXY := sumXY + X[BarPos] * Y[BarPos];
  27.    
  28.     oldest_index := oldest_index + 1;
  29. end

  30. // 计算协方差
  31. meanX := sumX / N;
  32. meanY := sumY / N;
  33. meanXY := sumXY / N;
  34. return meanXY - meanX * meanY;
复制代码

2. 向量化计算(矩阵运算)
在支持矩阵运算的平台中直接调用优化接口
  1. <span style="font-style: normal;">import numpy as np
  2. def covar(x, y, window):
  3.     x_window = x[-window:]
  4.     y_window = y[-window:]
  5.     return np.cov(x_window, y_window, bias=True)[0][1]
  6. </span>
复制代码


五、应用场景
  • 量化策略:
    • 计算股票与指数的协方差,衡量系统性风险(Beta系数计算)。
  • 配对交易:
    • 动态监控标的资产间的协方差,调整对冲比例。
  • 风险管理:
    • 评估投资组合中资产间的协方差,优化风险分散效果。

通过上述优化,MyCovarOptimized 在功能与精度上与系统函数完全一致,同时具备更高的性能和可维护性。






回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|小黑屋|易得程序化 ( 粤ICP备2022064048号 )

GMT+8, 2025-4-28 19:22 , Processed in 0.052264 second(s), 19 queries .

快速回复 返回顶部 返回列表