设为首页收藏本站

 找回密码
 注册
查看: 9871|回复: 25
打印 上一主题 下一主题

一个容易犯得编程错误 [复制链接]

Rank: 5Rank: 5

精华
0
UID
5525
积分
1473
帖子
429
主题
93
阅读权限
60
注册时间
2009-9-22
最后登录
2022-5-23
跳转到指定楼层
1#
发表于 2010-5-19 20:28:40 |只看该作者 |倒序浏览
下面程序是我从程序中摘取的片段,它编译正确,但执行不是我要的结果。
Vars
   String MyLogFile; //日志文件名
   Numeric MyTicks(7); //计数值
Begin
   If (BarStatus==0)
   {       
       MyLogFile ="c:\\MyAutoExiter.Log";
       SetGlobalVar(0,0); //Ticks计数器归0
       FileAppend(MyLogFile,"启动交易程序 for "+SymbolName+" at "+TimeToString(CurrentTime));
   }
   SetGlobalVar(0,GetGlobalVar(0)+1);//计数器增1
   If (GetGlobalVar(0)>=MyTicks)
   {
       FileAppend(MyLogFile,"计数值==7");  //这句没有做出任何记录
      // CommentaryCommentary
       SetGlobalVar(0,0); //Ticks计数器归0
   }
End
程序中只有第一个FileAppend语句执行了,其后每一次执行FileAppend语句都没有结果。
我百思不得其解,我把大段程序注释掉,化简为上面的程序段,甚至在FileAppend语句后加了Commentary验证,发现FileAppend语句肯定是执行的,但为什么没有记录“计数器==7”呢?
我百思不得其解!

Rank: 5Rank: 5

精华
0
UID
5525
积分
1473
帖子
429
主题
93
阅读权限
60
注册时间
2009-9-22
最后登录
2022-5-23
2#
发表于 2010-5-19 20:54:17 |只看该作者
我甚至怀疑FileAppend函数是否在使用变量的情况下有问题,我把MyLogFile变量替换成"C:\\Test4.Log",竟然问题解决了,似乎我证实了FileAppend函数在使用变量时有问题。
我高兴了好一会,我对着程序有看了一遍。或然我感到我犯了一个非常简单的错误,就是以一般编程的思维来理解TB程序执行步骤,也就是在一般编程中,变量一旦初始化,在程序执行中一直有效,直到程序改变它。因此在我的头脑中,MyLogFile的内容始终是"c:\\MyAutoExiter.Log",但实际上它的值在第一个Bar以后都为N/A,自然不可能输出任何内容。
我忽略了我脑海中深深印记的TB执行流程,也就是TB始终是每个Bar执行一遍,然后在实时行情时每个Tick执行一遍程序,因此所有的变量都要重新计算。只有用公共变量能保留数值,或者利用SetTBProfileString和GetTBProfileString对数据库操作能保存字符串值。

用二种办法修改这段程序可解决问题。

使用道具 举报

Rank: 5Rank: 5

精华
0
UID
5525
积分
1473
帖子
429
主题
93
阅读权限
60
注册时间
2009-9-22
最后登录
2022-5-23
3#
发表于 2010-5-19 20:57:35 |只看该作者
方法一:

Vars
   String MyLogFile; //日志文件名
   Numeric MyTicks(7); //计数值
Begin
   If (BarStatus==0)
   {        
       //MyLogFile ="c:\\MyAutoExiter.Log"; //把这条语句移到IF语句之外
       SetGlobalVar(0,0); //Ticks计数器归0
       FileAppend(MyLogFile,"启动交易程序 for "+SymbolName+" at "+TimeToString(CurrentTime));
   }
   MyLogFile ="c:\\MyAutoExiter.Log"; //移过来的语句
   SetGlobalVar(0,GetGlobalVar(0)+1);//计数器增1
   If (GetGlobalVar(0)>=MyTicks)
   {
       FileAppend(MyLogFile,"计数值==7");  //这句没有做出任何记录
      // CommentaryCommentary
       SetGlobalVar(0,0); //Ticks计数器归0
   }
End

[ 本帖最后由 efrog 于 2010-5-19 21:25 编辑 ]

使用道具 举报

Rank: 5Rank: 5

精华
0
UID
5525
积分
1473
帖子
429
主题
93
阅读权限
60
注册时间
2009-9-22
最后登录
2022-5-23
4#
发表于 2010-5-19 21:01:47 |只看该作者
方法二(更简单):
Vars
   String MyLogFile("c:\\MyAutoExiter.Log"); //日志文件名。作为变量初始值,每次Tick执行时恢复该值。
   Numeric MyTicks(7); //计数值
Begin
   If (BarStatus==0)
   {        
       //MyLogFile ="c:\\MyAutoExiter.Log"; //去掉该语句
       SetGlobalVar(0,0); //Ticks计数器归0
       FileAppend(MyLogFile,"启动交易程序 for "+SymbolName+" at "+TimeToString(CurrentTime));
   }
   SetGlobalVar(0,GetGlobalVar(0)+1);//计数器增1
   If (GetGlobalVar(0)>=MyTicks)
   {
       FileAppend(MyLogFile,"计数值==7");  //这句没有做出任何记录
      // CommentaryCommentary
       SetGlobalVar(0,0); //Ticks计数器归0
   }
End

使用道具 举报

Rank: 5Rank: 5

精华
0
UID
5525
积分
1473
帖子
429
主题
93
阅读权限
60
注册时间
2009-9-22
最后登录
2022-5-23
5#
发表于 2010-5-19 21:21:26 |只看该作者
我原想使用MyLogFile=”C:\\My”+SymbolName+“.Log”; 来针对不同的交易品种来记录交易日志,发生了上述错误后放弃了,但现在想来还是可行的!

有一点建议给TB公司的开发人员,能否像MT4系统一样有一段初始化程序段:
Params
   //参数区
Vars
   //变量区
Initialize
   //初始化程序区,在程序中只执行一遍

Begin
   //循环执行区
End

[ 本帖最后由 efrog 于 2010-5-19 21:22 编辑 ]

使用道具 举报

Rank: 3Rank: 3

精华
0
UID
3091
积分
244
帖子
55
主题
11
阅读权限
40
注册时间
2008-12-19
最后登录
2011-4-9
6#
发表于 2010-7-27 15:02:30 |只看该作者
怎么没人回复?
好贴
彻底让我明白TB的执行流程,谢谢efrog了

使用道具 举报

Rank: 4

精华
0
UID
3136
积分
331
帖子
61
主题
11
阅读权限
50
注册时间
2008-12-23
最后登录
2013-10-13
7#
发表于 2010-9-15 15:21:02 |只看该作者
请问有人看的懂上面这个程序是用来干嘛的吗?

使用道具 举报

Rank: 5Rank: 5

精华
0
UID
5525
积分
1473
帖子
429
主题
93
阅读权限
60
注册时间
2009-9-22
最后登录
2022-5-23
8#
发表于 2010-9-15 20:29:32 |只看该作者
本帖最后由 efrog 于 2011-10-11 11:10 编辑

谢谢有人欣赏我的帖子,这是我学习TB的点滴心得,奉献给大家。
这段程序是告诉你:
如果一个变量要所有周期都要使用(如程序中的MyLogFile ="c:\\MyAutoExiter.Log";),那么你要么放在变量的初始化里(如Var String MyLogFile ("c:\\MyAutoExiter.Log");),要么放在程序的If 框架之外。否则的话如放在If (BarSatuts==0) 之内,那么在其他的周期MyLogFile的值实际上就等于N/A,所以发生1楼所看到的现象。明白了吗?
TB的每一个Bar(和Tick)来临后,所有的变量都从头赋值或计算,并不继承上一个Bar的值!!除非使用公共变量。

2011-10-11增加
这个问题也容易错:

If (con1 && Con2 && ......);
{
   语句1;
  .............;
}
错在If条件后习惯性加了语句分割符分号,结果导致条件内的语句总是被执行,还以为是条件计算错误。
上善若水,无欲则刚

使用道具 举报

Rank: 5Rank: 5

精华
0
UID
5525
积分
1473
帖子
429
主题
93
阅读权限
60
注册时间
2009-9-22
最后登录
2022-5-23
9#
发表于 2010-9-15 20:40:33 |只看该作者
本帖最后由 efrog 于 2010-9-15 20:41 编辑

另外使用:
  SetGlobalVar(0,GetGlobalVar(0)+1);//计数器增1
   If (GetGlobalVar(0)>=MyTicks)
   {
      SetGlobalVar(0,0); //Ticks计数器归0
   }
是为了防止重复发单,信号出现后,如果GV0的值大于7,则发出交易指令,否则等7个Tick。一般5个Tick以后,上一个发出的交易指令结果就返回了,你的账户函数的值已发生了变化,所以要用公共变量控制等7个Tick后处理出现的信号。
上善若水,无欲则刚

使用道具 举报

Rank: 3Rank: 3

精华
0
UID
15215
积分
170
帖子
39
主题
5
阅读权限
40
注册时间
2010-8-15
最后登录
2010-11-24
10#
发表于 2010-9-16 09:15:14 |只看该作者
你瞒会自娱自乐的,不过 加一个初始化模块是个好建议啊,但是那些闭门造车的人不会理你的
新手

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

bottom

静态版|手机版|联系我们|交易开拓者 ( 粤ICP备07044698   

GMT+8, 2024-5-5 23:43

Powered by Discuz! X2 LicensedChrome插件扩展

© 2011-2012 交易开拓者 Inc.

回顶部