Using Close Below MA To Take Profit Not Working

Erik W.  

Hi Everyone, 

I am struggling to get my EA to closes trades based on price closing below (for long trades) or above (for short trades) a weighted MA.  

I would like for the trade to be closed ONLY if price closes against the moving average.  


Currently the EA only seems to close the trade once TP (600 pts) or the SL (300 pts) is reached.


Any help is appreciated. 


Here is the code: 

//+------------------------------------------------------------------+
//|                                           Moving Average 1.0.mq5 |
//|                                                    Erik Williams |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+

#property copyright "Erik Williams"
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <Trade\Trade.mqh> // Get code from other places
//--- input parameters
input int      StopLoss=30;            // Stop Loss
input int      TakeProfit=60;          // Take Profit
input int      MA_1D_Period=5;         // 1D MA Periods (5) - Weighted - Adjust later if needed 
input int      MA_4H_Period=10;        // 4H MA Periods (10) - Wighted - Adjust later if needed
input int      MA_1H_Period=10;        // 1H MA Periods (10) - Weighted - Adjust later if needed  
input int      EA_Magic=12345;         // EA Magic Number
input double   Lot=.01;                // Lots per trade

//--- Other Parameters 
int MA_1D_Handle;                             //Handle for MA_1
int MA_4H_Handle;                             //Handle for MA_2
int MA_1H_Handle;                             //Handle for MA_3
double MA_1D_Val[], MA_4H_Val[], MA_1H_Val[]; //Dynamic Array For MA values 
int STP, TKP;                                 // Stop Loss and Take Profit Values
 
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Get Handle for 1 Day MA
   MA_1D_Handle= iMA(_Symbol,PERIOD_D1,MA_1D_Period,0,MODE_LWMA,PRICE_CLOSE);
//--- Get Handle for 4 Hour MA
   MA_4H_Handle= iMA(_Symbol,PERIOD_H4,MA_4H_Period,0,MODE_LWMA,PRICE_CLOSE);
//---Get Handle For 1 Hour MA
   MA_1H_Handle= iMA(_Symbol,PERIOD_H1,MA_1H_Period,0,MODE_LWMA,PRICE_CLOSE);
   
//--- Handling currency pairs with 5 or 3 Digit prices instead of 4 
   STP = StopLoss;
   TKP = TakeProfit;
   if(_Digits==5 || _Digits==3)
      {
      STP = STP*10;
      TKP = TKP*10;
      }        
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---Release our indicator Handles 
   IndicatorRelease(MA_1D_Handle);
   IndicatorRelease(MA_4H_Handle);
   IndicatorRelease(MA_1H_Handle);
      
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   
   CTrade  trade; // Declaring trade function 
   
//---Create an empty string for Buy and Sell Entrys
   string entry ="";
   
//--- Create an empty string for Buy and Sell Exits 
   string exit ="";

//---Get the Ask Price
   double Ask=NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK),_Digits);
   
//---Get the bid price 
   double Bid=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);      
    
//---- Check if this is the start of a new candlebar ----

   // We will use the static Old_Time variable to serve the bar time.
// At each OnTick execution we will check the current bar time with the saved one.
// If the bar time isn't equal to the saved time, it indicates that we have a new tick.

   static datetime Old_Time;
   datetime New_Time[1];
   bool IsNewBar=false;

// copying the last bar time to the element New_Time[0]
   int copied=CopyTime(_Symbol,_Period,0,1,New_Time);
   if(copied>0) // ok, the data has been copied successfully
     {
      if(Old_Time!=New_Time[0]) // if old time isn't equal to new bar time
        {
         IsNewBar=true;   // if it isn't a first call, the new bar has appeared
         if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("We have new bar here ",New_Time[0]," old time was ",Old_Time);
         Old_Time=New_Time[0];            // saving bar time
        }
     }
   else
     {
      Alert("Error in copying historical times data, error =",GetLastError());
      ResetLastError();
      return;
     }

//--- EA should only check for new trade if we have a new bar
   if(IsNewBar==false)
     {
      return;
     }
  
//--- Defining Structures we will use for the trade
   MqlTick latest_price;      //To be used for getting the latest price quote
   MqlTradeRequest mrequest;  //To be used for sending trade requests 
   MqlTradeResult mresult;    //To be used to get our trade results 
   MqlRates mrate[];          //To be used for storing prices, volume, and spread of each bar
   ZeroMemory(mrequest);      // Initialization of mrequest structure
   
   
 //---Ensuring all data in the arrays are stored newest to oldest
  
   ArraySetAsSeries(mrate,true);       // Price Array
   ArraySetAsSeries(MA_1D_Val,true);   // 1 Day Array
   ArraySetAsSeries(MA_4H_Val, true);  // 4 Hour Array
   ArraySetAsSeries(MA_1H_Val, true);  // 1 Hour Array

//--- Get the last price quote using the MQL5 MqlTick Structure
   if(!SymbolInfoTick(_Symbol,latest_price))
     {
      Alert("Error getting the latest price quote - error:",GetLastError(),"!!");
      return;
     }  
//--- Get the details of the latest 3 bars
      CopyRates(_Symbol,PERIOD_H1,0,3,mrate);
     
//--- Copy the new values of our indicators to buffers using the handle
      CopyBuffer(MA_1D_Handle,0,0,3,MA_1D_Val); 
      CopyBuffer(MA_4H_Handle,0,0,3,MA_4H_Val);
      CopyBuffer(MA_1H_Handle,0,0,3,MA_1H_Val);
      
//--- Checking to make sure we only have one open position 
      bool Buy_opened=false;  // variable to hold the result of Buy opened position
      bool Sell_opened=false; // variable to hold the result of Sell opened position
    
      if (PositionSelect(_Symbol) ==true)  // we have an opened position
      {
         if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
         {
            Buy_opened = true;  //It is a Buy
         }
         else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
         {
            Sell_opened = true; // It is a Sell
         }
      } 
//--- Copy the bar close price for the previous bar prior to the current bar, that is Bar 1
      //P_Close=mrate[1].close;  // bar 1 close price       

//--- Exit Rules - Long Exit - Using Exit indicator ---// 
   /* 
      1. Exit long trade if most recent close price is below 1 Hour Moving average
   */
//--- Declaring the conditions for closing long/buy trades
      bool Close_Buy_Condition_1 = (mrate[1].close > MA_1H_Val[1]);
      bool Close_Buy_Condition_2 = (mrate[0].close < MA_1H_Val[0]);
      
    //Long positions - Check if Exit condition is true
     if (
             (Close_Buy_Condition_1 == true) 
          && (Close_Buy_Condition_2 == true)
        )
         {
         exit = "close long";
         }
         
      // Close open buy positions 
      if (exit == "close long")
      trade.PositionClose(_Symbol, ULONG_MAX);
      
         
//--- Exit Rules - Short Exit - Using Exit indicator ---// 
   /* 
      1. Exit long trade if closing price is Above 1 Hrour Moving average
   */
//--- Declaring the conditions for closing Short/Sell trades
      bool Close_Sell_Condition_1 = (mrate[1].close < MA_1D_Val[1]);
      bool Close_Sell_Condition_2 = (mrate[0].close > MA_1H_Val[0]);
      
    //Short Positions - Check if Exit condition is true
     if (
             (Close_Sell_Condition_1 == true) 
          && (Close_Sell_Condition_2 == true)   
        )
         {
         exit = "close short";
         }
     
     // Close open sell position
     if (exit == "close short")
     trade.PositionClose(_Symbol, ULONG_MAX);                       

//--- Entry Rules - Long Entry  --- //
   /* 
      1. 1 Hour Closing Price must be greater than the current[0] 1 Day MA Value
      2. 1 Hour Closing Price must be greater than 4 Hour Moving Average
      3. 1 Hour Closing Price must be greater than 1 hour Moving Average
   */

//--- Declaring the buy conditions using bool (True/False) functions
      bool Buy_Condition_1 = (mrate[0].close > MA_1D_Val[0]);
      bool Buy_Condition_2 = (mrate[0].close > MA_4H_Val[0]);
      bool Buy_Condition_3 = (mrate[0].close > MA_1H_Val[0]);
      
  //Buy Entry Check all conditions are true
   if(
          (Buy_Condition_1 == true)
       && (Buy_Condition_2 == true)
       && (Buy_Condition_3 == true)   
     )
         {
         entry = "buy";
         }
   
   //Place Buy Entry 
   if (entry == "buy" && PositionsTotal()<1)
   trade.Buy(Lot, NULL, Ask,(Ask - STP * _Point),(Ask + TKP * _Point),NULL);
   

//--- Entry Rules - Short Entry  --- //
   /* 
      1. 1 Hour Closing Price must be less than the current[0] 1 Day MA Value
      2. 1 Hour Closing Price must be less than 4 Hour Moving Average
      3. 1 Hour Closing Price must be less than 1 hour Moving Average
   */

//--- Declaring the buy conditions using bool (True/False) functions
      bool Sell_Condition_1 = (mrate[0].close < MA_1D_Val[0]);
      bool Sell_Condition_2 = (mrate[0].close < MA_4H_Val[0]);
      bool Sell_Condition_3 = (mrate[0].close < MA_1H_Val[0]);
      
  //Buy Entry Check all conditions are true
   if(
          (Sell_Condition_1 == true)
       && (Sell_Condition_2 == true)
       && (Sell_Condition_3 == true)   
     )
         {
         entry = "sell";
         }
   
   //Place Sell Entry 
   if (entry == "sell" && PositionsTotal()<1)
   trade.Sell(Lot, NULL, Bid,(Bid + STP * _Point),(Bid - TKP * _Point),NULL);   
   
     
  }
//+------------------------------------------------------------------+
Vladimir Karputov  
1. When you create an indicator handle, you need to check the success of the operation.
2. the m_trade object must be placed in the "header" of the advisor
3. You need to check the result of copying data from indicators.
Vladimir Karputov  
4. Carefully check the conditions Close_Buy_Condition_xxxx and Close_Sell_Condition_xxxx
Erik W.  
Vladimir Karputov:
4. Carefully check the conditions Close_Buy_Condition_xxxx and Close_Sell_Condition_xxxx

Hi Vladimir, 

Thank you for your response. 

Based on the information you have provided I believe the issue has been resolved and the EA is executing trades as desired. 

Your help is appreciated!

Reason: