摘要:本文详解MT4 EA移动止损策略,提供完整MQL4代码实现。通过设定启动盈利阈值与追踪点数,EA自动遍历持仓订单,仅在利润达标且方向有利时动态上移止损,有效锁定收益并规避回撤风险。代码包含盈利计算、单订单处理及批量遍历函数,逻辑清晰,可直接嵌入OnTick使用,帮助交易者实现自动化利润保护,提升风控效率。
我们在 MT4中写EA的时候,经常会用到移动止损的功能。
移动止损,可以让EA实时检测每一张订单的报价。当订单的收益不断扩大的时候。实时把止损的位置移动到新的位置,锁定我们的利润。
一般有两个参数我们可以自己设定:第1个是我们可以指定,只有当每张订单的利润超过多少个点位的时候,才去启动这个移动止损。第2个参数是移动止损的点数,也就是说我们的止损价总是和最新的报价保持多少个点的距离。当我们的利润超过了这个盈利点数的时候,止损就会移动。但是假如订单收益回撤的时候移动止损不会随之移动。这样就锁定了我们的收益同时又可以获得订单最大的利润。假如行情让收益开始回撤时最大的损失也就是打到止损,但是此时我们已经保存了我们大部分的订单收益。相反,如果行情让订单的收益不断扩大,那么因为我们的止损随着行情实时移动又可以在尽最大可能的情况下,收获订单的更多收益。
以下是移动止损的实现代码。放在这里供大家参考交流。
首先是把我们移动止损中所需要的参数,把它声明到代码的最顶端
//==== 输入参数 ====
input int TrailPips = 20; //移动止损追踪点数
input int StartTrailProfitPips = 15; //盈利达到多少点才启动移动止损
input int MagicNum = 12345; //魔术号
//全局变量:记录上一根收盘K线时间,判断新K线
datetime last_closed_bar_time = 0;
然后是写一段代码,检测每一张订单,他当前的收益点数。这样我们就可以根据当前收益点数是否满足来决定要不要启动移动止损。
//+------------------------------------------------------------------+
//| 计算订单当前浮动盈利点数 |
//+------------------------------------------------------------------+
double GetOrderProfitPips(int ticket)
{
if(!OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES))
return 0.0;
double point = _Point;
if(_Digits == 5 || _Digits == 3) point *= 10;
double profitPips = 0;
if(OrderType() == OP_BUY)
{
profitPips = (Bid - OrderOpenPrice()) / point;
}
else if(OrderType() == OP_SELL)
{
profitPips = (OrderOpenPrice() - Ask) / point;
}
return profitPips;
}
接下来给出的是移动止损的函数,这个函数放在任何一个策略里面都是可以执行的。
//+------------------------------------------------------------------+
//| 单个订单移动止损逻辑 |
//+------------------------------------------------------------------+
void TrailStopSingleOrder(int ticket)
{
if(!OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES))
{
Print("OrderSelect失败! Ticket:",ticket," Err:",GetLastError());
return;
}
//过滤条件:品种 + 魔术号
if(OrderSymbol() != _Symbol || OrderMagicNumber() != MagicNum)
return;
//计算当前盈利点数
double currentProfitPips = GetOrderProfitPips(ticket);
//盈利不足阈值 → 不启动移动止损,直接返回
if(currentProfitPips < StartTrailProfitPips)
{
return;
}
double point = _Point;
if(_Digits == 5 || _Digits == 3) point *= 10;
double trail_distance = TrailPips * point;
double bid = Bid;
double ask = Ask;
double new_sl = 0.0;
bool need_modify = false;
if(OrderType() == OP_BUY)
{
new_sl = bid - trail_distance;
//多头:止损只能向上移动(向盈利方向)
if(new_sl > OrderStopLoss())
need_modify = true;
}
else if(OrderType() == OP_SELL)
{
new_sl = ask + trail_distance;
//空头:止损只能向下移动
if(new_sl < OrderStopLoss())
need_modify = true;
}
if(need_modify && new_sl > 0)
{
bool res = OrderModify(ticket, OrderOpenPrice(), new_sl, OrderTakeProfit(), 0, Green);
if(res)
{
Print("订单",ticket,"移动止损执行成功,盈利点数:",currentProfitPips," 新SL=",new_sl);
}
else
{
Print("订单",ticket,"修改止损失败!错误码:",GetLastError());
}
}
}
上面我们给出的移动止损函数,只是对一张订单执行的操作。一般在实际交易当中,我们需要遍历所有的当前持仓订单,所以我们还需要一个便利订单执行移动止损的函数。
//+------------------------------------------------------------------+
//| 遍历全部持仓订单 |
//+------------------------------------------------------------------+
void RunAllTrailingStop()
{
for(int i=0; i<OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
int ticket = OrderTicket();
TrailStopSingleOrder(ticket);
}
}
}
有了以上这四个函数,基本上你在EA当中移动止损所需要的全部部件就备齐了。
最后,还要做的就是在你的OnTick()函数当中写几行简单的代码,就可以清晰的实现移动止损了。
//+------------------------------------------------------------------+
//| 主循环 OnTick |
//+------------------------------------------------------------------+
void OnTick()
{
Print("==== 新K线形成,开始扫描订单执行移动止损 ====");
RunAllTrailingStop();
}
【关于作者】
王老师,吉宽科技创始人,专注量化交易和AI应用。
官网:吉宽科技 - 多元化科技创新企业
量化商城:EA量化商城 - MT4/MT5 EA智能交易系统购买平台
文章评论
0 条评论请登录后发表评论