2025年10月27日 星期一

MT5 EA交易策略開發教學[19]

核心策略概述 (商品 NAS100)
這是一個基於技術指標的趨勢突破與逆勢交易策略。策略整合MACD背離分析、CDP逆勢指標、ADX趨勢強度等多項技術指標來識別進場機會,並採用嚴格的風險控制與交易時段管理。

風險控制
資金風控門檻: 帳戶餘額 < 資金風控時停止所有交易
點差控制: 進場前檢查 SP < 商品平均點差 * Point()

交易限制
每日進場次數: 限制 < 1次(EntriesToday(MagicNumber,Symbol()) < 1)
平倉冷卻期: 距離上次出場至少2根K棒(`BarSinceExit > 1`)
K棒控制: 同一根K棒不重複進場(`BarNumber != OrderBarNo`)

進出場策略
多單進場條件
LE_Cond = (High[1] == Highest_OHLC(10日) && Close[1] > Close[2]);
條件分析:
1. 創新高突破: 前一根K棒最高價 = 最近10日最高價
2. 收盤強勢: 前一根收盤價 > 前二根收盤價(確認突破有效性)

進場執行:
方式: 市價單買入(`Buy_at_MARKET`)
前置條件: 
  - 空手狀態(多單部位() == 0 && 空單部位() == 0)
  - 點差合理(SP < 商品平均點差*Point())
  - 今日未進場(EntriesToday < 1)
  - 平倉冷卻期已過(BarSinceExit > 1)
  - 不同K棒(BarNumber != OrderBarNo)

空單進場條件
SE_Cond = (Close[1] < CDP && Close[1] < NL && a_ADX[1] > a_ADX[2]);
條件分析:
1. 跌破CDP中心: 收盤價 < CDP(逆勢指標的中心軸)
2. 跌破近低值: 收盤價 < NL(CDP系統的近低值)
3. *趨勢增強: ADX上升(a_ADX[1] > a_ADX[2]),確認下跌趨勢強度增加

進場執行:
方式: 市價單賣出(`Short_at_MARKET`)
前置條件: 
  - 空手狀態(多單部位() == 0 && 空單部位() == 0)
  - 點差合理(SP < 商品平均點差*Point())
  - 今日未進場(EntriesToday < 1)
  - 平倉冷卻期已過(BarSinceExit > 1)
  - 不同K棒(BarNumber != OrderBarNo)

//+------------------------------------------------------------------+
//| MT5 自動交易程式 (Expert Advisor)                                                 
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>                                             // 引入 MT5 交易函數庫
#include <MagicMT5_函數庫V2.mqh>                            // 引入自定義函數庫

ENUM_TIMEFRAMES 時間週期 = PERIOD_M6; // 主要分析時間框架(6分鐘) ENUM_TIMEFRAMES 時間框架 = PERIOD_H1; // 相對大週期(1 小時)

//+------------------------------------------------------------------+
//| EA 初始化函數 - 當 EA 載入到圖表時執行一次                         
//+------------------------------------------------------------------+
int OnInit()
  {
   // 記錄 EA 載入的時間
   LoadEA = TimeCurrent();
   
   // 顯示交易品種的最小交易手數和點值資訊
   Alert(" 最小手數=",string(SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MIN))," point=",string(Point())) ;
   
   // 顯示合約規格和每跳點的美元價值
   Alert(" 合約規格=",string(SymbolInfoDouble(Symbol(),SYMBOL_TRADE_CONTRACT_SIZE))," 1 跳點可換美元 = ",string(SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE))) ;

   return(INIT_SUCCEEDED); // 返回初始化成功
  }

//+------------------------------------------------------------------+
//| OnTick 函數 - 每次價格變動時執行                                 
//+------------------------------------------------------------------+
void OnTick()
  {
   //+------------------------------------------------------------------+
   //| 資金風控檢查 - 如果帳戶餘額低於設定值則停止交易                  
   //+------------------------------------------------------------------+
   if(AccountInfoDouble(ACCOUNT_BALANCE) < 資金風控)
     {
      Alert("**********  資金不足 *************");
      return; // 資金不足時直接返回,不執行任何交易邏輯
     }

   //+------------------------------------------------------------------+
   //| K 棒計數器與新 K 棒判斷                                            
   //+------------------------------------------------------------------+
   // 計算從 EA 載入到現在經過了多少根 K 棒
   BarNumber = iBarShift(Symbol(),時間週期,LoadEA);
   
   // 計算從上次平倉到現在經過了多少根 K 棒
   BarSinceExit = BarNumber-CloseOrderNo ;
   
   // 判斷是否為新的第一根 K 棒(用於開盤時的初始化交易)
   if((BarNumber == 1 && BarNumber != JudgeNo))
     {
      // 執行市價多單進場並立即平倉(可能是測試或初始化用途)
      多單進場單號 = Buy_at_MARKET(Symbol(),Lots,0,0,"1st_K",MagicNumber) ;
      LX_CloseByTicket(多單進場單號,Lots) ;
      
      // 執行市價空單進場並立即平倉
      空單進場單號 = Short_at_MARKET(Symbol(),Lots,0,0,"1st_K",MagicNumber) ;
      SX_CloseByTicket(空單進場單號,Lots) ;
      
      // 更新平倉 K 棒編號
      CloseOrderNo =  iBarShift(Symbol(),時間週期,LoadEA);
      
      // 計算快慢均線週期(取較小值和較大值)
      FastSma = MathMin(LenA1, LenB1);
      SlowSma = MathMax(LenA1, LenB1);
     }

   //+------------------------------------------------------------------+
   //| 新 K 棒時更新指標與交易時段                                          
   //+------------------------------------------------------------------+
   if(BarNumber != JudgeNo)
     {
      換K棒();           // 更新所有指標、OHLC 數據
      交易時段賦值();    // 判斷當前是否在允許交易的時段
     }

   //+------------------------------------------------------------------+
   //| 更新市場報價與帳戶資訊                                               
   //+------------------------------------------------------------------+
   Ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);                    // 當前賣出價(做多時的成交價)
   Bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);                    // 當前買入價(做空時的成交價)
   AccountBalance=AccountInfoDouble(ACCOUNT_BALANCE);             // 帳戶餘額
   Tickvalue=SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE); // 每跳點的價值
   SP = NormalizeDouble(MathAbs(Ask-Bid),Digits()) ;             // 當前點差

   //+------------------------------------------------------------------+
   //| 動態計算交易手數                                                  
   //+------------------------------------------------------------------+
   if(動態計算手數 == true)
     {
      // 根據風險百分比、帳戶餘額和停損點數動態計算手數
      Lots = get_dynamic_lot_size(是否偶數單,Symbol(),風險百分比,AccountBalance,SL) ;
      
      // 限制手數在 0.01 到 0.3 之間
      Lots = MathMin(0.3,MathMax(0.01,Lots)) ;
     }

   //+------------------------------------------------------------------+
   //| 交易時段檢查 - 只在允許的時段內執行進場邏輯                          
   //+------------------------------------------------------------------+
   if(允許交易時段 == true)
     {
      //+------------------------------------------------------------------+
      //| 多單進場邏輯                                                      
      //+------------------------------------------------------------------+
      set_BuyCondition(); // 設定多單進場條件
      
      // 多單進場條件:
      // 1. 滿足多單進場條件(LE_Cond)
      // 2. 點差小於設定的平均點差
      // 3. 最近 6 筆交易內有空單平倉(表示市場可能反轉)
      if(LE_Cond == true && SP < NormalizeDouble(商品平均點差*Point(),Digits()) && 最近幾筆內有空單平倉(Symbol(),6) == true)
        {
         // 確保當前為空手狀態且不在同一根 K 棒重複進場
         if(多單部位() == 0 && 空單部位() == 0 && BarNumber != OrderBarNo)
           {
            // 確保距離上次出場至少 2 根 K 棒,且當日進場次數少於 1 次
            if(BarSinceExit > 1 && EntriesToday(MagicNumber,Symbol()) < 1)
              {

                  // 執行市價多單進場
           多單進場單號 = Buy_at_MARKET(Symbol(),Lots,TP,SL,"BUY MARKET",MagicNumber) ;
                  
                  // 記錄進場的 K 棒編號,避免同一根 K 棒重複進場
                  OrderBarNo = iBarShift(Symbol(),時間週期,LoadEA);

              }
           }
        }
        
      //+------------------------------------------------------------------+
      //| 空單進場邏輯                                                       
      //+------------------------------------------------------------------+
      set_ShortCondition() ; // 設定空單進場條件
      
      // 空單進場條件:
      // 1. 滿足空單進場條件(SE_Cond)
      // 2. 點差小於設定的平均點差
      if(SE_Cond == true && SP < NormalizeDouble(商品平均點差*Point(),Digits()))
        {
         // 確保當前為空手狀態且不在同一根 K 棒重複進場
         if(多單部位() == 0 && 空單部位() == 0 && BarNumber != OrderBarNo)
           {
            // 確保距離上次出場至少 2 根 K 棒,且當日進場次數少於 1 次
            if(BarSinceExit > 1 && EntriesToday(MagicNumber,Symbol()) < 1)
              {

                  // 執行市價空單進場
                 空單進場單號 = Short_at_MARKET(Symbol(),Lots,TP,SL,"Short Market",MagicNumber) ;
                  
                  // 記錄進場的 K 棒編號
                  OrderBarNo = iBarShift(Symbol(),時間週期,LoadEA);
                 }              
           }
        }
     } // end of 允許交易時段 == true

   //+------------------------------------------------------------------+
   //| 出場邏輯 - 不受交易時段限制,任何時候都可以停損停利                    
   //+------------------------------------------------------------------+
   交易時段外也可停損停利();
   
   // 更新判斷用的 K 棒編號,用於下次迴圈比對
   JudgeNo = iBarShift(Symbol(),時間週期,LoadEA);

  } // end of onTick

//+------------------------------------------------------------------+
//| 自訂函數庫                                                        
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| 函數: 多單部位                                                    
//| 功能: 回傳當前多單(買單)的持倉數量                                
//+------------------------------------------------------------------+
int 多單部位()
  {
   int count;
   // 取得指定品種、魔術碼的多單數量
   count = get_TradeCounts(Symbol(), MagicNumber,POSITION_TYPE_BUY) ;
   return count ;
  }

//+------------------------------------------------------------------+
//| 函數: 空單部位                                                 
//| 功能: 回傳當前空單(賣單)的持倉數量                              
//+------------------------------------------------------------------+
int 空單部位()
  {
   int count;
   // 取得指定品種、魔術碼的空單數量
   count = get_TradeCounts(Symbol(), MagicNumber,POSITION_TYPE_SELL) ;
   return count ;
  }

//+------------------------------------------------------------------+
//| 函數: 換K棒                                                      
//| 功能: 當新 K 棒形成時,更新所有指標、刪除掛單、計算技術指標            
//+------------------------------------------------------------------+
void 換K棒()
  {
     
   // 設定 K 棒數據陣列為序列模式(索引 0 為最新 K 棒)
   Set_OHLC_Bar_Series();
   
   // 設定日線數據陣列為序列模式
   Set_OHLC_Day_Series();
   
   // 取得最近 30 根 K 棒的 OHLC 數據
   Get_OHLC_Bar(30) ;
   
   // 取得最近 15 根日線的 OHLC 數據
   Get_OHLC_Day(15) ;
   
   // 計算 MACD 指標
   set_MACD();
   
   // 計算 CDP 指標(逆勢操作指標)
   set_CDP();
   
   // 計算固定週期的高低點
   FixBarHL();
   
   // 計算 ADX 指標(趨勢強度指標)
   set_ADX();

   // 計算最近 5 日的平均波動範圍
   Day5Range = ((HighD[1] - LowD[1])+(HighD[2] - LowD[2])+(HighD[3] - LowD[3])+(HighD[4] - LowD[4])+(HighD[5] - LowD[5]))/5;
  }

//+------------------------------------------------------------------+
//| 函數: 交易時段賦值                                                  |
//| 功能: 根據當前時間判斷是否在允許交易的時段內                           |
//+------------------------------------------------------------------+
void 交易時段賦值()
  {
   // 交易時段編號 11: 允許在 14:00 到次日 06:00 之間交易
      允許交易時段 = (getTM_hour(TimeCurrent()) >= 14 || getTM_hour(TimeCurrent()) < 6) ;
  }

//+------------------------------------------------------------------+
//| 函數: 交易時段外也可停損停利                                         |
//| 功能: 不論是否在交易時段,都執行停損停利邏輯                            |
//+------------------------------------------------------------------+
void 交易時段外也可停損停利()
  {
   //+------------------------------------------------------------------+
   //| 多單出場邏輯                                                       |
   //+------------------------------------------------------------------+
   if(多單部位() > 0)
     {
      double 多單最小停利 = 0.0;
      bool LX_MinPF = false ;
      
      // 取得多單進場價格
      多單進場價格 = LE_EntryPrice(MagicNumber,多單進場單號);
      
      // 計算多單最小停利價格(進場價 + 3 倍點差)
      多單最小停利 = NormalizeDouble(多單進場價格 + SP*3,Digits()) ;
      
      // 判斷是否達到最小停利
      LX_MinPF = Bid > 多單最小停利 ;
      
      // 計算多單停利價格(進場價 + 停利點數)
      多單停利價格 = NormalizeDouble(多單進場價格 + TP * Point(),Digits()) ;
      
      // 計算多單停損價格(進場價 - 停損點數)
      多單停損價格 = NormalizeDouble(多單進場價格 - SL * Point(),Digits()) ;

      // 1. 達到最小停利且空單進場條件成立(反向訊號)
      // 2. 或價格跌破停損價(前一根收盤在停損價之上,現在跌破)

         LX_Cond = ((LX_MinPF == true && SE_Cond) || (Close[1] >= 多單停損價格 && Bid < 多單停損價格)) ;

      // 執行多單平倉
      // 條件: 出場條件成立 && 不在同一根 K 棒重複平倉 && 持倉至少 1 根 K 棒
      if(LX_Cond == true && BarNumber != CloseOrderNo && LE_BarsSinceEntry(MagicNumber,多單進場單號,時間週期) > 0)
        {
         // 平倉指定單號的多單
         LX_CloseByTicket(多單進場單號,Lots) ;

         // 如果全部多單已平倉,記錄平倉的 K 棒編號
         if(多單部位() == 0)
           {
            CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA) ;
           }
        }
     } // end of 多單部位() > 0

   //+------------------------------------------------------------------+
   //| 空單出場邏輯                                                       |
   //+------------------------------------------------------------------+
   if(空單部位() > 0)
     {
      double 空單最小停利 = 0.0;
      bool SX_MinPF = false ;
      
      // 取得空單進場價格
      空單進場價格 = SE_EntryPrice(MagicNumber,空單進場單號);
      
      // 計算空單最小停利價格(進場價 - 3 倍點差)
      空單最小停利 = NormalizeDouble(空單進場價格 - SP*3,Digits()) ;
      
      // 判斷是否達到最小停利
      SX_MinPF = Ask < 空單最小停利 ;
      
      // 計算空單停利價格(進場價 - 停利點數)
      空單停利價格 = NormalizeDouble(空單進場價格 - TP * Point(),Digits()) ;
      
      // 計算空單停損價格(進場價 + 停損點數)
      空單停損價格 = NormalizeDouble(空單進場價格 + SL * Point(),Digits()) ;

      // 1. 達到最小停利且 MACD DIF 由負轉正(反向訊號)
      // 2. 或價格突破停損價(前一根收盤在停損價之下,現在突破)

         SX_Cond = ((SX_MinPF == true && CrossOver(a_DIF[2],0,a_DIF[1],0)) || (Close[1] <= 空單停損價格 && Ask > 空單停損價格)) ;


      // 執行空單平倉
      // 條件: 出場條件成立 && 不在同一根 K 棒重複平倉 && 持倉至少 1 根 K 棒
      if(SX_Cond == true && BarNumber != CloseOrderNo && SE_BarsSinceEntry(MagicNumber,空單進場單號,時間週期) > 0)
        {
         // 平倉指定單號的空單
         SX_CloseByTicket(空單進場單號,Lots) ;

         // 如果全部空單已平倉,記錄平倉的 K 棒編號
         if(空單部位() == 0)
           {
            CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA) ;
           }
        }
     } // end of 空單部位() > 0
  } // end of 交易時段外也可停損停利()

//+------------------------------------------------------------------+
//| 函數: set_BuyCondition                                            |
//| 功能: 設定多單進場條件(根據不同的模組編號使用不同策略)                  |
//+------------------------------------------------------------------+
void set_BuyCondition()
  {

   // 條件: 前一根 K 棒創 10 日新高 && 前一根收盤價高於前二根收盤價
      LE_Cond = (High[1] == Highest_OHLC(Symbol(),時間週期,MODE_HIGH,10,1) && Close[1] > Close[2]) ;
  }

//+------------------------------------------------------------------+
//| 函數: set_ShortCondition                                          |
//| 功能: 設定空單進場條件(根據不同的模組編號使用不同策略)                  |
//+------------------------------------------------------------------+
void set_ShortCondition()
  {

   // 條件: 
   // 1. 收盤價跌破 CDP(逆勢指標的中心點)
   // 2. 收盤價跌破 NL(近低點)
   // 3. ADX 指標上升(趨勢增強)
      SE_Cond = (Close[1] < CDP && Close[1] < NL && a_ADX[1] > a_ADX[2]) ;
  }

//+------------------------------------------------------------------+
//| OHLC 數據陣列宣告                                                   |
//+------------------------------------------------------------------+
// K 棒數據陣列
double Open[], High[], Low[], Close[],Range[],Body[],UPshadow[],DNshadow[] ;

// 日線數據陣列
double OpenD[], HighD[], LowD[], CloseD[] ;

// 成交量相關陣列
long Volume[],BigVolume[] ;

//+------------------------------------------------------------------+
//| 函數: Set_OHLC_Bar_Series                                         |
//| 功能: 將 K 棒數據陣列設為序列模式(索引 0 為最新數據)                   |
//+------------------------------------------------------------------+
void Set_OHLC_Bar_Series()
  {
   ArraySetAsSeries(Open,true);      // 開盤價陣列
   ArraySetAsSeries(High,true);      // 最高價陣列
   ArraySetAsSeries(Low,true);       // 最低價陣列
   ArraySetAsSeries(Close,true);     // 收盤價陣列
   ArraySetAsSeries(Volume,true);    // 成交量陣列
  }

//+------------------------------------------------------------------+
//| 函數: Get_OHLC_Bar                                                |
//| 功能: 取得指定數量的 K 棒 OHLC 和成交量數據                           |
//| 參數: argCount - 要取得的 K 棒數量                                  |
//+------------------------------------------------------------------+
void Get_OHLC_Bar(int argCount)
  {
   get_OpenData(Symbol(),時間週期,argCount,Open) ;      // 取得開盤價
   get_HighData(Symbol(),時間週期,argCount,High) ;      // 取得最高價
   get_LowData(Symbol(),時間週期,argCount,Low) ;        // 取得最低價
   get_CloseData(Symbol(),時間週期,argCount,Close) ;    // 取得收盤價
   get_VolumeData(Symbol(),時間週期,argCount,Volume) ;  // 取得成交量
  }

//+------------------------------------------------------------------+
//| 函數: Set_OHLC_Day_Series                                         |
//| 功能: 將日線數據陣列設為序列模式(索引 0 為最新數據)                    |
//+------------------------------------------------------------------+
void Set_OHLC_Day_Series()
  {
   ArraySetAsSeries(OpenD,true);     // 日線開盤價陣列
   ArraySetAsSeries(HighD,true);     // 日線最高價陣列
   ArraySetAsSeries(LowD,true);      // 日線最低價陣列
   ArraySetAsSeries(CloseD,true);    // 日線收盤價陣列
  }

//+------------------------------------------------------------------+
//| 函數: Get_OHLC_Day                                                |
//| 功能: 取得指定數量的日線 OHLC 數據                                   |
//| 參數: argCount - 要取得的日線數量                                   |
//+------------------------------------------------------------------+
void Get_OHLC_Day(int argCount)
  {
   get_OpenData(Symbol(),PERIOD_D1,argCount,OpenD) ;    // 取得日線開盤價
   get_HighData(Symbol(),PERIOD_D1,argCount,HighD) ;    // 取得日線最高價
   get_LowData(Symbol(),PERIOD_D1,argCount,LowD) ;      // 取得日線最低價
   get_CloseData(Symbol(),PERIOD_D1,argCount,CloseD) ;  // 取得日線收盤價
  }

//+------------------------------------------------------------------+
//| 指標計算區                                                     
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| MACD 指標相關                                                
//+------------------------------------------------------------------+
double a_DIF[], a_MACD[], a_OSC[] ; // DIF線、MACD線、柱狀圖陣列

//+------------------------------------------------------------------+
//| 函數: set_MACD                                                  
//| 功能: 計算 MACD 指標(DIF、MACD、OSC)                            
//+------------------------------------------------------------------+
void set_MACD()
  {
   int MacdLen, FastLen, SlowLen ;
   int h_DIF,h_MACD ;
   
   // 計算 MACD 週期(取 LenA1 和 LenB1 的較大值,最大為 15)
   MacdLen = MathMax(LenA1,LenB1) ;
   if(MacdLen > 15)
      MacdLen = 15 ;
      
   // 快線週期 = MACD 週期 * 1.33
   FastLen = (int)MathRound(MacdLen*1.33) ;
   
   // 慢線週期 = MACD 週期 * 2.66
   SlowLen = (int)MathRound(MacdLen*2.66) ;

   // 建立 MACD 指標句柄(使用加權收盤價)
   h_DIF = iMACD(Symbol(),時間週期,FastLen,SlowLen,MacdLen,PRICE_WEIGHTED);
   ArraySetAsSeries(a_DIF, true);
   
   h_MACD = iMACD(Symbol(),時間週期,FastLen,SlowLen,MacdLen,PRICE_WEIGHTED);
   ArraySetAsSeries(a_MACD, true);

   // 取得 DIF 和 MACD 的數據(最近 10 根)
   get_IndexData(h_DIF,0,0,10,a_DIF) ;    // 0 = 主線(DIF)
   get_IndexData(h_MACD,1,0,10,a_MACD) ;  // 1 = 訊號線(MACD)

  }

//+------------------------------------------------------------------+
//| CDP 指標相關變數                                                    |
//+------------------------------------------------------------------+
double CDP,AH,NH,NL,AL,CDPrange ;  // CDP 各關鍵價位
bool CrossAH,CrossAL;               // 是否突破最高值/最低值區間

//+------------------------------------------------------------------+
//| 函數: set_CDP                                                      |
//| 功能: 計算 CDP 逆勢操作指標                                          |
//| 說明: CDP 是根據前一日的高低收計算出的 5 個關鍵價位                    |
//+------------------------------------------------------------------+
void set_CDP()
  {
   double Highest2,Lowest2 ;
   
   // CDP = (前日高 + 前日低 + 2*前日收) / 4
   CDP = (HighD[1]+LowD[1]+2*CloseD[1])/4;
   
   // AH(最高值) = CDP + 前日波動
   AH = CDP + (HighD[1] - LowD[1]);
   
   // NH(近高值) = CDP*2 - 前日低
   NH = CDP*2 - LowD[1];
   
   // NL(近低值) = CDP*2 - 前日高
   NL = CDP*2 - HighD[1];
   
   // AL(最低值) = CDP - 前日波動
   AL = CDP - (HighD[1] - LowD[1]);
   
   // CDP 波動範圍
   CDPrange = HighD[1] - LowD[1] ;
   
   // 計算最近 2 根 K 棒的高低點
   Highest2 = Highest_OHLC(Symbol(),時間週期,MODE_HIGH,2,1) ;
   Lowest2 = Lowest_OHLC(Symbol(),時間週期,MODE_LOW,2,1) ;
   
   // 判斷是否在最高值區間震盪(突破 AH 但回落到 NH 以下)
   CrossAH = Highest2 > AH && Lowest2 < NH ;
   
   // 判斷是否在最低值區間震盪(跌破 AL 但反彈到 NL 以上)
   CrossAL = Highest2 > NL && Lowest2 < AL ;
  }

//+------------------------------------------------------------------+
//| ADX 指標相關變數                                                 
//+------------------------------------------------------------------+
double a_ADX[], a_PLUSDI[], a_MINUSDI[] ; // ADX主線、+DI、-DI陣列

//+------------------------------------------------------------------+
//| 函數: set_ADX                                             
//| 功能: 計算 ADX 趨勢強度指標                                         
//| 說明: ADX 用於衡量趨勢的強度,+DI/-DI 用於判斷趨勢方向              
//+------------------------------------------------------------------+
void set_ADX()
  {
   int h_ADX,h_PLUSDI,h_MINUSDI  ;
   
   // 建立 ADX 指標句柄(週期使用 LenA2 參數)
   h_ADX = iADX(Symbol(),時間週期,LenA2);
   ArraySetAsSeries(a_ADX, true);
   
   // 建立 +DI 指標句柄
   h_PLUSDI = iADX(Symbol(),時間週期,LenA2);
   ArraySetAsSeries(a_PLUSDI, true);
   
   // 建立 -DI 指標句柄
   h_MINUSDI = iADX(Symbol(),時間週期,LenA2);
   ArraySetAsSeries(a_MINUSDI, true);

   // 取得最近 5 根 K 棒的指標數據
   get_IndexData(h_ADX,0,0,5,a_ADX) ;           // 0 = ADX 主線
   get_IndexData(h_PLUSDI,1,0,5,a_PLUSDI) ;    // 1 = +DI 線(正向方向指標)
   get_IndexData(h_MINUSDI,2,0,5,a_MINUSDI) ;  // 2 = -DI 線(負向方向指標)
  }


回測結果
測試參數交易商品:NAS100(那斯達克指數)
樣本內區間:2019/1/1 ~ 2023/8/31
交易手數:固定 1 手
時間框架:M6 分鐘圖表
交易模式:波段交易

現在就加入《外匯實戰 MT5 EA基礎班》,用量化思維,開啟你的交易新紀元!


★ ~~~ 早鳥優惠 ( 2025/11/13 前報名) ~~~ ★ 
可攜伴2位參加文創手作聖誕樹 DIY才藝班





沒有留言:

張貼留言