| 
 | 
 
mt5ea 抄底摸顶ea 
多单过滤条件:均线60>84>120>144>200>300 
多单开单条件:macd在0轴下,macd柱子越来越短(监测前面2根,如果第三根主子比前面两根短,开多单) 
 
空单过滤条件:均线60<84<120<144<200<300 
开单条件:macd在0轴上,macd柱子越来越短(监测前面2根,如果第三根主子比前面两根短,开多单) 
 
//+------------------------------------------------------------------+ 
//|                                                   ReversalEA.mq5 | 
//|                        Copyright 2023, MetaQuotes Software Corp. | 
//|                                             https://www.mql5.com | 
//+------------------------------------------------------------------+ 
#property copyright "Copyright 2023, MetaQuotes Software Corp." 
#property link      "https://www.mql5.com" 
#property version   "1.00" 
 
//--- 输入参数 
input double LotSize        = 0.1;      // 交易手数 
input int    TakeProfit     = 10000;      // 止盈点数 
input int    StopLoss       = 10000;      // 止损点数 
input int    MagicNumber    = 12345;    // 魔术码 
input bool   TimeFilterEnable = true;   // 启用时间过滤 
input int    StartHour      = 5;       // 开始交易小时(0-23) 
input int    EndHour        = 19;       // 结束交易小时(0-23) 
input bool   SundayOff      = true;     // 周日禁止交易 
 
input int    MA60_Period    = 60;       // 均线60周期 
input int    MA84_Period    = 84;       // 均线84周期 
input int    MA120_Period   = 120;      // 均线120周期 
input int    MA144_Period   = 144;      // 均线144周期 
input int    MA200_Period   = 200;      // 均线200周期 
input int    MA300_Period   = 300;      // 均线300周期 
 
//--- 全局变量 
int    macdHandle;                  // MACD指标句柄 
int    maHandles[6];                // 均线指标句柄数组 
datetime lastBarTime;               // 最后K线时间 
 
//+------------------------------------------------------------------+ 
//| Expert initialization function                                   | 
//+------------------------------------------------------------------+ 
int OnInit() 
{ 
   // 参数有效性检查 
   if(StartHour < 0 || StartHour > 23 || EndHour < 0 || EndHour > 23) { 
      Print("错误:交易时间参数无效(0-23)"); 
      return(INIT_PARAMETERS_INCORRECT); 
   } 
 
   // 创建MACD指标句柄 
   macdHandle = iMACD(_Symbol, _Period, 12, 26, 9, PRICE_CLOSE); 
 
   // 创建均线指标句柄 
   maHandles[0] = iMA(_Symbol, _Period, MA60_Period, 0, MODE_SMA, PRICE_CLOSE); 
   maHandles[1] = iMA(_Symbol, _Period, MA84_Period, 0, MODE_SMA, PRICE_CLOSE); 
   maHandles[2] = iMA(_Symbol, _Period, MA120_Period, 0, MODE_SMA, PRICE_CLOSE); 
   maHandles[3] = iMA(_Symbol, _Period, MA144_Period, 0, MODE_SMA, PRICE_CLOSE); 
   maHandles[4] = iMA(_Symbol, _Period, MA200_Period, 0, MODE_SMA, PRICE_CLOSE); 
   maHandles[5] = iMA(_Symbol, _Period, MA300_Period, 0, MODE_SMA, PRICE_CLOSE); 
 
   // 检查句柄是否有效 
   if(macdHandle == INVALID_HANDLE) { 
      Print("MACD指标初始化失败!"); 
      return(INIT_FAILED); 
   } 
   for(int i=0; i<6; i++) { 
      if(maHandles == INVALID_HANDLE) { 
         Print("均线指标",i,"初始化失败!"); 
         return(INIT_FAILED); 
      } 
   } 
 
   return(INIT_SUCCEEDED); 
} 
 
//+------------------------------------------------------------------+ 
//| Expert deinitialization function                                 | 
//+------------------------------------------------------------------+ 
void OnDeinit(const int reason) 
{ 
   // 释放指标句柄 
   IndicatorRelease(macdHandle); 
   for(int i=0; i<6; i++) { 
      IndicatorRelease(maHandles); 
   } 
} 
 
//+------------------------------------------------------------------+ 
//| Expert tick function                                             | 
//+------------------------------------------------------------------+ 
void OnTick() 
{ 
   if(!IsNewBar()) return; 
 
   CheckForLong(); 
   CheckForShort(); 
} 
 
//+------------------------------------------------------------------+ 
//| 时间过滤检查函数                                                 | 
//+------------------------------------------------------------------+ 
bool IsTradingTimeAllowed() 
{ 
   if(!TimeFilterEnable) return true; 
 
   MqlDateTime timeStruct; 
   datetime currentTime = TimeCurrent(); 
   TimeToStruct(currentTime, timeStruct); 
 
   // 周日检查 
   if(SundayOff && timeStruct.day_of_week == 0) return false; 
 
   // 交易时段检查 
   if(timeStruct.hour >= StartHour && timeStruct.hour < EndHour) { 
      return true; 
   } 
 
   return false; 
} 
 
//+------------------------------------------------------------------+ 
//| 多单交易条件检查                                                 | 
//+------------------------------------------------------------------+ 
void CheckForLong() 
{ 
   if(!IsTradingTimeAllowed()) return; 
 
   // 获取均线数据 
   double maValues[]; 
   ArrayResize(maValues, 6); 
   if(!GetMAsValues(maValues)) return; 
 
   // 验证均线排列:60 > 84 > 120 > 144 > 200 > 300 
   for(int i=0; i<5; i++) { 
      if(maValues <= maValues[i+1]) return; 
   } 
 
   // 获取MACD数据 
   double macdMain[], macdSignal[]; 
   if(!GetMACDValues(macdMain, macdSignal)) return; 
 
   // MACD条件检查 
   if(macdMain[0] >= 0) return;                // MACD主线在0轴下 
   if(!IsHistogramDecreasing(macdMain)) return; // 柱状线连续缩短 
 
   OpenOrder(ORDER_TYPE_BUY); 
} 
 
//+------------------------------------------------------------------+ 
//| 空单交易条件检查                                                 | 
//+------------------------------------------------------------------+ 
void CheckForShort() 
{ 
   if(!IsTradingTimeAllowed()) return; 
 
   // 获取均线数据 
   double maValues[]; 
   ArrayResize(maValues, 6); 
   if(!GetMAsValues(maValues)) return; 
 
   // 验证均线排列:60 < 84 < 120 < 144 < 200 < 300 
   for(int i=0; i<5; i++) { 
      if(maValues >= maValues[i+1]) return; 
   } 
 
   // 获取MACD数据 
   double macdMain[], macdSignal[]; 
   if(!GetMACDValues(macdMain, macdSignal)) return; 
 
   // MACD条件检查 
   if(macdMain[0] <= 0) return;                // MACD主线在0轴上 
   if(!IsHistogramDecreasing(macdMain)) return; // 柱状线连续缩短 
 
   OpenOrder(ORDER_TYPE_SELL); 
} 
 
//+------------------------------------------------------------------+ 
//| 获取均线数值                                                     | 
//+------------------------------------------------------------------+ 
bool GetMAsValues(double &values[]) 
{ 
   if(ArraySize(values) < 6) ArrayResize(values, 6); 
 
   for(int i=0; i<6; i++) { 
      double buf[1]; 
      if(CopyBuffer(maHandles, 0, 0, 1, buf) != 1) return false; 
      values = buf[0]; 
   } 
   return true; 
} 
 
//+------------------------------------------------------------------+ 
//| 获取MACD数值                                                     | 
//+------------------------------------------------------------------+ 
bool GetMACDValues(double &main[], double &signal[]) 
{ 
   double mainBuf[3], signalBuf[3]; 
 
   if(CopyBuffer(macdHandle, 0, 0, 3, mainBuf) < 3) return false; 
   if(CopyBuffer(macdHandle, 1, 0, 3, signalBuf) < 3) return false; 
 
   ArraySetAsSeries(mainBuf, true); 
   ArraySetAsSeries(signalBuf, true); 
 
   ArrayResize(main, 3); 
   ArrayResize(signal, 3); 
   ArrayCopy(main, mainBuf); 
   ArrayCopy(signal, signalBuf); 
 
   return true; 
} 
 
//+------------------------------------------------------------------+ 
//| 判断MACD柱状线是否递减                                           | 
//+------------------------------------------------------------------+ 
bool IsHistogramDecreasing(double &macdMain[]) 
{ 
   if(ArraySize(macdMain) < 3) return false; 
 
   // 计算最近三根柱子的绝对值长度 
   double hist[3]; 
   for(int i=0; i<3; i++) { 
      hist = MathAbs(macdMain); 
   } 
 
   // 检查是否递减:hist[2] > hist[1] > hist[0] 
   return (hist[2] > hist[1] && hist[1] > hist[0]); 
} 
 
//+------------------------------------------------------------------+ 
//| 开单函数                                                         | 
//+------------------------------------------------------------------+ 
void OpenOrder(ENUM_ORDER_TYPE orderType) 
{ 
   MqlTradeRequest request; 
   MqlTradeResult result; 
   ZeroMemory(request); 
   ZeroMemory(result); 
 
   double price = (orderType == ORDER_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_ASK)  
                                              : SymbolInfoDouble(_Symbol, SYMBOL_BID); 
   double sl = (orderType == ORDER_TYPE_BUY) ? price - StopLoss * _Point  
                                           : price + StopLoss * _Point; 
   double tp = (orderType == ORDER_TYPE_BUY) ? price + TakeProfit * _Point  
                                           : price - TakeProfit * _Point; 
 
   request.action    = TRADE_ACTION_DEAL; 
   request.symbol    = _Symbol; 
   request.volume    = LotSize; 
   request.type      = orderType; 
   request.price     = price; 
   request.sl        = sl; 
   request.tp        = tp; 
   request.deviation = 5; 
   request.magic     = MagicNumber; 
 
   if(!OrderSend(request, result)) { 
      Print("订单发送失败,错误代码:", GetLastError()); 
   } 
} 
 
//+------------------------------------------------------------------+ 
//| 判断是否新K线                                                    | 
//+------------------------------------------------------------------+ 
bool IsNewBar() 
{ 
   datetime currentTime[1]; 
   if(CopyTime(_Symbol, _Period, 0, 1, currentTime) != 1) return false; 
 
   if(lastBarTime != currentTime[0]) { 
      lastBarTime = currentTime[0]; 
      return true; 
   } 
   return false; 
} 
 
 |   
 
 
 
 |