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会接收两次吗?)。

我先确定一下我对基础机制的理解是否正确,根据情况再完善测试代码,请老师们解惑!!!

OnBaropen
关于OnBarOpen
关于OnBarOpen的问题
关于onbaropen 是否会有闪烁
多图层策略关于onbaropen?
OnBarOpen调仓的问题
onbaropen使用中的问题
OnBarOpen(ArrayRef<Integer> indexs) 的应用
连续合约、主力合约、onbaropen
多数据源onbaropen问题

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;

测试结果如下,请看最后一行问题仍然存在