Simple MA Crossover EA

 

Hello Everyone, after taking several MQL4 courses online, I'm trying to write my own EA. My EA is a simple MA crossover which opens a short/long position based on MA crossover. It should close the current position on the opposite signal and open a new position. I wrote the code, tested it and it works. I'm not really confident about the OrderClose function. Can you guys take a look at my code and let me know if I've done it properly, or is there a better way to close the position and open a new one? Thanks


#property copyright ""
#property link      ""
#property version   ""
#property strict
#property show_inputs


input int FASTMA = 7;
input int SLOWMA = 25;
input ENUM_MA_METHOD MA_METHOD = MODE_EMA;
input ENUM_APPLIED_PRICE PRICE_METHOD = PRICE_CLOSE;
int magicNB = 55555;
int openOrderID;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   Alert("");
   Alert("Starting Moving Average Crossover Strategy");

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Alert("Stopping Moving Average Crossover Strategy");
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
  
 
   double FastMovingAverageCurr = iMA(NULL,0,FASTMA,0,MA_METHOD,PRICE_METHOD,0); 
   double FastMovingAveragePrev = iMA(NULL,0,FASTMA,0,MA_METHOD,PRICE_METHOD,1); 
   double SlowMovingAverageCurr = iMA(NULL,0,SLOWMA,0,MA_METHOD,PRICE_METHOD,0); 
   double SlowMovingAveragePrev = iMA(NULL,0,SLOWMA,0,MA_METHOD,PRICE_METHOD,1); 
  
  
   if(!CheckIfOpenOrdersByMagicNB(magicNB))//if no open orders try to enter new position
   {
   
   //Open  Order
   
   if((SlowMovingAveragePrev < FastMovingAveragePrev) && (SlowMovingAverageCurr > FastMovingAverageCurr) && (MathAbs(SlowMovingAverageCurr-FastMovingAverageCurr)>0.00005)) 
   {
   
   openOrderID = OrderSend(NULL,OP_SELL,0.1,Bid,3,0,0,NULL,magicNB,0,clrGreen);
   if(openOrderID < 0) Alert("order rejected. Order error: " + GetLastError());
   }
   
   if((SlowMovingAveragePrev > FastMovingAveragePrev) && (FastMovingAverageCurr > SlowMovingAverageCurr) && (MathAbs(FastMovingAverageCurr-SlowMovingAverageCurr)>0.00005)) 
   {
   
   openOrderID = OrderSend(NULL,OP_BUY,0.1,Ask,3,0,0,NULL,magicNB,0,clrRed);
   if(openOrderID < 0) Alert("order rejected. Order error: " + GetLastError()); 
   } 
   }

   //Close Order

   if((SlowMovingAveragePrev > FastMovingAveragePrev) && (SlowMovingAverageCurr < FastMovingAverageCurr)) 
   {
   OrderClose(openOrderID,0.1,Ask,3,clrRed);
   }
  
   if((SlowMovingAveragePrev < FastMovingAveragePrev) && (FastMovingAverageCurr < SlowMovingAverageCurr)) 
   {
   OrderClose(openOrderID,0.1,Bid,3,clrGreen);
    
   }    
      
   }

   bool CheckIfOpenOrdersByMagicNB(int magicNB)
      {
      int openOrders = OrdersTotal();
   
      for(int i = 0; i < openOrders; i++)
         {
      if(OrderSelect(i,SELECT_BY_POS)==true)
        {
          if(OrderMagicNumber() == magicNB) 
        {
          return true;
        }  
     }
   }
  return false;
}
 

hello, I think there is a filter method, can you add it to the code you wrote?

 
bekir serhat #:

hello, I think there is a filter method, can you add it to the code you wrote?

You write your filter here, adding it to the code is simple.

 

Normally I would put the Closing orders before opening orders... the program runs from top to bottom ... so if you have an order buy open and new tick comes, and new tick will make the condition of selling is true, it will not open a sell trade because you have one order open... so program will run past opening orders section and go to the closing section...it will close your Buy trade and then stop... only next tick will open your trade... 

Also on a closing trade I would loop through the opened orders pool, and select the one I need and close it... this way you don't need to worry about closing price (Bid/Ask).. you can use OrderClosingPrice() instead.

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2018, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""
#property version   ""
#property strict
#property show_inputs


input int FASTMA = 7;
input int SLOWMA = 25;
input ENUM_MA_METHOD MA_METHOD = MODE_EMA;
input ENUM_APPLIED_PRICE PRICE_METHOD = PRICE_CLOSE;
int magicNB = 55555;
int openOrderID;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   Alert("");
   Alert("Starting Moving Average Crossover Strategy");

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Alert("Stopping Moving Average Crossover Strategy");
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double FastMovingAverageCurr(int shift) {return(iMA(NULL,0,FASTMA,0,MA_METHOD,PRICE_METHOD,shift));}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double FastMovingAveragePrev(int shift) {return(iMA(NULL,0,FASTMA,0,MA_METHOD,PRICE_METHOD,shift));}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double SlowMovingAverageCurr(int shift) {return(iMA(NULL,0,SLOWMA,0,MA_METHOD,PRICE_METHOD,shift));}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double SlowMovingAveragePrev(int shift) {return(iMA(NULL,0,SLOWMA,0,MA_METHOD,PRICE_METHOD,shift));}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

   if(!CheckIfOpenOrdersByMagicNB(magicNB))//if no open orders try to enter new position
     {

      //Open  Order

      if(Sell() == true)
        {
         CloseBuyOrder();

         openOrderID = OrderSend(NULL,OP_SELL,0.1,Bid,3,0,0,NULL,magicNB,0,clrGreen);
         if(openOrderID < 0)
            Alert("order rejected. Order error: " + GetLastError());
        }

      if(Buy() == true)
        {

         CloseSellOrder();

         openOrderID = OrderSend(NULL,OP_BUY,0.1,Ask,3,0,0,NULL,magicNB,0,clrRed);
         if(openOrderID < 0)
            Alert("order rejected. Order error: " + GetLastError());
        }
     }

  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool CheckIfOpenOrdersByMagicNB( int MmagicNB)
  {
   int openOrders = OrdersTotal();

   for(int i = 0; i < openOrders; i++)
     {
      if(OrderSelect(i,SELECT_BY_POS)==true)
        {
         if(OrderMagicNumber() == MmagicNB)
           {
            return true;
           }
        }
     }
   return false;
  }

//++++++++++++++++++

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool Buy()
  {
   bool buy = false;
   if((SlowMovingAveragePrev(1) > FastMovingAveragePrev(1))
      && (FastMovingAverageCurr(0) > SlowMovingAverageCurr(0))
      && (MathAbs(FastMovingAverageCurr(0)-SlowMovingAverageCurr(0))>0.00005))
      buy=true;

   return(buy);

  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool Sell()
  {
   bool sell=false;
   if((SlowMovingAveragePrev(1) < FastMovingAveragePrev(1))
      && (SlowMovingAverageCurr(0) > FastMovingAverageCurr(0))
      && (MathAbs(SlowMovingAverageCurr(0)-FastMovingAverageCurr(0))>0.00005))

      sell=true;

   return(sell);

  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseSellOrder()
  {
   for(int i = OrdersTotal() - 1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS))
        {
         if(OrderSymbol() == _Symbol)
           {
            if(OrderMagicNumber()==magicNB)
              {
               if(OrderType()==OP_SELL)
                 {
                  bool result=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0);
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
void CloseBuyOrder()
  {
   for(int i = OrdersTotal() - 1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS))
        {
         if(OrderSymbol() == _Symbol)
           {
            if(OrderMagicNumber()==magicNB)
              {
               if(OrderType() == OP_BUY)
                 {
                  bool result=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0);
                 }
              }
           }
        }
     }
  }