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

MQL4中RSI智能交易系统追踪止损失效问题求助

追踪止损失效的问题排查与修复方案

核心问题分析

你的EA追踪止损失效主要源于止损计算逻辑错误及细节处理疏漏,具体问题如下:

  • 利润计算逻辑错误:使用OrderProfit()(订单货币利润)计算点位差,而非直接用市场价格与开仓价的点位差值,完全偏离追踪止损的计算逻辑。
  • 追踪止损规则错误:原代码中trailingStopLevel和newStopLoss的计算公式不符合追踪止损的核心逻辑——多单止损应随价格上涨向上移动,空单止损应随价格下跌向下移动,且不能回退。
  • 订单遍历风险:正序遍历订单时,若订单状态变化(如平仓)会导致索引错位,遗漏部分订单。
  • OrderSend参数顺序错误:原代码中止损、止盈参数位置颠倒,导致初始止损未正确设置,进一步影响追踪止损触发。
  • 订单修改细节缺失:未标准化止损价格(不符合平台最小变动单位),且未区分多空单的修改颜色。

修复后的完整代码

// Define parameters for your EA outside of functions
input int takeProfit = 20;   // Take Profit value in pips
input int stopLoss = 50;     // Stop Loss value in pips
input int trailingStop = 50; // Trailing stop distance in pips

// Flag to track if a trade has been placed in the current tick
bool tradePlaced = false;

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    // Reset the tradePlaced flag at the beginning of each tick
    tradePlaced = false;

    // We create a string variable for the signal
    string signal = "";

    // Calculate the RSI value
    double RSIValue = iRSI(_Symbol, _Period, 14, PRICE_CLOSE, 0);

    // Declare take profit and stop loss variables
    double takeProfitLevel, stopLossLevel;

    // If it is above 70
    if (RSIValue > 70)
    {
        signal = "sell";
        takeProfitLevel = Bid - takeProfit * _Point;
        stopLossLevel = Bid + stopLoss * _Point;
    }

    // If it is below 30
    if (RSIValue < 30)
    {
        signal = "buy";
        takeProfitLevel = Ask + takeProfit * _Point;
        stopLossLevel = Ask - stopLoss * _Point;
    }

    // Buy or sell 10 Microlot based on the signal
    if (OrdersTotal() == 0 && !tradePlaced)
    {
        if (signal == "buy")
        {
            // 修正OrderSend参数顺序:止损、止盈位置调换
            int buyTicket = OrderSend(_Symbol, OP_BUY, 0.50, Ask, 3, stopLossLevel, takeProfitLevel, "Buy Order", 0, 0, Green);
            if (buyTicket > 0)
            {
                Print("Buy Order placed successfully. Ticket: ", buyTicket);
                tradePlaced = true; // Set the flag to true
            }
            else
            {
                Print("Error placing Buy Order. Error code: ", GetLastError());
            }
        }
        else if (signal == "sell")
        {
            // 修正OrderSend参数顺序:止损、止盈位置调换
            int sellTicket = OrderSend(_Symbol, OP_SELL, 0.50, Bid, 3, stopLossLevel, takeProfitLevel, "Sell Order", 0, 0, Red);
            if (sellTicket > 0)
            {
                Print("Sell Order placed successfully. Ticket: ", sellTicket);
                tradePlaced = true; // Set the flag to true
            }
            else
            {
                Print("Error placing Sell Order. Error code: ", GetLastError());
            }
        }
    }

    // Trailing stop logic
    if (OrdersTotal() > 0)
    {
        // 倒序遍历避免订单状态变化导致的索引错位
        for (int i = OrdersTotal() - 1; i >= 0; i--)
        {
            if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
            {
                // 仅处理当前品种的活跃市价单
                if (OrderSymbol() == _Symbol && (OrderType() == OP_BUY || OrderType() == OP_SELL))
                {
                    double openPrice = OrderOpenPrice();
                    double currentStopLoss = OrderStopLoss();
                    double newStopLoss = currentStopLoss;

                    if (OrderType() == OP_BUY)
                    {
                        // 多单追踪止损:当前Bid价减去止损点数,仅向上移动
                        double trailingLevel = Bid - trailingStop * _Point;
                        // 确保止损不低于初始止损,且不回退
                        if (trailingLevel > currentStopLoss && trailingLevel >= (openPrice - stopLoss * _Point))
                        {
                            newStopLoss = trailingLevel;
                        }
                    }
                    else if (OrderType() == OP_SELL)
                    {
                        // 空单追踪止损:当前Ask价加上止损点数,仅向下移动
                        double trailingLevel = Ask + trailingStop * _Point;
                        // 确保止损不高于初始止损,且不回退
                        if (trailingLevel < currentStopLoss && trailingLevel <= (openPrice + stopLoss * _Point))
                        {
                            newStopLoss = trailingLevel;
                        }
                    }

                    // 标准化止损价格,符合平台最小变动单位
                    newStopLoss = NormalizeDouble(newStopLoss, _Digits);

                    if (newStopLoss != currentStopLoss && newStopLoss != 0)
                    {
                        bool modifySuccess = OrderModify(OrderTicket(), OrderOpenPrice(), newStopLoss, OrderTakeProfit(), 0, 
                                                        OrderType() == OP_BUY ? Green : Red);
                        if (modifySuccess)
                        {
                            Print("Trailing Stop updated successfully. Ticket: ", OrderTicket(), " New SL: ", newStopLoss);
                        }
                        else
                        {
                            Print("Error updating Trailing Stop. Ticket: ", OrderTicket(), " Error code: ", GetLastError());
                        }
                    }
                }
            }
        }
    }

    // Chart output for the signal
    Comment("The current signal is: ", signal);
}

关键修复点说明

  1. 修正利润计算逻辑:移除错误的OrderProfit(),改用当前市场价格(Bid/Ask)直接计算追踪止损点位,符合追踪止损的核心逻辑。
  2. 调整追踪止损规则:
    • 多单:仅当Bid - trailingStop*_Point高于当前止损且不低于初始止损时,才更新止损(确保止损只向上移动,锁定利润)
    • 空单:仅当Ask + trailingStop*_Point低于当前止损且不高于初始止损时,才更新止损(确保止损只向下移动)
  3. 倒序遍历订单:避免正序遍历中订单状态变化导致的索引错位问题。
  4. 标准化止损价格:使用NormalizeDouble()确保止损价格符合平台最小变动单位要求,避免订单修改失败。
  5. 修正OrderSend参数顺序:将止损、止盈参数位置调换,确保初始止损、止盈正确设置。
  6. 区分订单修改颜色:多单用Green、空单用Red,直观区分订单类型。

内容的提问来源于stack exchange,提问作者Jesper Koch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:49:50