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

MQL4(34):风险管理 - 盈亏平衡止损

盈亏平衡止损

除了追踪止损外,另一种常用的订单风险管理技术是盈亏平衡止损 。它的核心逻辑相对简单:当一笔订单的浮动盈利达到或超过预先设定的一个最小盈利点数后,就自动将该订单的止损位移动到其开仓价格。

这样做的目的是,一旦交易向有利方向发展并达到一定程度,就确保这笔交易至少不会亏损(理论上是这样,实际结果可能受点差、滑点或手续费影响)。盈亏平衡止损通常是一个一次性的操作——一旦止损被移动到开仓价,它通常会固定在那里,除非后续被其他逻辑(例如追踪止损)再次修改。它是一个独立于初始止损设置和追踪止损的功能,但可以与它们结合使用(例如,达到盈亏平衡后再启动追踪)。

首先,定义一个外部输入参数,让用户设置触发盈亏平衡所需的最小盈利点数:

// 输入参数
extern double BreakEvenProfitPips = 25; // 达到多少 Pips 盈利后将止损移至开仓价 (设为0或负数则禁用)

然后,在 OnTick() 函数的订单遍历循环中,为符合条件的订单(例如买单)添加检查和修改逻辑。强烈建议将此逻辑也封装成一个独立的函数,例如MoveToBreakEvenIfProfitReached(),以保持 OnTick() 函数的简洁和模块化。

// --- 在 OnTick() 函数的订单遍历循环内 ---
// (假设 MagicNumber, g_onePipValue, PipPoint(), WaitForTradeContext(), HandleTradeError() 等已定义或包含)
int total = OrdersTotal();
for (int i = total-1; i >=0 ; i--)
{
    if (OrderSelect(i, SELECT_BY_POS) == true) // 选中订单
    {
        // --- 仅处理由本 EA 管理的【买入市价单】 ---
        if (OrderSymbol() == Symbol() &&
            OrderMagicNumber() == MagicNumber &&
            OrderType() == OP_BUY)
        {
            // --- 执行买单的盈亏平衡止损逻辑 ---
            if (BreakEvenProfitPips > 0) // 检查是否启用了盈亏平衡功能
            {
                // 1. 获取所需信息
                double openPrice = OrderOpenPrice();
                double currentStopLoss = OrderStopLoss();
                RefreshRates(); // 获取最新价格
                double currentBid = MarketInfo(Symbol(), MODE_BID);
                // 2. 计算【当前盈利】对应的价格差
                double currentProfitPriceDiff = currentBid - openPrice;
                // 3. 计算【最小盈利阈值】对应的价格差
                double minProfitPriceThreshold = BreakEvenProfitPips * PipPoint(Symbol()); // 需要 PipPoint 函数
                // 4. 【核心判断条件】: 同时满足以下条件才执行移动
                //    a) 当前盈利已达到或超过最小盈利阈值
                //    b) 当前止损【还未被精确设置到】开仓价 (避免重复无效修改)
                if (currentProfitPriceDiff >= minProfitPriceThreshold && // 条件 a: 盈利达标
                    MathAbs(currentStopLoss - openPrice) > Point*0.1 ) // 条件 b: 当前 SL 不是开仓价 (允许浮点误差)
                {
                    // 5. 目标止损价 = 开仓价
                    double breakEvenStopPrice = openPrice;
                    // (可选:为覆盖成本,可设为 openPrice + N*Point)
                    breakEvenStopPrice = NormalizeDouble(breakEvenStopPrice, Digits); // 规范化
                    // 6. (重要) 理论上开仓价本身满足 StopLevel,但严格可验证
                    // if (!VerifyBelowStopLevel(Symbol(), breakEvenStopPrice)) continue;
                    // 7. 等待环境空间并修改订单
                    if (!WaitForTradeContext()) continue; // 等待失败则跳过
                    bool modified = OrderModify(OrderTicket(),
                                                openPrice,
                                                breakEvenStopPrice, // 新止损设为开仓价
                                                OrderTakeProfit(),
                                                OrderExpiration(),
                                                clrNONE); // 保持TP/Expiration
                    // 8. 错误处理
                    if (!modified) {
                        HandleTradeError(StringFormat("Break Even (Buy) 修改 #%d", OrderTicket()), GetLastError());
                    } else {
                        Print("成功将买单 #", OrderTicket(), " 止损移动到盈亏平衡点: ", breakEvenStopPrice);
                    }
                } // end if (满足移动条件)
            } // end if (启用盈亏平衡)
        } // end if (是目标的买单)
         // --- 此处可添加对卖单的盈亏平衡逻辑 (OrderType == OP_SELL) ---
         // ... 盈利判断: openPrice - currentAsk >= minProfitPriceThreshold ...
         // ... 目标止损: openPrice ...
         // ... 避免重复: MathAbs(currentStopLoss - openPrice) > Point*0.1 ...
         // ... 验证: VerifyAboveStopLevel ...
    } // end if OrderSelect
}
  • 代码解释:
    • 循环遍历订单,筛选出目标买单。
    • 检查是否启用了盈亏平衡功能 (BreakEvenProfitPips > 0)。
    • 计算当前盈利的价格差 currentProfitPriceDiff (Bid - openPrice)。
    • 计算最小盈利阈值的价格差 minProfitPriceThreshold (BreakEvenProfitPips * PipPoint)。
    • 核心判断: 只有当 currentProfitPriceDiff >= minProfitPriceThreshold (盈利达标) 并且 MathAbs(currentStopLoss - openPrice) > Point*0.1 (当前止损还不是开仓价,使用 MathAbs 比较浮点数以允许微小误差),才满足执行盈亏平衡操作的条件。后者是为了防止在止损已经被移到开仓价后,每个 tick 还重复发送无效的 OrderModify 请求(会导致 Error 1)。
    • 执行修改: 如果条件满足,将目标止损价设为开仓价 openPrice (可选地,可以加上一两个点作为缓冲以覆盖可能的交易成本),然后等待交易上下文,最后调用 OrderModify 将订单的止损更新为 openPrice
    • 错误处理: 对 OrderModify 的结果进行处理。

总结: 通过在订单循环中加入盈亏平衡止损的逻辑,可以在订单达到一定盈利后自动将风险移除(回到成本价),是一种简单且被广泛应用的风险管理技巧。虽然原文未将其封装成函数,但为了代码的整洁性和复用性,推荐您在实际开发中这样做。

赞(0)
未经允许不得转载:图道交易 » MQL4(34):风险管理 - 盈亏平衡止损
分享到