How to make EA opens only 1 trade per candle?

Hello Everyone,

I am new to EA coding. Somehow i was able yo make a code for simple RSI. But the problem i am facing is that it opens so many order whenever the RSI condition is met.

It is opening position at every tick.
I need to add a piece of code so that this EA opens only 1 trade per candle.

#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>

int pos=0;
int myRSIDefinition;

CTrade trade; // To send orders and close positions
CPositionInfo positionInfo; // to get info about current positions

int OnInit()
  {
// Define the handler once at EA Init, not every tick
   myRSIDefinition=iRSI(Symbol(),Period(),14,PRICE_CLOSE);
// If is not posible to get indicator handler print some error information and return with error code
   if(myRSIDefinition==INVALID_HANDLE)
     {
      Print("There was an error creating RSI handler!");
      return(INIT_FAILED);
     }
   return INIT_SUCCEEDED;
  }

void OnTick()
  {
  
  
   string signal="";
   double  Ask=NormalizeDouble(SymbolInfoDouble(Symbol(),SYMBOL_ASK),Digits());
   double  Bid=NormalizeDouble(SymbolInfoDouble(Symbol(),SYMBOL_BID),Digits());
   double myRSIArray[];
   ArraySetAsSeries(myRSIArray,true);
   CopyBuffer(myRSIDefinition,0,0,3,myRSIArray);
   double myRSIValue=NormalizeDouble(myRSIArray[0],2);
   if(myRSIValue>70)
      signal="sell";
   if(myRSIValue<30)
      signal="buy";

   if(signal=="buy")
     {
      //First close all Sell positions
      for(pos=0; pos<PositionsTotal(); pos++)
        {
         //Select the position to load info
         if(positionInfo.SelectByIndex(pos))
           {
            // Get the position type, if sell then close it
            if(positionInfo.PositionType()==POSITION_TYPE_SELL)
              {
               trade.PositionClose(positionInfo.Ticket());
              }
           }
        }
        if (signal =="buy" && PositionsTotal()<1)
      trade.Buy(0.01,Symbol());
     Comment ("The current signal is: ",signal);
     }

   if(signal=="sell")
     {
      //First close all Buy positions
      for(pos=0; pos<PositionsTotal(); pos++)
        {
         //Select the position to load info
         if(positionInfo.SelectByIndex(pos))
           {
            // Get the position type, if buy then close it
            if(positionInfo.PositionType()==POSITION_TYPE_BUY)
              {
               trade.PositionClose(positionInfo.Ticket());
              }
           }
        }
        
        if (signal =="sell" && PositionsTotal()<1)
      trade.Sell(0.01,Symbol());
     Comment ("The current signal is: ",signal);
     }
     


  }

Hi

You can use this code on this link:

https://www.mql5.com/en/forum/216567

Hello,

Thanks for your response. When it Run your code here. I do not know which part of the code i should put here. My code is as follows

datetime NewTime=0;
void start()
  {
   if(NewTime!=Time[0]) // Run only on new bars
     {
      NewTime=Time[0];
  // Enter code to run once per bar here.   /// I do not know how to enter the code RSI code here Please help
     }
  }

#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>

int pos=0;
int myRSIDefinition;

CTrade trade; // To send orders and close positions
CPositionInfo positionInfo; // to get info about current positions

int OnInit()
{
// Define the handler once at EA Init, not every tick
myRSIDefinition=iRSI(Symbol(),Period(),14,PRICE_CLOSE);
// If is not posible to get indicator handler print some error information and return with error code
if(myRSIDefinition==INVALID_HANDLE)
{
Print(“There was an error creating RSI handler!”);
return(INIT_FAILED);
}
return INIT_SUCCEEDED;
}

void OnTick()
{

string signal="";
double Ask=NormalizeDouble(SymbolInfoDouble(Symbol(),SYMBOL_ASK),Digits());
double Bid=NormalizeDouble(SymbolInfoDouble(Symbol(),SYMBOL_BID),Digits());
double myRSIArray[];
ArraySetAsSeries(myRSIArray,true);
CopyBuffer(myRSIDefinition,0,0,3,myRSIArray);
double myRSIValue=NormalizeDouble(myRSIArray[0],2);
if(myRSIValue>70)
signal=“sell”;
if(myRSIValue<30)
signal=“buy”;

if(signal==“buy”)
{
//First close all Sell positions
for(pos=0; pos<PositionsTotal(); pos++)
{
//Select the position to load info
if(positionInfo.SelectByIndex(pos))
{
// Get the position type, if sell then close it
if(positionInfo.PositionType()==POSITION_TYPE_SELL)
{
trade.PositionClose(positionInfo.Ticket());
}
}
}
if (signal ==“buy” && PositionsTotal()<1)
trade.Buy(0.01,Symbol());
Comment ("The current signal is: ",signal);
}

if(signal==“sell”)
{
//First close all Buy positions
for(pos=0; pos<PositionsTotal(); pos++)
{
//Select the position to load info
if(positionInfo.SelectByIndex(pos))
{
// Get the position type, if buy then close it
if(positionInfo.PositionType()==POSITION_TYPE_BUY)
{
trade.PositionClose(positionInfo.Ticket());
}
}
}

    if (signal =="sell" && PositionsTotal()<1)
  trade.Sell(0.01,Symbol());
 Comment ("The current signal is: ",signal);
 }

}

You need to add a new bar check and from there you set the signal. So when a new bar occurs you copy the RSI buffer for bars 1 and 2 (2 values) and check if you had an upcross or downcross in the last candle.

bool isNewBar=IsNewBar(); // new bar check
signal="";

if(isNewBar)
  {
   static double myRSIArray[2];
   int shift=1;
   int amount=2;
   if(CopyBuffer(myRSIDefinition,MAIN_LINE,shift,amount,myRSIArray)!=amount) { Print("CopyBuffer failed, error: ",_LastError); return; }
   double rsi1=myRSIArray[1];
   double rsi2=myRSIArray[0];
   if(rsi2<=70 && rsi1>70)
      signal="sell";
   if(rsi2>=30 && rsi1<30)
      signal="buy";
  }