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

标题: 从头开始TB编程 [打印本页]

作者: ohuangkai    时间: 2011-10-15 22:21:09     标题: 从头开始TB编程

本帖最后由 ohuangkai 于 2011-10-18 19:53 编辑

今天听了陈剑灵老师的课,有一些感悟,想把他写下来,但又不知道从哪里开始。
    因为觉得自己最近再也没有进步,希望能有些突破,只是找不到突破口。
    我想,把自己TB编程的过程一点点写下来,在帮助新的初学者的同时,也能帮到自己。
     好。废话不再多说。
    -----------------------------------------------------------------
                                 第一个程序
    做程序化交易遇到的第一个问题就是:我怎么在图上画均线?
    我们先试着写第一个程序,写第一个程序前,先不用问为什么。照做就是了。 呵呵。
    先点:tb公式->新建公式应用
    填写简称,这个简称就是将要写得程序的名字。建议你起一个好找一点的名字:AA001,然后是公式名字。这里写你的公式的特征:这是第一个测试均线程序。这个注释就不用填了,我从来没发现这个注释有啥作用(知道的同学请告诉我,呵呵)。好了,点确定。
    这时候你看到了一段这程序的简要说明。删掉留下你随意。建议你现在别动他们。
    在中间插入下面的语句:
Vars
        Numeric ma;
Begin
        ma = Average(CLose,10);    //取10日平均值
        PlotNumeric("ma",ma);         //画出这条平均线。
End

    然后,点:校验并保存公式。当下方出现:成功保存当前公式信息,那么好了,恭喜你,第一个最简单的画均线的程序完成了。
    我们在打开分时图表,点右键,插入公式应用时,看到,我们的AA001在第一个!!!(名字很重要,以后你找起来会省点力气)
   
    第一个程序后
    我们完成了第一个公式.现在要明白这些都是做什么的。
    Vars 是一个标记,告诉系统,我要用一些变量。Numeric ma;这个是说我用数字型变量名字叫做ma。然后Begin 告诉程序,我的程序开始了。对应的最后一句:End 告诉系统,我的程序到这里结束。
    ma = Average(Close,10); 这条语句中 Average(Close,10) 是一个系统函数,求前10日收盘(用Close表示)的平均价格,把他的结果放在ma这个变量中。
    PlotNumeric("ma",ma); 这条语句是。。。我是不是说得太详细了? 点工具栏中一个小问号,把这个函数名字输入进去查查看? TB的帮助系统还是很好用的。如果遇到什么奇怪的系统函数可以在里面查到。
    看懂了没?我第一次是真没看得太懂。说白了,这里他就是画一条线。一条10周期收盘平均价的曲线。
    他还有更多用法,你在公式应用设置里点:设置->线型,看到了没? 这里有个ma(如果你程序里还画了其他的线,这里也会显示他们的名字)。 你可以尝试着看看各种状态都是什么样子,以后需要的时候在这里改。比如隐藏。。。

    好,我们可以再改进一下这个公式:
Vars
        Numeric ma1;
        Numeric ma2;
Begin
        ma1  = Average(CLose,10);
        ma2 = Average(CLose,20);

        PlotNumeric("ma1",ma1);
        PlotNumeric("ma2",ma2,0,Red);

End
     注意,我们修改了第二根均线的颜色,如果你想修改第一根,可以像这里一样修改他。
     在完成上面的步骤后,我们可以尝试继续:

Vars
        Numeric ma1;
        Numeric ma2;
Begin
        ma1  = Average(CLose,10);
        ma2 = Average(CLose,20);

        PlotNumeric("HHH",ma1,ma2,red);
End

    看看他会是什么结果? 你再设置一下线型,把他设置成:柱状图。你就知道原来PlotNumeric("ma2",ma2,0,Red) 这语句中为什么是0了,大概也能明白这个函数的用法了。

    恩,关于均线的画法,基本就到这里了。
    。。。
    什么,你不要10日均线,你要能随时变动的?这个简单,你要再改改系统:
Params
        Numeric n1(10);
        Numeric n2(20);
Vars
        Numeric ma1;
        Numeric ma2;
Begin
        ma1  = Average(CLose,n1);
        ma2 = Average(CLose,n2);

        PlotNumeric("ma1",ma1);
        PlotNumeric("ma2",ma2);
End
      n1,n2这就是2个参数,你可以在参数栏修改他看变动结果。
作者: ohuangkai    时间: 2011-10-15 23:56:32

本帖最后由 ohuangkai 于 2011-10-16 00:38 编辑

第一个交易程序
   作为一个初学者,最希望的是先看到一个能实用的程序。这个最最简单的程序。他甚至可以简化成4行。 你可以尝试着这么做一下。

Params
        Numeric n1(5);
Begin
        If ( Close[1] > Close[n1]) Buy(0,Open);
        If ( Close[1] < Close[n1]) SellShort(0,Open);
End

(这里并没有平仓命令。 在反手的时候,系统反手,然后平仓。这里,注意次序,是先反手交易,然后平仓。和我们手工的习惯有些差异。保证金在一瞬间使用增加 )

    恩,把这个程序放在不同周期下执行看看?
    你可以看看测试报告,毕竟这是我们的第一个程序。结果怎样?
    这个程序是说:如果:昨日收盘价(用close[1]表示)大于n1日前收盘价(用close[n1]表示),那么买入。反之卖出。
    1 注意这里的使用格式: IF ( 条件 ) 条件成立要执行的交易指令; 如果有其他语句要执行,要用{} 包起来。
    2 buy(0,Open) 中的0是买入手数,这个手数多少你可以在全局交易设置里看看。全局交易变量里还有其他设置,都可以尝试一下。这里的设置就是针对这个图表和这个公式,不是真正意义上的全局交易设置。你可以尽量去试验。

    这是一个最简单的趋势交易程序。但他包含了一个交易系统最重要的3个方面:买入,卖出,平仓。形成了一个完整的交易回路。
作者: ohuangkai    时间: 2011-10-16 12:06:41

增加一个过滤条件
   虽然有了这样一个程序,使用起来效果非常不好。我们看到他得交易非常频繁,而且,在趋势向上时 ,也会买入,趋势向下时也会卖出,我们希望的是找到的是一个入场机会,且顺着交易趋势入场。
   等等,问题来了,趋势大家都知道,我们怎样确定趋势?
   有很多确认趋势的方法,但我们现在用的可能是最简单的趋势确认方法,就是前一天收盘价和前几天的收盘价相比较。。。。这个方法受到的干扰太大,随便一个波动就可能干扰到程序的判断,几乎没法用。我们再增加一条均线,用这根均线来将我们可能违反趋势进行的操作过滤掉。这样,我们就能抓住主要的趋势。
    有了这个思路,结合我们上面提到的均线,可以完成如下的程序:
Params
        Numeric n1(10);
        Numeric n2(3);
Vars
        NumericSeries ma;
Begin
        ma = Average(Close,60);
        PlotNumeric("ma",ma);
        If ( ma[1]>ma[10] && Close[1] > Close[n1])            Buy(0,Open);
        If ( ma[1]<ma[10] && Close[1] < Close[n1])      SellShort(0,Open);
End   
    先运行下程序,看他能不能抓住主要趋势? 再尝试一下在不同的周期下运行,看看运行结果,曲线。




小尾巴拖出一个大头来。
    现在,提出一个疑问疑问:为什么要用ma[1]>ma[10] 这是什么东西?刚才我们用的时候可不是这样! 恩,这说来话长。
    我们看VAR里申明了:NumericSeries ma;  这个NumericSerics和刚才的Numeric 不一样。 这里是一个序列变量。说到序列变量,这就是TB程序不同于一般程序的地方了: 一个序列变量在每一根K线上都独立存在,在之后的K线上可以使用之前K线上的序列变量值。我们经常用的 Open,Close,High,Low,Date,Time,Vol,OpenInt 这些变量都属于序列变量,他们是系统给的。我们可以调用他。这里的ma是我们造的,可以使用他。
    明白了序列变量,重温了一遍Close[1]的使用方法,基本也能明白他的用法了:可以调用以前的数据。

    剩下一个问题是:If ( ma>ma[10] && Close > Close[n1])            Buy(0,CLose);为什么不行?
    回答:这样的写法没有语法错误,但他不能正常运行。
    实际运行中,ma 当前数值是在不断变化的,这个大家都能明白。 Close 在最后一个bar中,代表的是“最新价”!! 而不是我们过两天看到的收盘价。
    这又牵涉了一个更大的头。理解TB公式的执行方式。
作者: ohuangkai    时间: 2011-10-16 12:19:49

本帖最后由 ohuangkai 于 2011-10-17 10:07 编辑

TB是怎样执行交易程序的。
    在测试和加载程序时,TB在每一根BAR上,都把这程序执行一遍。
    而在实盘运行的时候,TB几乎每秒钟把我们的交易程序运行2遍。你没看错,是2遍,如果你的网络和电脑没什么大问题的话。 在最后这根bar上,他的CLOSE 还没有真正出现,你却已经在用了,不是吗?这时候,程序就是把最新价当做Close来用。现在你会估计到buy(0,Close)会是什么结果了,同样,MA也是不断变化的,只有这根bar走完,开始新的bar的时候,他成了历史数据,结果不再发生变化。

    现在,我们应该明白为什么要用Close[1]这样看起来有点奇怪的数据了吧。而Open不会发生变化,他一旦出现,就是固定不变了。
作者: 莫小漠    时间: 2011-10-16 12:57:36

很好。。支持一下
作者: ohuangkai    时间: 2011-10-16 13:10:07

本帖最后由 ohuangkai 于 2011-10-16 13:27 编辑

程序改进
    现在我们要把程序再修正一下,为了平滑一点,我们用一个均线代替收盘价进行判断;增加了几个参数,使他能适应不同的品种。
Params
        Numeric n1(10);
        Numeric n2(3);
        Numeric d1(10);
        Numeric d2(3);
Vars
        NumericSeries m1;
        NumericSeries m2;
Begin

        m1 = Average(Close,n1);
        m2 = Average(Close,n2);
        PlotNumeric("m1",m1);
        PlotNumeric("m2",m2);
       
        If ( m1[1]>m1[d1] && m2[1] > m2[d2]) {                Buy(0,Open); Return;}
        If ( m1[1]<m1[d1] && m2[1] < m2[d2]) { SellShort(0,Open); Return;}
End
      你可以加载他到一个品种的指数图表上进行测试,并更换周期。并多试验几个品种(指数),或者修改参数看看其表现。
    这里,我们看到 {}的用法,为什么没有换行? 这是我的习惯,如果没有什么复杂的语句,我宁可把他写成一行,这样可以和下面一行相对,减少程序错误,并利于阅读。
    Return 这语句告诉系统下面部分不再执行。返回去。这个用法在调试程序的时候可能会给编程者造成一定的困扰。除非你的程序不是很复杂,或者你有足够的能力驾驭她,否则建议不用。实际上这里完全可以省略他。
      这个模型的根本思想是寻找两个不同周期的共振点,如果方向达到一致,则进行交易。 否则,维持原有状态。
作者: xiaoshansanzhi    时间: 2011-10-17 09:31:39

回复 6# ohuangkai


    认真学习
作者: ohuangkai    时间: 2011-10-17 10:30:57

本帖最后由 ohuangkai 于 2011-10-17 14:15 编辑

看盘同时再写一点。
    -----------------------------------------------------
    没有止损的程序总是让人觉得不放心。虽然这个程序的反手已经是一种形式的止损。总没有能看到的止损更让人放心。
    现在我们增加一个最常见的止损:跟踪止损。
Params
        Numeric n1(10);
        Numeric n2(3);
        Numeric d1(10);
        Numeric d2(3);
        Numeric nLoss(100);    // 止损点  需要根据不同品种特性与周期进行调整。
       
Vars
        NumericSeries m1;
        NumericSeries m2;
        Numeric bStop;
        Numeric sStop;
        Numeric OnePoint;
Begin

        OnePoint = MinMove*PriceScale;       
        m1 = Average(Close,n1);
        m2 = Average(Close,n2);
        PlotNumeric("m1",m1);
        PlotNumeric("m2",m2);
       
        If ( m1[1]>m1[d1] && m2[1] > m2[d2])       Buy(0,Open);
        If ( m1[1]<m1[d1] && m2[1] < m2[d2]) SellShort(0,Open);
       
        bStop = Highest(High,BarsSinceEntry) - nLoss*OnePoint;    //买盘止损线不断移动到买入后产生的最高价减去止损限额
        sStop =  Lowest( Low,BarsSinceEntry) + nLoss*OnePoint;    //卖盘止损线不断移动到卖出后产生的最低价减去止损限额
        If (MarketPosition == 1) PlotNumeric("bStop",bStop);    // 画出多单止损线。   
        If (MarketPosition ==-1) PlotNumeric("sStop",sStop);    // 画出空单止损线。  
       
        If ( BarsSinceEntry > 0)
        {       
            If ( MarketPosition == 1 &&  Low<bStop )       Sell(0,Min(Open,bStop));
            If ( MarketPosition ==-1 && High>sStop ) BuyToCover(0,Max(Open,sStop));
        };
End
    注意:1 需要在公式应用设置里将 设置 ->线型 把bStop,sStop这个设置改为线段。因为买入的止损线只有在持有买入仓位时才有效。
         2 判断两个值相等时一定要用 == 而不是 =
             3 这里用到一个min(Open,bStop) ,如果想知道和直接用 SELL(0,Open)有什么差别,可以修改交易命令,存成另外一个公式,将两个公式加载到一张图表,看看两个公式的信号点有什么不同。
作者: myangsoft    时间: 2011-10-17 12:59:25

谢谢分享
作者: ohuangkai    时间: 2011-10-17 13:00:50

本帖最后由 ohuangkai 于 2011-10-17 16:34 编辑

将这个程序实用化。
    这样,一个简单的趋势跟随的交易程序就差不多了,但如果直接拿他去进行交易,还是有些问题的。
    在每天早晨开盘前,TB价格就会出来,这时候如果正好有信号出现时,就会造成委托单无效,影响我们的交易。 我们增加了一条控制语句。
    我们需要对交易数量的控制,还需要在价格快速变动的时候也能成交(增加滑点)。在增加了这一部分后,程序就变成这个样子:
Params
        Numeric n1(10);
        Numeric n2(3);
        Numeric d1(10);
        Numeric d2(3);
        Numeric lots(2);           // 交易数量
        Numeric offset(2);        // 滑点
        Numeric nLoss(100);
       
Vars
        NumericSeries m1;
        NumericSeries m2;
        Numeric bStop;
        Numeric sStop;
        Numeric OnePoint;
Begin
        If (Time == 0.0900 && High==Low) Return;      // 过滤掉每天第一根K线前的竞价
        OnePoint = MinMove*PriceScale;       
        m1 = Average(Close,n1);
        m2 = Average(Close,n2);
        PlotNumeric("m1",m1);
        PlotNumeric("m2",m2);
       
        If ( m1[1]>m1[d1] && m2[1] > m2[d2])       Buy(lots,Open+offset*OnePoint);
        If ( m1[1]<m1[d1] && m2[1] < m2[d2]) SellShort(lots,Open-offset*OnePoint);
       
        bStop = Highest(High,BarsSinceEntry) - nLoss*OnePoint;    //买盘止损线不断移动到买入后产生的最高价减去止损限额
        sStop =  Lowest( Low,BarsSinceEntry) + nLoss*OnePoint;    //卖盘止损线不断移动到卖出后产生的最低价加上止损限额
        If (MarketPosition == 1) PlotNumeric("bStop",bStop);
        If (MarketPosition ==-1) PlotNumeric("sStop",sStop);
       
        If ( BarsSinceEntry > 0)
        {       
            If ( MarketPosition == 1 &&  Low<bStop )       Sell(lots,Min(Open,bStop)-offset*OnePoint);
                If ( MarketPosition ==-1 && High>sStop ) BuyToCover(lots,Max(Open,sStop)+offset*OnePoint);
        };
End
     运行后,止损线太杂乱,你需要把这个线型改为线段。
作者: guitar22412    时间: 2011-10-17 15:17:15

先顶你一下,再慢慢看
作者: ohuangkai    时间: 2011-10-17 15:56:54

本帖最后由 ohuangkai 于 2011-10-18 19:28 编辑

再说序列变量
    在群里,有朋友提醒我:IF ( ) 里面和后面最好不要用序列变量,否则会出错,非常感谢他的提醒。
    那么,到底能不能这样用呢? 毕竟,我前面的程序里有用到。而且,TB的说明里也有这样的警告:可能会发生不可预估的错误。

    前面讲过,每根BAR都有一些系统的序列变量,如:close,open,time 等等,我们创造的序列变量也自动会和他们一样保留下来。所以,才有ma[1]这样的用法。
    那么序列变量有哪些特性呢?
    第一:序列变量在每根BAR上都存在而且会保留下来。这个已经讲过了。
    第二:不能修改当前BAR之前的序列变量,如:ma[1] = 400 这样的语句会出错的。
    第三:序列变量是可以传递的。如果我们在本BAR中没有给他赋值,他会等于上一根BAR的值。这个用处非常大。就像一个全局变量一样,前面曾经定义过的值,以后都能直接拿来用。相应的,普通变量每根bar上开始计算时,他都要归位,不受以前的影响。
   
    因为这些特性,我们写程序时,要注意下面几点:
    1 如果在条件判断语句里给序列变量赋值时,要考虑条件不成立的时候序列变量应该是什么值,比如有一个序列变量 xyz,  
     IF ( 条件 ) { ...;xyz=Close*(1+0.005);...}
                  else { ...;xyz=Close*(1-0.005);...};
     如果你没有第二行,这个值可能会给你以后的程序执行造成一定的麻烦。
     从上面的这个例子也可以看到,序列变量有时候不可避免地要在IF语句里出现,这是没有办法的事,如果他在左侧,我们就要遵循上面这个规则。
    2 在条件判断语句( IF )里,我们要尽量避免序列变量出现在 = 号的右边,如: if ( 条件 ) { ...;mmm = xyz*xyz;...}
        要避免这个现象,我们可以先用一个普通变量保存这个值,然后在条件语句里用:
     Vars
             ...
             NumericSeries xyz;
             Numeric mmm;
             Numeric temp;
       Begin
            ...
           temp = xyz*xyz;
          if ( 条件 )
      {  ...
             mmm = temp;
          };
             ...      
      End
    3 在使用序列变量时,要考虑第一根BAR上使用时,他是否已经被赋值,如果没有,就要给他一个合适的值。还有你引用的是否是不存在的的序列变量,如:你在第三根BAR上用CLOSE[10],很显然,这个值是个无效值.如使用EMA的计算公式方法,构造一个序列变量:
     xyz = xyz/6+close[1]*5/6;
     这个结果会是什么样呢?  在第一根BAR上,CLOSE[1]不存在,那么,xyz就是一个无效值。 在第二根BAR上运行时,close[1]恢复正常,但是等式右边的xyz 却是继承上一根BAR的值----无效值,结果自然还是无效。
作者: arthurs    时间: 2011-10-17 17:29:38

好好学习,楼主好人
作者: ohuangkai    时间: 2011-10-17 20:21:06

本帖最后由 ohuangkai 于 2011-10-17 20:23 编辑

有错就改。
    刚才我们讲了如何避免序列变量出现在IF 等判断语句里,现在我们看看具体实现出来是什么样子,为了简单而且说明问题,发一个双均线的模型模板:
Params
        Numeric nShort(3);
        Numeric nLong(30);
        Numeric lots(1);
       
Vars
        NumericSeries m0;
        NumericSeries m1;
        Bool c1;
        Bool c2;
Begin
        If (CurrentBar < Max(nShort,nLong)) Return;
       
        m0 = AverageFC(Close,nSHort);
        m1 = XAverage(Close,nLong);
       
        PlotNumeric("m0",m0);
        PlotNumeric("m1",m1);
       
        c1 = CrossOver(m0[1],m1[1]);  // 向上穿越
        c2 = CrossUnder(m0[1],m1[1]); // 向下穿越
       
        If (c1 ) Buy(lots,Open);
        If (c2) SellShort(lots,Open);
       
End
作者: rexxar    时间: 2011-10-17 20:25:02

顶,谢谢老大,例子很好
作者: xiaoshansanzhi    时间: 2011-10-18 09:05:40

回复 1# ohuangkai


    在交易中不断学习,在学习中不断进步
作者: xiaoshansanzhi    时间: 2011-10-18 15:23:14

回复 4# ohuangkai


    坐下啦慢慢学
作者: ohuangkai    时间: 2011-10-20 18:13:07

本帖最后由 ohuangkai 于 2011-10-20 20:46 编辑

这两天有一个朋友要我看看他程序错在哪里了。我看了后,发现他程序比较专业,循环控制一类的语句都用到了,可他TB编程用的是对图表遍历,出发点就错了。
   TB的程序是在每根BAR上运行的,而不是在整个表上遍历的。这个是最初编程的要点,所以再次提及一下。
   这个和文华交易系统有差异,从思想上来说,TB实际上更容易,也更灵活一些。

代码跟踪与调试
    继续侃调试方法。
    编程语法错误是最容易修正的,提示也基本到位。但改完了,没有按照自己想象的方式运行,错误的现象不可思议,这时候,就考验基本功了。
    commentary: 在关键的地方前面和后面,显示你认为可能有问题的变量,如xyz, 我们可以插入一行:commentary("xyz="+text(xyz))  这样在每根K线上都可能显示出:xyz=.... 这样的东西。 我们就能知道XYZ的变化了。
    fileappend: 这个命令把结果写到一个文件里,是跟踪的最好的办法。比如:fileappend("d:\\1.txt"," xyz="+text(xyz)) ,这样,你在D盘根目录下就能找到1.txt,打开来看就行了。
                这个命令有个缺点,因为程序在每根BAR上都执行一次,你的这个记录就会很多,查找起来非常麻烦。实际上,你只想看在某一根BAR上的输出结果,找出你的逻辑问题。
                你可以设计一个变量: Bool cFile;    然后, cFile= DATE==20110924&&TIME==0.0935  输出时,就用: if ( cFile ) fileappend("d:\\1.txt"," xyz="+text(xyz)) 这样类似的语句,大量的输出你需要的信息,可以很精细地进行调试。
    用上面两个语句,也是程序员们经常用到的技巧。
    TB编程最容易出错的地方是序列变量。
    序列变量的用法。前面也说到过,序列变量的第一次前一定要赋值,否则,麻烦就跟影子一样,给你带来一些说不清楚的麻烦。如果在条件语句里赋值,那么要考虑没有满足条件的时候,这个序列变量应该是什么值,给他了没有。

        恩,就到这里吧。写程序是件快乐的事,调试程序是件很让人上火的事。技巧方法不一而足,做得多了,就简单了。
作者: CFTRADE    时间: 2011-10-20 19:18:35

学习了   楼主继续
作者: rexxar    时间: 2011-10-24 13:12:00

谢谢,学习了
作者: xiaoshansanzhi    时间: 2011-10-24 15:03:06

回复 12# ohuangkai


   搬张凳子,慢慢学习
作者: 蔡宛宏    时间: 2011-12-16 18:13:40

这个帖子收藏起来看看,有用处
作者: 海鱼    时间: 2012-6-6 10:26:56

不错的教学帖,好好学习一下!
作者: 感悟人生    时间: 2012-6-6 20:26:42

xiexie
作者: ‰汢荳※嘙    时间: 2012-6-14 15:51:41

这个帖子真的很有用,楼主讲的很清楚,真的希望楼主能够继续,带领我们走上程序化的道路。
作者: 奋斗不止    时间: 2012-6-23 14:25:16

看着是有点简单,真写起来需要来熟练!
作者: 还在路上    时间: 2012-6-27 10:28:07

又是一个好教程,TB要普及啦
作者: zerocool    时间: 2012-7-9 11:13:11

很好!

作者: 光数斗    时间: 2012-8-5 21:52:21

  楼主是好心人  交易者要做有心人啊
作者: 迎风尿十丈    时间: 2012-10-16 19:45:55

学习了
作者: baikaishui    时间: 2014-6-8 07:42:09

真的很谢谢楼主,帮了我很大的忙啊,这个贴子
作者: baikaishui    时间: 2014-6-8 07:53:56

  Bool c1;
        Bool c2;
Begin
        If (CurrentBar < Max(nShort,nLong)) Return;
        
        m0 = AverageFC(Close,nSHort);
        m1 = XAverage(Close,nLong);
        
        PlotNumeric("m0",m0);
        PlotNumeric("m1",m1);
        
        c1 = CrossOver(m0[1],m1[1]);  // 向上穿越
        c2 = CrossUnder(m0[1],m1[1]); // 向下穿越
        
        If (c1 ) Buy(lots,Open);
        If (c2) SellShort(lots,Open);
        
End
能请问下老大,这里面的IF(C1)是指IF(C1(TRUE))吗,这个条件判断默认的都是TRUE吗
作者: lierwang    时间: 2014-7-13 22:56:58

baikaishui 发表于 2014-6-8 07:53
Bool c1;
        Bool c2;
Begin

理解正确,不过说的有问题,这里的IF(C1)是指IF(C1==true)),意思为:如果C1这个条件为真
作者: wolf0413042    时间: 2017-4-23 22:55:59

学习了,开始学习TB编程
作者: swjtusan    时间: 2018-10-20 08:38:05

mark




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