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
相关产品推荐
相关产品推荐

