开拓者期货期权程序化系统交易论坛
标题:
一个容易犯得编程错误
[打印本页]
作者:
efrog
时间:
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”呢?
我百思不得其解!
作者:
efrog
时间:
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对数据库操作能保存字符串值。
用二种办法修改这段程序可解决问题。
作者:
efrog
时间:
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 编辑
]
作者:
efrog
时间:
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
作者:
efrog
时间:
2010-5-19 21:21:26
我原想使用MyLogFile=”C:\\My”+SymbolName+“.Log”; 来针对不同的交易品种来记录交易日志,发生了上述错误后放弃了,但现在想来还是可行的!
有一点建议给TB公司的开发人员,能否像MT4系统一样有一段初始化程序段:
Params
//参数区
Vars
//变量区
Initialize
//初始化程序区,在程序中只执行一遍
Begin
//循环执行区
End
[
本帖最后由 efrog 于 2010-5-19 21:22 编辑
]
作者:
leevolvo
时间:
2010-7-27 15:02:30
怎么没人回复?
好贴
彻底让我明白TB的执行流程,谢谢efrog了
作者:
bjcifco
时间:
2010-9-15 15:21:02
请问有人看的懂上面这个程序是用来干嘛的吗?
作者:
efrog
时间:
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条件后习惯性加了
语句分割符分号
,结果导致条件内的语句总是被执行,还以为是条件计算错误。
作者:
efrog
时间:
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后处理出现的信号。
作者:
zhudaqun
时间:
2010-9-16 09:15:14
你瞒会自娱自乐的,不过 加一个初始化模块是个好建议啊,但是那些闭门造车的人不会理你的
作者:
zhudaqun
时间:
2010-9-16 09:21:42
不过给你提个建议啊,千万不要用等多长时间然后处理 这种方法。网络延迟,服务器连不上这种异常经常发生
作者:
herbert_tan
时间:
2010-12-14 21:09:13
好贴啊!!!
作者:
bluefire999
时间:
2011-3-9 10:27:03
好贴!确实的小心变量放到if条件语句外的情况,否则N/A不小心因为tb机制原因误导操作
作者:
yishengu
时间:
2011-4-3 22:02:36
确实新接触TB的人是会忽视这个问题,尽管TB的帮助文档中提到了TB程序的执行过程,但是惯有的编程思维定势还是会导致犯这种错误。谢谢efrog分享!
作者:
allin
时间:
2011-4-7 23:13:43
好贴啊,对楼主很欣赏
作者:
读书山林
时间:
2011-8-10 12:10:09
好贴,如果一个变量要所有周期都要使用,那么你要么放在变量的初始化里,要么放在程序的If 框架之外。
作者:
读书山林
时间:
2011-8-10 12:11:53
我原想使用MyLogFile=”C:\\My”+SymbolName+“.Log”; 来针对不同的交易品种来记录交易日志,发生了上述错 ...
efrog 发表于 2010-5-19 21:21
建议tb增加这个功能
作者:
lzl563
时间:
2011-8-11 00:33:16
没太看懂。。
作者:
alex647l
时间:
2011-8-11 09:11:17
TB没有全局变量,LZ说的初始化的部分。。。。。。。可以用代码解决的问题,又不是写大程序,不需要怎么苛求把
作者:
lhmindson
时间:
2011-9-4 20:55:33
学习中。。。
作者:
skyfis
时间:
2011-10-4 15:34:54
非常欣赏efrog天天向上的精神,要写出专业的交易系统,出了对技术面的总结提炼,还要包括对开发平台的深入了解。
工欲善其事必先利其器。
作者:
Amymylove
时间:
2011-10-10 09:57:12
马克留名学习之
作者:
xiaoshansanzhi
时间:
2011-11-2 09:37:05
好贴,对于我们这些初学者来说这样的讨论太有意义了,谢谢LZ
作者:
slarkmonk
时间:
2011-11-2 09:38:43
这个帖子必须顶啊...
作者:
goolybody
时间:
2011-11-2 10:58:55
简单的方法: Stringseries MyLogFile;
作者:
蔡宛宏
时间:
2011-12-16 17:50:18
谢谢LZ分享
欢迎光临 开拓者期货期权程序化系统交易论坛 (http://bbs.tb18.net/)
Powered by Discuz! X2