2025年5月9日 星期五

MT5 外匯商品 交易策略開發 [05]

參考一目均衡表交易模型系列文章
轉換線 = (9 日內最高+9 日內最低)/2,以9日為一短線周期 (周期長短可任意更改)。
轉換線,作為短期支持線、阻力線;確定走勢已形成時的低買高賣價位;判斷走勢強度。
轉換線和基準線相比,是較短時間的買賣平均值。也就是說,轉換線是從大趨勢中捕捉小的波浪,設定低進高拋的目標值

多單進場方式 ~ 利用 MACD多方趨勢 搭配一目均衡表轉換線價格掛單突破進場
空單進場方式 ~ 利用 連續K棒收盤價低於布林通道下緣 市價進場

#include <Trade\Trade.mqh>
#include <MagicMT5_函數庫V1.mqh>

ENUM_TIMEFRAMES  時間週期 = PERIOD_M15;

int OnInit()
  {
   LoadEA = TimeCurrent();
   return(INIT_SUCCEEDED);
  }

void OnTick()
  {
   if(AccountInfoDouble(ACCOUNT_BALANCE) <= 資金風控)
     {
      Alert("**********  資金不足 *************");
      return;
     }

   BarNumber = iBarShift(Symbol(),時間週期,LoadEA);
   BarSinceExit = BarNumber-CloseOrderNo ;
   if((BarNumber == 1 && BarNumber != JudgeNo))
     {
      多單進場單號 = Buy_at_MARKET(Symbol(),Lots,0,0,"1st_K",MagicNumber) ;
      LX_CloseByTicket(多單進場單號,Lots) ;
      CloseOrderNo =  iBarShift(Symbol(),時間週期,LoadEA);
      FastSma = MathMin(LenA1, LenB1);
      SlowSma = MathMax(LenA1, LenB1);
     }

   if(BarNumber != JudgeNo)
     {
      換K棒();
//時間濾網
      允許交易時段 =(getTM_hour(TimeCurrent()) >= 12 || (getTM_hour(TimeCurrent()) >= 4 && getTM_hour(TimeCurrent()) < 10)) ;
     }

   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(Lots_AutoCal == true)
     {
      Lots = get_dynamic_lot_size(Lots_Even,Symbol(),RiskPercent,AccountBalance,SL) ;
      Lots = MathMin(0.3,MathMax(0.01,Lots)) ;
     }

   if(允許交易時段 == true)
     {
      //+------------------------------------------------------------------+
      //|多單進場 MACD 多方走勢
      //+------------------------------------------------------------------+
      LE_Cond = (Close[1] > NL && a_DIF[1] > a_DIF[2] && a_MACD[1] > 0) ;
      if(LE_Cond == true)
        {
         if(多單部位() == 0 && 空單部位() == 0 && BarNumber != OrderBarNo)
           {
                  買入價格 = NormalizeDouble(a_ICHI_C[2] + a_ATR[2] ,Digits()) ;
//距離上筆出場經過一根K棒 且當日未進場    
            if(BarSinceExit > 1 && EntriesToday(MagicNumber,Symbol()) < 1)
              {
               // 空手+掛單突破買入
                     if(Close[1] < 買入價格)
                       {
                        多單進場單號 = Buy_at_STOP(Symbol(),MagicNumber,買入價格,Lots,TP,SL,"BUY STOP",3600) ;
                        OrderBarNo = iBarShift(Symbol(),時間週期,LoadEA);

                       }


              } // end of BarSinceExit > 1
           } // end of 空手且不同根K棒() == true
        } // end of LE_Cond == true

      //+------------------------------------------------------------------+
      //|空單進場 連三根K收盤價低於布林通道下緣
      //+------------------------------------------------------------------+
      SE_Cond = (_3LessThanBBDn());
      if(SE_Cond == true)
        {
         if(多單部位() == 0 && 空單部位() == 0 && BarNumber != OrderBarNo)
           {

//距離上筆出場經過一根K棒 且當日未進場 
            if(BarSinceExit > 1 && EntriesToday(MagicNumber,Symbol()) < 1)
              {
                  // 空手+市價賣出
                  空單進場單號 = Short_at_MARKET(Symbol(),Lots,TP,SL,"Short Market",MagicNumber) ;
                  OrderBarNo = iBarShift(Symbol(),時間週期,LoadEA);
                
              } //end of BarSinceExit > 1
           } // end of 空手且不同根K棒() == true
        } // end of SE_Cond == true
     } //end of 允許交易時段 == true

   if(多單部位() > 0)
     {
      //+------------------------------------------------------------------+
      //|    Buy Exit Method  多單 固定停損利平倉
      //+------------------------------------------------------------------+

      多單進場價格 = LE_EntryPrice(MagicNumber,多單進場單號);
多單停利價格 = NormalizeDouble(多單進場價格 + (TP+Day5Range) * Point(),Digits()) ;
      多單停損價格 = NormalizeDouble(多單進場價格 - SL * Point(),Digits()) ;
        
         LX_Cond = ((Close[1] <= 多單停利價格 && Bid > 多單停利價格) || (Close[1] >= 多單停損價格 && Bid < 多單停損價格)) ;

      //---------------------------------------------------------多單出場

      if(LX_Cond == true && BarNumber != CloseOrderNo && BarNumber != OrderBarNo && LE_BarsSinceEntry(MagicNumber,多單進場單號,時間週期) > 0)
        {
         LX_CloseByTicket(多單進場單號,Lots) ;

         if(多單部位() == 0)
           {
            CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA) ;
           }
        }
     } // end of 多單部位() > 0

   if(空單部位() > 0)
     {
      //+------------------------------------------------------------------+
      //|    Short Exit Method  空單 固定停損利平倉
      //+------------------------------------------------------------------+
      空單進場價格 = SE_EntryPrice(MagicNumber,空單進場單號);
      空單停利價格 = NormalizeDouble(空單進場價格 - (TP+Day5Range) * Point(),Digits()) ;
      空單停損價格 = NormalizeDouble(空單進場價格 + SL * Point(),Digits()) ;
         SX_Cond = ((Close[1] >= 空單停利價格 && Ask < 空單停利價格) || (Close[1] <= 空單停損價格 && Ask > 空單停損價格)) ;

      //---------------------------------------------------------空單出場

      if(SX_Cond == true && BarNumber != CloseOrderNo && SE_BarsSinceEntry(MagicNumber,空單進場單號,時間週期) > 0)
        {
         SX_CloseByTicket(空單進場單號,Lots) ;

         if(空單部位() == 0)
           {
            CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA) ;
           }
        }
     } // end of 空單部位() > 0


   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 ;
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void 換K棒()
  {
// 新K棒刪除所有掛單
   if(total_pending_order_count(Symbol(), MagicNumber,-1) != 0)
     {
      delete_pending_orders_all(Symbol(), MagicNumber, -1, 0x0000ff);

     }
   Set_OHLC_Bar_Series();
   Get_OHLC_Bar(10) ;
   Set_OHLC_Day_Series();
   Get_OHLC_Day(10) ;
   set_BarInfo();
   set_ATR(); 

   set_BBAND();
   set_MACD();
   set_ICHIMOKU();

   Day5Range = ((HighD[1] - LowD[1])+(HighD[2] - LowD[2])+(HighD[3] - LowD[3])+(HighD[4] - LowD[4])+(HighD[5] - LowD[5]))/5;
  }

//+--------------------------------------------------------+
//| 設定 開高低收 陣列序列
//+--------------------------------------------------------+
//********BarPrice Array variables
double Open[], High[], Low[], Close[],Range[],Body[],UPshadow[],DNshadow[] ;
double OpenD[], HighD[], LowD[], CloseD[] ;

//+------------------------------------------------------------------+
//|                                                             
//+------------------------------------------------------------------+
void Set_OHLC_Bar_Series()
  {
   ArraySetAsSeries(Open,true);
   ArraySetAsSeries(High,true);
   ArraySetAsSeries(Low,true);
   ArraySetAsSeries(Close,true);
  }
//+------------------------------------------------------------------+
//|                                                               
//+------------------------------------------------------------------+
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) ;
  }

//+------------------------------------------------------------------+
//|                                                                 
//+------------------------------------------------------------------+
void set_BarInfo()
  {
   ArrayResize(Range,ArraySize(Open)) ;
   ArraySetAsSeries(Range,true) ;
   ArrayResize(Body,ArraySize(Open)) ;
   ArraySetAsSeries(Body,true) ;
   ArrayResize(UPshadow,ArraySize(Open)) ;
   ArraySetAsSeries(UPshadow,true) ;
   ArrayResize(DNshadow,ArraySize(Open)) ;
   ArraySetAsSeries(DNshadow,true) ;

   for(int i = 0; i < ArraySize(Open)-1; i=i+1)
     {
      Range[i] = High[i]-Low[i];
      Body[i] = MathAbs(Close[i]-Open[i]);
      UPshadow[i] = High[i]-MathMax(Close[i],Open[i]);
      DNshadow[i] = MathMin(Close[i],Open[i])-Low[i];
     }
  }

//+------------------------------------------------------------------+
//|                                                             
//+------------------------------------------------------------------+
void Set_OHLC_Day_Series()
  {
   ArraySetAsSeries(OpenD,true);
   ArraySetAsSeries(HighD,true);
   ArraySetAsSeries(LowD,true);
   ArraySetAsSeries(CloseD,true);
  }
//+------------------------------------------------------------------+
//|                                                           
//+------------------------------------------------------------------+
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) ;
  }
//+------------------------------------------------------------------+
//|  指標及通道計算                                                             
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|   計算 布林通道值                                                               
//+------------------------------------------------------------------+
double a_BBUP[],a_BBDN[] ;
void set_BBAND()
  {
   int BBLen,h_BBUP,h_BBDN ;

   BBLen = MathMax(LenA2,LenB2) ;
   h_BBUP = iBands(Symbol(),時間週期,BBLen,0,2,PRICE_CLOSE);
   ArraySetAsSeries(a_BBUP, true);
   h_BBDN = iBands(Symbol(),時間週期,BBLen,0,2,PRICE_CLOSE);
   ArraySetAsSeries(a_BBDN, true);
   get_IndexData(h_BBUP,1,0,10,a_BBUP) ;
   get_IndexData(h_BBDN,2,0,10,a_BBDN) ;

  }
//+------------------------------------------------------------------+
//|    計算 MACD 值                                                               
//+------------------------------------------------------------------+
double a_DIF[], a_MACD[], a_OSC[] ;
void set_MACD()
  {
   int MacdLen, FastLen, SlowLen ;
   int h_DIF,h_MACD ;
   MacdLen = MathMax(LenA1,LenB1) ;
   if(MacdLen > 15)
      MacdLen = 15 ;
   FastLen = (int)MathRound(MacdLen*1.33) ;
   SlowLen = (int)MathRound(MacdLen*2.66) ;

   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);

   get_IndexData(h_DIF,0,0,10,a_DIF) ;
   get_IndexData(h_MACD,1,0,10,a_MACD) ;

   ArraySetAsSeries(a_OSC, true);
   ArrayResize(a_OSC,ArraySize(a_DIF)) ;

   for(int i = 0;i < ArraySize(a_OSC); i++)
     {
      a_OSC[i] = a_DIF[i]-a_MACD[i] ;
     }
  }  
//+------------------------------------------------------------------+
//|  計算 ATR 值
//+------------------------------------------------------------------+
double a_ATR[] ;
void set_ATR()
  {
   int h_ATR ;
   h_ATR = iATR(Symbol(),時間週期,LenB2);
   ArraySetAsSeries(a_ATR, true);
   get_IndexData(h_ATR,0,0,5,a_ATR) ;
  }
//+------------------------------------------------------------------+
//|  計算 一目均衡表 值
//+------------------------------------------------------------------+
double a_ICHI_B[],a_ICHI_C[],a_ICHI_SA[],a_ICHI_SB[],a_ICHI_LC[] ;
void set_ICHIMOKU()
  {
   int h_ICHI_C,h_ICHI_B,h_ICHI_SA,h_ICHI_SB,h_ICHI_LC ;
   h_ICHI_C = iIchimoku(Symbol(),時間週期,9,26,52);
   ArraySetAsSeries(a_ICHI_C, true);
   h_ICHI_B = iIchimoku(Symbol(),時間週期,9,26,52);
   ArraySetAsSeries(a_ICHI_B, true);
   h_ICHI_SA = iIchimoku(Symbol(),時間週期,9,26,52);
   ArraySetAsSeries(a_ICHI_SA, true);
   h_ICHI_SB = iIchimoku(Symbol(),時間週期,9,26,52);
   ArraySetAsSeries(a_ICHI_SB, true);
   h_ICHI_LC = iIchimoku(Symbol(),時間週期,9,26,52);
   ArraySetAsSeries(a_ICHI_LC, true);

   get_IndexData(h_ICHI_C,0,0,5,a_ICHI_C) ;
   get_IndexData(h_ICHI_B,1,0,5,a_ICHI_B) ;
   get_IndexData(h_ICHI_SA,2,0,5,a_ICHI_SA) ;
   get_IndexData(h_ICHI_SB,3,0,5,a_ICHI_SB) ;
   get_IndexData(h_ICHI_LC,4,0,5,a_ICHI_LC) ;
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool _3LessThanBBDn()
  {
   int  j = 0;
   for(int i = 1; i <= 3; i=i+1)
     {
      if(Close[i] < a_BBDN[i])
        {
         j = j + 1;

        }
     }
   if(j == 3)
     {
      return true;
     }
   return false;
 }

//+------------------------------------------------------------------+
交易商品 XAUUSD 樣本內區間 2019/1/1 ~2022/12/31 交易手數 固定 0.1手
波段留倉




沒有留言:

張貼留言