MQL4程序的常见错误以及如何避免它们_第1页
MQL4程序的常见错误以及如何避免它们_第2页
MQL4程序的常见错误以及如何避免它们_第3页
MQL4程序的常见错误以及如何避免它们_第4页
MQL4程序的常见错误以及如何避免它们_第5页
已阅读5页,还剩10页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实用文档MQL4程序的常见错误以及如何避免它们介绍一些较旧的程序可能在HYPERLINK新版本的MQL4编译器中返回错误。为了避免关键的程序完成,以前版本的编译器在运行环境中处理了许多错误。例如,除数为零或数组越界都是严重错误,并通常会导致应用程序崩溃。这些错误只在一些状态下针对某些变量值而发生。阅读这篇文章了解如何处理这样的情况。

新的编译器可以检测实际或潜在的错误源并提高代码质量。在这篇文章中,我们讨论了旧程序编译过程中检测到的可能出现的错误,以及解决这些问题的方法。编译错误HYPERLINK1.1.与关键字一致的标识HYPERLINK1.2.变量和函数名的特殊字符HYPERLINK1.3.使用switch操作符的错误HYPERLINK1.4.函数返回值

HYPERLINK1.5.函数参数数组

运行时间错误HYPERLINK2.1.数组越界HYPERLINK2.2.除数为零HYPERLINK2.3.当前字符用0替代NULLHYPERLINK2.4.Unicode格式字符串和它们在DLL中的使用HYPERLINK2.5.文件共享HYPERLINK2.6.日期时间转换HYPERLINK编译器警告HYPERLINK3.1.全局和局部变量名称一致HYPERLINK3.2.类型不匹配HYPERLINK3.3.未使用的变量1编译错误如果程序代码中包含HYPERLINK错误,则它不能被编译。要完全控制所有的错误,建议使用HYPERLINK严谨的编译模式,它通过以下指令来设置:#propertystrict这种模式大大简化了故障排除。

1.1.与关键字一致的标识如果变量或函数的名称与其中一个HYPERLINK关键字一致intchar[];

//incorrectintchar1[];//correctintchar()

//incorrect{return(0);}编译器会返回一个错误信息:图1.错误“unexpectedtoken(非预期标记)”和“nameexpected(预期名称)”要解决这个错误,您需要使用变量或函数的正确名称。1.2.变量和函数名的特殊字符如果变量或函数名称中包含特殊字符($,@,点):

int$var1;//incorrectint@var2;//incorrectintvar.3;//incorrectvoidf@()

//incorrect{return;}编译器会返回一个错误信息:图2.错误“unknownsymbol(未知交易品种)”与“semicolonexpected(预期分号)”要解决这个错误,您需要使用正确的函数或变量名。1.3.使用switch操作符的错误在旧版本的编译器中,您可以在HYPERLINKswitch操作符的表达式和常量中使用任何值:voidstart(){doublen=3.14;switch(n){case3.14:Print("Pi");break;case2.7:Print("E");break;}}在新的编译器中,switch操作符的常量和表达式必须是整数,所以当您尝试使用这样的结构时会发生错误:图3.错误“illegalswitchexpressiontype(非法switch表达式类型)”和“constantexpressionisnotintegral(常量表??达式不是整数)”在这种情况下,您可以使用明确的数值比较,例如:voidstart(){doublen=3.14;if(n==3.14)Print("Pi");elseif(n==2.7)Print("E");}1.4.函数返回值除了空值外的所有函数都应该返回声明的类型值。例如:intfunction(){}在严谨的编译模式下发生错误:图4.错误“notallcontrolpathsreturnavalue(并非所有的控制路径返回一个值)”在默认的编译模式下,编译器会返回一个警告:图5.警告:“notallcontrolpathsreturnavalue(并非所有的控制路径返回一个值)”如果函数的返回值与声明的不匹配:intinit()

{return;

}在严格的编译中会检测错误:图6.错误“functionmustreturnavalue(函数必须返回一个值)”在默认的编译模式下,编译器会返回一个警告:图7.警告'return-functionmustreturnavalue(回报-函数必须返回一个值)”要解决这样的错误,添加带有相应类型返回值的HYPERLINKreturn操作符到函数代码。1.5.函数参数数组在函数参数,数组现在只引用传递。

doubleArrayAverage(doublea[]){return(0);}在严谨的编译模式下,该代码将导致错误:图8.编译器错误“arrayspassedbyreferenceonly(数组只引用传递)”在默认的编译模式下,编译器会返回一个警告:图9.编译器警告“arrayspassedbyreferenceonly(数组只引用传递)”要修复此错误,您必须通过在数组名称之前添加前缀来指定数组是通过引用传递的:doubleArrayAverage(double&a[]){return(0);}但应注意的是,现在常量数组(HYPERLINKTime[],

HYPERLINKOpen[],

HYPERLINKHigh[],

HYPERLINKLow[],

HYPERLINKClose[],

HYPERLINKVolume[])不能引用传递。例如,下面的调用:ArrayAverage(Open);无论何种编译模式都会导致错误:图10.错误'Open'-constantvariablecannotbepassedasreference(‘打开’-常量变量不能引用传递)为了避免这些错误,从常量数组??复制所需的数据://---anarraythatstoresopenpricevaluesdoubleOpenPrices[];//---copythevaluesofopenpricestotheOpenPrices[]arrayArrayCopy(OpenPrices,Open,0,0,WHOLE_ARRAY);//---functioncallArrayAverage(OpenPrices);2.运行时间错误程序代码执行过程中出现的错误称为运行时间错误。这种错误通常是依赖于程序的状态,并与变量的不正确的值相关联。

例如,如果变量用作数组元素的索引,其负值将不可避免地导致数组超出范围的错误。2.1.数组超出范围访问指标缓冲区时常常在指标中发生这个错误。该HYPERLINKIndicatorCounted()函数返回自上次指标调用的不变的柱数。先前计算的柱的指标值不需要重新计算,所以为了更快的计算,您只需要处理最后的几个柱。

大部分使用这种计算优化的方法的指标看起来如下://+------------------------------------------------------------------+//|Customindicatoriterationfunction

|//+------------------------------------------------------------------+intstart(){//---somecalculationsrequirenolessthanNbars(e.g.100)

if(Bars<100)//iflessbarsareavailableonachart(forexampleonMNtimeframe)

return(-1);//stopcalculationandexit//---thenumberofbarsthathavenotchangedsincethelastindicatorcallintcounted_bars=IndicatorCounted();//---exitifanerrorhasoccurredif(counted_bars<0)return(-1);//---positionofthebarfromwhichcalculationintheloopstartsintlimit=Bars-counted_bars;//---ifcounted_bars=0,reducethestartingpositionintheloopby1,

if(counted_bars==0){limit--;

//toavoidthearrayoutofrangeproblemwhencounted_bars==0//---weuseashiftof10barsbackinhistory,soaddthisshiftduringthefirstcalculationlimit-=10;}else//---theindicatorhasbeenalreadycalculated,counted_bars>0{

//---forrepeatedcallsincreaselimitby1toupdatetheindicatorvaluesforthelastbarlimit++;}//---themaincalculationloopfor(inti=limit;i>0;i--){Buff1[i]=0.5*(Open[i+5]+Close[i+10])//valuesofbars5and10barsdeepertohistoryareused}}通常counted_bars==0的情况处理不当(初始限制持仓应该通过等于相对循环变量的1+最大指数的值来降低)。另外,请记住,在执行start()函数的时候,我们可以从0到HYPERLINKBars()-1的访问指标缓冲区的数组元素。如果您需要使用无指标缓冲区的数组,那么按照指标缓冲区的当前大小使用HYPERLINKArrayResize()函数来增加其大小。也可以通过调用用作参数的指标缓冲区的

HYPERLINKArraySize()来获得元素地址的最大指数。2.2.除数为零当除法运算中除数为零时则会发生零除的错误:voidOnStart(){//---inta=0,b=0,c;c=a/b;Print("c=",c);}当您运行这个脚本时,专家选项卡会出现一条错误的消息,并且程序关闭:图11.错误消息“zerodivide(除数为零)”当除数的值由任何外部数据值来决定时,通常会出现此错误。例如,如果交易参数进行分析,如果没有新建订单,那么已用预付款的值等于0。另一个例子:如果要从一个文件读取分析数据,如果该文件不可用,那么我们也不能保证正确的操作。所以您应该考虑到这样的情况并正确地处理它们。最简单的方法是除法运算前检查除数并报告不正确的参数值:voidOnStart(){//---inta=0,b=0,c;if(b!=0){c=a/b;Print(c);}else{Print("Error:b=0");return;};}这不会导致严重的错误,但是不正确参数值的消息一出现则程序即关闭:图12.不正确的除数消息2.3.当前字符用0替代NULL

在旧版本的编译器中0(零)可用作满足金融工具规范的函数参数。例如,当前交易品种的移动平均线技术指标的值可能被要求如下:AlligatorJawsBuffer[i]=iMA(0,0,13,8,MODE_SMMA,PRICE_MEDIAN,i);//incorrect在新的编译器中您应该明确地指定NULL来规定当前的交易品种:AlligatorJawsBuffer[i]=iMA(NULL,0,13,8,MODE_SMMA,PRICE_MEDIAN,i);//correct此外,当前交易品种和图表周期可使用HYPERLINKSymbol()和HYPERLINKPeriod()函数来指定。AlligatorJawsBuffer[i]=iMA(Symbol(),Period(),13,8,MODE_SMMA,PRICE_MEDIAN,i);//correct2.4.Unicode字符串和它们在DLL中的使用字符串现在表示为Unicode字符序列。记住这一点,并使用适当的Windows函数。例如,使用wininet.dll库来替代InternetOpenA()和InternetOpenUrlA(),您应该调用InternetOpenW()和InternetOpenUrlW()。该HYPERLINK字符串的内部结构在MQL4中(现在只需要12个字节)发生了变化,当传递字符串到DLL时应使用MqlString结构:#pragmapack(push,1)structMqlString{int

size;

//32bitinteger,containsthesizeofthebufferallocatedforthestringLPWSTR

buffer;

//32bitaddressofthebufferthatcontainsthestringint

reserved;

//32bitinteger,reserved,donotuse};#pragmapack(pop,1)2.5.文件共享在新MQL4中,FILE_SHARE_WRITE和FILE_SHARE_READ标志应明确地指定以便打开文件时共享使用。

如果标志不存在,那么该文件以单独模式打开,直到文件由打开它的用户关闭才可以被其他人打开。例如,使用离线图表时共享标志应明确指定://1-stchange-addshareflagsExtHandle=FileOpenHistory(c_symbol+i_period+".hst",FILE_BIN|FILE_WRITE|FILE_SHARE_WRITE|FILE_SHARE_READ);欲了解更多详情,请阅读HYPERLINK新MQL4的离线图表。2.6.日期时间转换转换HYPERLINK日期时间为一个字符串现在取决于编译模式:datetimedate=D'2014.03.0515:46:58';stringstr="mydate="+date;//---str="mydate=1394034418"-oldcompiler,nodirective#propertystrictinthenewcompiler//---str="mydate=2014.03.0515:46:58"-newcompilerwiththedirective#propertystrict例如,尝试使用文件名中包含冒号的文件会导致错误。3.编译器警告HYPERLINK编译器警告是信息性而非错误的讯息,但它们指出了可能的错误来源。一个清晰的代码不应该包含警告。3.1.全局和局部变量名称一致如果全局和局部各级变量具有相似的名称:inti;//aglobalvariablevoidOnStart(){//---inti=0,j=0;//localvariablesfor(i=0;i<5;i++){j+=i;}PrintFormat("i=%d,j=%d",i,j);}编译器会显示指出全局变量的声明行号的警告:图13.警告“decl

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论