Need help with MA cross when MA's are a set distance apart

 

Hi guys,

I'm fairly new to mql4, but not programming. Heres the code I've tried so far but it's not working. What I'm trying to do is enter a trade when the 2 MA's are a certain distance apart, and then exit when they cross.

int Period1 = 7;
int Period2 = 18;
int orderNumber;
double stopLossConst = 2000;     // SL for an opened order
double takeProfitConst = 2000;
double stopLoss;
double takeProfit;
double numLots = 1;
int crossing = 0;
int openOrderNumber;
double openOrderLots;
bool isClosed = false;
int modifyCount = 0;

string symb;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
//int init()
//  {
//----

//----
//   return(0);
//  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
//int deinit()
//  {
//----
   
//----
//   return(0);
//  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
   symb = Symbol();
   //Make sure there are enough bars int he window for the MA's to work
   if (Bars < Period2)
   {
      return;
   }
   crossing = 0;
   
   double movingAverage7, movingAverage18, movingAverage7Prev, movingAverage18Prev, movingAverageDif;
   RefreshRates();
   //Get the price of the moving averages
   movingAverage7 = iMA(NULL, 0, Period1, 0, MODE_EMA, PRICE_CLOSE, 0);
   movingAverage7Prev = iMA(NULL, 0, Period1, 0, MODE_EMA, PRICE_CLOSE, 1);
   movingAverage18 = iMA(NULL, 0, Period2, 0, MODE_EMA, PRICE_CLOSE, 0);
   movingAverage18Prev = iMA(NULL, 0, Period2, 0, MODE_EMA, PRICE_CLOSE, 1);
   
   //Buying or selling?
   if (movingAverage7Prev < movingAverage18Prev && movingAverage7 > movingAverage18)
   {
      movingAverageDif = movingAverage7 - movingAverage18;
      crossing = 1;
   }
   if (movingAverage7Prev < movingAverage18Prev && movingAverage7 > movingAverage18)
   {  
      movingAverageDif = movingAverage18 - movingAverage7;
      crossing = -1;
   }

   if (IsOrderOpen() == false)
   {
      if (movingAverageDif > 14 * Point) // If the difference is acceptable, open an order
      {
         while (true)
         {
            //Open a trade
            RefreshRates();
            if (crossing > 0)
            {
               stopLoss = Bid - stopLossConst*Point;     // Calculating stop loss
               takeProfit = Bid + takeProfitConst*Point;   // Calculating take profit
               orderNumber = OrderSend(symb, OP_BUY, numLots, Ask, 2, stopLoss, takeProfit, NULL, 0, 0, Red);//Opening Buy
               takeProfit = 0;
               stopLoss = 0;
            }
            if (crossing < 0)
            {
               stopLoss = Ask + stopLossConst*Point;     // Calculating stop loss
               takeProfit = Ask - takeProfitConst*Point;   // Calculating take profit
               orderNumber = OrderSend(symb, OP_SELL, numLots, Bid, 2, stopLoss, takeProfit, NULL, 0, 0, Green);//Opening Buy
               takeProfit = 0;
               stopLoss = 0;
            }
            if (orderNumber < 0)                        // Success
            {
               //Alert ("Opened order Buy ",orderNumber);
               return;                             // Exit start()
            }
            if (Process_Error(GetLastError())==1)    // Processing errors
            {
               continue;                           // Retrying
            }
            return;
         }                               // Exit start()
      }
   }
   else //Open Order so test for close or recalculate stops
   {
      //If the MA's cross, close the order (******TODO******:potentially on a new bar???)
      //If buying, close sell, if selling, close buy
      if (crossing > 0)
      {
         //Alert("Close condition met.");
         while (!isClosed)
         {
            RefreshRates();
            isClosed = OrderClose(openOrderNumber, openOrderLots, Ask, 2);
            if (isClosed)
            {
               return;
            }
            if (Process_Error(GetLastError())==1)    // Processing errors
            {
               continue;                           // Retrying
            }
            else
            {
               Alert ("Unable to close order!!", openOrderNumber);
            }
         }
      }
      else
      {
         
            // Modify Sell.
        
      }
      if (crossing < 0)
      {
         Alert("Close condition met.");
         while (!isClosed)
         {
            RefreshRates();
            isClosed = OrderClose(openOrderNumber, openOrderLots, Bid, 2);
            if (isClosed)
            {
               return;
            }
            if (Process_Error(GetLastError())==1)    // Processing errors
            {
               continue;                           // Retrying
            }
            else
            {
               Alert ("Unable to close order!!", openOrderNumber);
            }
         }
      }   
      else
      {
         
            // Modify Buy.
            
      }
      
    }
//----
   return(0);
  }
//+------------------------------------------------------------------+

bool IsOrderOpen(){
   for(int i=0; i<OrdersTotal(); i++)                      // Loop through all open orders
   {                    
      if (OrderSelect(i,SELECT_BY_POS))                     // Select the open order at the position of the index
      {                   
         if (OrderType() > 1)
         {
            //Alert("Pending Order");
            return (true);                                  // Return true as pending order
         }
         if (OrderSymbol()== symb)
         {
            //Alert("Open Order Ticket ", OrderTicket());
            openOrderNumber = OrderTicket();
            openOrderLots = OrderLots();
            return (true);                                  // Return true (meaning order open for the current security)
         }
      }
   }
   //Alert("NO Open Order");
   return (false);
}

I've got a lot of this from the book and these forums. I still don't fully understand why I need 4 Ma's (https://www.mql5.com/en/forum/139415) as well, if someone could explain that? Cheers :)

 

I only read through your code as far as this and stopped as it doesn't make sense.

 if (movingAverage7Prev < movingAverage18Prev && movingAverage7 > movingAverage18)
   {
      movingAverageDif = movingAverage7 - movingAverage18;
      crossing = 1;
   }
   if (movingAverage7Prev < movingAverage18Prev && movingAverage7 > movingAverage18)
   {  
      movingAverageDif = movingAverage18 - movingAverage7;
      crossing = -1;
   }

The 2 if conditions are exactly the same, but with different actions based on the condition.

 
GBen: I still don't fully understand why I need 4 Ma's (https://www.mql5.com/en/forum/139415)
  1. How do you define cross? Fast WAS below slow and now fast IS above slow? Isn't that 4 values (not 4 Ma's?) Fast previous, fast current, slow previous, and slow current.
  2. Like GumRai said same condition. Or learn to use booleans correctly
    bool wasBelow  = movingAverage7Prev < movingAverage18Prev,
          isBelow  = movingAverage7     < movingAverage18,
         isCrossed = wasBelow != isBelow;
    crossing = movingAverage7 - movingAverage18; // +/- crossing should be renamed direction
    movingAverageDif = MathAbs(crossing);
  3. What is the initial value going into the while loop?
             Alert("Close condition met.");
             while (!isClosed)

 

1. When looking at a chart with just 2 MA's, just see one cross the other but don't really think about the values. Thanks for the explanation, makes sense.

2. My dumb mistake. Fixed. Your code here also helped me figure out where I went wrong, thanks :) Picking up crosses and entering at what looks like the right spot!

3. Missed that line, isClosed was set to true, I copied out the code I thought relevant but I guess I missed that line.

Reason: