|
发表于 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 时可能访问负数索引,需增加边界检查。
二、优化代码
- function MyRelateOptimized(X, Y, N)
- begin
- if (BarPos >= N-1) then // 确保至少有N根K线(索引从0开始)
- begin
- sumX := 0.0;
- sumY := 0.0;
- sumXY := 0.0;
- sumX2 := 0.0;
- sumY2 := 0.0;
-
- // 遍历最近N根K线
- for i = BarPos-N+1 to BarPos do
- begin
- sumX := sumX + X[i];
- sumY := sumY + Y[i];
- sumXY := sumXY + X[i] * Y[i];
- sumX2 := sumX2 + X[i] * X[i];
- sumY2 := sumY2 + Y[i] * Y[i];
- end
-
- // 计算均值
- meanX := sumX / N;
- meanY := sumY / N;
-
- // 协方差与标准差
- covXY := (sumXY / N) - meanX * meanY;
- varX := max(0, (sumX2 / N) - meanX * meanX);
- varY := max(0, (sumY2 / N) - meanY * meanY);
- stdX := sqrt(varX);
- stdY := sqrt(varY);
-
- // 计算相关系数
- if (stdX * stdY != 0) then
- r := covXY / (stdX * stdY)
- else
- r := 0; // 处理零标准差情况
-
- return r;
- end
- else
- begin
- return 0; // 数据不足时返回0或NaN
- end
- 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σYcov(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/A | 0 或 NaN | 2. 平台差异处理- 索引起点:若平台中 BarPos 从1开始,需调整循环为 BarPos-N to BarPos-1。
- 浮点精度:确保与系统函数使用相同的精度(如四舍五入到小数点后4位)。
五、性能优化建议增量计算:
若需高频调用,可缓存 sumX, sumXY 等值,每次更新时减去退出窗口的值并加入新值,复杂度从 O(N) 降至 O(1): - // 全局缓存变量
- var prev_sumX, prev_sumY, prev_sumXY, prev_sumX2, prev_sumY2;
- // 更新逻辑
- if (BarPos > N-1) then
- begin
- oldX := X[BarPos-N];
- oldY := Y[BarPos-N];
- prev_sumX := prev_sumX - oldX + X[BarPos];
- prev_sumY := prev_sumY - oldY + Y[BarPos];
- // 类似更新其他sum值
- end
复制代码
并行计算:
在支持向量化计算的平台(如Python NumPy)中,直接调用矩阵运算加速。
六、应用场景- 因子分析:计算个股与指数的相关性,判断市场联动性。
- 配对交易:筛选高相关性标的,监控价差稳定性。
- 风险模型:评估投资组合中各资产的相关性,优化分散性。
通过上述优化,MyRelateOptimized 在功能上应与系统 Relate 函数完全一致,且具备更高的可读性和健壮性。
|
|