实盘(模拟账户)时出现了信号闪烁问题,程序发出了平空委托,但再次打开程序的K线信号图时,平空信号却消失了。
一、先上代码:
Global Numeric BuyLine;
Global Numeric SellLine;
OnInit()
{
SubscribeBar("000300.SSE","1d",20220901);//订阅沪深300指数(000300.SSE)日K线行情
SubscribeBar("000300.SSE","5m",20220901);//订阅沪深300指数1分钟K线行情
SubscribeBar("IF888.CFFEX","5m",20220901);//订阅沪深300期货1分钟K线行情
}
Range[2:2]
{
If(data1.High > BuyLine AND time >= 0.1 AND time <= 0.143 and BarsSinceToday>0)
{
If(MarketPosition==0)
{
Buy(lot,max(open,BuyLine));
data1.PlotString("Buy","多",low,red);
}
Else if (MarketPosition==-1)
{
BuyToCover(lot,max(open,BuyLine));
Buy(lot,max(open,BuyLine));
data1.PlotString("Buy","反多",low,red);
}
}
else If(data1.Low < SellLine and Time >= 0.1 and Time <= 0.143 and BarsSinceToday >0) //当向下突破并且无多单时,开空单
{
If(MarketPosition==0)
{
SellShort(lot,min(open,SellLine));
data1.PlotString("Sell","空",high,Green);
}
Else if (MarketPosition==1)
{
Sell(lot,min(open,SellLine));
SellShort(lot,min(open,SellLine));
data1.PlotString("Sell","反空",high,Green);
}
}
Else if (data1.Low[1] >= SellLine and data1.High[1] <= BuyLine and time==0.1 AND MarketPosition<>0)
//如果在10:00分没有向上或向下突破,且昨日有持仓,则平仓
{
If(MarketPosition==1 and BarsSinceEntry >0)
{
Sell(lot,Open[0]);
data1.PlotString("Cover","平多",high,Yellow);
}
Else If(MarketPosition==-1 and BarsSinceEntry >0)
{
BuyToCover(lot,Open[0]);
data1.PlotString("Cover","平空",low,Yellow);
}
}
}
如上图的红色代码所示,当10:00时由于上一根bar的最高点和最低点没有突破区间,则要进行平仓操作,如下图所示:
这里有两个问题,求老师解答:
1、为什么9:59:59秒就发出了委托单?
2、平仓信号出现后又消失了,这是为什么?是因为time的时候不对吗?是否要改成currenttime?抑或是其他原因?
首先,第一个原则,如果是跨周期的模型,交易信号一定要出在最小的周期上,而且这个最小的周期数一定是所有周期的公约数,这个在跨周期的专题课里也详细说明了。
建议用fileappend或者print函数输出日志,记录一下发生信号时的所有条件值,方便跟踪确定。
这个信号闪烁已经属于比较复杂难解决的案例了,能提供的帮助有限,只能依靠自身编写日志语句,通过查询模型的运行轨迹来诊断
我这里用了三个图层,hs300指数的日K,5分钟K线为0、1号图层,if888的5分钟K线为2号图层。0号图层只是用于计算buyline和sellline,1号图层的价格用于判断是否出交易信号,然后在2号图层交易,并没有违反小周期出交易信号的逻辑。
我再想想问题出在哪,但应该不是global变量导致,谢谢老师指导
你确定你明白造成信号闪烁的原因吗?你的buyline和sellline也没有给出具体的算法,你怎么能确定在实时的bar的跳动中,low和sellline能保证一致成立?global的sellline你确定不会因为bar中值的变化导致条件不成立?
你如果觉得你没错,那我可能也帮不了你了。
buyline和sellline是使用Dual Thrust策略编写的,用的都是前5日K线的历史数据,所以不会随着行情变化而变化,代码如下(0号图层用的是指数的日K线,用于计算前5日价格数据)。
我在《深入浅出学习TBL语言》中找到一段话:“buy、sellshort 在图表上标识买卖信号,与 k 线、行情数据有关,可用于历史回测及实时交易, 该函数同一个 bar 不会重复发单( TB 底层保证)”,这个机制是否会限制我在帖子中写的代码?在代码中,有可能需要在同一根bar中平仓后再开仓。
Range[0:0]
{
Ks_temp=0.3;
Kx_temp=0.3;
ma10 = Average(Close[1],10);
If(Close[1] >= ma10)
{
Ks_temp=0.2; //如果沪深300在10日均线之上,则将触发看涨的阀值降低
}
If(Close[1] < ma10)
{
Kx_temp=0.2; //如果沪深300在0日均线之下,则将触发看跌的阀值降低
}
HH = Highest(High[1],N);
LC = Lowest(Close[1],N);
HC = Highest(Close[1],N);
LL = Lowest(Low[1],N);
R = Max(HH-LC,HC-LL);
BuyLine = Open[0] + Ks_temp*R;
SellLine = Open[0] - Kx_temp*R;
}
再说一遍,逻辑顺序是,1执行代码,2图上标记信号,3系统根据图上信号报送委托单。
不会重复发单这个机制,是在顺序3这里执行的,而信号闪烁是由顺序1处发生问题导致的,怎么可能是后来发生的事影响之前发生的事?因果颠倒了?
如果计算算法上不存在变动,那考虑是否是跨周期导致的问题
@kyover
老师好,我认真思考了一下,没看出global变量操作有什么问题,不重复发单可能是tb的同一个bar不重复发单造成的。
我的需求是当10:00时,如果没有突破则先平仓,但如果在10:00的这根K线触发条件时,也要开多或开空,那就是在同一个bar中会出现两次以上委托,请问该如何实现这些需求。
第一 bar时间和机器时间是可能发生误差的。bar时间是以交易所时间为准,而委托时间以本地时间为准。
第二 看到你的两个global就知道大概率是要信号闪烁了。信号闪烁专题可以自己搜索一下论坛以前的帖子,或者视频区的专题课程,了解产生原因再着手修改。
再次学习了视频“信号闪烁产生原因及处理方法20211104”,好像没有提到global变量导致信号闪烁的问题
如果你知道close会随着tick跳动变化,也应该知道,一个global的数据如果操作不当也发生变化,就会导致信号闪烁吧?
老师只能把信号闪烁的原理讲清楚,并不能把所有会导致信号闪烁的代码统统都讲一遍,那是不可能的。
自己要学会举一反三啊
麻烦老师看一下帖子最新的评论,我觉得不是global变量的问题,而是同一个bar不能发两次委托导致,麻烦老师指导
不重复发委托是信号闪烁的结果,不是原因,你根本就本末倒置了,不知道你是怎么会有这种想法的,但凡理解系统的运行机制都不会产生这样的想法。
第一,你如果确实需要帮助,看置顶帖,把源码发送右键,直播讲解。
第二,如果你觉得老师的判断不正确,你自己是正确的,那就尝试自行处理看看吧。