ONBAROPEN

帮助文档中描述如下:onbaropen只在这根BAR的第一个TICK才会驱动代码运行一遍。我在测试过程发现:onbaropen的触发时间在本BAR的TIME之前,请问此种情况合理吗?(感觉象是BAR[1]的ONBARCLOSE)此时BAR[1]的CLOSE形成了吗?(直接关系到均线、布林等技术指标的计算,从而影响至出入场)onbaropen的设计原理是什么呢?我用数组记录每个TICK的TIME,在onbar域中设定open时间(即:第1个TICK)为:TickTime[1]<Time AND TickTime[0]>Time,又发生了重复触发的问题(原因大概是:TickTime有重复,难道一个TICK会接收两次吗?)。我先确定一下我对基础机制的理解是否正确,根据情况再完善测试代码,请老师们解惑!!!

onbarclose-onbaropen-onbar只有Onbar是正统的你要是喜欢全部在onbar自己控制

回复:控制成onbaropen-onbar-onbarclose反正我就是这么干的

回复:要么加深、正确理解要么不喜欢TB给出来的机制就自己重构

回复:老师,请问您是如何实现在onbar中控制onbaropen的?可以分享思路吗(如有代码就更好了)?望不吝赐教,谢谢!!!

我在测试过程发现:onbaropen的触发时间在本BAR的TIME之前,请问此种情况合理吗?请给出得到这个结论的证据onbaropen的设计原理是什么呢?用户需要,所以我们设计。常见需求举两个例子第一个,有些指标在bar开盘的时候就已经确定了,放在onbar里计算就冗余了第二个,有些状态变量可以放在onbaropen里做重置,避免放在onbar里被污染。如果没有以上需求,无视就好了

回复://------------------------------------------------------------------------ // 简称: ZS39_2 // 名称: OPEN触发时间 // 类别: 公式应用 // 类型: 用户应用 // 输出: Void //------------------------------------------------------------------------ Vars Global Numeric StartTime; Series<Numeric> BAR0(0); // BAR索引 Global BOOL TimeCond;//实时行情 Tick My_Tick; Global Numeric TickTime2(0);//图层2/Tick时间 Global Numeric TickTime1(0);//图层1/Tick时间 Global Array<Integer> OrderId;//单号 Defs//自定义函数 Integer LogFile(StringRef str)//日志函数 { IF (StrategyMode()==1) FileAppend("D:\\"+FormulaName()+"\\"+DATA2.Symbol()+".txt","["+Text(SystemDateTime())+"] "+ str+"/"+StrategyModeName); Return 0; } Events OnInit()//策略执行前的初始化事件,只运行一次。/可以订阅数据,数据准备等操作。 { SubscribeBar(Data0.Symbol,"5M",Data0.BeginDateTime);//图层1 SubscribeBar(relativesymbol,"1M",Data0.BeginDateTime);//图层2 } OnReady() { StartTime=SystemDateTime; //返回值为YYYYMMDD.HHMMSS LogFile("OnReady//"+SymbolName+"/开始时间="+TEXT(SystemDateTime())); PrintClear; } OnBarOPEN(ArrayRef<Integer> indexs) { Range[1:1] { BAR0=CurrentBar(); TimeCond=IsTradingTime(Symbol,SystemDateTime)AND QuoteStatus==Enum_QuoteStatus_RealTime; IF (!TimeCond) Return; IF (GetTick(symbol,My_tick)) TickTime1=My_tick.dateTime; Numeric Sc1=TimeDiffV2(Time,TickTime1);//时差1 LogFile("图层1/TickTime1="+Text(TickTime1,9)+"/Time1="+Text(Time,9)+"/BAR1="+TEXT(BAR0)+"/时差1="+Text(Sc1,9)); IF (Sc1<0) LogFile("*******TickTime1提前/时差="+Text(Sc1,9)); } Range[2:2] { BAR0=CurrentBar(); TimeCond=IsTradingTime(Symbol,SystemDateTime) AND QuoteStatus==Enum_QuoteStatus_RealTime; IF (!TimeCond) Return; IF (GetTick(symbol,My_tick)) TickTime2=My_tick.dateTime; Numeric Sc2=TimeDiffV2(Time,TickTime2);//时差1 LogFile("图层2/TickTime2="+Text(TickTime2,9)+"/Time2="+Text(Time,9)+"/BAR2="+TEXT(BAR0)+"/时差2="+Text(Sc2,9)); IF (Sc2<0) LogFile("TickTime2提前/时差="+Text(Sc2,9)); } IF (1==2) A_Buy(symbol,1,Q_AskPrice,OrderId );//不发单 IF (1==2) A_Sell(symbol,1,Q_BidPrice,OrderId );//不发单 } 上面是测试代码,下面是日志的截图(部分)暂时未能捕捉到触发时间明显提前的情况。但是仍有几个问题再请教1、图层1(5分钟)为何多次触发?是否我在此域中对图层控制不够?如何控制其只在本图层的第一个TICK触发?2、日志第7行,时差2=0有问题(SC2明明应该等于2)。TimeDiffV2应该返回毫秒级差值,此函数的准确性有问题吗?(函数本身设定的精度是多少?会四舍五入吗?)3、日志第7行,触发时间点是在本BAR的TIME之前(尽管只提前了2毫秒), 是否可以推定上1个TICK就已产生了上1个BAR的CLOSE?4、老师如需复现上述问题,请多试几个品种,盼解惑,谢谢!!!

回复:驱动和执行是两码事。你现在写的逻辑是,无论哪个图层驱动,都要执行图层1和图层2的代码

回复:请问如何控制其只在本图层执行?

回复:现在的测试代码,影响2、3两个疑问的成立吗?

回复:建议看一下零基础教程里的说明。行情驱动的事件域,参数indexes数组里存放的就是驱动的图层序号这个教程里应该都是说过的

回复:// 简称: ZS39_2 // 名称: OPEN触发时间 // 类别: 公式应用 // 类型: 用户应用 // 输出: Void //------------------------------------------------------------------------ Vars Global Numeric StartTime; Series<Numeric> BAR0(0); // BAR索引 Global BOOL TimeCond;//实时行情 //Tick My_Tick1; //Tick My_Tick2; //Global Numeric TickTime(0);//图层2/Tick时间 //Global String Ticksymbol;//图层1/Tick时间 Global Array<Integer> OrderId;//单号 Defs//自定义函数 Integer LogFile(StringRef str)//日志函数 { IF (StrategyMode()==1) FileAppend("D:\\"+FormulaName()+"\\"+DATA2.Symbol()+".txt","["+Text(SystemDateTime())+"] "+ str+"/"+StrategyModeName); Return 0; } Events OnInit()//策略执行前的初始化事件,只运行一次。/可以订阅数据,数据准备等操作。 { SubscribeBar(Data0.Symbol,"5M",Data0.BeginDateTime);//图层1 SubscribeBar(relativesymbol,"1M",Data0.BeginDateTime);//图层2 } OnReady() { StartTime=SystemDateTime; //返回值为YYYYMMDD.HHMMSS LogFile("Ready时间="+TEXT(SystemDateTime())+"/图层0="+SymbolName+"/图层1="+Data1.Symbol+"/图层2="+Data2.Symbol); PrintClear; } OnBarOPEN(ArrayRef<Integer> indexs) { TimeCond=IsTradingTime(Symbol,SystemDateTime) AND QuoteStatus==Enum_QuoteStatus_RealTime; IF (!TimeCond) Return; If(ArrayFind(indexs,1)) { BAR0=CurrentBar(); Commentary("BAR0="+Text(BAR0)); Tick My_Tick1; GetTick(DATA1.symbol,My_tick1); Numeric TickTime1=My_tick1.dateTime; String Ticksymbol1=My_tick1.symbol; Numeric Diff1=TimeDiffV2(Time,TickTime1);//时差1 LogFile("图层1/"+ticksymbol1+"/Time="+Text(DATA1.Time,9)+"/TickTime="+Text(TickTime1,9)+"/时差="+Text(Diff1,9)+"/BAR="+TEXT(BAR0)); IF (Diff1<0) LogFile("*******TickTime1提前/时差="+Text(Diff1,9)); } //Range[2:2] If(ArrayFind(indexs,2)) { BAR0=CurrentBar(); Commentary("BAR0="+Text(BAR0)); Tick My_Tick2; GetTick(DATA2.symbol,My_tick2); Numeric TickTime2=My_tick2.dateTime; String Ticksymbol2=My_tick2.symbol; Numeric Diff2=TimeDiffV2(Time,TickTime2);//时差2 LogFile("图层2/"+ticksymbol2+"/Time="+Text(DATA2.Time,9)+"/TickTime="+Text(TickTime2,9)+"/时差="+Text(Diff2,9)+"/BAR="+TEXT(BAR0)); IF (Diff2<0) LogFile("TickTime2提前/时差="+Text(Diff2,9)); } IF (1==2) A_Buy(symbol,1,Q_AskPrice,OrderId );//不发单 IF (1==2) A_Sell(symbol,1,Q_BidPrice,OrderId );//不发单 } 上面是修改后的测试代码,下面是测试日志,相关问题仍然存在2、日志第8行,时差=32760000有问题(明明应该等于-2)。TimeDiffV2应该返回毫秒级差值,此函数的准确性有问题吗?3、日志第8行,触发时间点是在本BAR的TIME之前(尽管只提前了2毫秒), 是否可以推定上1个TICK就已产生了上1个BAR的CLOSE?感觉有的OnBarOPEN像是上根BAR的OnBarCLOSE

回复:那你为什么不输出一下time呢?diff2不对,你输出了ticktime2,那输出一下time不就知道了么?虽然你没有说明图层0是什么周期,但是我研究很久以后,推测你图层0是日线。日线的time,是0。而你2图层分钟线,090559,换成毫秒数,就是自己算算是不是对上了吧

回复:TIME已经输出了,且已核对:与图层相对应况且TimeDiffV2是忽略日期差异的

回复:感觉TimeDiffV2这个函数有点异常你回看我昨天的日志,计算结果与今天差异太大,难道是函数本身发生变动了?

回复:对测试代码修改了以下两行Numeric TickTime1=My_tick1.dateTime-DATE; Numeric TickTime2=My_tick2.dateTime-DATE; 测试结果如下,请看最后一行问题仍然存在