MT4如何导入指标 - MQL4时间条件控制非交易时段订单的编写方法

为什么非交易时段必须单独处理
外汇市场的交易时间是周一到周五,每天24小时连续运转,但周末是彻底关闭的。不过这里有个容易忽略的细节,MT4服务器时间下的周五收盘并不是24点整,不同交易品种收盘时间有差异,比如黄金通常在周五晚上11点或12点就停了。如果你在周五晚上还让EA继续开仓,订单会挂在服务器上,直到下周一开盘才执行,这中间两天的隔夜风险完全不可控。
更麻烦的是节假日。欧美国家的圣诞节、感恩节,还有复活节,这些时候流动性急剧下降,点差能扩大到平时的三到五倍。我见过最夸张的一次,有个EA在平安夜当天还开了一单欧元兑美元,点差差了将近40个点,一开仓就亏了20多美元。所以说,时间条件控制不是可有可无的锦上添花,而是EA能不能长期稳定运行的基本保障。
其实还有一层很多人没想到的,就是交易商服务器时间和你本地时间可能不一样。如果你在电脑上判断当前时间,用了本地时间,那和MT4服务器时间对不上,判断结果就会出错。MQL4里有个内置函数TimeCurrent(),返回的就是服务器时间,这才是判断交易时段的正确依据。
MQL4里时间判断的核心函数用法
MQL4里处理时间最常用的就是TimeCurrent()、TimeDayOfWeek()和Hour()这几个函数。TimeDayOfWeek()返回的是星期几的数字,周日是0,周一是1,依次类推到周六是6。Hour()返回的是当前服务器时间的小时数,范围从0到23。这两个函数组合起来,就能判断出当前是否处于允许交易的时间窗口内。
写代码的时候,通常的做法是写一个专门的判断函数,比如叫IsTradingTime(),返回布尔值。函数内部先判断星期几,如果是周六或周日,直接返回false。如果是周五,还要进一步判断当前小时数是否超过允许的截止时间。比如你设定周五下午5点之后不再开新仓,那就判断Hour()是否大于等于17,如果是就返回false。其他工作日就按照正常的交易起止时间来判断。
这里有个实际经验要分享,就是判断时间的时候最好留一点缓冲。比如你计划每天下午6点停止开仓,那代码里最好写成17点50分就停止,因为订单执行有延迟,如果卡着整点判断,可能刚好在临界点附近出现意外成交。留出十分钟的余量,能避免很多不必要的麻烦。
挂单和持仓在非交易时段的不同处理逻辑
限价单和止损单在非交易时段的表现完全不同。限价单如果挂在当前位置附近,非交易时段不会触发,但会一直保留到下周开盘。如果周一开盘价格跳空穿过了限价单的价格,那这个单子就会以跳空后的价格成交,而不是你设定的价格。止损单同理,跳空缺口如果直接越过止损位,成交价会远远差于你设定的止损价。
针对这个问题,我的做法是在时间判断函数里加入对挂单的检查。当进入非交易时段时,先遍历所有挂单,把那些距离当前价格太近的挂单全部删除。怎么算太近?我一般用当前价格的千分之二作为阈值,比如欧美兑美元价格在1.1000附近,那距离现价超过22个点的挂单就保留,低于这个距离的挂单直接删掉。这样即使周一跳空,也不会出现离谱的成交价格。
持仓单的处理思路又不一样。如果你做的是中长线策略,持仓过周末是正常操作,不需要平仓。但如果你做的是日内短线,那周五收盘前就应该把所有持仓清掉。这就要在EA里加一个判断,当时间进入周五的某个特定时刻时,强制平掉所有持仓并删除所有挂单。我习惯把周五下午3点作为日内策略的强制平仓时间,这样即使有延迟,也能在收盘前完成所有操作。
还有一个细节值得注意,就是对冲锁仓的情况。如果同时存在多单和空单,非交易时段前是否要解锁?其实锁仓状态下风险是可控的,因为盈亏被锁定,跳空影响不大。我建议锁仓的单子不用动,让它继续锁着,等下周开盘后再根据行情决定怎么解锁。
结合日历事件做更精细的时间控制
单纯靠星期几和小时数做判断,只能处理常规的周末休市。但节假日这种情况是每年变化的,比如复活节前后,很多券商会在耶稣受难日休市,这个日期每年都不一样。如果EA里写死了时间判断,遇到这类节假日就会失效。解决办法是在EA里加入一个节假日日期列表,用数组或者自定义结构体存储这些特殊日期。
MQL4里判断日期可以用TimeCurrent()配合Year()、Month()和Day()函数。先取出当前的年、月、日,然后和预设的节假日列表逐一对比。如果匹配上了,就返回false表示非交易时间。这个列表每年需要手动更新一次,虽然麻烦点,但比EA乱开单造成的损失要划算得多。
我实际用下来觉得,更聪明的做法是直接读取交易商的交易品种规格。MQL4里有个MarketInfo()函数,传入MODE_TRADEALLOWED参数,能返回当前品种是否允许交易。这个标志位是交易商后台控制的,他们休市时会自动把它设为false。用这个函数做兜底判断,比自己去算节假日靠谱得多。
把时间判断和MarketInfo()结合起来用,双保险。先判断星期几和小时数是否符合设定,再检查一下MODE_TRADEALLOWED是否为true,只有两个条件都满足才允许开仓。这样即使你忘了更新节假日列表,交易商那边的标志位也能帮你挡住错误开单。
最后提醒一下,写好的时间判断逻辑一定要经过充分的回测验证。把EA挂在MT4的策略测试器里,选一个包含节假日的时间段跑一跑,看看在非交易时段有没有出现意外开单或者平仓的情况。我见过很多EA在模拟盘上表现完美,一上实盘就出错,很大一部分原因就是时间判断逻辑没考虑周全,只在常规交易时间里测试过,碰到节假日就原形毕露了。