EA continue to open trades

 

Hello, i'm trying to build an EA.
When I run it works as coded, the problem verify once the condition for Long or Short position are met.
Let me explain deeper, when the price met all the conditions to open a Long/Short position the EA open the position, when the price hit the StopLoss or TakeProfit the position is closed correctly, is here that the problem occurs,
on the next Tick, the EA open a new position on the same direction even if the conditions to go Long/Short aren't met.


THIS IS PART OF THE CODE

---------------------------------------------------------------------------- 

if(totalOrders < maxOpenTrade && !orderAlreadyOpen) //CHECK IF MAX ORDER REACHED && IF THERE IS NOT AN ORDER ALREADY OPEN ON THE CURRENT SYMBOL
         {     
            if(goLong)//IF ALL THE PARAMS FOR THE LONG POSITION ARE MET
            { 
               
               double takeProfit = CalculateTakeProfit(true, Ask, tpPips); //CALCULATE THE TP AS PRICE BASED ON THE PIPS 
               double stopLoss = CalculateStopLoss(true, Ask, slPips); //CALCULATE THE SL AS PRICE BASED ON THE PIPS 
               double lotSize = CalculateLotSize(riskPerTrade, slPips); //CALULATE THE POSITION SIZE BASED ON THE RISK IN % CHOOSEN
            
               int orderID = OrderSend(NULL,OP_BUY,lotSize,Ask,10,stopLoss,takeProfit,NULL,magicNum); //SEND THE ORDER WITH ALL THE PARAMS SETTED
               goLong = false;
               
               
               if(orderID < 0)  //IF THE ORDER IS NOT SENT(orderID < 0) 
               {
                  Alert("Order Rejected: Error" + GetLastError() + Symbol()); //SHOW THE ERROR AS AN ALERT
               }  else {
                  Alert("Order Sent"); //ELSE, IF THE ORDER IS SENT, PRINT IT
               }
               
              
            }
            
             else if(goShort)//ELSE, IF ALL THE PARAMS FOR THE SHORT POSITION ARE MET
            { 
               double takeProfit = CalculateTakeProfit(false, Bid, tpPips); //CALCULATE THE TP AS PRICE BASED ON THE PIPS 
               double stopLoss = CalculateStopLoss(false, Bid, slPips); //CALCULATE THE SL AS PRICE BASED ON THE PIPS 
               double lotSize = CalculateLotSize(riskPerTrade, slPips); //CALULATE THE POSITION SIZE BASED ON THE RISK IN % CHOOSEN 
            
               int orderID = OrderSend(NULL,OP_SELL,lotSize,Bid,10,stopLoss,takeProfit,NULL,magicNum); //SEND THE ORDER WITH ALL THE PARAMS SETTED
               goShort = false;
               
               if(orderID < 0)  //IF THE ORDER IS NOT SENT(orderID < 0) 
               {
                  Alert("Order Rejected: Error" + GetLastError() + Symbol()); //SHOW THE ERROR AS AN ALERT
               }  else {
                  Alert("Order Sent"); //ELSE, IF THE ORDER IS SENT, PRINT IT
               }
               
     
            }                            
    
            // IF NEITHER THE PARAMS FOR THE LONG NOR THOSE FOR THE SHORT ARE MET, NOTHING HAPPENS
          
           }//END maxOpenTrade & orderAlreadyOpen CHECK

Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / Order Properties
Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / Order Properties
  • www.mql5.com
Requests to execute trade operations are formalized as orders. Each order has a variety of properties for reading. Information on them can be...
 
that's usually because of a boolean condition - while the conditions for opening a short or long position are still true...then it will continue trying to open the same position after it closes. so you need a boolean flag to say "wait" 

if(signal){

//inform EA
wait = false; //reset the flag

}


if(previous position was in profit){

        wait = true;
}
else{

  //manage things
}



if(conditions are met for trade  && !wait){

//make a new trade

}
 



Conor Mcnamara #
:

that's usually because of a boolean condition - while the conditions for opening a short or long position are still true...then it will continue trying to open the same position after it closes. so you need a boolean flag to say "wait" 




The problem is that it continue trying to open new position even if the condition are not met, and as you can see in my code, once the EA open the position i reset "goShort/goLong" to false.  
 
Pr0Tr4d3r #:

The problem is that it continue trying to open new position even if the condition are not met, and as you can see in my code, once the EA open the position i reset "goShort/goLong" to false.  
Depending on how your code is set up, you need to zone in on the area where the EA gets his new signal for a trade. You have to make that signal stop when there is a condition like "last trade was in profit" or something else.
 

based on the code you posted, you can also try this:


if(PARAMS FOR NEW TRADE){


      orderAlreadyOpen = false;    //You reset the flag here only

}


//
//
//

if(totalOrders < maxOpenTrade && !orderAlreadyOpen) //CHECK IF MAX ORDER REACHED && IF THERE IS NOT AN ORDER ALREADY OPEN ON THE CURRENT SYMBOL
         {     
            if(goLong)//IF ALL THE PARAMS FOR THE LONG POSITION ARE MET
            { 
               
               double takeProfit = CalculateTakeProfit(true, Ask, tpPips); //CALCULATE THE TP AS PRICE BASED ON THE PIPS 
               double stopLoss = CalculateStopLoss(true, Ask, slPips); //CALCULATE THE SL AS PRICE BASED ON THE PIPS 
               double lotSize = CalculateLotSize(riskPerTrade, slPips); //CALULATE THE POSITION SIZE BASED ON THE RISK IN % CHOOSEN
            
               int orderID = OrderSend(NULL,OP_BUY,lotSize,Ask,10,stopLoss,takeProfit,NULL,magicNum); //SEND THE ORDER WITH ALL THE PARAMS SETTED
               goLong = false;
               
               
               if(orderID < 0)  //IF THE ORDER IS NOT SENT(orderID < 0) 
               {
                  Alert("Order Rejected: Error" + GetLastError() + Symbol()); //SHOW THE ERROR AS AN ALERT
               }  else {
                  Alert("Order Sent"); //ELSE, IF THE ORDER IS SENT, PRINT IT
               }
 
            }
            
             else if(goShort)//ELSE, IF ALL THE PARAMS FOR THE SHORT POSITION ARE MET
            { 
               double takeProfit = CalculateTakeProfit(false, Bid, tpPips); //CALCULATE THE TP AS PRICE BASED ON THE PIPS 
               double stopLoss = CalculateStopLoss(false, Bid, slPips); //CALCULATE THE SL AS PRICE BASED ON THE PIPS 
               double lotSize = CalculateLotSize(riskPerTrade, slPips); //CALULATE THE POSITION SIZE BASED ON THE RISK IN % CHOOSEN 
            
               int orderID = OrderSend(NULL,OP_SELL,lotSize,Bid,10,stopLoss,takeProfit,NULL,magicNum); //SEND THE ORDER WITH ALL THE PARAMS SETTED
               goShort = false;
               
               if(orderID < 0)  //IF THE ORDER IS NOT SENT(orderID < 0) 
               {
                  Alert("Order Rejected: Error" + GetLastError() + Symbol()); //SHOW THE ERROR AS AN ALERT
               }  else {
                  Alert("Order Sent"); //ELSE, IF THE ORDER IS SENT, PRINT IT
               }
               
     
            }                            
    
            // IF NEITHER THE PARAMS FOR THE LONG NOR THOSE FOR THE SHORT ARE MET, NOTHING HAPPENS
          
           }//END maxOpenTrade & orderAlreadyOpen CHECK




            if(PositionsTotal() == 0){

                   orderAlreadyOpen = true;
                }   
 

I guess you use MQL4 and not MQL5....in that case use OrdersTotal() instead of PositionsTotal()


if(OrdersTotal() == 0){

     orderAlreadyOpen = true;
}
 
Pr0Tr4d3r:vTHIS IS PART OF THE CODE
               int orderID = OrderSend(NULL,OP_BUY,lotSize,Ask,10,stopLoss,takeProfit,NULL,magicNum); //SEND THE ORDER WITH ALL THE PARAMS SETTED

Be careful with NULL.

  1. On MT4, you can use NULL in place of _Symbol only in those calls that the documentation specially says you can. iHigh does, iCustom does, MarketInfo does not, OrderSend does not.
  2. Don't use NULL (except for pointers where you explicitly check for it.) Use _Symbol and _Period, that is minimalist as possible and more efficient.
  3. Zero is the same as PERIOD_CURRENT which means _Period. Don't hard code numbers.
  4. MT4: No need for a function call with iHigh(NULL,0,s) just use the predefined arrays, i.e. High[].
    MT5: create them.
  5. Cloud Protector Bug? - MQL4 programming forum (2020)
 
Conor Mcnamara #:

I guess you use MQL4 and not MQL5....in that case use OrdersTotal() instead of PositionsTotal()


i'm using MQL4, anyway the boolean that I want to reset are goLong and goShort, because once they became true(it means that all the condition to open a trade are true) they never came back FALSE, even if the conditions to open a trade aren't met anymore, i need to COMPILE the code in order to let it works again correctly.
But again once the conditions are met and the EA open the trade, the goLong/goShort will stay forever TRUE. But as you can see once i send the order i set again the boolean goLong/goShort to FALSE, and it doesn't work. 
I'm trying to send the whole code, maybe i'm doing something wrong.
Sorry for my English, maybe i'm not expleaning well the problem.
Thank you for your time.

#property copyright "GG"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property show_inputs

#include <CustomFunctions.mqh>

//DATA 

int magicNum = 888;  //UNIQUE EXPERT NUMBER
string curSymbol = Symbol(); //NAME OF THE SYMBOL IN WHICH THE EA IS RUNNING
input double percentageToRisk = 0.5;  //BALANCE PERCENTAGE TO RISK
double riskPerTrade = percentageToRisk / 100.0; //PERCENTAGE TO RISK IN DECIMAL
input int maxOpenTrade = 3; //MAX NUMBER OF TRADE OPEN SIMULTANEOUSLY
bool longDirection; //BOOLEAN IF TRUE IS LONG, ELSE IS SHORT
int slPips = 12; //STOP LOSS IN PIPS
int tpPips = 12; //DECLARING TAKE PROFIT
int totalOrders = OrdersTotal(); //TOTAL NUMBER OF ORDERS OPENED AND PENDING
double lastCandleClose = iClose(NULL,0,1);
datetime lastBarTime = 0; //VARIABLE TO STORE THE TIME OF THE LAST BAR PROCESSED
bool isTradingTime = true; //BOOLEAN TO CHECK IF IS TIME TO TRADE
int hourOfTheDay = TimeHour(TimeLocal());


//SELECT OF DIFFERENT RISK REWARD
enum ENUM_RISK_REWARD  
{ 
RR_1,
RR_2, 
RR_3 
};

input ENUM_RISK_REWARD myRiskReward = RR_1; //RISK REWARD

// BollingerBand StdDeviation2
double bb2Up = iBands(NULL,0,20,2,0,0,MODE_UPPER,1); 
double bb2Down = iBands(NULL,0,20,2,0,0,MODE_LOWER,1);
double bbMid = iBands(NULL, 0, 20, 2, 0, 0, MODE_SMA, 1);

// BollingerBand StdDeviation1
double bb1Up = iBands(NULL,0,20,1,0,0,MODE_UPPER,1);
double bb1Down = iBands(NULL,0,20,1,0,0,MODE_LOWER,1);
 
// SMMA Period 125
double smma125 = iMA(NULL,0,125,0,MODE_SMMA,0,1);
 
// SMMA Period 11
double smma11 = iMA(NULL,0,11,0,MODE_SMMA,0,1);
   
// SMMA Period 5
double smma5 = iMA(NULL,0,5,0,MODE_SMMA,0,1); 
  
// RSI
double stoch = iStochastic(NULL,0,5,1,1,0,0,0,1);
   
// STOCHASTIC
double rsi = iRSI(NULL,0,14,0,1);




//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   Alert("");
   Alert("EA just started");
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
    Alert("EA just closed");
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
//--
      
       
    if(myRiskReward == RR_1) 
         {
            tpPips = 12;
         } 
         else if(myRiskReward == RR_2) 
         {
            tpPips = 20;
         } 
         else 
         {
            tpPips = 35; 
         }

   if(hourOfTheDay > 7 && hourOfTheDay < 18) {
      isTradingTime = true;
   } else {
      isTradingTime = false;
   }
   
   if(isTradingTime) 
   {
      
       if(Time[0] != lastBarTime)  //CHECK IF THE CURRENT BAR'S TIME IS DIFFERENT FROM THE LAST
       {
   
         lastBarTime = Time[0]; // UPDATE lastBarTime TO THE CURRENT BAR'S TIME
         Alert("NEW BAR CREATED " + Symbol());
         bool orderAlreadyOpen = IsOrderOpenForSymbol(curSymbol); //DEFINE IF THE PAIR HAS ALREADY AN OPEN TRADE
         //goLong = isLong(lastCandleClose,smma125,smma5,smma11,stoch,rsi);
         bool goLong = lastCandleClose > smma125 && smma5 > smma11 && stoch <= 20 && rsi > 50; //DEFINE THE PARAMETERS FOR A LONG POSITION 
         bool goShort =  lastCandleClose < smma125 && smma5 < smma11 && stoch >= 80 && rsi < 50; //DEFINE THE PARAMETERS FOR A SHORT POSITION  
      

         
         if(totalOrders < maxOpenTrade && !orderAlreadyOpen) //CHECK IF MAX ORDER REACHED && IF THERE IS NOT AN ORDER ALREADY OPEN ON THE CURRENT SYMBOL
         {     
            if(goLong)//IF ALL THE PARAMS FOR THE LONG POSITION ARE MET
            { 
               
               double takeProfit = CalculateTakeProfit(true, Ask, tpPips); //CALCULATE THE TP AS PRICE BASED ON THE PIPS 
               double stopLoss = CalculateStopLoss(true, Ask, slPips); //CALCULATE THE SL AS PRICE BASED ON THE PIPS 
               double lotSize = CalculateLotSize(riskPerTrade, slPips); //CALULATE THE POSITION SIZE BASED ON THE RISK IN % CHOOSEN
            
               int orderID = OrderSend(NULL,OP_BUY,lotSize,Ask,10,stopLoss,takeProfit,NULL,magicNum); //SEND THE ORDER WITH ALL THE PARAMS SETTED
               
               if(orderID < 0)  //IF THE ORDER IS NOT SENT(orderID < 0) 
               {
                  Alert("Order Rejected: Error" + GetLastError() + Symbol()); //SHOW THE ERROR AS AN ALERT
               }  else {
                  Alert("Order Sent"); //ELSE, IF THE ORDER IS SENT, PRINT IT
               }
               
              
            }
            
             else if(goShort)//ELSE, IF ALL THE PARAMS FOR THE SHORT POSITION ARE MET
            { 
               double takeProfit = CalculateTakeProfit(false, Bid, tpPips); //CALCULATE THE TP AS PRICE BASED ON THE PIPS 
               double stopLoss = CalculateStopLoss(false, Bid, slPips); //CALCULATE THE SL AS PRICE BASED ON THE PIPS 
               double lotSize = CalculateLotSize(riskPerTrade, slPips); //CALULATE THE POSITION SIZE BASED ON THE RISK IN % CHOOSEN 
            
               int orderID = OrderSend(NULL,OP_SELL,lotSize,Bid,10,stopLoss,takeProfit,NULL,magicNum); //SEND THE ORDER WITH ALL THE PARAMS SETTED
               goShort = false;
               
               if(orderID < 0)  //IF THE ORDER IS NOT SENT(orderID < 0) 
               {
                  Alert("Order Rejected: Error" + GetLastError() + Symbol()); //SHOW THE ERROR AS AN ALERT
               }  else {
                  Alert("Order Sent"); //ELSE, IF THE ORDER IS SENT, PRINT IT
               }
               
     
            }                            
    
            // IF NEITHER THE PARAMS FOR THE LONG NOR THOSE FOR THE SHORT ARE MET, NOTHING HAPPENS
          
           }//END maxOpenTrade & orderAlreadyOpen CHECK
           goLong = false;
           goShort = false;
       } //END newBar CHECK
   
   }//END isTradingTime CHECK

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

  
 

I'm not sure if you understood me...like I was saying, you have to change the code to fix this issue you have.

I can't test it, but this is how you should change it:


if(goLong){

     tradeInitialize = 1;
    orderAlreadyOpen = false;
}
else if(goShort){

      tradeInialize = -1;
    orderAlreadyOpen = false;

}
else{
      tradeInitialize = 0;
   orderAlreadyOpen = true;
}


  if(totalOrders < maxOpenTrade && !orderAlreadyOpen) //CHECK IF MAX ORDER REACHED && IF THERE IS NOT AN ORDER ALREADY OPEN ON THE CURRENT SYMBOL
         {     
            if(tradeInitialize == 1)//IF ALL THE PARAMS FOR THE LONG POSITION ARE MET
            { 
               
               double takeProfit = CalculateTakeProfit(true, Ask, tpPips); //CALCULATE THE TP AS PRICE BASED ON THE PIPS 
               double stopLoss = CalculateStopLoss(true, Ask, slPips); //CALCULATE THE SL AS PRICE BASED ON THE PIPS 
               double lotSize = CalculateLotSize(riskPerTrade, slPips); //CALULATE THE POSITION SIZE BASED ON THE RISK IN % CHOOSEN
            
               int orderID = OrderSend(NULL,OP_BUY,lotSize,Ask,10,stopLoss,takeProfit,NULL,magicNum); //SEND THE ORDER WITH ALL THE PARAMS SETTED
               
               if(orderID < 0)  //IF THE ORDER IS NOT SENT(orderID < 0) 
               {
                  Alert("Order Rejected: Error" + GetLastError() + Symbol()); //SHOW THE ERROR AS AN ALERT
               }  else {
                  Alert("Order Sent"); //ELSE, IF THE ORDER IS SENT, PRINT IT
               }
               goLong = false;
              
            }
            
             else if(tradeInitialize == -1)//ELSE, IF ALL THE PARAMS FOR THE SHORT POSITION ARE MET
            { 
               double takeProfit = CalculateTakeProfit(false, Bid, tpPips); //CALCULATE THE TP AS PRICE BASED ON THE PIPS 
               double stopLoss = CalculateStopLoss(false, Bid, slPips); //CALCULATE THE SL AS PRICE BASED ON THE PIPS 
               double lotSize = CalculateLotSize(riskPerTrade, slPips); //CALULATE THE POSITION SIZE BASED ON THE RISK IN % CHOOSEN 
            
               int orderID = OrderSend(NULL,OP_SELL,lotSize,Bid,10,stopLoss,takeProfit,NULL,magicNum); //SEND THE ORDER WITH ALL THE PARAMS SETTED
               
               
               if(orderID < 0)  //IF THE ORDER IS NOT SENT(orderID < 0) 
               {
                  Alert("Order Rejected: Error" + GetLastError() + Symbol()); //SHOW THE ERROR AS AN ALERT
               }  else {
                  Alert("Order Sent"); //ELSE, IF THE ORDER IS SENT, PRINT IT
               }
               goShort = false;
              }

     
     }   
     

if(OrdersTotal() == 0){

    orderAlreadyOpen = true;
}
 

Hi

You must overwrite goLong/goShort variables somewhere else in the code. The conditions have to be checked again during trade’s life and set to true.

That’s why later the EA opens trade immediately after the old trade is closed. Please show us the full code of your EA and maybe we will be able to help you more.

Best Regards

 
  1. int totalOrders = OrdersTotal(); //TOTAL NUMBER OF ORDERS OPENED AND PENDING
    double lastCandleClose = iClose(NULL,0,1);
    double bb2Up = iBands(NULL,0,20,2,0,0,MODE_UPPER,1); 
    double bb2Down = iBands(NULL,0,20,2,0,0,MODE_LOWER,1);
    double bbMid = iBands(NULL, 0, 20, 2, 0, 0, MODE_SMA, 1);
    double bb1Up = iBands(NULL,0,20,1,0,0,MODE_UPPER,1);
    double bb1Down = iBands(NULL,0,20,1,0,0,MODE_LOWER,1);
    double smma125 = iMA(NULL,0,125,0,MODE_SMMA,0,1);
    double smma11 = iMA(NULL,0,11,0,MODE_SMMA,0,1);
    double smma5 = iMA(NULL,0,5,0,MODE_SMMA,0,1); 
    double stoch = iStochastic(NULL,0,5,1,1,0,0,0,1);
    double rsi = iRSI(NULL,0,14,0,1);
    

    Those are not assignments; they are initialization of a common (globally declared), or static variable(s) with a constant. They work exactly the same way in MT4/MT5/C/C++.

    1. They are initialized once on program load.

    2. They don't update unless you assign to them.

    3. In C/C++ you can only initialize them with constants, and they default to zero. In MTx you should only initialize them with constants. There is no default in MT5, or MT4 with strict (which you should always use).

      MT4/MT5 actually compiles with non-constants, but the order that they are initialized is unspecified and Don't try to use any price (or indicator) or server related functions in OnInit (or on load or in OnTimer before you've received a tick), as there may be no connection/chart yet:

      1. Terminal starts.
      2. Indicators/EAs are loaded. Static and globally declared variables are initialized. (Do not depend on a specific order.)
      3. OnInit is called.
      4. For indicators OnCalculate is called with any existing history.
      5. Human may have to enter password, connection to server begins.
      6. New history is received, OnCalculate called again.
      7. A new tick is received, OnCalculate/OnTick is called. Now TickValue, TimeCurrent, account information and prices are valid.

    4. Unlike indicators, EAs are not reloaded on chart change, so you must reinitialize them, if necessary.
                external static variable - MQL4 programming forum #2 (2013)


  2. Why did you post your MT4 question in the MT5 Trading Systems section instead of the MQL4 section, (bottom of the Root page)?
              General rules and best pratices of the Forum. - General - MQL5 programming forum? (2017)
    Next time, post in the correct place. The moderators will likely move this thread there soon.