目录

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

MQL4时间条件控制交易时段的编写方法
编写EA的时候,时间条件控制是个绕不开的话题。很多交易策略对时段有严格要求,比如只做伦敦盘或者只做纽约盘,非交易时段开单往往容易吃亏。MQL4里处理这个问题其实不复杂,但新手容易踩坑——比如直接用服务器时间判断,结果发现和本地时间对不上,或者忘了考虑周末休市的情况。这篇文章就专门讲讲怎么用时间条件把交易时段卡得死死的。

服务器时间与本地时间的区别

写时间过滤条件之前,必须先搞清楚MetaTrader 4用的到底是哪个时间。MT4默认显示的是服务器时间,不是你的电脑本地时间。很多交易者一开始没意识到这点,写了个“9点到17点交易”的条件,结果发现开单时间完全不对,其实就是因为服务器时间和北京时间差了几个小时。要查看服务器时间,直接在MT4左上角就能看到。

判断时段的时候,建议统一用服务器时间作为标准。比如你想做欧洲盘,那服务器时间可能是早上8点到下午4点,而不是你本地时间的下午3点到晚上11点。写代码时用TimeHour()函数获取当前服务器时间的小时数,再和预设的起止时间比较就行。这里有个细节:Hour()函数也是返回服务器时间的小时,但TimeHour()更明确,不会引起歧义。

还有一种情况是夏令时。有些券商的服务器时间会随夏令时调整,但有些不会。如果你的EA跑了好几个月突然发现时段判断不准了,很有可能就是夏令时切换导致的。
解决办法是不要写死小时数,而是用偏移量或者干脆让用户自己配置参数,这样遇到夏令时调整时改个参数就行,不用重新编译代码。

说实话,我见过不少人直接拿电脑本地时间来判断,结果换台电脑或者改了时区,EA就乱套了。所以写时间条件时,第一原则就是:只用服务器时间,永远不要用本地时间。

用Hour和DayOfWeek函数构建时段过滤

MQL4里最基础的时段控制就是Hour()和DayOfWeek()这两个函数。Hour()返回0到23的整数,代表当前服务器时间的小时;DayOfWeek()返回1到5的整数,1是星期一,5是星期五。组合这两个函数,就能精确控制“星期几的几点到几点”允许交易。比如你想只在周一至周五的上午9点到11点开单,就判断DayOfWeek()在1到5之间,并且Hour()大于等于9且小于11。

写这类条件时有个常见的坑:跨天时段。比如你想做晚上10点到凌晨2点的行情,这时候起始小时大于结束小时,简单的“hour >= start && hour < end”就不成立了。处理办法是拆成两个条件,或者用取模运算。我习惯拆成两个区间判断:如果起始时间小于结束时间,就是普通区间;如果起始时间大于结束时间,就分成“从起始时间到24点”和“从0点到结束时间”两段。

还有个容易被忽略的问题:周末休市。虽然DayOfWeek()已经限制了周一至周五,但周五晚上收盘后和周一早上开盘前,服务器时间可能已经过了交易时段。这时候光靠小时判断不够,最好再判断一下当前K线的时间戳,确保当前Bar是有效交易时段生成的。另外,节假日休市(比如圣诞节、新年)用时间函数是判断不出来的,只能靠其他方式处理,比如检查Bar的成交量是否为零。

我自己写EA时,习惯把时段配置做成外部参数,比如StartHour、EndHour、AllowMondayToFriday这些。这样不同品种、不同策略,直接在MT4的输入参数面板里改就行了,不用每次改代码再重新编译。这也是一个提高效率的好习惯,尤其是当你的EA要跑多个品种的时候,每个品种的交易时段可能都不一样。

非交易时段的挂单与持仓处理

时段过滤不只是控制开新单,还要考虑非交易时段里已有的挂单和持仓怎么办。如果EA在交易时段内下了一个挂单(比如buy stop),结果到了非交易时段,这个挂单还在那里,价格波动剧烈时可能会被意外触发。为了避免这种情况,可以在非交易时段里把挂单全部删除。用OrderDelete()函数遍历所有挂单,条件判断当前不在交易时段内就执行删除操作。

对于已经持仓的单子,处理方式就要看策略目的了。有些策略是时段内开仓,时段外平仓,那就需要在非交易时段里执行平仓逻辑。有些策略是时段内开仓后一直持有,那就不能随便平仓。我见过一种做法:在非交易时段里只平掉亏损的单子,盈利的单子继续持有。这个逻辑用OrderClose()加上盈利判断就能实现,但要注意别把浮亏的单子也平错了方向。

还有一点必须提醒:非交易时段里虽然不开新单,但止损和止盈还是有效的。如果你不想让止损止盈在非交易时段触发(比如周末跳空),那就得在非交易时段里把止损止盈改成0,等交易时段恢复时再重新挂上。这个操作要用OrderModify()函数,修改订单的止损止盈值。不过说实话,跳空行情里不设止损风险很大,我一般不建议这么做。

处理非交易时段的订单,最核心的思路就是“该收的收,该留的留”。挂单要清理干净,持仓要根据策略决定去留,止损止盈要么保留要么临时取消,但必须想清楚后果。

实战案例:一个简单的时段控制EA框架

光讲理论没用,直接看代码更直观。下面这个例子是一个最简单的时段控制框架:只在周一至周五的8点到20点之间开多单,其他时间不开新单,但不清除已有持仓。核心逻辑就在start()函数里,先判断是否在交易时段内,如果在才执行开仓逻辑。

代码里用了一个IsTradingTime()自定义函数,返回布尔值。这个函数内部先检查DayOfWeek()是不是1到5,再检查Hour()是不是在8到20之间。如果两个条件都满足,就返回true,否则返回false。这种封装的好处是,以后想改时段规则,只需要改这个函数内部就行,不用动主逻辑。

开仓部分用了一个简单的均线交叉条件:快线上穿慢线就做多。这只是演示用的,实际策略你可以换成任何你想用的信号。关键是开仓前先调用IsTradingTime()做判断,不满足就直接return,一根K线只判断一次。这里用了Volume[0] == 1来确保只在当前Bar刚形成时执行一次,避免一根K线内重复开仓。

另外,代码里还加了一个检查:如果当前已有持仓,就不开新单。这是用OrdersTotal()遍历所有订单,看有没有同品种的持仓。虽然这个例子没写平仓逻辑,但框架搭好了,你可以在非交易时段里加上平仓或者清挂单的代码。这套框架虽然简单,但已经能应付大部分时段控制的需求了。

文章目录