易得程序化交易技术论坛

登录 | 注册

积分: 0 |用户组: 游客

搜索
查看: 1954|回复: 2

通过自定义函数实现Relate两样本的相关系数

[复制链接]

22

主题

65

帖子

1423

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1423
发表于 2022-6-26 11:24:47 | 显示全部楼层 |阅读模式
两样本的相关系数的用法:  
Relate(X,Y,N)为X与Y的N周期相关系数,其有效值范围在-1 - 1之间  
例如:Relate(Close,IndexC,10)表示收盘价与大盘指数之间的10周期相关系数

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

  1. function MyRelate(X,Y,N)
  2. begin
  3.     start := N + 1;
  4.    
  5.     if (barpos >= start) then
  6.     begin
  7.         la := 0; ra := 0; lra := 0; la2 := 0; ra2 := 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.             la2 := la2 + X[i] * X[i];
  15.             ra2 := ra2 + Y[i] * Y[i];
  16.         end
  17.         
  18.         la := la / N;
  19.         ra := ra / N;
  20.         lra := lra / N;
  21.         la2 := la2 / N;
  22.         ra2 := ra2 / N;

  23.         covarx := lra-la*ra;
  24.         stddevx := sqrt(max(0, la2-la*la));
  25.         stddevy := sqrt(max(0, ra2-ra*ra));
  26.         ssx := stddevx * stddevy;
  27.         if (ssx != 0) then
  28.             res :=  covarx / ssx;

  29.         return res;
  30.     end
  31. end

  32. // a和b的值相同
  33. a:MyRelate(c, IndexC, 10);  // 调用自定义函数MyRelate
  34. b:Relate(c, IndexC, 10);    // 调用系统Relate函数
复制代码


回复

使用道具 举报

5

主题

15

帖子

411

积分

中级会员

Rank: 3Rank: 3

积分
411
发表于 2023-3-19 19:19:37 | 显示全部楼层
长知识了。谢谢!
回复

使用道具 举报

8

主题

37

帖子

1586

积分

金牌会员

Rank: 6Rank: 6

积分
1586
QQ
发表于 2025-3-9 15:52:05 | 显示全部楼层
本帖最后由 cheetor 于 2025-3-9 15:54 编辑

一、原函数问题诊断
1. 窗口索引偏移错误
  • 错误点:原函数中 start := N + 1,导致 BarPos >= N+1 时才触发计算,实际需要的是 最近N根K线,正确条件应为 BarPos >= N-1(假设 BarPos 从0开始)。
  • 影响:当 BarPos = N 时,原函数无法计算,而系统函数 Relate 可能已开始输出有效值,导致 a 和 b 不一致。
2. 循环范围误差
  • 原循环 for i = BarPos+1-N to BarPos 在 BarPos < N-1 时可能访问负数索引,需增加边界检查。

二、优化代码
  1. function MyRelateOptimized(X, Y, N)
  2. begin
  3.     if (BarPos >= N-1) then  // 确保至少有N根K线(索引从0开始)
  4.     begin
  5.         sumX := 0.0;
  6.         sumY := 0.0;
  7.         sumXY := 0.0;
  8.         sumX2 := 0.0;
  9.         sumY2 := 0.0;
  10.         
  11.         // 遍历最近N根K线
  12.         for i = BarPos-N+1 to BarPos do
  13.         begin
  14.             sumX := sumX + X[i];
  15.             sumY := sumY + Y[i];
  16.             sumXY := sumXY + X[i] * Y[i];
  17.             sumX2 := sumX2 + X[i] * X[i];
  18.             sumY2 := sumY2 + Y[i] * Y[i];
  19.         end
  20.         
  21.         // 计算均值
  22.         meanX := sumX / N;
  23.         meanY := sumY / N;
  24.         
  25.         // 协方差与标准差
  26.         covXY := (sumXY / N) - meanX * meanY;
  27.         varX := max(0, (sumX2 / N) - meanX * meanX);
  28.         varY := max(0, (sumY2 / N) - meanY * meanY);
  29.         stdX := sqrt(varX);
  30.         stdY := sqrt(varY);
  31.         
  32.         // 计算相关系数
  33.         if (stdX * stdY != 0) then
  34.             r := covXY / (stdX * stdY)
  35.         else
  36.             r := 0;  // 处理零标准差情况
  37.         
  38.         return r;
  39.     end
  40.     else
  41.     begin
  42.         return 0;  // 数据不足时返回0或NaN
  43.     end
  44. end
复制代码


三、关键优化说明
1. 修正窗口索引
  • 条件判断:将触发计算的阈值改为 BarPos >= N-1,确保当有足够数据时立即计算。
  • 循环范围:BarPos-N+1 to BarPos 明确遍历最近N根K线(如 N=10 时,BarPos=9 对应索引 0 to 9)。
2. 变量命名与公式透明性
  • 命名规范化:sumX, sumXY 等变量名更直观反映计算内容。
  • 公式对齐:严格遵循皮尔逊相关系数公式:
    �=cov(�,�)����,cov(�,�)=�[��]−�[�]�[�]r=σX​σY​cov(X,Y)​,cov(X,Y)=E[XY]−E[X]E[Y]

3. 健壮性增强
  • 方差非负处理:max(0, ...) 防止计算误差导致负方差。
  • 零标准差处理:当 stdX 或 stdY 为零时返回0,避免除零错误。

四、与系统函数 Relate 的一致性验证
1. 测试用例[td]
场景输入数据预期输出(a 和 b)
完全正相关X = Y = [1,2,3,4,5]1.0
完全负相关X = [1,2,3], Y = [3,2,1]-1.0
零相关X = [1,3,5], Y = [2,2,2]0
数据不足(BarPos < N-1)N/A0 或 NaN
2. 平台差异处理
  • 索引起点:若平台中 BarPos 从1开始,需调整循环为 BarPos-N to BarPos-1。
  • 浮点精度:确保与系统函数使用相同的精度(如四舍五入到小数点后4位)。

五、性能优化建议
  • 增量计算:
    若需高频调用,可缓存 sumX, sumXY 等值,每次更新时减去退出窗口的值并加入新值,复杂度从 O(N) 降至 O(1):
    1. // 全局缓存变量
    2. var prev_sumX, prev_sumY, prev_sumXY, prev_sumX2, prev_sumY2;

    3. // 更新逻辑
    4. if (BarPos > N-1) then
    5. begin
    6.     oldX := X[BarPos-N];
    7.     oldY := Y[BarPos-N];
    8.     prev_sumX := prev_sumX - oldX + X[BarPos];
    9.     prev_sumY := prev_sumY - oldY + Y[BarPos];
    10.     // 类似更新其他sum值
    11. end
    复制代码

  • 并行计算:
    在支持向量化计算的平台(如Python NumPy)中,直接调用矩阵运算加速。


六、应用场景
  • 因子分析:计算个股与指数的相关性,判断市场联动性。
  • 配对交易:筛选高相关性标的,监控价差稳定性。
  • 风险模型:评估投资组合中各资产的相关性,优化分散性。
通过上述优化,MyRelateOptimized 在功能上应与系统 Relate 函数完全一致,且具备更高的可读性和健壮性。




回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-28 16:21 , Processed in 0.056449 second(s), 20 queries .

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