保持敬畏之心
交易是一场持久战

​MQL4(28):封装添加/修改止损止盈函数

封装添加/修改止损止盈函数 (AddStopProfit)

为了进一步细化函数职责,我们将为现有订单添加或修改止损 (SL) 和止盈 (TP) 的操作也封装成一个独立的函数。这个函数尤其适用于配合那些为了兼容 ECN 而在下单时不设置 SL/TP 的 OpenBuyOrder / OpenSellOrder 函数使用。

设计要点:

  • 输入: 函数接收目标订单的票号 argTicket,以及已经过计算和验证的目标止损价 argStopLoss 和止盈价 argTakeProfit
  • 前提: 函数假设传入的 argStopLossargTakeProfit 价格已经是有效的(满足 MODE_STOPLEVEL 要求)。函数本身不执行价格验证。
  • 操作: 函数内部会选中订单,然后调用 OrderModify 来更新 SL 和 TP,同时保持订单的开仓价格和到期时间不变。
  • 返回值: 返回 OrderModify 操作的结果 (true 表示指令发送成功,false 表示失败或无需修改)。

函数定义:

/**
 * @brief 为指定的现有订单添加或修改止损和止盈。
 * 假设传入的 SL/TP 价格已经过验证。
 * @param argTicket       目标订单的订单号 (Ticket)
 * @param argStopLoss     新的止损价格 (0 或负数表示移除或不设置)
 * @param argTakeProfit   新的止盈价格 (0 或负数表示移除或不设置)
 * @return bool           true: 修改指令成功发送; false: 失败或无需修改
 */
bool AddStopProfit(int argTicket, double argStopLoss, double argTakeProfit)
{
    // 1. 如果传入的 SL 和 TP 都无效 (<=0), 则认为无需操作
    if (argStopLoss <= 0 && argTakeProfit <= 0) {
        Print("AddStopProfit: 无有效的 SL(<=0) 或 TP(<=0) 提供给订单 #", argTicket);
        return(false); // 返回 false 表示未执行有效修改
    }

    bool modifySuccess = false; // 初始化返回值

    // 2. 选中订单
    if (OrderSelect(argTicket, SELECT_BY_TICKET))
    {
        // 3. (可选优化) 检查传入值是否与当前值几乎相同,避免无效调用
        // if (MathAbs(argStopLoss - OrderStopLoss()) < Point*0.1 && MathAbs(argTakeProfit - OrderTakeProfit()) < Point*0.1) {
        //    Print("AddStopProfit: 新的 SL/TP 与当前值相同,无需修改订单 #", argTicket);
        //    return true; // 无需修改视为成功
        // }

        // 4. 等待交易环境 (假设 WaitForTradeContext 已定义)
        if (!WaitForTradeContext()) return(false);

        // 5. 调用 OrderModify 更新 SL/TP
        //    保持开仓价 (OrderOpenPrice()) 和 到期时间 (OrderExpiration()) 不变
        modifySuccess = OrderModify(argTicket, OrderOpenPrice(), argStopLoss, argTakeProfit,
                                   OrderExpiration(), // 传入当前到期时间以保持不变
                                   clrNONE);        // 不绘制修改箭头

        // 6. 处理修改结果
        if (!modifySuccess)
        {
            // 调用统一错误处理函数 (假设 HandleTradeError 已定义)
            HandleTradeError(StringFormat("AddStopProfit 修改订单 #%d", argTicket), GetLastError());
        }
        else
        {
            Print("成功发送 SL/TP 修改指令 for #", argTicket);
        }
    }
    // else { HandleTradeError(StringFormat("AddStopProfit: 无法选中订单 #%d", argTicket), 0); } // 可选:处理 OrderSelect 失败

    // 返回修改指令发送结果
    return(modifySuccess);
}

函数首先检查传入的 SL 和 TP 是否都无效(都小于等于 0)。如果都无效,则直接返回 false(表示未执行有效操作)。否则,它会选中订单,等待交易环境空闲,然后调用 OrderModify 来尝试更新止损和止盈。在 OrderModify 调用中,开仓价参数传入 OrderOpenPrice(),到期时间参数传入 OrderExpiration(),以确保这两项在修改 SL/TP 时保持不变。函数最后返回 OrderModify 的布尔结果,并内置了错误处理逻辑(建议封装)。这个函数设计上可以用于修改任何类型的活动订单(无论是市价单还是挂单)的 SL/TP。

赞(0)
未经允许不得转载:图道交易 » ​MQL4(28):封装添加/修改止损止盈函数
分享到