量化交易软件:赫兹量化中MQL5中的结构及其数据打印方法

本文介绍了MQL4编程中的MqlDateTime结构,包括其组成字段、标准函数如TimeCurrent和TimeToStruct的用法,以及如何使用ArrayPrint函数展示和打印日期结构。还涉及了如何创建辅助函数以提供更易理解的日期描述。
摘要由CSDN通过智能技术生成

概述
结构是一种方便的工具,用于存储、记录和检索属于单个变量的任何定义的逻辑相关数据。
MqlDateTime 结构
数据结构包含八个int类型的字段。

struct MqlDateTime
  {
   int year;           // year
   int mon;            // month
   int day;            // day
   int hour;           // hour
   int min;            // minutes
   int sec;            // seconds
   int day_of_week;    // day of the week (0-Sunday, 1-Monday, ... ,6-Saturday)
   int day_of_year;    // number of a day in the year (1st of January has number 0)
  };
标准函数TimeCurrent()、TimeGMT()、TimeLocal()、TimeTradeServer()和TimeToStruct()用于填充结构字段。

前四个函数,除了返回当前日期、GMT日期、本地计算机时间和交易服务器日期外,每个函数都有一个重载函数。在函数的形式参数中,可以通过引用将日期结构传递给它。执行函数后,传递给函数的结构字段将填充函数返回的日期数据。

TimeToStruct()函数专门用于将datetime值类型(自1970年1月1日起的秒数)中的结构填充到MqlDateTime结构类型变量中。

bool  TimeToStruct(
   datetime      dt,            // date and time
   MqlDateTime&  dt_struct      // structure for accepting values 
   );
如果成功,返回true,否则-false。操作后,日期结构将填充在datetime类型的变量中第一个参数中传递的时间数据。

我们的日期结构已经完整了,但我们如何打印它?有一个标准的TimeToString()函数,它将包含自1970年1月1日以来以秒为单位的时间的值转换为“yyyy.mm.dd hh:min:sec”格式的字符串。

但是该函数不适用于MqlDateTime结构,而是适用于datetime日期。那么,我们应该将结构转换回时间值吗?当然不要。每个函数都有其自身的用途。我们可以从日期结构中单独提取日期和时间的任何组成部分——一年、一个月、一小时、一分钟、一周中的一天等等。。。但是我们怎样才能显示所有的结构数据呢?
ArrayPrint()函数适用于此任务,该函数记录简单类型或简单结构的数组。它以表的形式显示数据,其中列是结构的字段,行表示数组单元。换句话说,为了只显示一个日期的结构,我们需要一个1的数组。对于一个交易周,如果数据来自D1图表,数组大小通常为5个交易日。

MqlDateTime, 打印方法
这样的脚本使用ArrayPrint()打印从日志中的当前时间获得的日期结构:

void OnStart()
  {
//--- Declare a date structure variable
   MqlDateTime  time;
//--- Get the current time and at the same time fill in the date structure
   TimeCurrent(time);
//--- Declare an array with the MqlDateTime type and write the data of the filled structure into it

   MqlDateTime array[1];
   array[0]=time;
//--- Display the header and time using the standard ArrayPrint()
   Print("Time current (ArrayPrint):");
   ArrayPrint(array);
   /* Sample output:
      Time current (ArrayPrint):
          [year] [mon] [day] [hour] [min] [sec] [day_of_week] [day_of_year]
      [0]   2023     7    17     12     8    37             1           197
   */
  }

相应地,采用日期结构并将其打印在日志中的函数将如下所示:

//+------------------------------------------------------------------+
//| Take a date structure and display its data to the journal.       |
//| Use ArrayPrint() for display                                     |
//+------------------------------------------------------------------+
void MqlDateTimePrint(const MqlDateTime& time_struct)
  {
//--- Declare an array with the MqlDateTime type and write the data of the obtained structure into it
   MqlDateTime array[1];
   array[0]=time_struct;
//--- Print the array
   ArrayPrint(array);
   /* Sample output:
      Time current (ArrayPrint):
          [year] [mon] [day] [hour] [min] [sec] [day_of_week] [day_of_year]
      [0]   2023     7    17     12     8    37             1           197
   */
  }

该函数允许在日志中打印time_struct变量中传递给它的一个日期。

使用上述函数记录单个日期结构的脚本:

void OnStart()
  {
//--- Declare a date structure variable
   MqlDateTime  time;
//--- Get the current time and at the same time fill in the date structure
   TimeCurrent(time);
//--- Display the header and time using the standard ArrayPrint()
   Print("Time current (ArrayPrint):");
   MqlDateTimePrint(time);
   /* Sample output:
      Time current (ArrayPrint):
          [year] [mon] [day] [hour] [min] [sec] [day_of_week] [day_of_year]
      [0]   2023     7    17     12     8    37             1           197
   */
  }

如果我们需要打印一个日期数组(毕竟这是ArrayPrint()的主要目标),那么我们需要将数据数组传递给datetime函数,填写MqlDateTime数组并打印它。

接受日期时间数组并打印MqlDateTime数组的函数:

//+------------------------------------------------------------------+
//| Accept the datetime array, convert it into MqlDateTime and       |
//| display converted data into the journal.                         |
//| Use ArrayPrint() for display                                     |
//+------------------------------------------------------------------+
void MqlDateTimePrint(const datetime& array_time[])
  {
//--- Declare a dynamic array of the MqlDateTime type
   MqlDateTime array_struct[];
//--- Get the size of the array passed to the function
   int total=(int)array_time.Size();
//--- If an empty array is passed, report on that and leave the function
   if(total==0)
     {
      PrintFormat("%s: Error. Empty array.",__FUNCTION__);
      return;
     }
//--- Change the size of the MqlDateTime array to match the size of the datetime array
   ResetLastError();
   if(ArrayResize(array_struct,total)!=total)
     {
      PrintFormat("%s: ArrayResize() failed. Error %s",__FUNCTION__,(string)GetLastError());
      return;
     }
//--- Convert dates from the datetime array into the date structure in the MqlDateTime array
   for(int i=0;i<total;i++)
     {
      ResetLastError();
      if(!TimeToStruct(array_time[i],array_struct[i]))
         PrintFormat("%s: [%s] TimeToStruct() failed. Error %s",__FUNCTION__,(string)i,(string)GetLastError());
     }
//--- Print the filled MqlDateTime array
   ArrayPrint(array_struct);
   /* Sample output:
      Time data of the last 10 bars GBPUSD H1 (ArrayPrint):
          [year] [mon] [day] [hour] [min] [sec] [day_of_week] [day_of_year]
      [0]   2023     7    17      7     0     0             1           197
      [1]   2023     7    17      8     0     0             1           197
      [2]   2023     7    17      9     0     0             1           197
      [3]   2023     7    17     10     0     0             1           197
      [4]   2023     7    17     11     0     0             1           197
      [5]   2023     7    17     12     0     0             1           197
      [6]   2023     7    17     13     0     0             1           197
      [7]   2023     7    17     14     0     0             1           197
      [8]   2023     7    17     15     0     0             1           197
      [9]   2023     7    17     16     0     0             1           197
   */
  }

因此,使用上述函数打印日志中datetime数组的脚本将如下所示:

void OnStart()
  {
//--- Declare a time array
   datetime array[];
//--- Copy the time of the last 10 bars to the array
   ResetLastError();
   if(CopyTime(Symbol(),Period(),0,10,array)<0)
     {
      PrintFormat("CopyTime() failed. Error %s",(string)GetLastError());
      return;
     }
//--- Display the header and the time data array of the last 10 bars using the standard ArrayPrint()
   PrintFormat("Time data of the last 10 bars %s %s (ArrayPrint):",Symbol(),StringSubstr(EnumToString(Period()),7));
   MqlDateTimePrint(array);
   /* Sample output:
      Time data of the last 10 bars GBPUSD H1 (ArrayPrint):
          [year] [mon] [day] [hour] [min] [sec] [day_of_week] [day_of_year]
      [0]   2023     7    17      7     0     0             1           197
      [1]   2023     7    17      8     0     0             1           197
      [2]   2023     7    17      9     0     0             1           197
      [3]   2023     7    17     10     0     0             1           197
      [4]   2023     7    17     11     0     0             1           197
      [5]   2023     7    17     12     0     0             1           197
      [6]   2023     7    17     13     0     0             1           197
      [7]   2023     7    17     14     0     0             1           197
      [8]   2023     7    17     15     0     0             1           197
      [9]   2023     7    17     16     0     0             1           197
   */
  }

用于处理MqlDateTime结构数据的函数。

上面测试的一切都是方便、实用和简洁的。但有时需要更完整的信息,最好是在同样简洁的陈述中。或者,相反,我们可能需要更详细的描述,减少数据呈现的简洁和枯燥。例如,仅一天的数字就可能令人困惑。但如果写的是“星期四”,那么我们马上就明白我们说的是星期四。一个月的数字也是如此——有时看到“07(七月)”比回忆哪个月是第七个要好。。。当然,这可能有些夸张,但这些小的改进仍然增加了便利性。当分析程序日志中的大量条目时,这些小便利加起来会带来非常明显的时间增益。

为了增加这些便利性,我们必须编写您自己的函数,以MqlDateTime格式返回日期描述。

该函数将:

以短格式显示数据(星期几、月、日、年、时间);
在表格视图中显示数据(数据头值);
在我们开始创建返回结构字段描述的函数之前,我们将创建返回周、日和月名称的辅助函数。

辅助函数

要获得一星期中某一天的名称,让我们编写一个简单的函数,根据以数字格式存储星期天的结构字段中的值返回星期天的文本:

//+------------------------------------------------------------------+
//| Return the name of a week day                                    |
//+------------------------------------------------------------------+
string DayWeek(MqlDateTime &date_time)
  {
//--- Define a week day name
   string dw=EnumToString((ENUM_DAY_OF_WEEK)date_time.day_of_week);
//--- Convert all obtained symbols to lower case and replace the first letter from small to capital
   if(dw.Lower())
      dw.SetChar(0,ushort(dw.GetChar(0)-0x20));
//--- Return a resulting string
   return dw;
   /* Sample output:
      Wednesday
   */
  }
 

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值