
处理时间(第一部分):基础
哪一个时间
准确的时序也许是交易中的一个关键因素。 在当前钟点,伦敦或纽约的证券交易所是否已经或尚未开市,外汇交易的交易时间何时开始和结束? 对于一名实况手工交易者来说,这不算是个大问题。 透过各种互联网工具,金融工具的规格、自身时间,您可以快速查看什么时间是您策略的正确时机。 对于哪些只关注价格走势的交易者来说,一旦价格走势给他发出一个信号,他就做多或做空,而时间并不重要。 而对于“夜间剥头皮”的交易者来说,其中大有区别,有些人在纽约(股票)市场收盘后和欧盟公开市场(股票)开盘前进行交易;亦或有些交易者专门针对特定状况交易,例如“伦敦突破”;或有些交易者在最高反转处进行交易;或所有那些交易股票或期货的交易者。 这些交易者不会遵循经纪商的时间,但必须遵照美国、日本、伦敦、欧盟或莫斯科各自交易所的开市或闭市的当地实际时间,或特定期货的特殊交易时间。
夏季时间、冬季时间、和经纪商时移
如前所述,坐在屏幕前进行买卖的交易员可以轻松处理不同的时间。 无论是通过互联网还是某些功能,PC 均能保持这些数值或时钟可用,且可随时调用 MQL 函数,譬如 TimeGMT(),TimeGMTOffset() 和其它函数获取这些数值。 若是有人想依据历史数据编写和测试与时间相关的交易程序,情况就有所不同了。 事实上,与实况交易类似,这个问题也同样容易回答。
从 UTC(世界协调时间)或格林尼治标准时间(GMT,https://greenwichmeantime.com/what-is-gmt/),简单地加上地理或金融工具相关的时移,就可以推算出时间所在。 但这并非如此简单。 冬季和夏季时间(DST 或夏令时)的转换是在时间基础上增加或减少若干小时。 然而,这并非一成不变,每个国家或地区(如欧洲)都会自行定义,有时多年不变(欧盟和美国),或者时不时地改变,比如在俄罗斯于 2014 年被废除。 在欧盟,2018 年发起过一次讨论,包括关于取消年度时间变更问题的调查(https://ec.europa.eu/germany/news/20180831-konsultation-sommerzeit_de),结果显示大多数人赞成废除,因此委员会提交了一份关于终结时间变更的立法提案(https://ec.europa.eu/germany/news/20180914-kommission-gesetzesvorschlag-ende-zeitumstellung_de),不过最后不了了之。
似乎这还不够混乱,现在经纪商正在加入混战,即如何各自定义服务器时间的方式。 在 2015,一家德国经纪商通知我:
- 在 2015 年 3 月 8 日之前,我们的 MT4 服务器时间设置到伦敦时间(= GMT)。
- 而在 2015 年 3 月 8 日,至 3 月 29 日间,设置到 CET(GMT + 1)
- 后从 3 月 29 日起,服务器设置回伦敦时间(= GMT + 1)
也就是说,德国经纪商使用 GMT + DST - USA,或者(主要)伦敦时间 + 美国的 DST,您必须首先遵守它,尽管原因可以理解,因为外汇交易在纽约时间 17:00 开始,故需取决于美国的时间变更。 结果就是,对于法兰克福的那些人来说,外汇交易有时在 21:00 开始,通常是 22:00,秋季的第一周或第两周则是 23:00
对于我们这些交易员和客户来说,这更像是在幼儿园。 每个人都能决定自己想做什么,以及怎么做。 故此,交易者或开发人员会面临许多不同的时间,所有这些时间都可能很重要,所有这些时间都必须根据 MQL 的“在案资源”判定 — 但不幸的是,如果策略测试器中正在运行指标、脚本或 EA,则不能做到。
我们要改变这一点。 不必咨询经纪商,我们将判断其各自的时间变更,如此就可以在任何时刻很简单地为策略测试器中任意时间戳确定 GMT,当然,更进一步就是任何所需的本地时间,像是纽约时间。 此外,因为它仅在这种背景下出现,而外汇市场在其余时间仍然开放,对于所有希望在周末前平仓的交易员来说,它是必要的。 不过,我们将在第二篇文章中讨论这些函数,因为现在我们只开发一些宏替换,这可令我们简化上述函数的计算和控制表述。
宏替代
所有一切都在(附件)包含文件 DealingWithTimePart1.mqh 里。 在这个文件的开头有各种宏替换。
首先,不同地区有一些时间偏移,如此您就不必一次再一次地推导或搜索它们:
//--- defines #define TokyoShift -32400 // always 9h #define NYShift 18000 // winter 17h=22h GMT: NYTime + NYshift = GMT #define LondonShift 0 // winter London offset #define SidneyShift -39600 // winter Sidney offset #define FfmShift -3600 // winter Frankfurt offset #define MoskwaShift -10800 // winter Moscow offset #define FxOPEN 61200 // = NY 17:00 = 17*3600 #define FxCLOSE 61200 // = NY 17:00 = 17*3600 #define WeekInSec 604800 // 60sec*60min*24h*7d = 604800 => 1 Week
为了更好地理解,我们同意 GMT 是一个不可变的时间锚点,而不同的本地时间,如纽约、伦敦或莫斯科,每一个都有不同的(可变)时移。 同样,我们也将夏季或冬季时间的变更作为变量。 原因很简单。 可变时移的符号定义如下:
可变时间 + 可变时移 = GMT
一些例子:
莫斯科 (16h) + 莫斯科时移 (-3h) = GMT (13h)
纽约时间 (16h) + 纽约时移 (+5h) = GMT (21h)
纽约时间 (16h) + (纽约时移 (+5h) + DST_US(-1h)) = GMT (20h)
法兰克福时间 (16h) + (法兰克福时移 (-1h) + DST_US(-1h)) = GMT (14h)
留心括号! 当根据 GMT 计算可变时间时,它们变得非常重要:
纽约时间 (16h) = GMT (20h) - (纽约时移 (+5h) + DST_US(-1h)) => 20 -(+5 + -1) = 20 - 5 +1 = 16h
法兰克福时间 (16h) = GMT (14h) - (法兰克福时移 (-1h) + DST_US(-1h)) => 14 -( -1 + -1) = 14 +1 +1 = 16h
相信我,这是标记错误和误解的永恒来源。
以这种形式中,MQL5 和 PC 也会处理时差,如 TimeGMTOffset(): TimeLocal() + TimeGMTOffset() = TimeGMT()) 或 TimeDaylightSavings(): TimeLocal() + TimeDaylightSavings() = 冬季或 PC 的标准本地时间。
作为本部分的最后一部分,诸如 FxOpen 和 FxClose 提供以秒为单位的整个星期的持续时间 WeekInSec,因为在为变量赋值时,这种设计比在代码中突兀加入数字(例如 604800)更容易理解。
后跟两个简化的变量输出。 TOSTR(A) 它打印变量的名称及其值 - 非常优美。 然后是内含工作日缩写的数组。 它在本项目的开发代码中多次被用到,其有助于节省代码行的空间,也有助于计算时间戳的朝向:
#define TOSTR(A) #A+":"+(string)(A)+" " // Print (TOSTR(hGMT)); => hGMT:22 (s.b.) string _WkDy[] = // week days { "Su.", "Mo.", "Tu.", "We.", "Th.", "Fr.", "Sa.", "Su." };
现在,遵循时间计算的备选方案,从而避免将时间分配给 MQ 结构 MqlDateTime 时读取标量值的迂回过程。 它们是直接进行计算的:
#define DoWi(t) ((int)(((t-259200)%604800)/86400)) // (int)Day of Week Su=0, Mo=1,... #define DoWs(t) (_WkDy[DoWi(t)]) // Day of Week as: Su., Mo., Tu., ....
DoWi(t) (周内星期化为整数)判断周内星期的整数值(星期日:0,星期一:1,…),而 DoWs(t) (周内星期的字符串形式)则返回调用 DoWi(t) 和数组 _WkDy[] 后组成的周内星期缩写文本。 由于本文的第二部分涉及周末的最后和第一个小时,因此将会更频繁地取用这些宏替换。
#define SoD(t) ((int)((t)%86400)) // Seconds of Day #define SoW(t) ((int)((t-259200)%604800)) // Seconds of Week
SoD(t) (一天中的秒数)返回自刚过去的 00:00 点以来的秒数。 因此,SoD(TimeCurrent()) 用这种简单的方法计算出一根蜡烛已经存在的持续时间(以秒为单位)。 类似地,SoW(t) 计算自上周日 00:00 点以来的秒数。 通过这种途径,很容易计算出已流逝时间(以秒为单位)的百分比,和当天的剩余时间。 如果将该值除以 864(=0.01*24*60*60),则得到当天已流逝时间的百分比:
(double)SoD(D’20210817 15:34‘) / 864. = 64.86% 86400 - SoD(D’20210817 15:34‘) = Print("D'20210817 15:34': ", DoubleToString((double)SoD(D'20210817 15:34')/864.0, 2),"% ", 86400 - SoD(D’20210817 15:34‘),“ sec left“ );
这些计算相应地起作用(无论需要它):
#define MoH(t) (int(((t)%3600)/60)) // Minute of Hour #define MoD(t) ((int)(((t)%86400)/60)) // Minute of Day 00:00=(int)0 .. 23:59=1439
函数 ToD(t) 把一天的秒数转换为数据类型 “datetime”,并返回。 这可以防止编译器在某种状况下发出警告消息:
#define ToD(t) ((t)%86400) // Time of Day in Sec (datetime) 86400=24*60*60
函数 HoW(t) 返回自星期日 00:00 点以来的小时数:
#define HoW(t) (DoW(t)*24+HoD(t)) // Hour of Week 0..7*24 = 0..168 0..5*24 = 0..120
一天中的小时数可以用一种简单的方法来计算,结果是一个整数,而不是一个日期:
#define HoD(t) ((int)(((t)%86400)/3600)) //Hour of Day: 2018.02.03 17:55 => 17
这与“商业”四舍五入相同:
#define rndHoD(t) ((int)((((t)%86400)+1800)/3600))%24 // rounded Hour of Day 17:55 => 18
并与 datetime 类型相同:
#define rndHoT(t) ((t+1800)-((t+1800)%3600)) // rounded Hour of Time: 2018.02.03 17:55:56 => (datetime) 2018.02.03 18:00:00
一天开始的时间化为 datetime,否则必须调用日线时间帧 D1 来额外判断:
#define BoD(t) ((t)-((t)%86400)) // Begin of day 17.5 12:54 => 17.5. 00:00:00
一周开始的时间化为 datetime,否则必须调周线时间帧来判断:
#define BoW(t) ((t)-((t-172800)%604800 - 86400)) // Begin of Week, Su, 00:00
以下片段利用 MQL 结构和函数,因为转换对我来说太复杂了,例如要考虑闰年,但它们遵循上面相同的格式原则;时间函数的名称主要是三个字母或首字母缩写,DoY、(=年内的天)、MoY(年内的月)和 YoY(年内的年):
MqlDateTime tΤ; // hidden auxiliary variable: the Τ is a Greek characker, so virtually no danger int DoY(const datetime t) {TimeToStruct(t,tΤ);return(tΤ.day_of_year); } int MoY(const datetime t) {TimeToStruct(t,tΤ);return(tΤ.mon); } int YoY(const datetime t) {TimeToStruct(t,tΤ);return(tΤ.year); }
以下仍然是根据美国定义来计算年内的周:
int WoY(datetime t) //Su=newWeek Week of Year = nWeek(t)-nWeeks(1.1.) CalOneWeek:604800, Su.22:00-Su.22:00 = 7*24*60*60 = 604800 { return(int((t-259200) / 604800) - int((t-172800 - DoY(t)*86400) / 604800) + 1); // calculation acc. to USA }
(有关每周计算的更多信息,请参见此处: https://zh.wikipedia.org/wiki/Week#Numbering)
季节性和地方性时差
在声明并解释了函数所需的简化,以及更多内容之后,我们现在准备进入更广泛领域,彻底了解本地和季节性时移的差别,以及经纪商和 MQL5 如何处理它们。 我们从编程语言 MQL5 开始。
MQL5 中的时间
第一个立即能想到的时间是经纪商提供的报价时间,反映在柱线的开盘时间中,并可用 TimeCurrent() 查询最后收到的报价。 在许多情况下 — 这也许会令人惊讶 — 这个时间相对来说并不重要,它只用在柱线、价格、以及交易活动的按时间排序。 故此,它仅在终端环境、实况交易环境、以及策略测试环境中具有相关性。
然后是 TimeTradeServer():返回交易服务器的当前计算时间。 不像 TimeCurrent() 函数,时间计算在客户端执行,并取决于用户计算机中的时间设置。但是:在策略测试器中进行测试时,TimeTradeServer() 是根据历史数据模拟的,且始终与 TimeCurrent() 相等。因此,对于那些需要在策略测试器中针对实况进行优化的程序,此功能没有多大帮助。
对于 TimeGMT() 和 TimeLocal():在策略测试器中进行测试期间,TimeGMT() 始终等于 TimeTradeServer() 模拟的服务器时间,这其实也等于 TimeCurrent()。
这也令 TimeGMTOffset() 在策略测试器中“无效”,因为 TimeGMTOffset() = TimeGMT() - TimeLocal(),故始终为零。 :(
剩下的最后一项是 TimeDaylightSaves():“如果转换到夏令时,返回夏令时的校正值(以秒为单位)。 取决于用户计算机中的设置。 ... 如果转换到冬季时间(标准时间),则返回 0。
以下是演示帐户实况的打印输出(从日期可以看出,MQ 在查询时是依据欧盟和美国当前的夏令时):
2021.08.26 09:25:45.321 MasteringTime (EURUSD,M1) TimeCurrent: 10:25
2021.08.26 09:25:45.321 MasteringTime (EURUSD,M1) TimeTradeServer: 10:25
2021.08.26 09:25:45.321 MasteringTime (EURUSD,M1) TimeLocal: 09:25
2021.08.26 09:25:45.321 MasteringTime (EURUSD,M1) TimeGMT: 07:25
2021.08.26 09:25:45.321 MasteringTime (EURUSD,M1) TimeDaylightSavings: -3600 h: -1
2021.08.26 09:25:45.321 MasteringTime (EURUSD,M1) TimeGMTOffset: -7200 h: -2
这里是策略测试器中相同帐户的打印输出(调试):
2021.08.26 10:15:43.407 2021.06.18 23:54:59 TimeCurrent: 23:54
2021.08.26 10:15:43.407 2021.06.18 23:54:59 TimeTradeServer: 23:54
2021.08.26 10:15:43.407 2021.06.18 23:54:59 TimeLocal: 23:54
2021.08.26 10:15:43.407 2021.06.18 23:54:59 TimeGMT: 23:54
2021.08.26 10:15:43.407 2021.06.18 23:54:59 TimeDaylightSavings: 0 h: 0
2021.08.26 10:15:43.407 2021.06.18 23:54:59 TimeGMTOffset: 0 h: 0
所有这些功能在策略测试器中都没有啥帮助,它们仅在实况下有用。 因此,我们仅有 TimeCurrent() 可以自己计算所有其它时间,而这一切都很混乱。 好吧,任何人都可以轻易做到 ;)
理论上您可以这样认为,您可以从经纪商那里得到一切,譬如他如何定义报价时间戳的时间变更。 例如,下面是来自 Alpari 的答案:
(GMT+2/GMT +3 DST) 并于周五服务器时间 23:55:00 结束。 夏日期间
交易在周日格林威治标准时间 21:05 开始,而在冬季则是
周日 22:05 GMT。
事实证明,只有部分是事实。 首先,未提及欧盟和美国在夏季或冬季的过渡时间并不相同;其次,未提及该过渡时间内的价格,例如 2021 年 3 月 26 日,并非在 23:55 结束,而是在 22:55 就结束了。 在 23 点 55 分之前和之后。
但在我们继续之前,先简单介绍一下不同时区及其首字母缩略词。 在我看来,这个网站对我的整个主题最有帮助: https://24timezones.com/time-zones。 那里的表格列出了 200 个不同的时区。 以下是与我们相关的:
缩略语 | 时区 | 网站 | UTC 时差 | GMT 时差 |
---|---|---|---|---|
CEST | 欧洲中部夏令时 | 法兰克福夏令时 | UTC+2 | GMT+2 |
中欧时间 | 欧洲中部时间 | 法兰克福正常时间 | UTC+1 | GMT+1 |
EDT | 东部夏令时 | 纽约正常时间 | UTC-4 | GMT-4 |
EEST | 欧洲东部夏令时 | 塞浦路斯,夏令时 | UTC+3 | GMT+3 |
东欧时间 | 欧洲东部时间 | 塞浦路斯正常时间 | UTC+2 | GMT+2 |
EST | 东部标准时间 | 纽约正常时间 | UTC-5 | GMT-5 |
ET | 东部时间 | 纽约 | UTC-5/UTC-4 | GMT-5/GMT-4 |
GMT | 格林威治标准时间 | 伦敦正常时间 | UTC+0 | GMT+0 |
UTC | 协调世界时间 | 伦敦正常时间 | UTC | GMT |
请注意,如果您纯粹看数字的话,纽约的正常时差为 -5 小时,夏季为 -4,因此“少了”一小时,而法兰克福自 MQ+2 时差为 +1,但夏季分别为 +2 和 +3,因此“多了”一小时。 请不要对此感到困惑,记住示例!
现在,我们来看看 MQ 演示帐户在一个周末前后的第一个和最后一个报价的时间戳是什么:在 “EURUSD” 的 M1 图表上,我们首先激活周期分隔,然后在图表上按 Enter 键,在每种情况下以 dd.mm.yyyy 格式输入星期一的日期。(不是 MQ 日期格式)。 然后用鼠标将图表向右移动一点。 现在,带垂直线的柱线图是新一周的第一根柱线图,其左侧的柱线图是上一周的最后一根柱线图。 此处是周五最后一根柱线和周末后第一根柱线的日期:
2020 年秋季时间转换前后的周末:
夏季-EU | 夏季-EU | 夏季-EU | 冬季-EU | 冬季-EU | 冬季-EU | 冬季-EU | 冬季-EU | 冬季-EU | 冬季-EU |
---|---|---|---|---|---|---|---|---|---|
夏季-US | 夏季-US | 夏季-US | 夏季-US | 夏季-US | 冬季-US | 冬季-US | 冬季-US | 冬季-US | 夏季-US |
周五 | 周一 | 周五 | 周一 | 周五 | 周一 | 周五 | 周一 | 周五 | 周一 |
2020.10.16 | 2020.10.19 | 2020.10.23 | 2020.10.26 | 2020.10.30 | 2020.11.02 | 2021.03.05 | 2021.03.08 | 2021.03.12 | 2021.03.15 |
23:54 | 00:05 | 23:54 | 00:05 | 22:54 | 00:02 | 23:54 | 00:03 | 23:54 | 00:00 |
1,1716 | 1,17195 | 1,18612 | 1,18551 | 1,16463 | 1,16468 | 1,19119 | 1,19166 | 1,19516 | 1,19473 |
1,17168 | 1,17208 | 1,18615 | 1,18554 | 1,16477 | 1,16472 | 1,19124 | 1,19171 | 1,19521 | 1,19493 |
1,1716 | 1,1718 | 1,18596 | 1,18529 | 1,16462 | 1,16468 | 1,19115 | 1,19166 | 1,19514 | 1,19473 |
1,1716 | 1,17188 | 1,18598 | 1,18534 | 1,16462 | 1,16472 | 1,1912 | 1,19171 | 1,19519 | 1,19491 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
29 | 22 | 35 | 48 | 30 | 3 | 33 | 2 | 23 | 25 |
4 | 11 | 2 | 6 | 2 | 61 | 1 | 38 | 1 | 29 |
这是 2021 年春季时间转换前后的周末:
冬季-EU | 冬季-EU | 冬季-EU | 冬季-EU | 冬季-EU | 冬季-EU | 冬季-EU | 夏季-EU | 夏季-EU | 夏季-EU |
---|---|---|---|---|---|---|---|---|---|
冬季-US | 冬季-US | 冬季-US | 夏季-US | 夏季-US | 夏季-US | 夏季-US | 夏季-US | 夏季-US | 夏季-US |
周五 | 周一 | 周五 | 周一 | 周五 | 周一 | 周五 | 周一 | 周五 | 周一 |
2021.03.05 | 2021.03.08 | 2021.03.12 | 2021.03.15 | 2021.03.19 | 2021.03.22 | 2021.03.26 | 2021.03.29 | 2021.04.02 | 2021.04.05 |
23:54 | 00:03 | 23:54 | 00:00 | 22:54 | 00:00 | 22:54 | 00:07 | 23:54 | 00:03 |
1,19119 | 1,19166 | 1,19516 | 1,19473 | 1,19039 | 1,18828 | 1,17924 | 1,17886 | 1,17607 | 1,17543 |
1,19124 | 1,19171 | 1,19521 | 1,19493 | 1,19055 | 1,18835 | 1,17936 | 1,17886 | 1,17608 | 1,17543 |
1,19115 | 1,19166 | 1,19514 | 1,19473 | 1,19038 | 1,18794 | 1,17922 | 1,17884 | 1,17607 | 1,17511 |
1,1912 | 1,19171 | 1,19519 | 1,19491 | 1,19044 | 1,18795 | 1,17933 | 1,17886 | 1,17608 | 1,17511 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
33 | 2 | 23 | 25 | 41 | 43 | 17 | 3 | 2 | 3 |
1 | 38 | 1 | 29 | 1 | 20 | 5 | 68 | 28 | 79 |
有趣的是,有时周末前的最后一次报价应该在 23:00(22:54)左右到达,但通常在 24:00(23:54)时才会到达,但第一次报价总能在 00:00 到达,这一点我还不太理解。 若纯粹按小时的角度来看,有时这会造成 1 小时的“价格漏洞”(23:00 闭市,00:00 开市),而外汇市场通常在周五 17:00(纽约时间)闭市,周日 17:00(纽约时间)开市。 我们来具体地看看周末行为,切换并计算与我们相关的其它时区的相应时间:
日期 |
| 最后的周五日期 |
|
|
| 日期 |
|
|
|
|
| 最后一根柱线 | 下一根 m1 柱线 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
美国切换 |
| 纽约时间 | 纽约-GMT | GMT | 欧洲切换 |
| 中欧时间-GMT | 中欧时间 | 东欧时间-GMT | 东欧时间 | MQ 内 | MQ 内 | |
| 夏季-US | Fr, 16. Oct 20 | 17:00 | GMT + 4 | 21 |
| 夏季-EU | GMT + 2 | 23 | GMT + 3 | 24 | 23:54 |
|
| 夏季-US | So, 18. Oct 20 | 17:00 | GMT + 4 | 21 |
| 夏季-EU | GMT + 2 | 23 | GMT + 3 | 24 |
| 00:05 |
| 夏季-US | Fr, 23. Oct 20 | 17:00 | GMT + 4 | 21 | 25.10.20 | 夏季-EU | GMT + 2 | 23 | GMT + 3 | 24 | 23:54 |
|
| 夏季-US | So, 25. Oct 20 | 17:00 | GMT + 4 | 21 |
| 冬季-EU | GMT + 1 | 22 | GMT + 2 | 23 |
| 00:05 |
01.11.20 | 夏季-US | Fr, 30. Oct 20 | 17:00 | GMT + 4 | 21 |
| 冬季-EU | GMT + 1 | 22 | GMT + 2 | 23 | 22:54 |
|
| 冬季-US | So, 1. Nov 20 | 17:00 | GMT + 5 | 22 |
| 冬季-EU | GMT + 1 | 23 | GMT + 2 | 24 |
| 00:02 |
| 冬季-US | Fr, 6. Nov 20 | 17:00 | GMT + 5 | 22 |
| 冬季-EU | GMT + 1 | 23 | GMT + 2 | 24 | 23:54 |
|
| 冬季-US | So, 8. Nov 20 | 17:00 | GMT + 5 | 22 |
| 冬季-EU | GMT + 1 | 23 | GMT + 2 | 24 |
| 00:03 |
14.03.21 | 冬季-US | Fr, 12. Mrz 21 | 17:00 | GMT + 5 | 22 |
| 冬季-EU | GMT + 1 | 23 | GMT + 2 | 24 | 23:54 |
|
| 夏季-US | So, 14. Mrz 21 | 17:00 | GMT + 4 | 21 |
| 冬季-EU | GMT + 1 | 22 | GMT + 2 | 23 |
| 00:00 |
| 夏季-US | Fr, 26. Mrz 21 | 17:00 | GMT + 4 | 21 | 28.03.21 | 冬季-EU | GMT + 1 | 22 | GMT + 2 | 23 | 22:54 |
|
| 夏季-US | So, 28. Mrz 21 | 17:00 | GMT + 4 | 21 |
| 夏季-EU | GMT + 2 | 23 | GMT + 3 | 24 |
| 00:07 |
| 夏季-US | Fr, 2. Apr 21 | 17:00 | GMT + 4 | 21 |
| 夏季-EU | GMT + 2 | 23 | GMT + 3 | 24 | 23:54 |
|
| 夏季-US | So, 4. Apr 21 | 17:00 | GMT + 4 | 21 |
| 夏季-EU | GMT + 2 | 23 | GMT + 3 | 24 |
| 00:03 |
在一周当中,欧盟和美国的时钟不会分别显示当地的夏时制或标准时间,纽约外汇市场周日开市时间为 EET 23:00,周五闭市时间为 EET 23:00。 然而,各种经纪商以及 MQ 的演示帐户始终在周日 24:00(或周一 00:00)才会提供第一次报价。 现在人们可能会想,报价的时间戳总是与第二次变换匹配,而非第一次变换。 然而,在周五,外汇市场收盘前的最后一次报价必须有一个 24:00 之前的时间戳,因为只有这样才会有完整的 24*5=120 小时,但因此会缺失一个小时。 这样就提出了一个问题,这一小时是在周末前的周五还是周末后的周日?
鉴于每周的收盘价格比之周日第一个交易小时的开盘价更为重要,因此可以推断,如果周五的最后一次价格是 23:00 之前不久的价格,但下一个价格若是 24:00 或 00:00,那么外汇市场的每周第一个小时就不见了,周日 23:00-24:00 的价格,其实不是最后一次,而是周五 23:00-24:00 的那次。 然而,如果第一次报价的时间戳是在周日 23:00 后不久,那么您如果遵循谨慎的策略,在周末之前所有持仓平仓,那么不仅很容易辨别时间变更,而且很容易知道外汇市场何时再次闭市(周日开市后 5d*24h=120 小时)。 正如所说的,任何人都能简单地做到。
首先,我们考虑我们可以做出什么假设。 在策略测试器中,我们只有 TimeCurrent()。 依靠这个,我们能判断 GMT 或 UTC,这样我们就可以轻松地计算其它时区的所有时间。 根据可能的假期或其它影响美国外汇市场开市和闭市时间的原因,我们假设:
- 外汇市场于纽约时间周五 17:00 闭市。
- 外汇市场将于纽约时间周日 17:00 开市。
- 正常来讲,开市(5*24=)120 小时,闭市(2*24=)48 小时。
- 如果在两个周五之间缺少若干个小时。 17:00 和周日 17:00,那么直到周日第一次报价,所有报价缺失,而非周五收到的最后一次报价之后。
- 传入的报价(无论时间戳是什么)始终是最新的(例如,不会是 1 小时前的)。
- 经纪商并没有改变它的时间变更政策,因为它曾是之前历史报价的最后一次。
展望
现在,我们已经定义了函数,或者更准确地说是宏替换,稍后我们将使用这些函数,并在下一篇文章“处理时间(第二部分):函数”中阐明了要开发的条件。这些函数能依据给定的任何时间为我们计算 GMT。
附件是 DealingwithTimePart1.mqh,其中包含此篇讨论的代码部分。 在第二篇文章中,会扩展上述函数。
请在文章的评论部分写下建议、评论和提示。
本文由MetaQuotes Ltd译自英文
原文地址: https://www.mql5.com/en/articles/9926
注意: MetaQuotes Ltd.将保留所有关于这些材料的权利。全部或部分复制或者转载这些材料将被禁止。
This article was written by a user of the site and reflects their personal views. MetaQuotes Ltd is not responsible for the accuracy of the information presented, nor for any consequences resulting from the use of the solutions, strategies or recommendations described.


终端中的时区是服务器所在地的时区,也就是说,如果代理位于伦敦,但服务器位于卢森堡等地,则时区是不同的。过去是这样,将来也是这样。
非常感谢,我正在核实该交易员是否真实,今天我检查了操作中报告的 cfds 价格,考虑到之前提到的时差,如果它们与我今天查阅的伦敦市场图表的值相吻合的话。
请通过私人信息向我发送有关该经纪商的更多信息,我可以告诉您它是否受监管等。论坛禁止此类讨论。
精彩的文章和帮助!
如果使用测试仪,应该会有任何提示:"注意测试仪中与时间相关的策略...... "之类的话。"之类的话。怎么才能知道呢?
我认为在第一张包含时区和缩写的表格中,您指的是第 3 行中的 "纽约,夏令时"(美国东部时间,UTC-4),而不是纽约,正常时间。
非常感谢,但我不会在这里做任何改动,因为某些集成函数的计算方法已经改变(我想是在矩阵和向量的扩展使用范围内)。我在这里发布了所有函数和宏的新版本,还有一个新版本:https://www.mql5.com/zh/code/45287。
此外,还有两个程序可用于测试和检查其工作和使用方式。
非常感谢,但我不会在这里做任何改动,因为某些综合函数的计算方法已经更改(我认为是在矩阵和向量的扩展使用背景下),我在这里发布了所有函数和宏的新版本,还有一个新版本: https://www.mql5.com/zh/code/45287。
此外,还有两个程序可用于测试和检查其工作和使用方式。
好的,我会检查你们的新版本,再次感谢。