MT4 自動止損腳本

@zgcwkj  2025年11月01日

分類:

代碼 其它 

MetaTrader 4 的 EA 代碼分享,對開倉的訂單自動追加止損

自動止損.mq4
需要打開自動交易功能
// 開倉自動止損EA.mq4
#property copyright "Copyright 2025."
#property link      "https://www.zgcwkj.com/"
#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