Mastering the 2 MA Crossing Strategy for MetaTrader 4

Mike 2021.03.30 19:18 37 0 0
Attachments

In this post, we're diving into how to create an Expert Advisor (EA) that utilizes the 2 MA Crossing strategy on MetaTrader 4. Let’s kick things off by defining our input variables.

//--- Input Parametersinput    int      period_ma_fast = 8;  // Fast MA Periodinput    int      period_ma_slow = 20; // Slow MA Periodinput    double  takeProfit  = 20.0;  // Take Profit in pipsinput    double  stopLoss    = 20.0;  // Stop Loss in pipsinput    double  lotSize     = 0.10;  // Lot Sizeinput    double  minEquity   = 100.0;// Minimum Equity ($)input    int slippage = 3;      // Slippageinput    int magicNumber = 889;  // Magic Number

Next up, let’s define our global variables. These variables will be accessible to all functions within our EA.

// Global Variablesdouble  myPoint    = 0.0;
int      mySlippage = 0;
int      buyTicket   = 0;
int      sellTicket  = 0;

When the EA runs, the first function it hits is OnInit(). We often use this function to validate and initialize the global variables we’ll be using.

intOnInit()
{
   // Validate Inputs
   if (period_ma_fast >= period_ma_slow || takeProfit < 0.0 || stopLoss < 0.0 || lotSize < 0.01 || minEquity < 10) {
      Alert("WARNING - Invalid input data!");
      return (INIT_PARAMETERS_INCORRECT);
   }
   
   double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   if(lotSize<min_volume) {
      string message =StringFormat("Volume is less than the allowed minimum of %.2f",min_volume);
      Alert (message);
      return(INIT_PARAMETERS_INCORRECT);
   }
   
   myPoint = GetPipPoint(Symbol());
   mySlippage = GetSlippage(Symbol(),slippage);

   return(INIT_SUCCEEDED);
}

As the market price fluctuates (ticks), the OnTick() function will trigger and execute all commands within this block.

Within the OnTick() function, we’ll invoke several other functions.

First, we’ll call the checkMinEquity() function to ensure we have enough trading equity. If our equity meets the requirement, we’ll set up a signal variable and call the NewCandle() function to recognize when a new candle forms.

The getSignal() function will check both moving average indicators and return whether a crossover has occurred, signaling whether to buy or sell.

Based on this signal, we’ll pass it to the transaction() function to open a buy or sell position, followed by invoking the setTPSL() function to establish the take profit and stop loss levels. If the equity doesn't meet the minimum requirement, an alert will pop up, and the EA will halt.

voidOnTick()
{
   if (checkMinEquity()) {
      int signal = -1;
      bool isNewCandle = NewCandle(Period(), Symbol());
      
      signal = getSignal(isNewCandle);
      transaction(isNewCandle, signal);
      setTPSL();
   } else {
      // Stop trading due to insufficient equity
      Print("EA will be stopped due to insufficient equity.");
   }
}

Let’s take a closer look at the setTPSL() function.

void setTPSL() {
    int  tOrder = 0;
    string  strMN = "", pair = "";
    double sl = 0.0, tp = 0.0;
   
    pair = Symbol();
   
    tOrder = OrdersTotal();
    for (int i=tOrder-1; i>=0; i--) {
      bool hrsSelect = OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      strMN = IntegerToString(OrderMagicNumber());
      if (StringFind(strMN, IntegerToString(magicNumber), 0) == 0 && StringFind(OrderSymbol(), pair, 0) == 0) {
         if (OrderType() == OP_BUY && (OrderTakeProfit() == 0 || OrderStopLoss() == 0)) {
            if (takeProfit > 0) {
               tp = OrderOpenPrice() + (takeProfit * myPoint);
            } else {
               tp = OrderOpenPrice();
            }
            if (stopLoss > 0) {
               sl = OrderOpenPrice() - (stopLoss * myPoint);
            } else {
               sl = OrderStopLoss();
            }
            if (OrderTakeProfit() != tp || OrderStopLoss() != sl) {
               if(OrderModify(OrderTicket(), OrderOpenPrice(), sl, tp, 0, clrBlue)) {
                  Print("Order modification successful!");
               }
            }
         }
         if (OrderType() == OP_SELL && (OrderTakeProfit() == 0 || OrderStopLoss() == 0)) {
            if (takeProfit > 0) {
               tp = OrderOpenPrice() - (takeProfit * myPoint);
            } else {
               tp = OrderOpenPrice();
            }
            if (stopLoss > 0) {
               sl = OrderOpenPrice() + (stopLoss * myPoint);
            } else {
               sl = OrderStopLoss();
            }
            if (OrderTakeProfit() != tp || OrderStopLoss() != sl) {
               if (OrderModify(OrderTicket(), OrderOpenPrice(), sl, tp, 0, clrRed)) {
                  Print("Order modification successful!");
               }
            }
         }
      }
// End of if magic number && pair
    }
// End of for
}

For those looking to connect and share knowledge, feel free to join our community on Telegram at t.me/codeMQL.

If you need an app to enhance your trading experience, check out our SignalForex app available on the Play Store!

SignalForex App on Play Store

List
Comments 0