多品种垮周期轮动策略图层和索引绑定问题



以下代码在运行时有两个问题,第一:如图一所示,回测时只有"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));
				}
			}
			
}


横截面策略轮动开仓的问题
请问TBQ支持编写ETF轮动的策略吗
请教!关于多品种,跨周期,多图层
多品种、跨周期
多图层回测中【周期设置】和【复权方式】选择问题
多周期,只设置图层时间,品种手选
请教!多品种,跨周期,多图层,RANGE下获取当前品种交易结束时间。
多策略多周期多品种实盘性能方面的疑问
多图层策略部分图层不成交问题
多图层onBar(),各品种bar的时间对齐问题


程序内部逻辑问题吧,你把你前面的品种去掉就有了


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