MT4 自动止损脚本

@zgcwkj  2025年11月01日

分类:

代码 其它 

MetaTrader 4 的 EA 代码分享,对开仓的订单自动追加止损

自动止损.mq4
需要打开自动交易功能
// 开仓自动止损EA.mq4
#property copyright "Copyright 2025."
#property link      "https://zgcwkj.cn/"
#property version   "1.00"
#property strict

// 输入参数(可在EA设置中调整)
input int    MagicNumber = 0;            // 管理的订单魔术数字
input double 止损点数 = 400;             // 固定止损点数
input bool   覆盖已有止损 = false;       // 是否覆盖订单已有的止损(false=只给无止损的订单设置)

// 初始化函数:打印启动信息
int OnInit()
{
   Print("=== 开仓自动止损EA启动 ===");
   Print("监控品种:", Symbol(), ",时间周期:", Period());
   Print("管理魔术数字:", MagicNumber, "(0=所有订单)");
   Print("止损点数:", 止损点数, "点,是否覆盖已有止损:", 覆盖已有止损 ? "是" : "否");
   return(INIT_SUCCEEDED);
}

// 实时监测:每 tick 检查订单,为符合条件的订单设置止损
void OnTick()
{
   // 遍历所有未平仓订单
   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         Print("订单选择失败(索引:", i, "),错误码:", GetLastError());
         continue;
      }
      
      // 过滤条件:当前品种 + 魔术数字匹配 + 多/空单
      if(OrderSymbol() != Symbol())
      {
         // 跳过非当前品种的订单(仅监控当前图表品种)
         continue;
      }
      if(OrderMagicNumber() != MagicNumber)
      {
         // 跳过魔术数字不匹配的订单
         continue;
      }
      if(OrderType() != OP_BUY && OrderType() != OP_SELL)
      {
         // 只处理多单和空单(跳过挂单等)
         continue;
      }
      
      // 检查是否需要设置(已有止损且不允许覆盖,则跳过)
      if(OrderStopLoss() != 0 && !覆盖已有止损)  // 存在止损
      {
         // Print("订单", OrderTicket(), "存在止损(", OrderStopLoss(), "),跳过处理");
         continue;
      }
      if(OrderTakeProfit() != 0 && !覆盖已有止损)  // 存在止盈
      {
         // Print("订单", OrderTicket(), "存在止盈(", OrderTakeProfit(), "),跳过处理");
         continue;
      }
      
      // 计算止损价格
      double openPrice = OrderOpenPrice();  // 开仓价格
      double stopLoss = 0;                  // 止损价格
      string orderType = (OrderType() == OP_BUY) ? "多单" : "空单";
      
      // 多单止损:开仓价 - 止损点数;空单止损:开仓价 + 止损点数
      if(OrderType() == OP_BUY)
      {
         stopLoss = openPrice - 止损点数 * Point;
      }
      else  // OP_SELL
      {
         stopLoss = openPrice + 止损点数 * Point;
      }
      // 标准化价格(对齐平台最小报价单位,避免价格无效)
      stopLoss = NormalizeDouble(stopLoss, Digits);
      
      // 打印开仓信息和止损计算日志
      // Print("\n--- 检测到订单需设置止损 ---");
      Print("订单号:", OrderTicket(), ",类型:", orderType);
      // Print("开仓时间:", TimeToString(OrderOpenTime(), TIME_DATE|TIME_SECONDS));
      // Print("开仓价格:", openPrice);
      // Print("止损点数:", 止损点数, "点,计算止损价:", stopLoss);
      
      // 修改订单设置止损
      bool modifySuccess = OrderModify(
         OrderTicket(),       // 订单号
         OrderOpenPrice(),    // 保持开仓价不变
         stopLoss,            // 新止损价
         OrderTakeProfit(),   // 保持止盈价不变(若有)
         0                    // 立即生效(无延迟)
      );
      
      // 打印设置结果日志
      if(modifySuccess)
      {
         Print("订单", OrderTicket(), "止损设置成功!最终止损价:", stopLoss);
      }
      else
      {
        Print("订单", OrderTicket(), "止损设置失败!错误码:", GetLastError());
        Print("失败可能原因:价格超出平台限制/网络延迟/订单已关闭");
      }
   }
}

// 销毁函数:打印停止信息
void OnDeinit(const int reason)
{
   Print("=== 开仓自动止损EA已停止 ===");
}


添加新评论

Top