文章 "处理时间(第二部分):函数" - 页 4

 

文章《处理 时间(第 2 部分)》中的DealingWithTime.mqh v. 1.01 版本:函数 (https://www.mql5.com/en/articles/9929) 停止工作的原因是 MQ 在这篇文章发表一段时间后更改了CopyTime( ) 函数的行为。现在,如果未来时间值大于为 start_time 和/或 stop_time 参数指定的TimeCurrent(),该函数将不再返回未来时间值。取而代之的是,最后一个当前条形图的开盘时间将作为最大可能值返回。

由于外汇交易时段的结束时间是通过这种方式确定的,以确定经纪商的时移,因此现在会导致不正确的值!

这一计算方法在 2.03 版中有所更改。该版本已在代码库中提供: https://www.mql5.com/en/code/45287

此外,时移计算方法也进行了全面修改,因此现在已经涵盖了悉尼(澳大利亚)20 世纪 70 年代的复杂时移。

另外,压缩文件中还附有DST 1975 - 2030.xlsx 表格,其中包含自 20 世纪 70 年代以来的所有时间变化,以便每个人都能检查计算公式是否正确,下面是表格中的一个系列示例:

1982 年 1 月 1 日是美国的标准时间(DST===0),下一次变化将是 1982 年 4 月 25 日,即 4 月份的最后一个(每月 25 日)星期日(4)。该表已按地理时区(A 栏)排序,然后按年份时区(L 栏,spr= 春季,aut= 秋季)排序,最后按查询日期(C 栏)排序。如果在调试模式下运行 Test_DST 2.mq5,并在调试器中复制日记日志中的行,然后将其粘贴到电子表格 中;单元格分隔符为空格。

此外,现在还有一个新的、简单的SecTillClose() 函数,它以秒(MQ 时间货币)为单位提供外汇市场关闭前的剩余时间--无需CopyTime()。这对那些想在周末前平仓或不想在周末前的规定时间内开新仓的人来说很有意义。

附带的指标DealingWithTime_TestIndi.mq5 作为图表注释,不仅显示欧洲、美国和澳大利亚(悉尼)的夏令时,还显示当前时间和不同城市的时差。在这里,您可以找到一张主要城市不同当地时间的对比表:https://www.timeanddate.com/worldclock/。因此,您可以随时查看数值。该指标还显示了这些值是如何确定和使用的(减去什么或加上什么),便于您自己使用--复制和粘贴,这是最快捷的编程方式。

最后两行还显示了当前外汇时段的最后一秒,以及以小时(更容易判断)和秒为单位的剩余时间。在纽约,当周五当地时间下午 5 点外汇交易时段结束时,纽约时间下午 5 点没有有效的条形图打开。因此,在该函数中,要减去 1 秒钟,才能得到经纪商时间内最后一栏的最后有效开仓时间。不过,有些经纪商会提前几分钟关闭外汇交易时段,不再提供价格,也不再接受交易订单。

Dealing with Time (Part 2): The Functions
Dealing with Time (Part 2): The Functions
  • www.mql5.com
Determing the broker offset and GMT automatically. Instead of asking the support of your broker, from whom you will probably receive an insufficient answer (who would be willing to explain a missing hour), we simply look ourselves how they time their prices in the weeks of the time changes — but not cumbersome by hand, we let a program do it — why do we have a PC after all.
 

文章处理时间(第 2 部分):函数 ( https://www.mql5.com/en/articles/9929 ) 的DealingWithTime.mqh v. 1.01 版本停止工作,因为 MQ 更改了CopyTime( )在本文发表后一段时间发挥作用。现在,如果未来时间值大于为 start_time 和/或 stop_time 参数指定的TimeCurrent(),则该函数不再返回未来时间值。相反,最后一个当前柱的开盘时间将作为最大可能值返回。

由于外汇交易时段的结束是通过这种方式确定的,以便确定经纪商时间偏移,因此现在会导致错误的值!

此计算在 2.03 版本中已更改。该版本现已在代码库中提供:https: //www.mql5.com/en/code/45287

而且时间变化的计算也完全改变了,这样现在就涵盖了从悉尼(澳大利亚)到 70 年代的时间变化的复杂时间。

还附上表格DST 1975 - 2030.xlsx作为 zip 文件,其中包含自 70 年代以来的所有时间变化,以便每个人都可以检查公式的正确工作,以下是表格的示例系列:

1982 年 1 月 1 日是美国标准时间 (DST==0),下一次更改时间为 1982 年 4 月 25 日,即 4 月的最后一个(每月 25 日)星期日 (4)。该表已按地理时区(A 列)排序,然后按年份时区(L 列,spr=spring,aut=autumn)排序,最后按查询日期(C 列)排序。该表可以由包含的EA自动创建(脚本不能在调试模式下运行)。 Test_DST 2.mq5如果您在调试模式下运行它并复制调试器中日志日志的行并将其粘贴到电子表格中;细胞分隔物就是空间。

此外,现在还有一个新的简单函数SecTillClose() ,它可以为您提供外汇市场关闭之前的剩余时间(以秒为单位)(MQ 的时间货币) - 无需CopyTime() 。对于那些想在周末之前平仓或不想在周末之前的指定时间内开立新头寸的人来说,这很有趣。

包含的指标DealingWithTime_TestIndi.mq5作为图表的注释,不仅显示欧洲、美国和澳大利亚(悉尼)的夏令时,还显示当前时间和各个城市的时差。在这里您可以找到主要城市不同当地时间的表格进行比较:https: //www.timeanddate.com/worldclock/ 。因此,您可以随时检查这些值。该指标还显示了如何确定和使用这些值(从什么中减去或添加什么),使您更容易使用自己 - 复制和粘贴,这是最快的编程形式。

最后两行还显示当前外汇交易时段的最后一秒以及以小时(更容易判断)和秒为单位的剩余时间。在纽约,当外汇交易时段于周五当地时间下午 5:00 关闭时,纽约时间下午 5:00 没有有效的酒吧开放。因此,在此函数中,减去 1 秒即可得到经纪商时间中最后一根柱的最后有效开盘时间。然而,一些经纪商提前几分钟结束外汇交易,不再提供价格,也不再接受交易订单。

Dealing with Time (Part 2): The Functions
Dealing with Time (Part 2): The Functions
  • www.mql5.com
Determing the broker offset and GMT automatically. Instead of asking the support of your broker, from whom you will probably receive an insufficient answer (who would be willing to explain a missing hour), we simply look ourselves how they time their prices in the weeks of the time changes — but not cumbersome by hand, we let a program do it — why do we have a PC after all.
 

DealingWithTime.mqh v. 的版本。文章《处理时间(第 2 部分)》中的 1.01:函数 (https://www.mql5.com/zh/articles/9929) 停止工作,因为 MQ 在这篇文章发表一段时间后更改了CopyTime( ) 的 行为。现在,如果未来时间值大于为 start_time 和/或 stop_time 参数指定的TimeCurrent( ) 值,该函数将不再返回该值。取而代之的是,它会返回当前最后一栏的最大可能开仓时间值。

由于货币会话的结束时间是以确定经纪商时间偏移的方式定义的,因此现在会导致不正确的值!

这一计算方法在 2.03 版中进行了修改。该版本现在可以在代码库中找到: https://www.mql5.com/zh/code/45287

此外,时间换算计算方法也进行了全面修改,因此现在已经涵盖了从澳大利亚悉尼到 70 年代的复杂时间换算。

另外还附上1975 - 2030.xlsx DST 表的压缩文件,其中包含自 70 年代以来的所有时间变化,以便大家检查公式是否正确,下面是该表系列的一个示例:

1982 年 1 月 1 日。- 美国标准时间(DST ==0),下一次变化是在 1982 年 4 月 25 日,即 4 月份的最后一个(每月 25 日)星期日(4)。表格已按地理时区排序(A 列),然后按年份时区排序(L 列,spr= 春季,aut= 秋季),最后按查询日期排序(C 列)。电子表格可由启用的EA 自动创建(脚本不能在调试模式下运行)。 如果在调试模式下运行 Test_DST 2.mq5, 并在调试器中复制日志行并将其粘贴到电子表格中;单元格分隔符将是空格。

此外,现在还有一个新的简单函数SecTillClose(),以秒为单位(MQ 时间货币)显示外汇市场收盘前的剩余时间--无需CopyTime()。这对那些想在周末前平仓或不想在周末前的某段时间内开新仓的人来说很有意义。

附带的指标DealingWithTime_TestIndi.mq5 作为图表注释,不仅显示欧洲、美国和澳大利亚(悉尼)的夏令时,还显示不同城市的当前时间和时差。在这里,您可以找到一份主要城市不同当地时间的比较表:https://www.timeanddate.com/worldclock/。这样您就可以随时查看这些数值。该指标还显示了这些值是如何定义和使用的(从哪些值中减去或加上哪些值),因此您可以轻松地自行使用--复制和粘贴,这是编程的最快形式。

最后两行还显示了当前外汇时段的最后一秒以及剩余时间,单位为小时(更容易判断)和秒。在纽约,当周五当地时间 17:00 外汇交易时段结束时,纽约时间 17:00 没有有效的交易栏打开。因此,该函数会减去 1 秒,以获得经纪商时间内最后一栏的最后有效开仓时间。不过,有些经纪商会提前几分钟结束货币交易时段,不再提供价格或接受交易订单。

Dealing with Time (Part 2): The Functions
Dealing with Time (Part 2): The Functions
  • www.mql5.com
Determing the broker offset and GMT automatically. Instead of asking the support of your broker, from whom you will probably receive an insufficient answer (who would be willing to explain a missing hour), we simply look ourselves how they time their prices in the weeks of the time changes — but not cumbersome by hand, we let a program do it — why do we have a PC after all.
 

你好@Anil Varma

我读了作者@Carl Schreiber 上一篇关于CopyTime() 函数的帖子,但由于我发现第一个版本更容易理解, 所以我仍在使用DealingWithTime.mqh1.01

在我的指标中,我希望

使用以下缓冲区为每个条形图分配纽约原始时间秒、纽约小时和纽约分钟,以便在数据窗口中显示:
double NyRawTimeBuffer[];
double NyHourBuffer[];
double NyMinuteBuffer[];
 void AssignNyTime (const datetime& time[],int rates_total)
   {
      
      MqlDateTime dT_struc;
      
      //--- 为每根蜡烛分配纽约原始时间(秒)、纽约小时、纽约分钟
      ArraySetAsSeries(time,true);
      for(int z=0;z<rates_total;z++)
         { 
            checkTimeOffset(time[z]);                   // 检查夏令时的变化
            datetime tC, tGMT, tNY;
            tC    = time[z];
            tGMT  = time[z] + OffsetBroker.actOffset;   // GMT
            tNY   = tGMT - (NYShift+DST_USD);           // 纽约时间
            int j = int (tNY);                          // 将日期时间转换为 int 
            NyRawTimeBuffer[z]=j;
            
            TimeToStruct(tNY,dT_struc);
            NyHourBuffer[z]=dT_struc.hour;
            NyMinuteBuffer[z]=dT_struc.min;
 
         }        
       
   return;
   }

当终端启动的时间框架图设置为 H1 时,函数才起作用。

如果我关闭终端,将时间框架设置为 M5,然后重新启动终端,则会出现以下错误:

2024.02.18 15:33:38.048 MyFractals_V4 (EURUSD,M5) 240:EURUSD H1 的 CopyTime() 失败:需要从 2024.02.12 02:00:00 开始的时间,但只有从 1970.01.01 00:00:00 开始的错误:4401

您已经通过短信建议我使用这篇文章 (https://www.mql5.com/zh/code/1251) 中的CheckLoadHistory() 函数,并将其放在您库中的 CopyXXXX() 函数之前:

//--- 查找经纪人偏移量
    OffsetBroker.set = false;
    
    CheckLoadHistory("EURUSD",PERIOD_H1,TERMINAL_MAXBARS,true);
      
    b = CopyTime("EURUSD",PERIOD_H1,BegWk+26*3600,5,arrTme);      // 获取欧盟切换前最后 1 小时的时间条

但问题仍然存在。

checkhistory.mqh(第 19 行)中,我注意到了以下注释,但我不明白这是否是一个问题。我试着注释它,并再次测试程序,但没有成功。

//-----------------------------------------------------如果是指标,则不要求加载其自身数据
   if(MQL5InfoInteger(MQL5_PROGRAM_TYPE)==PROGRAM_INDICATOR && Period()==period && Symbol()==symbol) return(true);

是否有办法在不改用更新的DealingWithTimeV2.03.mqh 不重新编写所有代码的情况下调整这个错误?




CheckHistory - Check and load history function
CheckHistory - Check and load history function
  • www.mql5.com
Slightly modified history load function from MetaQuotes.
 
Nauris Zukas 策略测试器中 也应该起作用,但却不起作用。


通过输入变量使用的替代方法 "是在策略测试器中获得正确时间的唯一方法吗?

您好

我试着修改了下面的代码,目前对我来说是有效的。请注意,我转换了带有构造函数的类,所有方法都是类的一部分。类需要在您的 EA/策略类中调用并初始化。

CDealWithTime.OnTick() 应放在 EA/Strategy OnTick() 中。

//+-----------------------------------------------------------------------------------------------------------------------------+
//| 确定给定时间 (tB) 的经纪人偏移量的函数
//+-----------------------------------------------------------------------------------------------------------------------------+
void CDealWithTime::OnTick(void) {

                string vMethod = __FUNCTION__ + " Line[" + (string)__LINE__ + "] ";

                // 对 TimeH01[] 进行每小时更新
                if(IsNewBarH01()) {
      // ...BegWk = BoW(tC),原始代码
                        datetime weekBegin = BoW(TimeCurrent());
                        // 原始代码为弱开始时间添加了 5 个小节。
                        // 将 5 天 * 3600 秒(InHour)加到弱开始时间,并不等于 5 个条形图,因为弱开始时间可能没有条形图。
                        // 周末/节假日。因此,WeekBegin+5*3600 的结果可能是一个时间,而上面没有横杠。
                        int                      barShift  = iBarShift(mSymbol,mTimeFrame,weekBegin+(5*3600));
                        // 将返回 Time(weekBegin+(5*3600) 时的第一个可用条形图。
                        datetime timeStop        = iTime(mSymbol,mTimeFrame,barShift);          // 欧盟切换前星期五的最后一小时条形图。
                        // 秒数增加 (weekBegin)+(5*3600) 时的结果:CDealWithTime::OnTick Line[229] : GetLastError[0] copiedTime EURUSD-PERIOD_H1 for [0] bars weekBegin[2024.01.01 02:00] to timeStop[2023.12.31 21:00] time5th[2023.12.29 23:00].
                        int bars = Bars(mSymbol,mTimeFrame,weekBegin,timeStop);

                        // 我们需要 while...循环,因为 IsNewBarH01() 只在 Tick 上检查一次,如果为真,则直到下一个新的条形图为止,不再检查
                        ResetLastError();
                        int attempt = 0;
                        while(CopyTime(mSymbol,mTimeFrame,weekBegin,timeStop,TimeH01) != bars && attempt <= 10) {
                                Sleep(100);
                                attempt++;
                        }
                        if(attempt > 0) {
                                PrintFormat("%s: GetLastError[%i] copiedTime %s-%s for [%i] bars weekBegin[%s] to timeStop[%i][%s]",vMethod,GetLastError(),mSymbol,EnumToString(mTimeFrame),bars,TimeToString(weekBegin),barShift,TimeToString(timeStop));
                        }
                }

                // 如果日光节约时间(DST)发生变化,每周进行一次检查
                if(IsNewBarW01()) {
                        checkTimeOffset(TimeCurrent());
                        int  attempt  = 0;
                        bool isOffset = false;
                        do{
                                isOffset = setBokerOffset();
                                attempt++;
                        } while(!isOffset && attempt <= 10);
                }

} // OnTick() 结束
 
amrali #:

该代码会自动计算欧洲和美国经纪人的 DST:

https://www.mql5.com/zh/code/27860

上述代码用于外汇市场时间https://www.mql5.com/zh/code/27771,以 计算夏令时的变化。

可为世界不同地区构建类似函数。

你好,阿姆拉利

作为 DealingWithTime v2.03 文章的替代代码,它既漂亮又简单。我将对其进行更详细的研究。

 
Daniel K #:
DealingWithTime.mqh v . 1.01.

你好,丹尼尔

DealingWithTime.mqh v . 1.01.卡尔在DealingWithTime.mqh v 2.03 文章 https://www.mql5.com/zh/code/45287 中解释说,由于 MQL 计算方法的改变,这篇文章及其代码已不再有效。

您根本不应该使用它。

Dealing with time (2) functions
  • www.mql5.com
Calculate DST for USA, EUR, AUD and RUB and the offset time of the broker automatically from the 70's until 2030 - even in the Strategy Tester of MQ.