MQL5如何实现单日仅开一单?现有校验方法失效求助
修复单日开仓限制代码的问题
你的代码未生效主要有两个核心问题:
问题1:未过滤开仓类型的订单
原代码遍历所有历史订单(包括平仓单),但我们只需要关注开仓单(买入/卖出)。如果先开仓再平仓,最后一条订单是平仓单,原代码会错误地将其计入判断,导致逻辑混乱。
问题2:用24小时窗口替代自然日判断
原代码通过计算时间差是否小于24小时来判断是否同天,但这不符合「当日」的需求——比如前一天23:00开仓,次日00:30尝试开仓,虽然间隔不足24小时,但已经是新的一天,应该允许开仓。
修正后的代码
bool IsOneDayPassedSinceLastDeal(string symbol) { datetime currentTime = TimeCurrent(); // 计算当日零点时间 datetime currentDayStart = currentTime - (TimeHour(currentTime)*3600 + TimeMinute(currentTime)*60 + TimeSecond(currentTime)); int totalDeals = HistoryDealsTotal(); if(totalDeals == 0) return true; // 从最新订单往前遍历 for(int i = totalDeals - 1; i >= 0; i--) { ulong dealTicket = HistoryDealGetTicket(i); if(dealTicket == INVALID_ORDER) continue; // 只处理当前品种的订单 string dealSymbol = HistoryDealGetString(dealTicket, DEAL_SYMBOL); if(dealSymbol != symbol) continue; // 只筛选开仓单(买入/卖出) ENUM_DEAL_TYPE dealType = (ENUM_DEAL_TYPE)HistoryDealGetInteger(dealTicket, DEAL_TYPE); if(dealType != DEAL_TYPE_BUY && dealType != DEAL_TYPE_SELL) continue; // 计算开仓单所属日期的零点时间 datetime dealTime = (datetime)HistoryDealGetInteger(dealTicket, DEAL_TIME); datetime dealDayStart = dealTime - (TimeHour(dealTime)*3600 + TimeMinute(dealTime)*60 + TimeSecond(dealTime)); // 开仓单与当前日期相同,返回false(不能开新仓) if(dealDayStart == currentDayStart) return false; // 找到第一个非当日的开仓单后直接终止循环(后续订单更早,无需再查) break; } // 当日无开仓记录,返回true(可以开新仓) return true; }
关键改动说明
- 筛选开仓单类型:通过
DEAL_TYPE判断,只处理DEAL_TYPE_BUY和DEAL_TYPE_SELL类型的订单,排除平仓等无关订单。 - 自然日判断逻辑:计算当日零点时间,对比开仓单所属日期的零点,确保判断的是同一个自然日,而非24小时窗口。
- 提前终止循环:从最新订单开始遍历,找到第一个符合条件的订单后立即退出循环,提升效率。
内容的提问来源于stack exchange,提问作者DIAAALDIN QOSA
相关产品推荐
相关产品推荐

