MQL5如何实现每小时仅交易一次的时间判断条件
MQL5实现每小时限交易1次的代码逻辑
核心思路非常简单,用整小时时间戳做标记比对即可,不需要复杂的时间函数嵌套,新手也能直接复用:
- 首先定义全局变量存储上一次成功交易所属的整小时时间戳,变量必须定义在所有函数外部,避免每次tick触发时变量值被重置:
datetime last_trade_hour = 0; - 时间比对逻辑的核心是计算当前小时的起始时间戳:1小时对应3600秒,用当前服务器时间对3600取余,就能得到当前小时已经流逝的秒数,用当前时间减去这个值,就得到本小时整点的时间戳,这个值每个小时只会变一次,跨天、跨月、跨年都不会重复,不会出现判断错误。
- 每次触发开仓信号时,先做时间间隔校验,只有当前整点时间戳和上一次记录的交易时间戳不一致时,才执行开仓操作,开仓成功后更新记录的时间戳即可。
完整可复用的代码片段如下:
// 全局变量,放在EA代码最顶部、所有函数外部 datetime last_trade_hour = 0; void OnTick() { // --- 这里是你原本的信号判断逻辑,比如满足金叉、突破条件等 bool open_signal = /* 替换成你自己写的开仓信号判断,返回true/false */; if(open_signal) { // 计算当前小时的整点时间戳 datetime current_hour = TimeCurrent() - (TimeCurrent() % 3600); // 校验本小时是否已经交易过 if(current_hour != last_trade_hour) { // 这里替换成你自己的OrderSend开仓逻辑 MqlTradeRequest request = {0}; MqlTradeResult result = {0}; // 以下request参数按你自己的策略修改即可 request.action = TRADE_ACTION_DEAL; request.symbol = _Symbol; request.volume = 0.1; request.type = ORDER_TYPE_BUY; request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); request.deviation = 10; request.magic = 12345; bool send_res = OrderSend(request, result); // 只有开仓成功才更新时间标记,避免下单失败也锁1小时 if(send_res && result.retcode == TRADE_RETCODE_DONE) { last_trade_hour = current_hour; Print("开仓成功,本小时不再允许新开交易"); } } else { Print("本小时已完成有效交易,跳过本次开仓信号"); } } }
新手常见踩坑提醒
- 不要直接用
Hour()返回的小时数值(即0-23的整数)做判断,否则每天同一小时的数值完全一致,会出现跨天判断失效的问题 - 如果需要同一个账户下多个品种、多个图表挂载的EA共用1小时交易限制,把
last_trade_hour换成MQL5全局缓存变量即可,写入用GlobalVariableSet("acc_last_trade_hour", current_hour),读取用GlobalVariableGet("acc_last_trade_hour"),不会出现单图表变量不互通的问题 - 不要在开仓前就更新时间标记,必须等订单确认成交后再更新,否则因为保证金不足、市场休市、滑点超限等原因下单失败时,会白白浪费一小时的交易额度
内容的提问来源于stack exchange,提问作者Bat Man
相关产品推荐
相关产品推荐

