• Welcome back! Thank you for being a part of this Traders Community. Let's discuss and share :)
    Selamat datang kembali! Trimakasih telah menjadi bagian dari Komunitas Trader ini. Mari berdiskusi dan berbagi :)

EA Parabolic SAR, MA, dan ADX

ikamutia

New Member
Credits
50
Selamat Pagi / Siang / Malam teman2, Saya sedang belajar dan mengembangkan EA MT4 berbasis trend following menggunakan kombinasi Parabolic SAR, Moving Average (MA), dan ADX. EA ini sudah saya lengkapi dengan validasi broker-safe dan source code MQL4 saya sertakan agar bisa direview.

Dan Mohon bantuannya untuk di backtest pada M15 dan M30, saya coba backtest terkendala,makasih


Ringkasan logika EA:
  • Entry hanya ketika ADX > 25 (indikasi trend kuat)
  • BUY: harga di atas MA & Parabolic SAR berada di bawah harga
  • SELL: harga di bawah MA & Parabolic SAR berada di atas harga
  • Entry dilakukan saat candle close
  • Maksimal 1 posisi per pair
Logikanya :
Code:
OnTick
 ├─ Candle baru?
 │   └─ Tidak → Stop
 ├─ Ada posisi?
 │   └─ Ya → Stop
 ├─ Hitung indikator
 ├─ ADX > 25?
 │   └─ Tidak → Stop
 ├─ Harga > MA & SAR bawah?
 │   └─ BUY
 └─ Harga < MA & SAR atas?
     └─ SELL

EA ini masih dalam tahap pembelajaran dan pengembangan, jadi segala saran, kritik, atau referensi tambahan akan sangat saya hargai.
Silakan dicek source code-nya dan mohon koreksinya jika ada bagian yang kurang tepat atau bisa dioptimalkan.

Source Code :

Code:
//+------------------------------------------------------------------+
//| EA SAR + MA + ADX (Broker Safe Version)                           |
//+------------------------------------------------------------------+
#property strict

//================ INPUT ==================
input double LotSize      = 0.01;
input int    MagicNumber  = 777;

input int    MAPeriod     = 50;
input int    MAMethod     = MODE_EMA;
input int    MAPrice      = PRICE_CLOSE;

input int    ADXPeriod    = 14;
input double ADXLevel     = 25.0;

input double SARStep      = 0.02;
input double SARMax       = 0.2;

input int    StopLoss     = 100;   // points
input int    TakeProfit   = 10;   // points

//================ GLOBAL =================
datetime lastCandleTime = 0;

//+------------------------------------------------------------------+
//| Expert initialization                                            |
//+------------------------------------------------------------------+
int OnInit()
{
   lastCandleTime = 0;
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick                                                      |
//+------------------------------------------------------------------+
void OnTick()
{
   // Entry hanya pada candle baru
   if(Time[0] == lastCandleTime) return;
   lastCandleTime = Time[0];

   // Hanya 1 posisi per symbol
   if(CountOpenOrders() > 0) return;

   //================ INDIKATOR =================
   double ma  = iMA(NULL, 0, MAPeriod, 0, MAMethod, MAPrice, 1);
   double sar = iSAR(NULL, 0, SARStep, SARMax, 1);
   double adx = iADX(NULL, 0, ADXPeriod, PRICE_CLOSE, MODE_MAIN, 1);

   double closePrice = Close[1];

   // Filter trend kuat
   if(adx <= ADXLevel) return;

   //================ LOGIKA ENTRY =================
   if(closePrice > ma && sar < closePrice)
      OpenBuy();

   if(closePrice < ma && sar > closePrice)
      OpenSell();
}

//+------------------------------------------------------------------+
//| OPEN BUY                                                         |
//+------------------------------------------------------------------+
void OpenBuy()
{
   RefreshRates();

   double lot   = FixLot(LotSize);
   double price = NormalizeDouble(Ask, Digits);
   double sl = 0, tp = 0;

   if(StopLoss > 0)
      sl = NormalizeDouble(price - StopLoss * Point, Digits);

   if(TakeProfit > 0)
      tp = NormalizeDouble(price + TakeProfit * Point, Digits);

   if(!CheckStopLevel(price, sl, tp)) return;

   int ticket = OrderSend(
      Symbol(), OP_BUY, lot, price, 3,
      sl, tp, "BUY SAR MA ADX", MagicNumber, 0, clrBlue
   );

   if(ticket < 0)
      Print("BUY Error: ", GetLastError());
   else
      Print("BUY Opened. Ticket: ", ticket);
}

//+------------------------------------------------------------------+
//| OPEN SELL                                                        |
//+------------------------------------------------------------------+
void OpenSell()
{
   RefreshRates();

   double lot   = FixLot(LotSize);
   double price = NormalizeDouble(Bid, Digits);
   double sl = 0, tp = 0;

   if(StopLoss > 0)
      sl = NormalizeDouble(price + StopLoss * Point, Digits);

   if(TakeProfit > 0)
      tp = NormalizeDouble(price - TakeProfit * Point, Digits);

   if(!CheckStopLevel(price, sl, tp)) return;

   int ticket = OrderSend(
      Symbol(), OP_SELL, lot, price, 3,
      sl, tp, "SELL SAR MA ADX", MagicNumber, 0, clrRed
   );

   if(ticket < 0)
      Print("SELL Error: ", GetLastError());
   else
      Print("SELL Opened. Ticket: ", ticket);
}

//+------------------------------------------------------------------+
//| LOT VALIDATION                                                   |
//+------------------------------------------------------------------+
double FixLot(double lot)
{
   double minLot  = MarketInfo(Symbol(), MODE_MINLOT);
   double maxLot  = MarketInfo(Symbol(), MODE_MAXLOT);
   double stepLot = MarketInfo(Symbol(), MODE_LOTSTEP);

   lot = MathMax(minLot, MathMin(lot, maxLot));
   lot = NormalizeDouble(lot / stepLot, 0) * stepLot;

   return NormalizeDouble(lot, 2);
}

//+------------------------------------------------------------------+
//| STOPLEVEL CHECK                                                  |
//+------------------------------------------------------------------+
bool CheckStopLevel(double price, double sl, double tp)
{
   double stopLevel = MarketInfo(Symbol(), MODE_STOPLEVEL);
   double minDist = stopLevel * Point;

   if(sl != 0 && MathAbs(price - sl) < minDist)
   {
      Print("SL too close");
      return false;
   }

   if(tp != 0 && MathAbs(price - tp) < minDist)
   {
      Print("TP too close");
      return false;
   }

   return true;
}

//+------------------------------------------------------------------+
//| COUNT OPEN ORDERS                                                |
//+------------------------------------------------------------------+
int CountOpenOrders()
{
   int total = 0;
   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderMagicNumber() == MagicNumber &&
            OrderSymbol() == Symbol())
         {
            total++;
         }
      }
   }
   return total;
}
//+------------------------------------------------------------------+
 

Attachments

Last edited:
Back
Top