加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

MQL5 编程基础:时间 2

(2016-04-25 22:19:42)
分类: 工作修行

确定日开始时间以及自日开始以来流逝的时间量

根据某给定时间来确定日开始时间最显而易见的方式,就是将时间分解成其各个分量,将小时、分钟和秒归零,然后再把它们加起来。但是,还有一种更简单的方式。一天有 86400 秒。我们需要获取一个时间除以一天秒数所得结果的整数,再乘以一天的秒数:


datetime tm=TimeCurrent(); tm=(tm/86400)*86400//--- output result Alert("Day start time: "+(string)tm);

注意! 此技巧仅于整数变量有效。如果您的计算中出现任何双精度和浮点型变量,则需要利用 MathFloor() 函数截掉小数部分:


MathFloor(tm/86400)*86400

乘法运算之后,则应利用 NormalizeDouble() 函数完成值的正态化。因为结果必须为整数,所以您可以利用一个取整函数 MathRound()


MathRound(MathFloor(tm/86400)*86400)

采用 integer 变量时,余数会被自动截掉。处理时间的过程中,很少会用到双精度或浮点型变量;如果用到它们,极有可能表明方法从根本上错了。

要确定自日开始起流逝的秒数,我们只需取时间除以 86400 的余数:


datetime tm=TimeCurrent(); long seconds=tm%86400//--- output result Alert("Time elapsed since the day start: "+(string)seconds+" sec.");

也可以用类似的方法,将获取的以秒计算的时间,转换为小时、分钟和秒。作为一个函数实施:


int TimeFromDayStart(datetime aTime,int &aH,int &aM,int &aS)   //--- Number of seconds elapsed since the day start (aTime�400), //--- divided by the number of seconds in an hour is the number of hours    aH=(int)((aTime%86400)/3600); //--- Number of seconds elapsed since the last hour (aTime600), //--- divided by the number of seconds in a minute is the number of minutes    aM=(int)((aTime%3600)/60); //--- Number of seconds elapsed since the last minute   aS=(int)(aTime%60); //--- Number of seconds since the day start   return(int(aTime%86400));   }

第一个传递的参数是时间。其它参数均用于返回值:aH - 小时,aM - 分钟,aS - 秒。此函数本身会返回自日开始起的总秒数。我们来看看这个函数:


datetime tm=TimeCurrent(); int t,h,m,s; t=TimeFromDayStart(tm,h,m,s); //--- output resultAlert("Time elapsed since the day start ",t," s, which makes ",h," h, ",m," m, ",s," s ");

您也可以计算确定日开始柱的指标中待使用的天数:


bool NewDay=(time[i]/86400)!=(time[i-1]/86400);

假设各柱由左至右索引,其中 time[i] 为当前柱的时间,而 time[i-1] 则为前一柱的时间。

 

确定周开始时间以及自周开始以来流逝的时间量

与确定日开始相比,确定周开始时间稍微复杂一些。尽管一周的天数是恒定的,而且也能计算出一周的秒数时长(604800 秒),但是只是计算出自时间戳记开始起流逝的整周数、再乘以周的持续时长是不够的。

问题在于,大多数国家的一周都是从周一开始,而有一些国家(美国、加拿大、以色列等)却是从周日开始。但我们还记得,时间测量的时间戳从周四开始。如果周四是一周的第一天,那么有这些简单的计算就足够了。

出于方便考虑,我们将以第一个时间戳日对应 0 值为例,来研究确定周开始的特殊性。我们需要找到这样一个值:当将添加到时间时,会改变时间戳的首日 (1970.01.01 00:00),从零开始计数,到第四日,即我们需要添加四日的持续时长。如果一周从周一开始,则周四是第四日,所以我们需要添加三日的持续时长。但如果一周从周日开始,则周四是第五日,所以我们需要添加四日的持续时长。

我们编写一个函数来计算周数:


long WeekNum(datetime aTime,bool aStartsOnMonday=false)   //--- if the week starts on Sunday, add the duration of 4 days (Wednesday+Tuesday+Monday+Sunday), //    if it starts on Monday, add 3 days (Wednesday, Tuesday, Monday)    if(aStartsOnMonday)      {       aTime+=259200// duration of three days (86400*3)      }    else      {       aTime+=345600// duration of four days (86400*4)        }    return(aTime/604800);   }

此函数可在确定新一周的第一个柱的指标中发挥作用:


bool NewWeek=WeekNum(time[i])!=WeekNum(time[i-1]);

假设各柱由左至右索引,其中 time[i] 为当前柱的时间,而 time[i-1] 则为前一柱的时间。

现在,我们可以计算周开始的时间。由于为了计算一周的天数,我们假设时间戳的开始提前三(或四)天,现在我们需要执行反向的时间纠正:


long WeekStartTime(datetime aTime,bool aStartsOnMonday=false)   {    long tmp=aTime;    longCorrector;    if(aStartsOnMonday)      {       Corrector=259200// duration of three days (86400*3)      }    else      {       Corrector=345600// duration of four days (86400*4)     }    tmp+=Corrector;    tmp=(tmp/604800)*604800;    tmp-=Corrector;    return(tmp);    

此函数会返回一个 long 类型值,因为第一周的值可能是负数(在时间戳开始前三、四天)。此函数的第二个参数可确定此周从周日还是周一开始。

现在,我们拥有了周开始的时间,就可以计算自周开始起流逝的秒数了:


long SecondsFromWeekStart(datetime aTime,bool aStartsOnMonday=false)   {    return(aTime-WeekStartTime(aTime,aStartsOnMonday));   }

秒数可被转换为日、小时、分钟和秒。尽管计算自日开始起的小时、分钟和秒不难,但像这种情况采用 TimeToStruct() 函数会更简单:


long sfws=SecondsFromWeekStart(TimeCurrent()); MqlDateTime stm; TimeToStruct(sfws,stm); stm.day--; Alert("Time elapsed since the week start "+(string)stm.day+" d, "+(string)stm.hour+" h, "+(string)stm.min+" m, "+(string)stm.sec+" s");

请注意,stm.day 值被减了 1。月的号数是从 1 计数,因为我们需要确定所有日数。有些人可能觉得,从实用角度看,这部分内容没什么用处。但您对于上述函数的了解作为处理时间的一项经验,十分有价值。

 

确定自某个给定日期、年开始或月开始以来的周数

注意 MqlDateTime 结构的各个字段,尤其是 day_of_year 字段,有人会喜欢创建确定自年开始和月开始起周数的函数。最好是编写一个确定自某给定日期起周数的一般函数。此函数的运行原理,与确定自时间戳开始起的周数所使用的函数类似:


long WeekNumFromDate(datetime aTime,datetime aStartTime,bool aStartsOnMonday=false)   {   long Time,StartTime,Corrector;    MqlDateTime stm;    Time=aTime;    StartTime=aStartTime; //--- determine the beginning of the reference epoch    StartTime=(StartTime/86400)*86400//--- determine the time that elapsed since the beginning of the reference epoch    Time-=StartTime;//--- determine the day of the week of the beginning of the reference epoch   TimeToStruct(StartTime,stm); //--- if the week starts on Monday, numbers of days of the week are decreased by 1, // and the day with number 0 becomes a day with number 6   if(aStartsOnMonday)      {       if(stm.day_of_week==0)         {          stm.day_of_week=6;         }       else         {          stm.day_of_week--;         }     //--- calculate the value of the time corrector    Corrector=86400*stm.day_of_week; //--- time correction    Time+=Corrector; //--- calculate and return the number of the week    return(Time/604800);   }

基于此函数,我们编写两个确定自年开始、自月开始起周数的函数。为此,我们首先需要确定年开始的时间和月开始的时间。将时间分解成其分量,调整某些字段的值,并将各分量重新转换为时间标记。

  • 确定年开始时间的函数:

    
    datetime YearStartTime(datetime aTime)   {    MqlDateTime stm;   TimeToStruct(aTime,stm);    stm.day=1;    stm.mon=1;    stm.hour=0;    stm.min=0;    stm.sec=0;    return(StructToTime(stm));   }
    
  • 确定月开始时间的函数:

    
    datetime MonthStartTime(datetime aTime)   {    MqlDateTime stm;   TimeToStruct(aTime,stm);    stm.day=1;    stm.hour=0;    stm.min=0;    stm.sec=0;   return(StructToTime(stm));   }
    

现在,下面就是确定自年开始、月开始起周数的函数。

  • 自年开始起:

    
    long WeekNumYear(datetime aTime,bool aStartsOnMonday=false)   {   return(WeekNumFromDate(aTime,YearStartTime(aTime),aStartsOnMonday));   }
    
  • 自月开始起:

    
    long WeekNumMonth(datetime aTime,bool aStartsOnMonday=false)   {   return(WeekNumFromDate(aTime,MonthStartTime(aTime),aStartsOnMonday));   }
    

最终,我们开始着手纯粹的实务。

 

创建试验工具集

前面提到过,有些交易中心的报价包含周日柱,也有的在整个周末都持续提供报价。我们要确保必要的函数在所有情况下都正常运行。当然,我们可以到互联网上找到一些适用的交易中心,并利用演示账户上的报价来测试各函数的运行情况。但是,除了寻找正确的交易中心外,我们还必须在图表中寻找适当的位置来运行所需测试。

我们来创建自己的测试函数测试区域。而周五、周末和周一则是我们的关注重点。我们将根据需要,创建一个包含周五、周一和周末柱时间的数组。共有 4 个选项:

  1. 无周末柱。
  2. 周日末尾的一些柱,即 4 个。
  3. 持续的周末报价。
  4. 周六柱,但没有周日柱。

为避免数组变得过大,我们将采用 H1 时间框架。数组最大尺寸将是 96 个元素(每天 24 个柱乘 4 天),而数组本身将在利用图形对象绘制时匹配图表。所以,我们会通过启动某指标时第一次执行 OnCalculate() 函数的类似方式,得到一种带有时间和可在循环中的数组上进行迭代的、类似指标缓冲区的东西。由此,我们将能够实现函数运行的可视化。

此工具以随附于本文的一个脚本的形式实施(sTestArea.mq5 文件)。准备工作则于脚本的 OnStart() 函数内执行。此函数代码最开头的 Variant 变量允许您选取上面列出的 4 个选项中的 1 个。而在 OnStart() 函数下方,您可以看到类似于指标的 OnCalculate() 函数的 LikeOnCalculate() 函数。此函数有两个参数:rates_total - 柱数,以及 time[] - 带柱时间的数组。

此外,我们会继续在此函数内工作,就像我们在编写一个指标一样。您可以通过调用 SetMarker() 函数,由此函数设定一个标记。传递给 SetMarker() 函数的参数分别为:柱索引、缓冲区索引(标记显示的行)及标记颜色。

图 4 所示为脚本性能结果,Variant 变量为 2,且在每个柱下设置两个标记行(用相关时间戳记标记柱)。所有图表元素的颜色设置均不可见。

https://c.mql5.com/2/5/005.png 
图 4. sTestArea.mq5 脚本性能

柱时间戳记根据周几取色:周五 - 红色,周六 - 洋红色,周日 - 绿色,周一 - 蓝色。现在,我们可以继续编写对周末柱需要特殊方法、且能够可视化监控其工作的各种函数了。

 

支点指标 - 备选 1

我们首先尝试创建一个简单的支点指标。要计算支点线,我们需要清楚昨日的收盘价格,以及昨日的最高和最低价格。该指标值是作为上述三值的平均进行计算。我们会找出一日内的新高新低,计算新的一日开始时的支点值,并进一步绘制并显示全天的价格。

我们将提供该指标运行的两种版本:

  1. 新的每一天,都计算支点(假设没有周末柱)。如果有周末柱,则周六和周日柱会被区别对待。
  2. 周六柱属于周五,而周日柱则属于周一(整个周末都持续提供报价、以及仅存在周日柱的情况均适用)。这里,您要记住的是,周末很可能没有柱。

在第一种版本中,只确定新的一天的开始就足够了。我们将当前时间 (aTimeCur) 和前一时间 (aTimePre) 传递给此函数,计算自时间戳开始起的天数,而且如果它们不匹配,我们就推断新的一天已经开始:


bool NewDay1(datetime aTimeCur,datetime aTimePre)   {    return((aTimeCur/86400)!=(aTimePre/86400));   }

第二种版本。如果周六已开始,则日开始应被忽略。如果周日已开始,我们则定义日开始(这自然只是另一天)。如果周一继周日后开始,则略过日开始。如果一周中其它任何一天(比如周六或周五)先于周一,则定义日开始。所得函数如下:


bool NewDay2(datetime aTimeCur,datetime aTimePre)   {    MqlDateTime stm; //--- new day   if(NewDay1(aTimeCur,aTimePre))      {       TimeToStruct(aTimeCur,stm);       switch(stm.day_of_week)         {          case 6// Saturday            return(false);             break;          case 0// Sunday            return(true);             break;          case 1// Monday            TimeToStruct(aTimePre,stm);             if(stm.day_of_week!=0)               // preceded by any day of the week other than Sunday                return(true);               }             else               {                return(false);               }             break;          default// any other day of the week             return(true);         }      }    return(false);   }

下面则是取决于版本的通用函数:


bool NewDay(datetime aTimeCur,datetime aTimePre,int aVariant=1)   {    switch(aVariant)      {       case 1:          return(NewDay1(aTimeCur,aTimePre));          break;       case 2:          return(NewDay2(aTimeCur,aTimePre));          break;      }    return(false);   }

我们利用 "sTestArea" 工具来测试函数的运行(随附的 sTestArea_Pivot1.mq5 文件;日开始被标记为褐色)。您需要运行 8 次测试: 4 个柱生成选项的 2 个函数版本。确保函数正常运行后,我们可以安全地展开指标开发了。但是,由于指标开发并非本文重点,所以我们随附了一个即用型指标(Pivot1.mq5 文件),详细讲解此开发过程中最困难的部分。

 

确定时段

我们需要允许 EA 交易在当天的指定时间范围内、每天按相同的间隔进行交易。我们指定交易时段开始的时与分,以及交易时段结束的时与分。时与分分别指定(而不是将时间指定为 "14:00" 的字符串变量),如此一来,只要 EA 交易中采用了此函数,我们就可以在策略测试程序中执行优化。

要确定时段,则操作如下:

  1. 计算自日开始起的秒数时间,作为时间起始点;同样再算出时间结束点。
  2. 计算自日开始起以秒计的当前时间。
  3. 将当前时间与起始、结束时间进行对比。

交易时段从某天开始、另一天结束的情况也不是不可能,即如果某交易时段经过了午夜,则计算出的自日开始起的结束时间会小于开始时间。因此,我们需要执行两次检查。所得函数如下:


bool TimeSession(int aStartHour,int aStartMinute,int aStopHour,int aStopMinute,datetimeaTimeCur)   //--- session start time    int StartTime=3600*aStartHour+60*aStartMinute; //--- session end time    int StopTime=3600*aStopHour+60*aStopMinute; //--- current time in seconds since the day start    aTimeCur=aTimeCur%86400;    if(StopTime//--- going past midnight       if(aTimeCur>=StartTime || aTimeCurreturn(true);         }      }    else      {       //--- within one day      if(aTimeCur>=StartTime && aTimeCurreturn(true);         }      }    return(false);   }

如果时段经过午夜,则当前时间应大于等于时段起始时间,或小于时段结束时间。如果时段是在当日内,则当前时间应大于等于起始时间,并小于结束时间。

本文末尾处附有一个创建用于测试函数运行的指标(Session.mq5 文件)。和任何其它应用指标一样,它不仅可被用于测试,还有其它的实用用途。

 

确定日内的一个时间点

简单地检查与指定时间的相等性不会有效,因为价格变动并不会定期出现,而且可能会有几秒到几分钟的延迟。在指定的时间内,很可能市场中根本就没有任何价格变动。我们需要检查给定的时间戳有无交叉。

当前时间应等于或大于指定时间,而前一时间则应小于指定时间。由于确定日内某时间点的需要,我们要将当前时间(及前一时间)转换为自日开始起的秒数。同样,给定的时间参数(时与分)亦应转换为秒数。前一时间很有可能属于前一天,即如果转换为自日开始起的秒数,它将大于当前时间。这种情况下,我们按照确定时段时的相同方式继续 - 执行两项检查。

所得函数如下:


bool TimeCross(int aHour,int aMinute,datetime aTimeCur,datetime aTimePre)   //--- specified time since the day start    datetime PointTime=aHour*3600+aMinute*60//--- current time since the day start    aTimeCur=aTimeCur%86400//--- previous time since the day start    aTimePre=aTimePre%86400;    if(aTimeCur//--- going past midnight      if(aTimeCur>=PointTime || aTimePrereturn(true);         }      }    else      {       if(aTimeCur>=PointTime && aTimePrereturn(true);         }      }    return(false);   }

有一个基于此函数创建的指标(随附于本文的 TimePoint.mq5 文件)。

 

支点指标 - 备选 2

我们已经了解了如何确定一个时间点,现在我们再让支点指标复杂一些。不再是通常的 00:00,日现在是从任何给定的时间开始。我们将称之为用户定义日。要确定用户定义日的开始,我们将使用之前提到的 TimeCross() 函数。由于周末柱的不同生成选项,有些日必须忽略。要马上得到所有的检验规则可不容易,所以我们还是一步一步来。重要的是从何处着手,并就如何继续有多个选项。我们有一个测试脚本 - sTestArea.mq5,所以甚至可以试着找到正确的解决方案。

“无周末柱”的情况最简单:新的一天,从某给定时间戳时间交叉处开始。

如果周日末尾仅有几个柱,则不管函数参数如何,TimeCross() 函数都会将第一个周日柱定义为日开始。假设周末没有报价(周日柱属于周一),那么应当忽略周日。如果某给定时间位于一系列周日柱的中间某处,则亦应忽略,因为新的日开始已于周五注册。

持续的周末报价:如果某用户定义日的开始位于某日历日的中间(图 5),

https://c.mql5.com/2/5/006.gif
图 5. 处于某日历日中间的某个用户定义日开始
周五 - 红色,周六 - 洋红色,周日 - 绿色,周一 - 蓝色。

周六的一半作为周五,周日的一半作为周一。但是,还有从周六中间到周日中间的一些柱,不属于任何一天。当然,我们可以将周六到周日的间隔划分为多个等分,并将一半视为周五,另一半视为周一。但这样会将一个非常简单的指标严重复杂化,尽管周末报价并没有这么重要。

最合理的解决方案会是,将所有周六与周日柱视为从周五持续到周一的一个用户定义日。也就是说,周六和周日开始的用户定义日全被忽略。

所得函数如下:


bool NewCustomDay(int aHour,int aMinute,datetime aTimeCur,datetime aTimePre)   {   MqlDateTime stm;    if(TimeCross(aHour,aMinute,aTimeCur,aTimePre))      {       TimeToStruct(aTimeCur,stm);       if(stm.day_of_week==0 || stm.day_of_week==6)         {          return(false);         }       else         {          return(true);         }      }    return(false);   }

有一个基于此函数创建的指标(随附于本文的 Pivot2.mq5 文件)。

 

确定一周的交易天数

要让某 EA 交易仅于特定日交易,实现起来相当简单。我们利用 TimeToStruct() 函数,将时间分解成其各个分量,并在 EA 交易的参数中,声明一周中每天的布尔型变量。根据是周几,此函数会返回对应变量的值。

这个可以通过一种更加优化的方式来完成。初始化某 EA 交易或指标时,利用允许或不允许在特定日交易的变量值来填充数组。之后,检查与周几对应的数组元素值。我们得到两个函数:一个在初始化期间被调用,另一个则按需调用。

变量:


input bool Sunday =true// Sunday input bool Monday =true// Monday input bool Tuesday =true// Tuesday input bool Wednesday=true// Wednesday input bool Thursday =true// Thursday input bool Friday =true// Friday input bool Saturday =true// Saturday boolWeekDays[7];

初始化函数:


void WeekDays_Init()   {    WeekDays[0]=Sunday;    WeekDays[1]=Monday;    WeekDays[2]=Tuesday;    WeekDays[3]=Wednesday;    WeekDays[4]=Thursday;    WeekDays[5]=Friday;    WeekDays[6]=Saturday;   }

主函数:


bool WeekDays_Check(datetime aTime)   {    MqlDateTime stm;    TimeToStruct(aTime,stm);   return(WeekDays[stm.day_of_week]);   }

本文末尾处附有一个基于此函数创建的指标(TradeWeekDays.mq5 文件)。

 

确定一周的交易时间

我们需要确定从一周中某天给定时间,到一周中另一天给定时间的交易时段。此函数与 TimeSession() 函数类似,仅有的区别在于计算是基于自周开始起流逝的时间。所得函数如下:


bool WeekSession(int aStartDay,int aStartHour,int aStartMinute,int aStopDay,int aStopHour,intaStopMinute,datetime aTimeCur)   //--- session start time since the week start    intStartTime=aStartDay*86400+3600*aStartHour+60*aStartMinute; //--- session end time since the week start    int StopTime=aStopDay*86400+3600*aStopHour+60*aStopMinute; //--- current time in seconds since the week start    long TimeCur=SecondsFromWeekStart(aTimeCur,false);   if(StopTime//--- passing the turn of the week      if(TimeCur>=StartTime || TimeCurreturn(true);         }      }    else      {       //--- within one week       if(TimeCur>=StartTime && TimeCurreturn(true);         }      }    return(false);   }

本文末尾处附有一个基于此函数创建的指标(SessionWeek.mq5 文件)。

我们已经完成了所有最常见时间相关任务的讲解,并研究了相关的编程技巧,以及解决它们所需的标准 MQL5 函数。

 

更多的 MQL5 函数

还有一些处理时间的 MQL5 函数:TimeTradeServer()TimeGMT()TimeDaylightSavings() 和 TimeGMTOffset()。而这些函数的主要特点,就是它们用于某用户 PC 的时钟和时间设置。

TimeTradeServer() 函数上文说过,TimeCurrent() 函数会在周末显示错误时间(周五最后一次价格变动的时间)。TimeTradeServer() 函数会计算正确的服务器时间:


datetime tm=TimeTradeServer(); //--- output result Alert(tm);

TimeGMT() 函数此函数会根据某用户计算机的时钟值和时间设置,计算 GMT 时间:时区和“夏令时”:


datetime tm=TimeGMT(); //--- output result Alert(tm);

为了更加精确,此函数返回 UTC 时间。

TimeDaylightSavings() 函数此函数会从用户计算机设置返回“夏令时”修正值。


int val=TimeDaylightSavings(); //--- output result Alert(val);

要获取不带“夏令时”修正值的时间,您要将修正值添加到本地时间。

TimeGMTOffset() 函数此函数允许您获取某用户计算机的时区。该值会在几秒内返回,以备添加到本地时间来获取 GMT 时间。


int val=TimeGMTOffset(); //--- output result Alert(val);

用户计算机上的时间将是 TimeGMT()-TimeGMTOffset()-TimeDaylightSavings():


datetime tm1=TimeLocal(); datetime tm2=TimeGMT()-TimeGMTOffset()-TimeDaylightSavings(); //--- output result Alert(tm1==tm2);

 

更多的处理时间的有用函数

确定闰年的函数


bool LeapYear(datetime aTime)   {    MqlDateTime stm;    TimeToStruct(aTime,stm); //--- a multiple of 4    if(stm.year%4==0)      {       //--- a multiple of 100      if(stm.year%100==0)         {          //--- a multiple of 400         if(stm.year%400==0)            {             return(true);            }         }       //--- not a multiple of 100       else         {          return(true);         }      }   return(false);   }

确定闰年的原理,已于上文的“时间测量的特殊性”部分中讲到。

确定月内天数的函数


int DaysInMonth(datetime aTime)   {    MqlDateTime stm;    TimeToStruct(aTime,stm);   if(stm.mon==2)      {       //--- February       if(LeapYear(aTime))         {          //--- February in a leap year          return(29);         }       else         {          //--- February in a non-leap year          return(28);         }      }    else      {       //--- other months       return(31-((stm.mon-1)%7)%2);      }   }

此函数会检查该年是否为闰年,以返回 2 月 28 日或 29 日的正确值,并计算其它月份的天数。前 7 个月的天数交替如下:31、30、31、30 等,以及剩余 5 个月的天数。因此,此函数会计算除以 7 的余数。然后我们执行奇数奇偶检验,并用 31 减去得到的修正值。

 

于策略测试程序中运行的时间函数的特殊性

策略测试程序会生成自己的报价流,而且 TimeCurrent() 函数的值与策略测试程序中的报价流相对应。TimeTradeServer() 函数值与 TimeCurrent() 值对应。同样,TimeLocal() 函数值亦与 TimeCurrent() 值对应。策略测试程序中的 TimeCurrent() 函数并未考虑时区和“夏令时”修正。EA 交易的运行基于价格变动,所以,如果您的 EA 交易需要处理时间,请使用 TimeCurrent() 函数。您便可以在策略测试程序中安全地测试自己的 EA 交易。

TimeGMT()、TimeDaylightSavings() 和 TimeGMTOffset() 函数完全基于用户计算机的当前设置运行(转为“夏令时”和改回标准时间并不在策略测试程序中模拟)。如果测试某 EA 交易时,您需要模拟改为“夏令时”和改回标准时间(如确有必要),自己要注意这一点。这就需要调整时钟的精确日期与时间的相关信息,以及一次全面的分析。

而此问题的解决方案,已经远远超出了一篇文章的论述范畴,所以这里亦不予考虑。如果某 EA 交易是在欧洲或美洲时段工作,尽管交易中心遵守“夏令时”,服务器时间与事件时间之间也不会有差异,这一点与亚洲时段不同(日本不实行“夏令时”,而且澳大利亚是在 11 月份改为“夏令时”)。

 

总结

本文讨论了处理时间的所有标准 MQL5 函数。讲述了处理时间相关任务时使用的编程技巧。此外,本文还演示了多种指标和一些有用函数的创建,且包含对于运行原理的详细描述。

处理时间的所有标准函数,均可划分为几个类别:

  1. TimeCurrent() 和 TimeLocal() 是用于确定当前时间的主函数。
  2. TimeToString()StringToTime()TimeToStruct() 和 StructToTime() 为时间处理函数。
  3. CopyTime() 是一种处理柱时间的函数。
  4. TimeTradeServer()TimeGMT()TimeDaylightSavings() 和 TimeGMTOffset() 是取决于用户计算机设置的函数。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有