2025年5月1日 星期四

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

型態學指的是透過觀察 金融商品歷史價格走勢圖形,並依出現特定型態後的價格表現,作為分析未來趨勢的工具之一,我們稱之為「型態學」。如果這項邏輯是正確可行的,那麼我們就可以透過回測的方式,來驗證並建立我們的交易策略

這個型態策略作為 波段留倉 或是 隔日沖策略 皆有不錯的表現

多單進場方式 ~ 即是利用 MACD低檔背離 掛單突破進場
空單進場方式 ~ 利用價格序列型態搭配KD指標 市價進場

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

   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 = (MACD_LDiv_01()) ;
      if(LE_Cond == true)
        {
         if(多單部位() == 0 && 空單部位() == 0 && BarNumber != OrderBarNo)
           {
                  買入價格 = NormalizeDouble(DH + Range[2]*0.5,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值小於 50
      //+------------------------------------------------------------------+
      SE_Cond = (High3Bar_LClose() && a_KA2[1] < 50) ;
      if(SE_Cond == true)
        {
         if(多單部位() == 0 && 空單部位() == 0 && BarNumber != OrderBarNo)
           {
            賣出價格 = NormalizeDouble(((LowD[1]+LowD[2])*0.5,Digits());
//距離上筆出場經過一根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(當沖 == true)
     {
      if(多單部位() > 0 || 空單部位() > 0)
        {
         當沖平倉();
        }
     }

   if(多單部位() > 0)
     {
      //+------------------------------------------------------------------+
      //|    Buy Exit Method  多單 依浮動盈虧位置平倉
      //+------------------------------------------------------------------+

      多單進場價格 = LE_EntryPrice(MagicNumber,多單進場單號);
      多單停利價格 = NormalizeDouble(多單進場價格 + TP * Point(),Digits()) ;
      多單停損價格 = NormalizeDouble(多單進場價格 - SL * Point(),Digits()) ;

         bool LXcond61,LXcond62 ;
         double LE_WinPoint ;
         多單最高價 = iHigh(Symbol(),時間週期, iHighest(Symbol(),時間週期,MODE_HIGH,LE_BarsSinceEntry(MagicNumber,多單進場單號,時間週期),1));
         LE_WinPoint = 多單最高價-多單進場價格 ;
         多單停利價格 = NormalizeDouble(多單進場價格 + (TP+Day5Range*0.618) * Point(),Digits()) ;
         if((LE_WinPoint/Point()) <= (SL*Point()*1.5))
            多單停損價格 = NormalizeDouble(多單進場價格-SL*Point(),Digits());
         if((LE_WinPoint/Point()) > (SL*Point()*1.5) && (LE_WinPoint/Point()) <= (TP*Point()))
            多單停損價格 = NormalizeDouble(多單最高價-SL*Point()/2,Digits());
         if((LE_WinPoint/Point()) > (TP*Point()))
            多單停損價格 = NormalizeDouble(多單最高價-LE_WinPoint/2,Digits());

         LXcond61 = (多單進場價格 < 多單停利價格 && Close[1] <= 多單停利價格 && Bid > 多單停利價格) ;
         LXcond62 = (多單進場價格 > 多單停損價格 && Close[1] >= 多單停損價格 && Bid < 多單停損價格) ;
         LX_Cond = (LXcond61 == true || LXcond62 == true) ;

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

      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  空單 以布林通道上下界平倉
      //+------------------------------------------------------------------+

         bool SXcond31,SXcond32 ;
         空單停利價格 = NormalizeDouble(MathMin(a_BBDN[1],a_BBDN[2]),Digits()) ;
         空單停損價格 = NormalizeDouble(MathMin((空單進場價格 + SL * Point()),MathMax(a_BBUP[1],a_BBUP[2])),Digits());
         SXcond31 = (空單進場價格 > 空單停利價格 && Close[1] >= 空單停利價格 && Ask < 空單停利價格) ;
         SXcond32 = (空單進場價格 < 空單停損價格 && Close[1] <= 空單停損價格 && Bid > 空單停損價格) ;
         SX_Cond = (SXcond31 == true || SXcond32 == true) ;

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

      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_BBAND();
   set_MACD();
   set_RSI();
   set_KD() ;
   FloatDayHL();

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

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void 當沖平倉()
  {
   if(getTM_hour(TimeCurrent()) == 當沖出場時間)
     {
      if(多單部位() > 0 && BarNumber != CloseOrderNo)
         LX_CloseByTicket(多單進場單號,Lots) ;
      if(空單部位() > 0 && BarNumber != CloseOrderNo)
         SX_CloseByTicket(空單進場單號,Lots) ;
      CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA) ;
     }
  }


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


隔日沖績效



沒有留言:

張貼留言