SierraChart中ACSIL代码编译错误:SimpleMovAvg函数调用问题
SierraChart ACSIL 指标迁移:数组处理与编译错误解决
核心问题分析
你遇到的编译错误本质是未将MA、Main、Signal声明为数组——SierraChart的ACSIL框架中,所有需要逐Bar计算并持久化的指标值都必须用数组承载,因为每个K线Bar对应一个独立的计算结果,单个变量无法存储全序列数据。
修正步骤与完整代码示例
1. 声明数组变量
直接使用SierraChart提供的SCDoubleArray类型声明动态数组,适配K线序列长度:
SCDoubleArray ssArray; // 存储每个Bar的ss累积值 SCDoubleArray MA; // 存储MA序列 SCDoubleArray Main; // 存储Main序列 SCDoubleArray Signal; // 存储Signal序列
2. 修正ss值的逐Bar计算逻辑
注意原逻辑中“遍历0至Length-1”是指对每个Bar向前回溯Length个周期计算ss累积值,而非仅计算一次。正确的循环实现如下:
for (int Index = 0; Index < sc.ArraySize; Index++) { int ss = 0; // 回溯Length个周期,超出数据范围则停止 for (int Lookback = 0; Lookback < Length; Lookback++) { const int CurrentIndex = Index - Lookback; if (CurrentIndex < 0) break; const float Close = sc.Close[CurrentIndex]; const float Open = sc.Open[CurrentIndex]; if (Close > Open) ss += 1; else if (Close < Open) ss -= 1; } ssArray[Index] = ss; }
3. 调用内置移动平均函数处理数组
使用SierraChart内置的SimpleMovAvg函数时,需传入输入数组、计算范围、周期参数,并将结果写入目标数组:
// 计算MA:ssArray的Length周期简单移动平均 SimpleMovAvg(ssArray, 0, sc.ArraySize, Length, MA); // 计算Main:MA的SmoothLength周期简单移动平均 SimpleMovAvg(MA, 0, sc.ArraySize, SmoothLength, Main); // 计算Signal:MA的CalcLength周期简单移动平均 SimpleMovAvg(MA, 0, sc.ArraySize, CalcLength, Signal);
4. 绑定副图输出(必须步骤)
将计算好的数组绑定到SierraChart的副图对象,确保指标能在图表上显示:
sc.Subgraph[0].Name = "MA"; sc.Subgraph[0].Data = MA; sc.Subgraph[1].Name = "Main"; sc.Subgraph[1].Data = Main; sc.Subgraph[2].Name = "Signal"; sc.Subgraph[2].Data = Signal;
完整可编译代码
#include "sierrachart.h" SCDLLName("Custom Momentum Indicator") SCSFExport scsf_CustomMomentumIndicator(SCStudyInterfaceRef sc) { if (sc.SetDefaults) { sc.GraphName = "Custom Momentum"; sc.AutoLoop = 0; // 关闭自动循环,手动控制计算逻辑 sc.FreeDLL = 0; // 初始化输入参数 sc.Input[0].Name = "Length"; sc.Input[0].SetInt(14); sc.Input[1].Name = "CalcLength"; sc.Input[1].SetInt(9); sc.Input[2].Name = "SmoothLength"; sc.Input[2].SetInt(5); // 初始化副图名称 sc.Subgraph[0].Name = "MA"; sc.Subgraph[1].Name = "Main"; sc.Subgraph[2].Name = "Signal"; return; } // 获取输入参数值 const int Length = sc.Input[0].GetInt(); const int CalcLength = sc.Input[1].GetInt(); const int SmoothLength = sc.Input[2].GetInt(); // 声明适配序列长度的数组 SCDoubleArray ssArray(sc.ArraySize); SCDoubleArray MA(sc.ArraySize); SCDoubleArray Main(sc.ArraySize); SCDoubleArray Signal(sc.ArraySize); // 逐Bar计算ss累积值 for (int Index = 0; Index < sc.ArraySize; Index++) { int ss = 0; for (int Lookback = 0; Lookback < Length; Lookback++) { const int CurrentIndex = Index - Lookback; if (CurrentIndex < 0) break; const float Close = sc.Close[CurrentIndex]; const float Open = sc.Open[CurrentIndex]; if (Close > Open) ss += 1; else if (Close < Open) ss -= 1; } ssArray[Index] = ss; } // 计算各层移动平均 SimpleMovAvg(ssArray, 0, sc.ArraySize, Length, MA); SimpleMovAvg(MA, 0, sc.ArraySize, SmoothLength, Main); SimpleMovAvg(MA, 0, sc.ArraySize, CalcLength, Signal); // 绑定数组到副图 sc.Subgraph[0].Data = MA; sc.Subgraph[1].Data = Main; sc.Subgraph[2].Data = Signal; }
关键错误点总结
- 单变量替代数组:如果用单个
double变量存储MA/Main/Signal,只能保存最后一个Bar的计算值,既不符合指标逻辑,也会因类型不匹配触发编译错误。 - 回溯逻辑偏差:原描述的“遍历0至Length-1”容易被误解为全局计算一次,实际需要对每个Bar独立回溯计算,否则指标输出完全不符合需求。
- 未绑定副图数组:即使完成了数组计算,若未将数组赋值给
sc.Subgraph[n].Data,图表上不会显示任何指标线条。
内容的提问来源于stack exchange,提问作者Sam.H
相关产品推荐
相关产品推荐

