【问题标题】:How to calculate (add) datetime values in MQL4?如何在 MQL4 中计算(添加)日期时间值?
【发布时间】:2016-11-11 21:55:53
【问题描述】:

使用 MQL4 我在处理 datetime 时遇到了麻烦。

我想要做的是按月或按年将datetime 放入数组中。

目前我是这样做的。

datetime myDate;

myDate[0] = D'2010.01.01 00:00';
myDate[1] = D'2010.02.01 00:00';
myDate[2] = D'2010.03.01 00:00';
myDate[3] = D'2010.04.01 00:00';
.
.

但是我想在下面这样做

myDate[0] = D'2010.01.01 00:00';
for (int i = 1;i < 6 ;i+=){
    myDate[i] = myDate[i - 1] + 1year;
}

如果是月份,

myDate[0] = D'2010.01.01 00:00';
for (int i = 1; i < 12 ; i++){
    myDate[i] = myDate[i - 1] + 1month
}

问:如何计算加法1month1year

【问题讨论】:

    标签: algorithmic-trading mql4 metatrader4 mt4


    【解决方案1】:

    使用MqlDateTime,TimeToStructStructToTime结构如下:

    MqlDateTime time;
    TimeToStruct(TimeCurrent(),time);
    
    time.year++;
    time.mon++;
    datetime newTime = StructToTime(time);
    

    【讨论】:

    • 应该是公认的答案
    【解决方案2】:

    MQL4 文档声明 datetime 类型在内部表示为自商定时间尺度数据(即 1970-01-01 00:00强>)。

    这说 (并稍微修饰一下语法合规性)
    代码
    可以读

    oneYear = 60 * 60 * 24 * 365;   // yes, astronomers would kill me
                                    // for not solving those seconds,
                                    // that sum up until a leap year
                                    // consumes 'em on Feb-29th day     :o)
    

    另一种选择
    以便更多地操作
    datetime
    舒适的方式,寻址
    datetime 的自然组件是 hacky,但值得: 字符串到时间

    string TimeToString( datetime aDatetimeVALUE,
                         int aModeOfDISPLAY = TIME_DATE|TIME_MINUTES
                        )
    

    将包含自 01.01.1970 以来经过的时间(以秒为单位)的值转换为 string"yyyy.mm.dd hh:mi" 格式。

    在这里,可以简单地将 +1 添加到此中间格式的适当位置(无需处理 struct MqlDateTime 中存在的所有派生和影响值,其中 day_of_weekday_of_year 绝对不是我最喜欢在移动 +1 个月等后重新计算的。

    aCurrentYEAR  = int(  StringSubstr( aDatetimeSTRING, 0, 4 ) );
    aCurrentMONTH = int(  StringSubstr( aDatetimeSTRING, 5, 2 ) );
    aCurrentDAY   = int(  StringSubstr( aDatetimeSTRING, 8, 2 ) );
    
    aNextYEAR     = aCurrentYEAR  + 1;
    aNextMONTH    = aCurrentMONTH + 1;
    

    终于

    StringFormat( "%04d.%02d.%02d 00:00", aYearNUMBER, aMonthNUMBER, aDayNUMBER )
    

    将重新组装以调用另一个 MQL4 标准函数:

    datetime StringToTime( string aDatetimeSTRING )

    该函数将"yyyy.mm.dd [hh:mi]"格式的包含时间或日期的字符串转换为datetime类型。

    另一种方法可以使用完全分解的 datetime 算法,方法是使用

    int aYE  = TimeYear(      aDatetimeVALUE );
    int aMO  = TimeMonth(     aDatetimeVALUE );
    int aDA  = TimeDay(       aDatetimeVALUE );
    int aHO  = TimeHour(      aDatetimeVALUE );
    int aMI  = TimeMinute(    aDatetimeVALUE );
    int aDoW = TimeDayOfWeek( aDatetimeVALUE );
    int aDoY = TimeDayOfYear( aDatetimeVALUE );
    
    datetime aSameTimeNextYEAR = StructToTime( (MqlDateTime) { aYE + 1,
                                                               aMO,
                                                               aDA,
                                                               aHO,
                                                               aMI,
                                                               aDoW,
                                                               aDoY
                                                               }
                                               );
    

    【讨论】:

    • 谢谢,我明白了。没有简单的方法可以添加 1 个月,但是这种解决方法对我很有帮助。
    【解决方案3】:
    int month = PeriodSeconds(PERIOD_MONTH);
    

    对于年份 - 不确定您是否可以使用一些常量,但看起来 12 个月是可以的,另一种选择是使用 MqlDateTime 分配年份,然后使用 StructToTime() 转换为 datetime

    更新:月份不是一个好方法,因为每个月都有不同的秒数

    【讨论】:

    • Daniel,PERIOD_MONTH 是人为的外汇时间流“框架”,服务于 constant 秒数 - 绝对不是解决问题的方法,作为 2 月份的自然时间流,{28|29}-calendar days 根据定义与 1 月份的秒数不同,31-calendar days
    【解决方案4】:

    我附上一个说明循环的脚本。

    基本逻辑:

    1. 在定义的日期时间上增加 31 天
    2. 获取新月份,忽略特定日期
    3. 将新日期生成为带有新月份的字符串
    4. 将字符串转换为新的日期时间
    5. 这个新的日期时间增加 31 天
    6. 从 2 开始重复

        void OnStart(){
    
           datetime myDate[6];
           myDate[0] = D'2010.01.01 00:00';
           Print(TimeToStr(myDate[0]));
    
           datetime dTempDate = myDate[0];
           int iSecondsIn31Days = 24*60*60*31, iTempMonth = 0;
    
           for(int i=1; i<6; i++){
              iTempMonth = TimeMonth(dTempDate + iSecondsIn31Days); //add 31 days and get the month, we don't care whether the day is the 1st, 2nd, or 3rd, we just want the month
              myDate[i] = dTempDate = StrToTime(TimeYear(myDate[0]) +"." +iTempMonth +"." +TimeDay(myDate[0])); //format the string to datetime
              Print(TimeToStr(myDate[i])); //to verify
           }
    
        }
    

    【讨论】:

      【解决方案5】:

      你需要使用的方法

      MqlDateTime , StructToTime ,TimeToStruct

      您可以使用这些以更少的步骤完成您的工作

      【讨论】:

        猜你喜欢
        • 2018-03-08
        • 1970-01-01
        • 1970-01-01
        • 2017-12-15
        • 1970-01-01
        • 1970-01-01
        • 2018-02-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多