需要实现一个限制持仓品种数量的策略,现有的逻辑是多图层不同品种相同周期叠加,但代码写完后不管是回测还是实盘模拟都有很多信号闪烁,可能我对多图层时的公式触发逻辑理解有误,是否代码逻辑有什么问题,请老师们指导一下。
Params
Numeric length(3);
Numeric ChiCangN(5);//持仓品种数
Vars
Series<Numeric> lots(1);
Series<Numeric> MA1;
Series<Numeric> MA2;
Series<Numeric> MA3;
Bool UPC;
Bool DNC;
Bool UPC2;
Bool DNC2;
Integer i;
Global Integer ChiCang;
Events
OnInit()
{
Range[0:DataCount-1]
{
AddDataFlag(Enum_Data_RolloverBackWard());//设置后复权
AddDataFlag(Enum_Data_RolloverRealPrice());//是否映射真实价格
AddDataFlag(Enum_Data_AutoSwapPosition());//设置自动换仓
AddDataFlag(Enum_Data_IgnoreSwapSignalCalc()); // 设置忽略换仓信号计算
}
}
onBar(ArrayRef<Integer> indexs)
{
//===========================================================================首先计算所有图层指标,再对需要平仓的图层进行平仓
Range[0:DataCount-1]//
{
MA1=Average(C,length);
MA2=Average(C,length*4);
MA3=Average(C,length*16);
ChiCang=0;
PlotAuto(\"MA1\",MA1);
PlotAuto(\"MA2\",MA2);
PlotAuto(\"MA3\",MA3);
UPC=CrossOver(MA1[1],MA2[1]) && MA2[1]>MA3[1];
DNC=CrossUnder(MA1[1],MA2[1]) && MA2[1]<MA3[1];
UPC2=MA1[1]>MA2[1];
DNC2=MA1[1]<MA2[1];
//=======平仓条件
If(MarketPosition>0 && DNC2)
{
Sell(0,O);
}
If(MarketPosition<0 && UPC2)
{
BuyToCover(0,O);
}
}
//===========================================================统计持仓品种数,得出可以开仓的次数。
Range[0:DataCount-1]
{
if(MarketPosition!=0)
{
ChiCang=ChiCang+1;
}
}
Commentary(\"ChiCang1=\"+Text(ChiCang));
//===========================================================然后对需要开仓的图层进行开仓。
Range[0:DataCount-1]
{
//开仓条件
If(MarketPosition<1 && UPC && ChiCang<ChiCangN )
{
Buy(Lots,O);
ChiCang=ChiCang+1;
}
If(MarketPosition>-1 && DNC && ChiCang<ChiCangN )
{
SellShort(Lots,O);
ChiCang=ChiCang+1;
}
if(ChiCang==ChiCangN)//持仓品种达到限制,跳出开仓循环
{
break;
}
}
Commentary(\"ChiCang2=\"+Text(ChiCang));
Print(\"ChiCang2=\"+Text(ChiCang));
/*Range[0:DataCount-1]//
{
}*/
//===========================================================
}
你自己回复了我以为有人答复过了就没点进来看了
如果你的数据是多图层不同品种之间数据要进行计算的话,那必须考虑k线对齐
因为不同品种,有可能出现有一个品种新出了k线,其他品种还是老k线,这种情况下就会发生,新品种的
k线数据变化了,导致你横向比较的结果也发生了闪烁,
所以你如果要横向比较不同图层数据最后得到信号条件的话,一定要加一个条件,就是k线对齐,
一般来说,k线对齐只要保证k线时间一致就行,也就是写一个循环比较,所有图层当前bar时间是否一致,不一致就不出计算结果
按照您的提示我这样修改了一下代码,保证k线时间一致时再执行开仓信号,但回测和实时行情测试都没什么效果依然是闪烁,这次的闪烁不是排在下面的图层信号消失,而是无规律的。您帮忙看看代码我写的对吗?如果不对应该怎么修改才能达到您说的效果?
Params
Numeric length(3);
Numeric ChiCangN(5);//持仓品种数
Vars
Series<Numeric> lots(1);
Series<Numeric> MA1;
Series<Numeric> MA2;
Series<Numeric> MA3;
Bool UPC;
Bool DNC;
Bool UPC2;
Bool DNC2;
Integer i;
Global Integer j;
Global Integer k;
Global Integer ChiCang;
Global Integer datatime;
Events
OnInit()
{
Range[0:DataCount-1]
{
AddDataFlag(Enum_Data_RolloverBackWard());//设置后复权
AddDataFlag(Enum_Data_RolloverRealPrice());//是否映射真实价格
AddDataFlag(Enum_Data_AutoSwapPosition());//设置自动换仓
AddDataFlag(Enum_Data_IgnoreSwapSignalCalc()); // 设置忽略换仓信号计算
}
}
onBar(ArrayRef<Integer> indexs)
{
//===========================================================================首先计算所有图层指标,再对需要平仓的图层进行平仓
Range[0:DataCount-1]//
{
MA1=Average(C,length);
MA2=Average(C,length*4);
MA3=Average(C,length*16);
ChiCang=0;
PlotAuto(\"MA1\",MA1);
PlotAuto(\"MA2\",MA2);
PlotAuto(\"MA3\",MA3);
UPC=CrossOver(MA1[1],MA2[1]) && MA2[1]>MA3[1];
DNC=CrossUnder(MA1[1],MA2[1]) && MA2[1]<MA3[1];
UPC2=MA1[1]>MA2[1];
DNC2=MA1[1]<MA2[1];
//=======平仓条件
If(MarketPosition>0 && DNC2)
{
Sell(0,O);
}
If(MarketPosition<0 && UPC2)
{
BuyToCover(0,O);
}
}
//===========================================================统计持仓品种数,得出可以开仓的次数。
datatime=Data[DataCount-1].Hour*10000+Data[DataCount-1].Minute*100+Data[DataCount-1].Second;
k=0;
For j=0 to DataCount-1
{
if(Data[j].Hour*10000+Data[j].Minute*100+Data[j].Second>=datatime)
{
k=k+1;
}
Print(\"k=\"+Text(k));
}
Range[0:DataCount-1]
{
if(k>=DataCount)
{
if(MarketPosition!=0)
{
ChiCang=ChiCang+1;
}
}
//Print(\"Hour=\"+Text(Hour*10000+Minute*100+Second));
}
Print(\"ChiCang1=\"+Text(ChiCang));
//Print(\"Hour=\"+Text(Hour*10000+Minute*100+Second));
//Print(\"Minute=\"+Text(Minute));
//Print(\"Second=\"+Text(Second));
//===========================================================然后对需要开仓的图层进行开仓。
Range[0:DataCount-1]
{
//开仓条件
If(MarketPosition<1 && UPC && ChiCang<ChiCangN && k>=DataCount)
{
Buy(Lots,O);
ChiCang=ChiCang+1;
}
If(MarketPosition>-1 && DNC && ChiCang<ChiCangN && k>=DataCount)
{
SellShort(Lots,O);
ChiCang=ChiCang+1;
}
if(ChiCang==ChiCangN)//持仓品种达到限制,跳出开仓循环
{
break;
}
}
Commentary(\"ChiCang2=\"+Text(ChiCang));
//Print(\"ChiCang2=:\" + Text(ChiCang));
/*Range[0:DataCount-1]//
{
}*/
//===========================================================
}
再次期待老师们的解答。
继续期待老师们的解答,如果可以的话,可否付费请老师编写一个解决方案?
期待老师们的解答。
盘中测试的情况如图。多图层时这个逻辑具体如何才能实现不让信号闪烁呢?
当20个品种叠加时,限制持仓5个品种,排列在下方的品种先出现的信号会被排在上方的图层品种后出现的信号给覆盖掉而出现闪烁,这个问题是什么原因呢?