

以下代码在运行时有两个问题,第一:如图一所示,回测时只有"rb888.SHFE","ao888.SHFE","au888.SHFE"这三个品种有交易记录,剩余三个品种没有交易记录。第二:如图二所示,多头的四个条件都满足时,最足条件仍然显示不满足。我调试了一周,仍然没找出原因,恳请高手帮忙看看。
Params
Numeric MA_Period_1(20); // 均线周期
Numeric MA_Period_2(60); // 均线周期
Numeric YZ(1.3); // 阈值
Numeric ATR_Period(14); // ATR周期
Numeric StopLossPct(1.5); // 止损百分比
Numeric TrailMultiplier(2.0); // ATR移动止盈倍数
Numeric lots(1); // 开仓手数
array<string> mysymbol(["rb888.SHFE","ao888.SHFE","au888.SHFE","br888.SHFE","bu888.SHFE","cu888.SHFE"]);//"au888.SHFE",
Vars
// 多周期图层编号(全局变量)
Global array<Numeric> i1_array; // 存储日线图层
Global array<Numeric> i3_array; // 存储30分钟图层
Global Numeric i; // 用于循环或查找的临时索引
Global Numeric j; // 用于循环或查找的临时索引
Global Numeric i1; //存储日线图层的图层编号
Global Numeric i3; // 存储日线图层的图层编号
// 多周期均线(通过Range绑定图层)
Series<Numeric> MA_20; // 20均线
Series<Numeric> MA_60; // 60均线
Series<Numeric> ATR_Val; // ATR值
Series<Numeric> VR; //成交量
// 其他变量
Numeric TrailStop;
Series<Numeric> HighSinceEntry;
Series<Numeric> LowSinceEntry;
Series<bool> MA_Bull;
Series<bool> MA_Bear;
Series<Numeric> myStopPrice;
Series<Numeric> myentryprice;
Series<Numeric> myexitprice;
Numeric profit;
Numeric pricediff;
Series<bool> cond1(False);
Series<bool> cond2(False);
Series<bool> cond3(False);
Series<bool> cond4(False);
Series<bool> cond5(False);
Series<bool> cond6(False);
Series<bool> cond7(False);
Series<bool> cond8(False);
Events
OnInit()
{
Range[0:DataCount-1]
{
AddDataFlag(Enum_Data_RolloverBackWard()); //设置为后复权
AddDataFlag(Enum_Data_RolloverRealPrice()); //开平仓价格映射到不复权或除权后的价格
AddDataFlag(Enum_Data_AutoSwapPosition()); //根据除权或复权点移仓换月
AddDataFlag(Enum_Data_IgnoreSwapSignalCalc()); //设置忽略换仓信号计算,把移仓换月的俩笔交易算做一笔,以便胜率等指标真实的反映策略的的盈利能力
AddDataFlag(Enum_Data_FullPeriod()); //完全交易时段
}
//数据源叠加处理
//SetBeginBarMaxCount(100);//设置最大起始bar数为100
// 循环为每个品种订阅数据
for i = 0 to GetArraySize(mysymbol) - 1
{
i1_array[i] = SubscribeBar(mysymbol[i], "1d", 20200101);
i3_array[i] = SubscribeBar(mysymbol[i], "30m", 20200101);
}
}
OnBar(ArrayRef<Integer> indexs)
{
//获取当前是哪个图层在触发OnBar
Numeric currentLayer = indexs[0];
Numeric symbolIndex = -1; // 初始化为-1,表示未找到
//查找当前图层属于哪个品种
for i = 0 to GetArraySize(i1_array) - 1
{
// 如果当前触发的是该品种的日线或30分钟图层
if (currentLayer == i1_array[i] || currentLayer == i3_array[i])
{
symbolIndex = i; // 找到品种索引
i1 = i1_array[i]; // 赋值该品种的日线图层
i3 = i3_array[i]; // 赋值该品种的30分钟图层
break; // 找到后跳出循环
}
}
// 3. 如果未找到对应品种(安全处理),则直接返回
if (symbolIndex == -1)
{
return;
}
Range[0:DataCount-1]
{
MA_20 = XAverage(Close, 20);
MA_60 = XAverage(Close, 60);
ATR_Val = AvgTrueRange(ATR_Period);
VR = Vol / (SummationFC(Vol[1], 3) / 3);
PlotNumeric("20日线MA值", MA_20);
PlotNumeric("60日线MA值", MA_60);
}
for j = 0 to GetArraySize(i3_array) - 1
{
Range[i3_array[j] : i3_array[j]]
{
if(VR > YZ)
{
PlotBool("超过阈值", True);
}
}
}
Data[i1].cond1 = Data[i1].Close[1] > Data[i1].MA_20[1]; // 多头开仓条件一
Data[i1]. cond2 = Data[i1].MA_20[1] > Data[i1].MA_60[1]; // 多头开仓条件二
Data[i1].cond3 = Data[i3].Close[1] < Data[i3].MA_20[1]; // 多头开仓条件三
Data[i1]. cond4 = Data[i3].VR[1] > YZ; // 多头开仓条件四
MA_Bull = Data[i1].cond1 && Data[i1].cond2 && Data[i1].cond3 && Data[i1].cond4; // 多头完整开仓条件
Data[i1].PlotBool("ma_bull", Data[i1].MA_Bull);
Data[i3].Commentary("MA_Bull判断过程:");
// 条件1:用IIFString函数,true返回"满足",false返回"不满足"
Data[i3].Commentary("条件1(日线收盘价 > EMA20): " + IIFString(Data[i1].cond1, "满足", "不满足") + " 【值:" + Text(Data[i1].Close[1]) + " > " + Text(Data[i1].MA_20[1]) + "】");
// 条件2:同理处理1小时周期条件
Data[i3].Commentary("条件2(20日均线 > 60日均线): " + IIFString(Data[i1].cond2, "满足", "不满足") + " 【值:" + Text(Data[i1].MA_20[1]) + " > " + Text(Data[i1].MA_60[1]) + "】");
// 条件3:同理处理15分钟周期条件
Data[i3].Commentary("条件3(30分钟收盘价 < 30分钟MA20): " + IIFString(Data[i1].cond3, "满足", "不满足") + " 【值:" + Text(Data[i3].Close[1]) + " < " + Text(Data[i3].MA_20[1]) + "】");
// 条件4:30分钟级别成交量放大
Data[i3].Commentary("条件4(30分钟成交量 > 前1.5小时成交量): " + IIFString(Data[i1].cond4, "满足", "不满足") + " 【值:" + Text(Data[i3].VR[1]) + " > " + Text(YZ) + "】");
// 最终结果:用IfString函数描述MA_Bull的真假
Data[i3].Commentary("最终MA_Bull: " + IIFString( Data[i1].MA_Bull, "真(所有条件满足)", "假(至少一个条件不满足)"));
// 多头开仓逻辑
If(Data[i3].MarketPosition != 1 And MA_Bull)
{
Data[i3].Buy(lots, Data[i3].Open);
Data[i3].myentryprice = Data[i3].Open;
Data[i3].myStopPrice = Data[i3].myentryprice * (1 - StopLossPct * 0.01);
Data[i3].HighSinceEntry = Data[i3].High;
Data[i3].Commentary("开仓:myentryprice=" + Text(Data[i3].myentryprice));
}
// 多头平仓逻辑
If(Data[i3].MarketPosition == 1 And Data[i3].BarsSinceEntry >= 1)
{
If(Data[i3].High > Data[i3].HighSinceEntry)
Data[i3].HighSinceEntry = Data[i3].High;
Data[i3].TrailStop = Max(Data[i3].myStopPrice, Data[i3].HighSinceEntry - TrailMultiplier * Data[i3].ATR_Val);
If(Data[i3].Low <= Data[i3].TrailStop)
{
Data[i3].myexitprice = Min(Data[i3].Open, Data[i3].TrailStop);
Data[i3].pricediff = Data[i3].myexitprice - Data[i3].myentryprice;
Data[i3].profit = Data[i3].pricediff * abs(Data[i3].CurrentContracts()) * ContractUnit() * BigPointValue();
Data[i3].Sell(lots,Data[i3]. myexitprice);
Data[i3].Commentary("平仓:profit=" + Text(Data[i3].profit));
}
}
// 空头开仓条件
Data[i1].cond5 = Data[i1].Close[1] < Data[i1].MA_20[1]; // 空头开仓条件一
Data[i1].cond6 = Data[i1].MA_20[1] < Data[i1].MA_60[1]; // 空头开仓条件二
Data[i1].cond7 = Data[i3].Close[1] > Data[i3].MA_20[1]; // 空头开仓条件三
Data[i1].cond8 = Data[i3].VR[1] > YZ; // 空头开仓条件四
MA_Bear = cond5 && cond6 && cond7 && cond8; // 空头完整开仓条件
Data[i1].PlotBool("ma_bear", MA_Bear);
// 空头开仓逻辑
If(Data[i3].MarketPosition != -1 And MA_Bear)
{
Data[i3].SellShort(lots, Data[i3].Open);
Data[i3].myentryprice = Data[i3].Open;
Data[i3].myStopPrice = Data[i3].myentryprice * (1 + StopLossPct * 0.01);
Data[i3].LowSinceEntry = Data[i3].Low;
Data[i3].Commentary("开空仓:myentryprice=" + Text( Data[i3].myentryprice));
}
// 空头平仓逻辑
If(Data[i3].MarketPosition == -1 And Data[i3].BarsSinceEntry >= 1)
{
If(Data[i3].Low < Data[i3].LowSinceEntry)
Data[i3].LowSinceEntry = Data[i3].Low;
Data[i3].TrailStop = Min( Data[i3].myStopPrice, Data[i3].LowSinceEntry + TrailMultiplier * ATR_Val);
If(Data[i3].High >= Data[i3].TrailStop)
{
Data[i3].myexitprice = Max(Data[i3].Open, Data[i3].TrailStop);
Data[i3].pricediff = Data[i3].myentryprice - Data[i3].myexitprice;
Data[i3].profit = Data[i3].pricediff * abs(Data[i3].CurrentContracts()) * ContractUnit() * BigPointValue();
Data[i3].BuyToCover(lots, Data[i3].myexitprice);
Data[i3].Commentary("平空仓:profit=" + Text( Data[i3].profit));
}
}
}

程序内部逻辑问题吧,你把你前面的品种去掉就有了
王老师,我把品种调整了顺序,现在的顺序是"br888.SHFE","bu888.SHFE","cu888.SHFE","rb888.SHFE","ao888.SHFE","au888.SHFE"。回测的时候br,bu,cu,au这四个品种有交易记录,rb和ao没有交易记录。请问这是数据源的问题,还是图层没对齐,还是因为图层和索引绑定问题?