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

MQL4代码追踪止损(Trailing Stop Loss)无法及时移动问题排查

问题修复方案

1. 修复做空止损函数的代码块缩进错误

selltrailingStopLoss函数中,OrderModify语句未被包含在条件判断的代码块内,导致无论订单是否匹配做空类型,都会执行修改操作,甚至可能修改错误订单。同时原代码的条件判断后缺少大括号包裹执行逻辑。

修改后的selltrailingStopLoss函数:

void selltrailingStopLoss()
{
    double HighValue = gettingRecentHigh();
    double LowValue = gettingRecentLow();
    // 遍历所有订单
    for(int b = OrdersTotal()-1; b>=0; b--)
    {
        // 选中当前订单
        if(OrderSelect(b,SELECT_BY_POS,MODE_TRADES))
        {
            // 检查订单品种是否匹配当前图表
            if(OrderSymbol() == _Symbol)
            {
                // 确认是做空订单
                if(OrderType() == OP_SELL)
                {
                    // 检查止损是否不等于目标高位值
                    if(NormalizeDouble(OrderStopLoss(), Digits) != NormalizeDouble(HighValue, Digits))
                    {
                        Alert("SELL WORKING");
                        // 修改止损
                        bool modifyResult = OrderModify(
                            OrderTicket(),
                            OrderOpenPrice(),
                            HighValue,
                            OrderTakeProfit(),
                            0,
                            Red
                        );
                        // 可选:添加修改失败日志
                        if(!modifyResult) Print("修改做空止损失败,错误码:",GetLastError());
                    }
                }
            }
        }
    }
}

2. 做多止损添加最小止损距离校验

平台要求止损必须与当前价格保持最小距离(minStopLossLevel),原代码直接将止损设为LowValue,如果该值与买入价的距离小于平台要求,会被平台自动调整到符合要求的最低位置,导致实际止损低于预期的红色线。

修改buyTrailingStopLoss函数中的止损计算逻辑:

void buyTrailingStopLoss()
{
    double HighValue = gettingRecentHigh();
    double LowValue = gettingRecentLow();
    // 遍历所有订单
    for(int a = OrdersTotal()-1; a>=0; a--)
    {
        if(OrderSelect(a,SELECT_BY_POS,MODE_TRADES))
        {
            if(OrderSymbol() == _Symbol)
            {
                if(OrderType() == OP_BUY)
                {
                    // 计算符合平台要求的止损价:不能低于买入价减去最小止损距离
                    double validStopLoss = MathMax(LowValue, OrderOpenPrice() - minStopLossLevel);
                    // 用NormalizeDouble避免浮点精度问题导致的无效修改
                    if(NormalizeDouble(OrderStopLoss(), Digits) != NormalizeDouble(validStopLoss, Digits))
                    {
                        bool modifyResult = OrderModify(
                            OrderTicket(),
                            OrderOpenPrice(),
                            validStopLoss,
                            OrderTakeProfit(),
                            0,
                            Red
                        );
                        if(!modifyResult) Print("修改做多止损失败,错误码:",GetLastError());
                    }
                }
            }
        }
    }
}

3. 更新全局价格数据到OnTick函数

原代码中bidPrice、askPrice等价格变量仅在初始化时赋值,不会随行情更新,导致gettingPriceData显示的价格过时,也可能影响订单判断逻辑。将这些变量的更新移到OnTick中:

void OnTick()
{
    // 每次Tick更新最新价格数据
    bidPrice = MarketInfo(_Symbol, MODE_BID);
    askPrice = MarketInfo(_Symbol, MODE_ASK);
    priceDifferece = askPrice - bidPrice;
    
    gettingPriceData();
    creatingLines();
    placeOrder();
}

同时删除全局变量的初始化赋值,改为仅声明:

double Lots = 0.01;
double minStopLossLevel = MarketInfo(_Symbol, MODE_STOPLEVEL) * Point;
double bidPrice; // 仅声明,不初始化
double askPrice;
double priceDifferece;

4. 可选:优化止损修改的有效性判断

为避免无效的止损修改操作,可在修改前添加规则校验:

  • 做多订单:止损必须低于买入价,且与买入价的距离不小于minStopLossLevel
  • 做空订单:止损必须高于卖出价,且与卖出价的距离不小于minStopLossLevel

示例(在buyTrailingStopLoss的止损修改前添加):

// 检查有效止损是否符合做多规则
if(validStopLoss < OrderOpenPrice() && (OrderOpenPrice() - validStopLoss) >= minStopLossLevel)
{
    // 执行OrderModify操作
}

内容的提问来源于stack exchange,提问作者Hari prasath

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 21:40:04