侦云取势 发表于 2025-4-1 23:48:24

macd抄底摸顶ea

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;                // 均线指标句柄数组
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 = iMA(_Symbol, _Period, MA60_Period, 0, MODE_SMA, PRICE_CLOSE);
   maHandles = iMA(_Symbol, _Period, MA84_Period, 0, MODE_SMA, PRICE_CLOSE);
   maHandles = iMA(_Symbol, _Period, MA120_Period, 0, MODE_SMA, PRICE_CLOSE);
   maHandles = iMA(_Symbol, _Period, MA144_Period, 0, MODE_SMA, PRICE_CLOSE);
   maHandles = iMA(_Symbol, _Period, MA200_Period, 0, MODE_SMA, PRICE_CLOSE);
   maHandles = 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) return;
   }

   // 获取MACD数据
   double macdMain[], macdSignal[];
   if(!GetMACDValues(macdMain, macdSignal)) return;

   // MACD条件检查
   if(macdMain >= 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) return;
   }

   // 获取MACD数据
   double macdMain[], macdSignal[];
   if(!GetMACDValues(macdMain, macdSignal)) return;

   // MACD条件检查
   if(macdMain <= 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;
      if(CopyBuffer(maHandles, 0, 0, 1, buf) != 1) return false;
      values = buf;
   }
   return true;
}

//+------------------------------------------------------------------+
//| 获取MACD数值                                                   |
//+------------------------------------------------------------------+
bool GetMACDValues(double &main[], double &signal[])
{
   double mainBuf, signalBuf;

   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;
   for(int i=0; i<3; i++) {
      hist = MathAbs(macdMain);
   }

   // 检查是否递减:hist > hist > hist
   return (hist > hist && hist > hist);
}

//+------------------------------------------------------------------+
//| 开单函数                                                         |
//+------------------------------------------------------------------+
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;
   if(CopyTime(_Symbol, _Period, 0, 1, currentTime) != 1) return false;

   if(lastBarTime != currentTime) {
      lastBarTime = currentTime;
      return true;
   }
   return false;
}

页: [1]
查看完整版本: macd抄底摸顶ea

人生者,生存也。
生存所需,财(钱)官(权)也。
财自食伤(子孙福德爻)生,
印星生身荫护,官财印全,适合人间生存也。
若命缺财,缺官,则失去生存权。
一旦脱离父母养育,将天天面临,
从绝望中醒来,又从绝望中睡去。来去如烟!