MT5 Trailing Stoploss设置失效及阶梯式移动止损需求技术问询
移动止损逻辑修正方案
问题需求
我一直在尝试设置一个比当前价格高10点的移动止损,但似乎无法正常工作。我希望它首先在盈利达到15点后,将止损调整至入场价上方5点,之后再逐步向上调整。
原代码
void ApplyTrailingStop(string symbol, int magicNumber, double stopLoss) { static int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS); // trailing from close prices double buyStopLoss = NormalizeDouble(SymbolInfoDouble(symbol, SYMBOL_BID)-stopLoss, digits); double sellStopLoss = NormalizeDouble(SymbolInfoDouble(symbol, SYMBOL_ASK)+stopLoss, digits); int count=PositionsTotal(); for (int i=count-1; i>=0; i--) { ulong ticket = PositionGetTicket(i); if (ticket>0) { if (PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_MAGIC)==InpMagicnumber) { if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY && buyStopLoss>PositionGetDouble(POSITION_PRICE_OPEN) && (PositionGetDouble(POSITION_SL)==0 || buyStopLoss>PositionGetDouble(POSITION_SL))) { trade.PositionModify(ticket, buyStopLoss, PositionGetDouble(POSITION_TP)); } else if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL && sellStopLoss<PositionGetDouble(POSITION_PRICE_OPEN) && (PositionGetDouble(POSITION_SL)==0 || sellStopLoss<PositionGetDouble(POSITION_SL))) { trade.PositionModify(ticket, sellStopLoss, PositionGetDouble(POSITION_TP)); } } } } }
问题分析
原代码未区分两个核心逻辑阶段:
- 盈利未达15点时,不触发任何止损调整
- 盈利达标后,先将止损拉至入场价上方5点,再按10点间距追踪价格上行
同时原代码直接用外部传入的stopLoss计算止损价,没有实现分阶段的条件控制。
修正后的代码
void ApplyTrailingStop(string symbol, int magicNumber) { static int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS); // 定义核心参数:触发止损调整的盈利点数、初始止损偏移、追踪止损步长 const double triggerProfit = 15 * SymbolInfoDouble(symbol, SYMBOL_POINT); const double initialSlOffset = 5 * SymbolInfoDouble(symbol, SYMBOL_POINT); const double trailingStep = 10 * SymbolInfoDouble(symbol, SYMBOL_POINT); int count = PositionsTotal(); for(int i = count - 1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); if(ticket <= 0) continue; if(PositionGetString(POSITION_SYMBOL) != symbol || PositionGetInteger(POSITION_MAGIC) != magicNumber) continue; double entryPrice = PositionGetDouble(POSITION_PRICE_OPEN); double currentSl = PositionGetDouble(POSITION_SL); double bid = SymbolInfoDouble(symbol, SYMBOL_BID); double ask = SymbolInfoDouble(symbol, SYMBOL_ASK); // 多单逻辑处理 if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { double currentProfit = bid - entryPrice; // 盈利未达触发阈值,不调整止损 if(currentProfit < triggerProfit) continue; double newSl = 0.0; // 首次触发:将止损设为入场价上方5点 if(currentSl == 0) { newSl = NormalizeDouble(entryPrice + initialSlOffset, digits); } else { // 追踪止损:按当前买价减10点计算,且仅当新止损高于现有止损时调整 newSl = NormalizeDouble(bid - trailingStep, digits); if(newSl <= currentSl) continue; } // 确保止损不低于入场价,锁定最低盈利 newSl = MathMax(newSl, entryPrice); trade.PositionModify(ticket, newSl, PositionGetDouble(POSITION_TP)); } // 空单逻辑处理(与多单对称) else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) { double currentProfit = entryPrice - ask; if(currentProfit < triggerProfit) continue; double newSl = 0.0; if(currentSl == 0) { newSl = NormalizeDouble(entryPrice - initialSlOffset, digits); } else { newSl = NormalizeDouble(ask + trailingStep, digits); if(newSl >= currentSl) continue; } newSl = MathMin(newSl, entryPrice); trade.PositionModify(ticket, newSl, PositionGetDouble(POSITION_TP)); } } }
关键逻辑说明
- 参数固化:在函数内直接定义触发盈利、初始止损偏移、追踪步长,避免外部参数混淆
- 阶段控制:明确区分“盈利达标前不操作”“首次达标设初始止损”“后续追踪调整”三个阶段
- 单向调整:确保止损只会向盈利方向移动,不会反向回撤
- 边界防护:用
MathMax/MathMin保证止损不会跌破/涨破入场价,锁定最低盈利空间
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

