设为首页 收藏本站 切换语言
| 发表于 2025-4-23 23:39:57 | 显示全部楼层 |复制链接
再次向各位大神求助!!!  


以下是我正在嘗試編寫的MACD交易策略EA,內容一樣是通拼西湊起來了,
雖然F7時沒出現錯誤,但是回測總是不開單,想請各位大神幫忙看看有什麼問題,
主要邏輯如下:

[多單進場]
(1)MACD在零線下方時,如果出現3個波峰,連續升高,此時波峰對應的K棒,低點也連續降低
(2)下一根K棒結束時,對應的MACD柱體變短,就進多單
(3)將入場價格減掉當根K棒的ATR數字,作為止損價格
[空單進場]
(1)MACD在零線上方,如果出現3個波峰,連續降低,此時波峰對應的K棒,低點也連續降低
(2)下一根K棒結束時,對應的MACD柱體變短,就進空單
(3)將入場價格加上當根K棒的ATR數字,作為止損價格


//+------------------------------------------------------------------+
#property strict

#include <Trade\Trade.mqh>
CTrade trade;

// ===== Input Parameters =====
input double   lotSize         = 0.1;         // 每次下單手數
input int      macdFast        = 13;          // MACD 快線
input int      macdSlow        = 34;          // MACD 慢線
input int      macdSignal      = 9;           // MACD 訊號線
input int      atrPeriod       = 13;          // ATR 週期

input bool     UseTrailingStop = true;        // 啟用追蹤止損
input double   TrailingStart   = 30;          // 啟動追蹤的獲利(點)
input double   TrailingStep    = 15;          // 追蹤止損距離(點)

// ===== Handles and Buffers =====
int macdHandle, atrHandle;
double macdMain[], macdSignalBuf[], macdHist[];
double atrBuf[];

datetime lastTradeTime = 0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   macdHandle = iMACD(_Symbol, PERIOD_M15, macdFast, macdSlow, macdSignal, PRICE_CLOSE);
   atrHandle  = iATR(_Symbol, PERIOD_M15, atrPeriod);

   if(macdHandle == INVALID_HANDLE || atrHandle == INVALID_HANDLE)
   {
      Print("Failed to create indicator handles.");
      return(INIT_FAILED);
   }

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   if(Period() != PERIOD_M15) return;

   int barsToCheck = 50;
   if(CopyBuffer(macdHandle, 0, 0, barsToCheck, macdMain) <= 0) return;
   if(CopyBuffer(macdHandle, 1, 0, barsToCheck, macdSignalBuf) <= 0) return;
   if(CopyBuffer(macdHandle, 2, 0, barsToCheck, macdHist) <= 0) return;
   if(CopyBuffer(atrHandle, 0, 0, 3, atrBuf) <= 0) return;

   // 檢查是否已有持倉
   if(!PositionSelect(_Symbol))
   {
// 多單機會
if(CheckBullishSignal())
{
   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double sl = NormalizeDouble(ask - atrBuf[1], _Digits);
   trade.Buy(lotSize, _Symbol, ask, sl, 0, "MACD Buy");
   lastTradeTime = TimeCurrent();
}

// 空單機會
if(CheckBearishSignal())
{
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double sl = NormalizeDouble(bid + atrBuf[1], _Digits);
   trade.Sell(lotSize, _Symbol, bid, sl, 0, "MACD Sell");
   lastTradeTime = TimeCurrent();
}
   }
   else
   {
      // 移動止盈邏輯
      CheckTrailingStop();
   }
}

//+------------------------------------------------------------------+
//| 多單條件:MACD零線下方 + 柱體升高 + 低點降低 + 柱體轉弱         |
//+------------------------------------------------------------------+
bool CheckBullishSignal()
{
   if(macdMain[1] > 0) return false; // MACD 主線應該在零線下方

   int found = 0;
   double prevPeak = -DBL_MAX;
   double prevLow = DBL_MAX;

   for(int i = 10; i < 30; i++)
   {
      if(macdHist[i] > macdHist[i-1] && macdHist[i] > macdHist[i+1])
      {
         double low = iLow(_Symbol, PERIOD_M15, i);

         if(macdHist[i] > prevPeak && low < prevLow)
         {
            found++;
            prevPeak = macdHist[i];
            prevLow = low;
         }
      }
      if(found >= 3)
         break;
   }

   // 若符合條件,且柱體正在轉弱(縮短)
   if(found >= 3 && macdHist[1] < macdHist[2])
      return true;

   return false;
}

//+------------------------------------------------------------------+
//| 空單條件:MACD零線上方 + 柱體降低 + 低點降低 + 柱體轉弱         |
//+------------------------------------------------------------------+
bool CheckBearishSignal()
{
   if(macdMain[1] < 0) return false; // MACD 主線應該在零線上方

   int found = 0;
   double prevPeak = DBL_MAX;
   double prevLow = DBL_MAX;

   for(int i = 10; i < 30; i++)
   {
      if(macdHist[i] < macdHist[i-1] && macdHist[i] < macdHist[i+1])
      {
         double low = iLow(_Symbol, PERIOD_M15, i);

         if(macdHist[i] < prevPeak && low < prevLow)
         {
            found++;
            prevPeak = macdHist[i];
            prevLow = low;
         }
      }
      if(found >= 3)
         break;
   }

   if(found >= 3 && macdHist[1] > macdHist[2])
      return true;

   return false;
}

//+------------------------------------------------------------------+
//| 追蹤止損功能(多空都適用)                                      |
//+------------------------------------------------------------------+
void CheckTrailingStop()
{
   if(!UseTrailingStop) return;

   if(!PositionSelect(_Symbol)) return;

   double point = _Point;
   double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
   double sl = PositionGetDouble(POSITION_SL);
   int type = (int)PositionGetInteger(POSITION_TYPE);

   double price = (type == POSITION_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_BID)
                                              : SymbolInfoDouble(_Symbol, SYMBOL_ASK);

   double profitPts = (type == POSITION_TYPE_BUY) ? (price - openPrice) / point
                                                  : (openPrice - price) / point;

   if(profitPts < TrailingStart) return;

   double newSL = (type == POSITION_TYPE_BUY) ? price - TrailingStep * point
                                              : price + TrailingStep * point;

   if((type == POSITION_TYPE_BUY && (newSL > sl)) ||
      (type == POSITION_TYPE_SELL && (newSL < sl || sl == 0.0)))
   {
      trade.PositionModify(_Symbol, NormalizeDouble(newSL, _Digits), 0);
   }
}





举报

评论 使用道具

发新帖
EA交易
您需要登录后才可以评论 登录 | 立即注册

简体中文
繁體中文
English(英语)
日本語(日语)
Deutsch(德语)
Русский язык(俄语)
بالعربية(阿拉伯语)
Türkçe(土耳其语)
Português(葡萄牙语)
ภาษาไทย(泰国语)
한어(朝鲜语/韩语)
Français(法语)