开拓者期货期权程序化系统交易论坛

标题: 深刻理解TB的执行流程 [打印本页]

作者: leixb    时间: 2009-9-22 19:40:04     标题: 深刻理解TB的执行流程

断断续续接触TB一个多月了,乍看之下,TB似乎比较简单,就是一个Bar一个Bar地去运行自己编写的公式。
通过模拟帐户测试了一段时间,才发现有很多东西需要进一步去弄清楚。

问题:TB在历史数据测试中的运行机制和交易时间的运行机制有何区别?
下面是我的理解,请大家来不断修改和完善。我认为,很多交易程序中的问题,都是由于对TB的运行机理不清楚而埋下了隐患。

【在历史数据测试时】假设商品样本中有2000条K线,TB的执行过程是:
1、先显示出2000条K线。此时,由于有历史数据,每根K线的数据都是现成的。最后一根K线,也是历史数据。所有的数据都是静止的,也没有新的数据进来。
2、从第一条K线开始(最左边的一条),开始执行交易公式,读取参数值。然后,初始化局部变量,执行begin和end之间的代码。
3、然后,进入下一根K线(Bar),再初始化局部变量,执行begin和end之间的代码。
4、依次处理所有的K线。
5、在某根K线上,发现符合开仓条件,于是在超级图表上显示出开仓标识,并修改marketposition的值。
6、继续运行下面的K线。
7、在某根K线上,发现符合平仓条件,于是在超级图表上显示出平仓标识,并在开仓和平仓价之间画出连线。若该笔交易盈利,则用红色连线,若该笔交易亏损,则用绿色连线。
8、继续运行后面的K线,直到最后一条。
值得注意的是:
1、由于是历史数据,每根Bar都是现成的,是没有Tick的概念的。交易代码,在每根bar上运行一遍。
2、由于参数是不能动态改变的,所以,虽然也是程序代码的一部分,但没有必要在每根Bar上都读取一次。只在第一根Bar上读取参数,以后共用即可。
3、由于是历史数据,不会再发生改变,所以,不会出现信号时有时无的现象。
4、由于是历史数据,没有买卖盘的动态数据,所以,不会出现滑点,也不会出现成交不了的现象。

【在交易时间前启动自动交易】假设商品样本中有200条数据,假设在开盘前2分钟启动TB的自动交易,TB的执行过程是:
1、对于已经存在的200条K线,第一根的BarStatus是0,中间的是1,最后面一根是2。对于BarStatus小于2的K线,只在每根Bar上运行一次交易代码。
2、从第一根K线,直到第200根K线,在每根K线上运行一次交易代码。如果发现某些K线符合开仓或平仓条件,只是显示标识符号,但不实际发出交易指令,因为还没开盘。
3、开盘后,分笔交易数据(tick)开始传过来。为了保持实时性,TB就必须对每个tick做出响应,就是在每个tick都运行一次程序代码。
   由此可见,交易时间里,每根最新的Bar上,程序代码都被多次执行。这一点,和历史数据测试时明显不同。
4、由于在最新的一根bar上,交易代码反复被Tick数据触发,而此时下一根bar还没出现,这条Bar的数据中,除了开盘价之外,其他的比如:收盘价、最高价、最低价都在随着每个Tick的变动而变动。当下一根K线出现的瞬间,这条Bar的所有数据才能被确定下来。
如果交易代码中的开平仓条件中,用到了close、high、low,则有可能使信号时有时无。同样的一根Bar上,由于主力的拉升,价格突然走高,符合了买入条件,该Tick出现后,交易代码执行一次,发现符合买入条件,就发出买入指令。下一笔,价格又被打压下来,再次执行交易代码,买入条件又不符合了,但刚才的买入指令已经发出去了,甚至已经成交了。价格如此反复几次,就会在该Bar上反复买入多次。从而形成反复开仓。如果该Bar最终定型时,价格被打压回来了,超级图表上在该Bar上是不会显示任何交易信号的,但实际上,却在该Bar上买入了多次。

【在交易时间内启动自动交易】假设商品样本中有200条数据,假设在开盘后2分钟启动TB的自动交易,TB的执行过程是:
1、读取出200条Bar,其中,有2条还是开盘后刚产生的。
2、在前199根Bar上,每根Bar上执行一次交易代码。如果发现某些Bar上符合开平仓条件,仅仅显示交易信号,但不实际发出交易指令。因为你迟到了,刚才的行情已经成为历史了。
3、在新的Bar上,依据Tick去运行交易代码。
由此可见,TB的交易指令,应该只能在Barstauts=2且有行情数据时才能发出。这一点,应该是TB内部的运行机制,不需要我们在TB代码中去再写一遍。

根据以上的分析,可得知:
1、如果交易代码中,在开平仓指令外假如if(barstatus==2),则在历史数据测试中,就不会显示出交易信号。因为除了最后一根bar之外,前面的Bar都不复合条件。但这样的代码,在交易开始后,是可以正常运作的。
问题是,加上这个条件有什么用呢?
在历史数据测试中,加上显示不了信号;在交易时间,TB又仅仅处理最新的一根Bar中的Tick,加了也没用。经常看到别人在代码中加上barstatus==2,不知道是想干什么用。
2、使用最新Bar的数据去做判断(Open除外),容易引发误开仓或反复开仓。要消除,在买卖条件中,就只能用前面K线的数据去做判断,或使用high>high[1],low<low[1]之类的判断。

上面是我对TB运行机制的一些粗浅理解,望高手对其中的错误之处给与纠正。谢谢!
作者: 幺林    时间: 2009-9-22 21:04:34

3、开盘后,分笔交易数据(tick)开始传过来。为了保持实时性,TB就必须对每个tick做出响应,就是在每个tick都运行一次程序代码。
   由此可见,交易时间里,每根Bar上,程序代码都被多次执行。这一点,和历史数据测试时明显不同。
====>
好象只有最新bar被反复执行。
作者: lh948    时间: 2009-9-23 10:44:04

在交易时间前启动自动交易:
4.如果你只用buy和sell函数的话,在同一个bar上是不会反复开仓的,如果你用A_sendorder就会反复开仓!,如果使用close写是会有反复开仓的可能。
作者: efrog    时间: 2009-9-24 14:55:34

受益非浅,谢谢各位!
作者: zjs    时间: 2009-9-24 15:05:33     标题: 回复 3# lh948 的帖子

那么用NextOpen是不是就可以了, 譬如If(Close满足某条件) Buy(lots, NextOpen, True) 是不是就可以保证每次的交易指令只是针对每个Bar的最后收盘价进行交易机会判断的?
作者: nopain    时间: 2009-9-24 16:11:43     标题: 回复 5# zjs 的帖子

是的。
作者: 天柏    时间: 2009-9-25 16:19:54

"2、在前199根Bar上,每根Bar上执行一次交易代码。如果发现某些Bar上符合开平仓条件,仅仅显示交易信号,但不实际发出交易指令。因为你迟到了,刚才的行情已经成为历史了。"
这点有点出入吧?实际要看你的代码是怎么写的。
作者: leixb    时间: 2009-9-27 09:00:59     标题: 回复 2# 幺林 的帖子

是的。最新Bar之前的Bar,都被计算过。只有最新的bar上,才会反复被Tick触发。
作者: kautz    时间: 2009-10-23 16:05:42

我的策略是在交易时间内启动自动交易 然后记录下最新bar 在最新把人下单 然后购买加仓。可是就是有问题,不能够记录下启动自动交易策略时刻的Bar!!。如下程序请帮修改
//------------------------------------------------------------------------
// 简称: test
// 名称: test
// 类别: 交易指令
// 类型: 多头建仓
// 输出:
//------------------------------------------------------------------------



Vars
        BoolSeries executed(False);
        BoolSeries recorded(False);
        NumericSeries FirstTradedBar(-10);
        NumericSeries TradeStage(0);   
Begin
               

    If(BarStatus == 0)
    {
                FirstTradedBar=-10;
                TradeStage=0;
                executed=False;
                recorded=False;
        }
        Else
        {
                TradeStage=TradeStage[1];
                FirstTradedBar=FirstTradedBar[1];
                executed=executed[1];
                recorded=recorded[1];

    }



        if((!recorded)&&(CurrentBar==BarCount-2))
                {
                                FirstTradedBar=CurrentBar+1;
                                recorded=True;
                }



        If(((CurrentBar==FirstTradedBar)||(CurrentBar==FirstTradedBar+1))&&(!executed)&&(TradeStage==0)&&(MarketPosition == 0)&&(time<0.1458))
                {

                                //If(Buy(1,Close))
                                If(Buy(1,NextOpen, True))
                                {
                                        Commentary("===做多成功(BARany)=====");
                                }

                                TradeStage=1;
                                executed=True;
                }

        Commentary("CurrentBar="+Text(CurrentBar));
        Commentary("FirstTradedBar="+Text(FirstTradedBar));
        Commentary("TradeStage="+Text(TradeStage));
        Commentary("executed="+IIFString(executed,"True","False"));       
        Commentary("recorded="+IIFString(recorded,"True","False"));       
END



//------------------------------------------------------------------------
// 编译版本        GS2004.06.12
// 用户版本        2009/10/23 13:59
// 版权所有        xltz02
// 更改声明        TradeBlazer Software保留对TradeBlazer平台
//                        每一版本的TrabeBlazer公式修改和重写的权利
//------------------------------------------------------------------------
作者: 女儿是期神    时间: 2009-11-17 09:52:02     标题: 关于MarketPosition实盘中的执行描述的对话

回复海风 9:08:30
请教个问题,marketposition,在我开平仓后,下一个Tick过来的时候是不是它的值就改变了,还是要等K线走完?
回复交易开拓者 9:13:28
TB的公式是从上向下算的。并且每一个TICK去运算一次
回复海风 9:13:41
这个我明白
回复交易开拓者 9:14:01
这样一来。MARKETPOSITION在某一个TICK发出了信号了,改变之后,可是下一个TICK来了,整个公式还会从头算起。
回复海风 9:14:44
那此时它是多少呢,假设原来是0,我现在开仓,它变成1,后一个tick来的时候它是多少呢?
回复交易开拓者 9:17:31
你的公式一开始还是这个BAR最开始的那个初始值的状态为0,
回复交易开拓者 9:17:46
然后算到开仓的部分,他就改变为1。
回复交易开拓者 9:18:04
下一个TICK来了,他还是从0开始计算。
回复海风 9:18:45
这样是不是说,如果想盘中开仓,一定要自己用全局变量来控制,否则就会重复发单?
回复交易开拓者 9:18:52
不会
回复交易开拓者 9:19:06
机制有控制的。
回复海风 9:20:01
就是说,在这个tick开了仓,下个tick过来的时候再次执行到开仓位置会先判断是不是已经开过仓了?
回复交易开拓者 9:20:09
如果你的上一个TICK是有发过单的,该TICK满足了条件便不会再发单的
回复交易开拓者 9:20:26
所以说你要保证信号不消失不反复就不会重复发单了。
回复海风 9:20:34
空上明白了
回复海风 9:20:38
这个
回复交易开拓者 9:21:28
但是如果你的公式写法有信号消失的问题。那么某个TICK上发过单了,但是中间有几个TICK信号是消失了。然后再出来的TICK有信号了,他就不会记得之前有开过仓,于是再次发单,
回复海风 9:22:31
了解了,谢谢.另外一个问题.
同一个Tick里marcketpostion会不会即时更新,如
if(marketposition==1)
  sell;
if(marketposition==1)
sell;
这样会不会在一个tick里平两次?(假设我有我余的持仓)
回复交易开拓者 9:22:49
不会
回复交易开拓者 9:23:18
除非你分别写两个平仓语句。
回复海风 9:23:49
分别写两个平仓语句是什么意思
回复交易开拓者 9:25:02
比如你现在有两个手多仓
if(condition1)
{
   sell(1,close);
}
if(condition2)
{
   sell(1,close);
}
这样就可能在同一个BAR上平两个仓
回复海风 9:26:06
如果我开仓时是buy(1);并且帐户上有多余的多单,会怎么样?
回复海风 9:26:28
这两个平仓条件里我都会加入marketposition==1的判断.
回复交易开拓者 9:27:41
只有一手的话,没法出两个平仓单的
回复海风 9:28:30
即使有多余持仓也不会平出?
回复交易开拓者 9:28:37
是的
回复海风 9:28:58
这样就是说模型只会计算自己的持仓情况了.
回复交易开拓者 9:29:23
是的,他只看图表上的信号来计算,不会知道你的交易帐户里有多少的持仓
回复海风 9:29:49
非常感谢,越来越佩服TB的机制了
作者: sensegray    时间: 2009-12-18 13:02:11

我也有这个疑问。。。请斑竹解答
“根据以上的分析,可得知:
1、如果交易代码中,在开平仓指令外假如if(barstatus==2),则在历史数据测试中,就不会显示出交易信号。因为除了最后一根bar之外,前面的Bar都不复合条件。但这样的代码,在交易开始后,是可以正常运作的。
问题是,加上这个条件有什么用呢?
在历史数据测试中,加上显示不了信号;在交易时间,TB又仅仅处理最新的一根Bar中的Tick,加了也没用。经常看到别人在代码中加上barstatus==2,不知道是想干什么用。

作者: 小米    时间: 2009-12-18 16:59:51

可以将某些判断与执行限制在barstatus==2之内,而此条件之外做其它的处理。
论坛上已经有不少关于if(barstatus==2)的例子,找几个来看一下,就明白其在不同公式中的作用都是什么了。
作者: hxbhz    时间: 2009-12-22 11:29:45

学习了,以后再研究
作者: mauricem    时间: 2010-12-27 14:40:23

4.如果你只用buy和sell函数的话,在同一个bar上是不会反复开仓的,如果你用A_sendorder就会反复开仓!,如果使用close写是会有反复开仓的可能。 ...
请问为何用buy和sell不会反复开仓呢?
作者: sunny_2010hh    时间: 2010-12-27 15:52:20

学习ing
作者: sunny_2010hh    时间: 2010-12-28 20:12:35

学习ING......
作者: ccbban    时间: 2011-1-4 20:23:04

这个帖子不能沉啊,buy不能在一个bar上开仓,那如果当日突破了加仓价格,岂不是不能加仓了么
作者: guowenjuan    时间: 2011-1-13 10:06:58

回复 10# 女儿是期神
“但是如果你的公式写法有信号消失的问题。那么某个TICK上发过单了,但是中间有几个TICK信号是消失了。然后再出来的TICK有信号了,他就不会记得之前有开过仓,于是再次发单,”它会再次发单的是吧?如果我写了两种开仓条件con1,con2,在同一周期,先满足con1,它开仓了,稍后满足con2,那是不是不会开仓呢?因为它之前的那个TICK已经因为con1而开仓了?
作者: guowenjuan    时间: 2011-1-14 15:59:47

回复 10# 女儿是期神
"回复交易开拓者 9:20:09
如果你的上一个TICK是有发过单的,该TICK满足了条件便不会再发单的
"
如果上一个TICK有发过单,但发单是因为另外的其他条件,而不是该条件,那该条件满足时还会不会发单呢?
作者: 从不倒翁    时间: 2011-11-6 19:46:11

这个应该置顶的
作者: xiaoshansanzhi    时间: 2011-11-7 10:08:41

好贴,楼主思考的正是我们好多人所迷糊的,希望大家积极讨论  支持
作者: macard    时间: 2011-11-23 12:29:11

模拟盘中,Buy和Sell好像不能用吧!
作者: phoenixbing    时间: 2011-11-23 13:17:52

我是个新手,我想问一个困扰我很久的问题.
如果marketposition 是持仓.他是委托就计入 还是 成交才计入.
如果是委托就计入.如果是挂单状态,那下一个信号出现平仓.就可能平仓失败,那不是可能就漏掉一次平仓 .
作者: wine2008    时间: 2011-11-25 17:12:15

這個帖子很好,學習中
作者: yangedwin99    时间: 2012-2-17 21:02:06

受益非浅
作者: CrewsHe    时间: 2012-4-13 12:40:49

学习了

作者: lanhai123    时间: 2012-4-14 08:06:17

学习,受益,提高,谢谢!
作者: 天崖    时间: 2012-4-14 11:54:32

学习,受益,提高~~~~~~~~~~~~~~~~~~~~~~
作者: 天空之城    时间: 2012-4-21 07:41:40

phoenixbing 发表于 2011-11-23 13:17
我是个新手,我想问一个困扰我很久的问题.
如果marketposition 是持仓.他是委托就计入 还是 成交才计入.
如 ...

最好不要用这么敏感的系统吧,谁都不能保证马上成交,用账户函数还有返回时间。
加上一个开仓一段时间内不平仓的代码吧,延迟一些就能解决了。
作者: 天空之城    时间: 2012-4-21 07:44:17

我决定要把陈四建老师4月十号讲的一点加进去:
序列变量使用在条件判断里的情况下,必须保证每根bar都计算一次,否则就可能出错。
最好把条件判断里的判断都揪出来用bool函数表示。
作者: 天空之城    时间: 2012-4-21 07:44:58

打错字,是觉得。。。
作者: ReadeX    时间: 2012-8-22 08:37:48

好贴,需要更多的时间和思考
作者: bookjojo    时间: 2012-8-23 07:13:19

这个得好好理解
作者: Tony    时间: 2013-3-23 20:38:04

TB应该把执行机制、使用marketposion的注意事项、使用A函数发单具体如何避免重复发单,写进帮助中。

新手100%会遇到这些问题,折腾很久。
作者: vividboy    时间: 2013-7-13 16:56:42

恩,是的,TB应该将整个运行机制写一个比较详细的官方说明。这样才能避免很多问题和主观的臆想。
毕竟是涉及到真金白银的事情,还是要谨慎为好。
作者: hezhusheng01    时间: 2013-8-15 11:52:42

实盘中,bar的close/high/low是根据tick动态变化的还是要等bar运行结束以后才确定的?例如bar是一分钟,当第一个tick来到时,open是知道了,他会不会先运行了?此时close/high/low确定了吗??还是要等一分钟过后才知道?

最后一个问题,实盘中每个tick带回来的包括些什么信息;历史数据测试时每次“投入”的数据以什么为单位(tick?还是bar?)

               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
       

作者: ll407489244    时间: 2013-8-21 08:29:51

hezhusheng01 发表于 2013-8-15 11:52
实盘中,bar的close/high/low是根据tick动态变化的还是要等bar运行结束以后才确定的?例如bar是一分钟,当 ...

1.在历史测试时,没有数据投入进来。
2.实盘中,bar的close,收盘价也就是最新价,一直在动,要1分钟后产生了一根新开的Bar才不变了,其他2个变量也一样,但是用high>high[1],low<low[1],这种方式来计算开平仓条件是不会有信号消失的问题,因为high只会越来越大,每次都必然大于high[1],而low只会越来越小,而low[1]不变,所以low一定小于low[1],lz说close、high、low,都会信号消失,不是这样子的。而是close才会信号消失,因为最新价一会大于high[1]一会小于,是很正常的。。。
作者: Miss_z    时间: 2013-12-6 14:49:31

牛贴!赞一个!
作者: xiaofeng    时间: 2014-3-5 21:23:06

赞你了学习的劲!胡来吧!终有一天,我们都整倒华尔街!!!!!!!!!!!!!!!!!!
作者: yanliangjr9702    时间: 2014-5-15 04:17:20

找到这个帖子了!
作者: tsbftwo    时间: 2015-5-7 21:30:48

看来用日线close作为入场条件总会遇到各种问题,跨周期也是一样。
作者: edwardkm    时间: 2015-6-9 13:33:54

感谢LZ分享!
作者: china_lizhi    时间: 2016-11-16 11:56:49

好贴,顶起来
作者: LANGGPGG    时间: 2017-8-21 16:03:33

给TB提个建议,在帮助文件里,给更多的例子吧。文华,通达信,人家的帮助文件,或者函数说明里,都是案例。。。很容易理解

这么好的软件,感觉认可度不是很大。。。显然需要TB公司考虑一下原因了。
作者: LANGGPGG    时间: 2017-8-21 16:07:18

我在信号处理这块,就用close【1】,不管是价格,还是指标,计算开平仓信号,全部用上一个bar的数据,执行buy sell 用 open。外加交易助手,几秒不成交,就撤单再下单。

比如螺纹,成交量在100手的话,基本没问题。
作者: xledoo    时间: 2017-8-24 16:08:07

LANGGPGG 发表于 2017-8-21 16:07
我在信号处理这块,就用close【1】,不管是价格,还是指标,计算开平仓信号,全部用上一个bar的数据,执行b ...

严重同意
作者: LANGGPGG    时间: 2017-9-16 21:29:27

为了阅读权限。顶。。。
作者: hustjiang    时间: 2021-3-30 19:26:07

楼主,你好啊 ~~! 过了十几年了  你还在做交易吗 ?




欢迎光临 开拓者期货期权程序化系统交易论坛 (http://bbs.tb18.net/) Powered by Discuz! X2