You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

关键改动说明

  1. 筛选开仓单类型:通过DEAL_TYPE判断,只处理DEAL_TYPE_BUY和DEAL_TYPE_SELL类型的订单,排除平仓等无关订单。
  2. 自然日判断逻辑:计算当日零点时间,对比开仓单所属日期的零点,确保判断的是同一个自然日,而非24小时窗口。
  3. 提前终止循环:从最新订单开始遍历,找到第一个符合条件的订单后立即退出循环,提升效率。

内容的提问来源于stack exchange,提问作者DIAAALDIN QOSA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 05:42:04