MQL5 When Stop Loss is hit, wait for MACD to cross 0 - page 2

 
Seng Joo Thio:

Hmm... that seems unnecessary, unless I misread your words again (LOL).

This algorithm (same as what I described earlier) should suffice:


Only slight tweaking, in future, if you decided to open more than one trade at one time...


I have edited the code, it runs but it isn't taking any position.

Check out the OnTradeTransaction and CheckforOpen functions. Those are the ones I edited. I have included the MACDstop but something must not be working.

What do you think?


//+------------------------------------------------------------------+
//|MartinStrategy.mq5 |
//+------------------------------------------------------------------+

#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\DealInfo.mqh>

input int  PositionSize           = 1;      // Position size (cost of one pip)
input int shortemaPeriods         = 50;
input int longemaPeriods          = 200;
input int stochastic_k_period     = 21;
input int stochastic_d_period     = 3;
input int stochastic_slowing_period =3;
input bool UseTakeProfit          = true;  // Use Take Profit
input int  Take_Profit            = 20;     // Take Profit
input int StopLossDistance        = 20;    // Stop loss distance in pips
input bool IsUseTrailingStop      = false;      //Use trailing stop
input int  TrailingStopDistance   = 40;    // Trailing stop distance in pips

bool MACDStop = false;
int  ordermax  = 1;

//---
CTrade myTradingControlPanel;
double shortemaData[], longemaData[]; // You can declare multiple variables of the same data type in the same line.
int numberOfShortemaData, numberOfLongemaData; 
int shortemaControlPanel, longemaControlPanel;
double shortema1, shortema2, longema1, longema2;
int    stochastic_handle=0;
bool   ext_hedging=true;
CTrade ext_trade;
CSymbolInfo symbol_info;
ulong arr_ticket_long_stochastic[];
ulong arr_ticket_long_rsi_stochastic[];
ulong arr_ticket_short_stochastic[];
ulong arr_ticket_short_rsi_stochastic[];
double adjusted_point;
double trailing_stop_value;
double take_profit_value;
double stop_loss_value;
int digits_adjust=1;
int tick_counter=0;
int time_in_open_function=-1;
int time_in_close_function=-1;

double ask_price=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
double bid_price=SymbolInfoDouble(_Symbol,SYMBOL_BID);

int Cnt;


#define MA_MAGIC 2719281928459450


//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{

   ArraySetAsSeries(shortemaData,true);   // Setting up table/array for time series data
   ArraySetAsSeries(longemaData,true);    // Setting up table/array for time series data

   shortemaControlPanel = iMA(_Symbol, PERIOD_M15, shortemaPeriods, 0, MODE_EMA, PRICE_CLOSE); // Getting the Control Panel/Handle for short SMA
   longemaControlPanel = iMA(_Symbol, PERIOD_M15, longemaPeriods, 0, MODE_EMA, PRICE_CLOSE); // Getting the Control Panel/Handle for long SMA


//--- prepare trade class to control positions if hedging mode is active
   ext_hedging=((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING);
   ext_trade.SetExpertMagicNumber(MA_MAGIC);
   ext_trade.SetMarginMode();
   symbol_info.Name(_Symbol);
   
   if(symbol_info.Digits()==3 || symbol_info.Digits()==5)
      digits_adjust=10;
   adjusted_point=symbol_info.Point()*digits_adjust;
   trailing_stop_value=TrailingStopDistance*adjusted_point;
   stop_loss_value=StopLossDistance*adjusted_point;
   take_profit_value=Take_Profit*adjusted_point;
   
   //initialize handle for stochastic
   stochastic_handle=iStochastic(_Symbol,_Period,stochastic_k_period,stochastic_d_period,stochastic_slowing_period,MODE_SMA,STO_LOWHIGH);
   if(stochastic_handle==INVALID_HANDLE)
   {
      printf("Error creating Stochastic oscillator");
      return(INIT_FAILED);
   }

   ArrayResize(arr_ticket_long_stochastic,0,100000);
   ArrayResize(arr_ticket_long_rsi_stochastic,0,100000);
   ArrayResize(arr_ticket_short_stochastic,0,100000);
   ArrayResize(arr_ticket_short_rsi_stochastic,0,100000);
//--- ok

   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

   IndicatorRelease(shortemaControlPanel);
   IndicatorRelease(longemaControlPanel);

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
 {
   CheckForClose();
   CheckForOpen();
//   TradeCount(PERIOD_CURRENT);

   numberOfShortemaData = CopyBuffer(shortemaControlPanel, 0, 0, 3, shortemaData); // Collect most current SMA(10) Data and store it in the datatable/array shortSmaData[]
   numberOfLongemaData = CopyBuffer(longemaControlPanel, 0, 0, 3, longemaData); // Collect most current SMA(40) Data and store it in the datatable/array longSmaData[]
   
   shortema1 = shortemaData[1];
   shortema2 = shortemaData[2];
   longema1 = longemaData[1];  
   longema2 = longemaData[2];  
   
 }

//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- get transaction type as enumeration value 
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
//--- if transaction is result of addition of the transaction in history

   if(type==TRADE_TRANSACTION_DEAL_ADD)
     {
      long     deal_entry        =0;
      long     deal_type         =0;
      double   deal_price        =0.0;
      double   deal_profit       =0.0;
      double   deal_volume       =0.0;
      string   deal_symbol       ="";
      long     deal_magic        =0;
      int      deal_reason       =0;
      if(HistoryDealSelect(trans.deal))
        {
         deal_entry=HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
         deal_type=HistoryDealGetInteger(trans.deal,DEAL_TYPE);
         deal_price=HistoryDealGetDouble(trans.deal,DEAL_PRICE);
         deal_profit=HistoryDealGetDouble(trans.deal,DEAL_PROFIT);
         deal_volume=HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
         deal_symbol=HistoryDealGetString(trans.deal,DEAL_SYMBOL);
         deal_magic=HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
         deal_reason=HistoryDealGetInteger(trans.deal,DEAL_REASON);
        }
      else
         return;

      if (deal_entry==DEAL_ENTRY_OUT && deal_reason==DEAL_REASON_SL)
        {
        MACDStop = true;
        }
     }
  }
   
//+------------------------------------------------------------------+
//| Try to open the deal                                          |
//+------------------------------------------------------------------+
 void CheckForOpen()
 {
   MqlRates rt[2];
   if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
   {
      Print("CopyRates of ",_Symbol," failed, no history");
      return ;
   }
  
   datetime cur_time=rt[1].time;
   MqlDateTime mdt;
   TimeToStruct(cur_time,mdt);
   int cur_calculated_time=mdt.hour*60+mdt.min;
   if(cur_calculated_time==time_in_open_function)
      return;
   time_in_open_function=cur_calculated_time;  
   /*if(rt[1].tick_volume>1)
      return ;*/

   //remove unnecessary orders
   RefreshOrders();
   //move trailing stop orders if it is necessary
   ModifyOrders();
         
   //reserve array for Stochastic 
   double   stochastic_k_line[3];
   double   stochastic_d_line[3];   
   
   //get Stochastic k-line values
   if(CopyBuffer(stochastic_handle,MAIN_LINE,0,3,stochastic_k_line)!=3)
   {
      Print("CopyBuffer from iStochastic failed, no data");
      return ;
   }
   //get Stochastic d-line values
   if(CopyBuffer(stochastic_handle,SIGNAL_LINE,0,3,stochastic_d_line)!=3)
   {
      Print("CopyBuffer from iStochastic failed, no data");
      return ;
   }
      
   string str_date_time= TimeToString(TimeCurrent())+" ";


   if (((shortema1 < longema1) && (shortema2 > longema2)) || ((shortema1 > longema1) && (shortema2 < longema2)))
   {
   MACDStop = false;
   }

   if (MACDStop = false)
   {
      if(shortema1 > longema1)
            {
         if(stochastic_k_line[1]>20 && stochastic_k_line[0]<=20)
         {
            if(bid_price > longema1)
            {
   
               Alert("Open long position, because k stochastic enters 0;20 zone");
               Print("Try to open long for ",_Symbol);
               OpenPosition(arr_ticket_long_stochastic,ORDER_TYPE_BUY);
               return;
            }
         }
      }

   //check condition "Stochastic indicator (%K line) leaves the 80-100 zone"
   //to open short position
      if(shortema1 < longema1)
      {
         if(stochastic_k_line[1]>80 && stochastic_k_line[0]<=80)
         {
            if(bid_price < longema1)
            {
   
               Alert("Open short position, because k stochastic leaves 80;100 zone");
               Print("Try to open short for ",_Symbol);
               OpenPosition(arr_ticket_short_stochastic,ORDER_TYPE_SELL);
               return;
            }
         }
      }
 }
 }
 //+------------------------------------------------------------------+
//| Open position                                                  |
//+------------------------------------------------------------------+
 void OpenPosition(ulong& arr_ticket[],ENUM_ORDER_TYPE order_type)
 {
        
    if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && Bars(_Symbol,_Period)>100)
    {
        string str_date_time= TimeToString(TimeCurrent())+" ";
        double stop_loss=0;
        double take_profit=0;
//        double ask_price=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
//        double bid_price=SymbolInfoDouble(_Symbol,SYMBOL_BID);

        double local_stop_loss_value=IsUseTrailingStop ? trailing_stop_value:stop_loss_value;
        //Calculate stop loss price
        if(local_stop_loss_value!=0)
           stop_loss=order_type==ORDER_TYPE_SELL ? NormalizeDouble(ask_price+local_stop_loss_value,Digits()):
                                                       NormalizeDouble(bid_price-local_stop_loss_value,Digits());

           take_profit=order_type==ORDER_TYPE_SELL ? NormalizeDouble(bid_price-take_profit_value,Digits()):
                                                       NormalizeDouble(ask_price+take_profit_value,Digits());

        //Calculate lot size                                               
        double lot_size=GetLotSize();
        string str_comment=_Symbol+_Period+TimeToString(TimeCurrent());
        bool is_open=ext_trade.PositionOpen(_Symbol,order_type,lot_size,
                               SymbolInfoDouble(_Symbol,order_type==ORDER_TYPE_SELL ? SYMBOL_BID:SYMBOL_ASK),
                               stop_loss,take_profit,str_comment);
        uint result_ret_code=ext_trade.ResultRetcode();
        if(is_open)
        {
           Print("Terminal opened the deal for ",_Symbol);
           ulong ticket=ext_trade.ResultDeal();
           uint total=PositionsTotal();
           for(uint i=0; i<total; i++)
           {
              string symbol=PositionGetSymbol(i);
              string comment=PositionGetString(POSITION_COMMENT);
              if(symbol==_Symbol && comment==str_comment)
              {
                 ticket=PositionGetInteger(POSITION_TICKET);
               
              }
              
           }
           int array_size=ArraySize(arr_ticket);
           ArrayResize(arr_ticket,array_size+1);
           arr_ticket[array_size]=ticket;
           
        }
        else
        {
           Print("Terminal could not open deal for ",_Symbol);
           Print("Terminal error code= ",result_ret_code);
        }
    }
        
 }
//+------------------------------------------------------------------+
//| Check for close position conditions                                                 |
//+------------------------------------------------------------------+
bool CheckForClose()
{
   MqlRates rt[2];
   if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
   {
      Print("CopyRates of ",_Symbol," failed, no history");
      return false;
   }
   datetime cur_time=rt[1].time;
   MqlDateTime mdt;
   TimeToStruct(cur_time,mdt);
   int cur_calculated_time=mdt.hour*60+mdt.min;
   if(cur_calculated_time==time_in_close_function)
      return false;
   time_in_close_function=cur_calculated_time;
   /*if(rt[1].tick_volume>1)
      return false;*/
      
   //--- get current Stochastic 
   double   stochastic_k_line[3];
   double   stochastic_d_line[3];
   if(CopyBuffer(stochastic_handle,MAIN_LINE,0,3,stochastic_k_line)!=3)
   {
      Print("CopyBuffer from iStochastic failed, no data");
      return false;
   }
   if(CopyBuffer(stochastic_handle,SIGNAL_LINE,0,3,stochastic_d_line)!=3)
   {
      Print("CopyBuffer from iStochastic failed, no data");
      return false;
   }
   
   return false;
}

//+------------------------------------------------------------------+
//| Close position with the specified ticket                                                 |
//+------------------------------------------------------------------+
void ClosePosition(ulong& arr_tickets[])
{

          ENUM_POSITION_TYPE position_type=PositionGetInteger(POSITION_TYPE);

   string date_time_string=TimeToString(TimeCurrent())+" ";
   for(int i=0;i<ArraySize(arr_tickets);i++)
   {
       ulong ticket=arr_tickets[i];
       
       bool is_selected=PositionSelectByTicket(ticket);
       if(is_selected)
       {
      
          if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && Bars(_Symbol,_Period)>100)
          {
             bool is_close=ext_trade.PositionClose(ticket,3);
             if(!is_close)
             {
                 uint result_ret_code=ext_trade.ResultRetcode();
                 Print("Terminal could not close the position for",_Symbol," the error Code=",result_ret_code);
             }
          }
         
       }
       else
       {
       
       }
       ticket=0;
   }
   ArrayResize(arr_tickets,0,10000);
}
//+------------------------------------------------------------------+
//| Remove unnecessary orders from tickets array                                                 |
//+------------------------------------------------------------------+
void RefreshArray(ulong& arr_ticket[])
{ 
   ulong buffer_array[];
   ArrayResize(buffer_array,0,10000);
   int count=0;
   for(int i=0;i<ArraySize(arr_ticket);i++)
   {
       ulong ticket=arr_ticket[i];
       bool is_selected=PositionSelectByTicket(ticket);
       if(is_selected)
       {
          ArrayResize(buffer_array,count+1,10000);
          buffer_array[count]=ticket;
          count++;
       }
   }
   if(ArraySize(buffer_array)!=ArraySize(arr_ticket))
   {
      ArrayResize(arr_ticket,ArraySize(buffer_array),10000);
      ArrayCopy(arr_ticket,buffer_array,0,0,WHOLE_ARRAY);
   }
}
//+------------------------------------------------------------------+
//| Remove unnecessary orders from all tickets array                                                 |
//+------------------------------------------------------------------+
void RefreshOrders()
{
   RefreshArray(arr_ticket_long_stochastic);
   RefreshArray(arr_ticket_long_rsi_stochastic);
   RefreshArray(arr_ticket_short_stochastic);
   RefreshArray(arr_ticket_short_rsi_stochastic);
}
//+------------------------------------------------------------------+
//| Get lot size for the deal                                                 |
//+------------------------------------------------------------------+
double GetLotSize()
{
    double lot_step=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
    double lot_value=SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE);
    double min_lot=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
    double max_lot=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
    double lot_size_for_deal=1.0*PositionSize/(lot_value*digits_adjust); 
    lot_size_for_deal=GetLotSize(lot_size_for_deal, lot_step,min_lot,max_lot); 
    return lot_size_for_deal;
}
//+------------------------------------------------------------------+
//| Get best fit lot size for the calculated one                                                 |
//+------------------------------------------------------------------+
double GetLotSize(double calculated_lot_size,double lot_size_step,double min_lot_size,double max_lot_size)
{
   if(calculated_lot_size<min_lot_size)
      return min_lot_size;
   if(calculated_lot_size>max_lot_size)
      return max_lot_size;
   double cur_lot_size=lot_size_step;
   double next_lot_size=cur_lot_size+lot_size_step;
   do
   {
     if(calculated_lot_size>=cur_lot_size && calculated_lot_size<=next_lot_size)
     {
        if(calculated_lot_size==cur_lot_size)
           return cur_lot_size;
        if(calculated_lot_size==next_lot_size)
           return next_lot_size;
        if(calculated_lot_size-cur_lot_size<next_lot_size-calculated_lot_size)
           return cur_lot_size;
        else
           return next_lot_size;
     }
     cur_lot_size=next_lot_size;
     next_lot_size=cur_lot_size+lot_size_step;
   }while(true);
}
//+------------------------------------------------------------------+
//| Move trailing stop if it is necessary for all orders                                                 |
//+------------------------------------------------------------------+
void ModifyOrders()
{
   ModifyOrders(arr_ticket_long_stochastic);
   ModifyOrders(arr_ticket_long_rsi_stochastic);
   ModifyOrders(arr_ticket_short_stochastic);
   ModifyOrders(arr_ticket_short_rsi_stochastic);
}
//+------------------------------------------------------------------+
//| Move trailing stop if it is necessary for all orders from array                                                |
//+------------------------------------------------------------------+
void ModifyOrders(ulong& arr_ticket[])
{

   if(!IsUseTrailingStop || TrailingStopDistance==0)
      return;
    for(int i=0;i<ArraySize(arr_ticket);i++)
   {
       ulong ticket=arr_ticket[i];
       bool is_selected=PositionSelectByTicket(ticket);
       if(is_selected)
       {
          ENUM_POSITION_TYPE position_type=PositionGetInteger(POSITION_TYPE);
          double open_price=PositionGetDouble(POSITION_PRICE_OPEN);
          double current_stop_loss=PositionGetDouble(POSITION_SL);
          double local_stop_loss;
//          double ask_price=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
//          double bid_price=SymbolInfoDouble(_Symbol,SYMBOL_BID);
          if(position_type==POSITION_TYPE_BUY)
          {
             if(bid_price-open_price>trailing_stop_value)
             {
                local_stop_loss=NormalizeDouble(bid_price-trailing_stop_value,Digits());
                if(current_stop_loss<local_stop_loss)
                {
                   ext_trade.PositionModify(ticket,local_stop_loss,0);
                }
             }
          }
          else if(position_type==POSITION_TYPE_SELL)
          {
             if(open_price-ask_price>trailing_stop_value)
             {
                 local_stop_loss=NormalizeDouble(ask_price+trailing_stop_value,Digits());
                 if(current_stop_loss>local_stop_loss)
                 {
                    ext_trade.PositionModify(ticket,local_stop_loss,0);
                 }
             
             }
          }
          
       }
   }
      
}
 
Martin:

I have edited the code, it runs but it isn't taking any position.

Check out the OnTradeTransaction and CheckforOpen functions. Those are the ones I edited. I have included the MACDstop but something must not be working.

What do you think?


(1) It doesn't take any position because of the bug here:

if (MACDStop = false)

should have been:

if (MACDStop == false)


(2) Now, once it starts to open positions, I noticed further bugs:

         if(stochastic_k_line[1]>80 && stochastic_k_line[0]<=80)

should have been:

         if(stochastic_k_line[1]<80 && stochastic_k_line[0]>=80)

so that it matches the reverse of the conditions for long trade.

And

//        double ask_price=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
//        double bid_price=SymbolInfoDouble(_Symbol,SYMBOL_BID);

should be uncommented. I did not do further checks, due to (3) below.


(3) Looking at the changes you made in OnTradeTransaction and CheckForOpen functions, and your persistent mentioning of the need to check closing price of the last trade, you seem to want to allow opening more than one position when a trade is already on-going. Because your changes only take care of blocking new open attempts when an existing position is stoplossed. This is in contradiction to your first post where you mentioned "Only have one trade at all times".

Now, assuming this is the logic you wanted (in lieu of your first post), then I think the code will run and you'll be able to carry on your testing with the above changes.

On the other hand, if you still want to stick to your first post's conditions, then you can relook at my algorithm above, which does not differentiate between positions closed by stoploss or takeprofit, and will prevent multiple positions to be opened, without using the OnTradeTransaction function (which, frankly, is not a robust way for setting flags like MACDStop, because you have to consider possible system down-time which essentially will skip that function).

 
Seng Joo Thio:

(1) It doesn't take any position because of the bug here:

should have been:


(2) Now, once it starts to open positions, I noticed further bugs:

should have been:

so that it matches the reverse of the conditions for long trade.

And

should be uncommented. I did not do further checks, due to (3) below.


(3) Looking at the changes you made in OnTradeTransaction and CheckForOpen functions, and your persistent mentioning of the need to check closing price of the last trade, you seem to want to allow opening more than one position when a trade is already on-going. Because your changes only take care of blocking new open attempts when an existing position is stoplossed. This is in contradiction to your first post where you mentioned "Only have one trade at all times".

Now, assuming this is the logic you wanted (in lieu of your first post), then I think the code will run and you'll be able to carry on your testing with the above changes.

On the other hand, if you still want to stick to your first post's conditions, then you can relook at my algorithm above, which does not differentiate between positions closed by stoploss or takeprofit, and will prevent multiple positions to be opened, without using the OnTradeTransaction function (which, frankly, is not a robust way for setting flags like MACDStop, because you have to consider possible system down-time which essentially will skip that function).

Aaah that's why it wasn't taking trades! Thanks for pointing that out.


Sorry for the confusion, let me clarify:

1. I want to only have one trade at all times.

2. Once a trade is lost, the system wouldn't open any other trades until MACD crosses the 0 level.


For some reason, it still opens more than one position. to do so, I went through the following code which makes complete sense but it isn't working when I implement it.

Is this the best way to only have one trade at a time?


//+------------------------------------------------------------------+
//| Trade Count                                                      |
//+------------------------------------------------------------------+
int TradeCount(ENUM_TIMEFRAMES TimeFrame)
  {
//---

   int      Cnt;
   ulong    Ticket;
   datetime DT[1];

   Cnt = 0;

   if(CopyTime(_Symbol, TimeFrame, 0, 1, DT) <= 0)
   {
      Cnt = -1;
   }
   else
   {
      HistorySelect(DT[0], TimeCurrent());

      for(int i = HistoryDealsTotal() - 1; i >= 0; i--)
      {
         Ticket = HistoryDealGetTicket(i);

         if(HistoryDealGetString(Ticket, DEAL_SYMBOL) == _Symbol)
         {
            if(HistoryDealGetInteger(Ticket, DEAL_ENTRY) == DEAL_ENTRY_IN)
            {
               Cnt++;
            }
         }
      }
   }

//---
   return(Cnt);
  }
 
Martin:

Aaah that's why it wasn't taking trades! Thanks for pointing that out.


Sorry for the confusion, let me clarify:

1. I want to only have one trade at all times.

2. Once a trade is lost, the system wouldn't open any other trades until MACD crosses the 0 level.


For some reason, it still opens more than one position. to do so, I went through the following code which makes complete sense but it isn't working when I implement it.

Is this the best way to only have one trade at a time?


Ok, for one trade at a time, there is a much easier way, without using the tradecount function (which looks complicated), and OnTradeTransaction function, as follows:

   if (!PositionSelect(Symbol()) && // This function returns false when there is no existing trade.
       ((shortema1 < longema1) && (shortema2 > longema2)) || ((shortema1 > longema1) && (shortema2 < longema2)))
   {
   MACDStop = false;
   }


Another way is to call PositionsTotal() which will return 0 if there is no existing trade.

Then, in the OpenPosition() function, I added one line:

 void OpenPosition(ulong& arr_ticket[],ENUM_ORDER_TYPE order_type)
 {
        
    if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && Bars(_Symbol,_Period)>100)
    {
        :
        :
           int array_size=ArraySize(arr_ticket);
           ArrayResize(arr_ticket,array_size+1);
           arr_ticket[array_size]=ticket;
           MACDStop = true; // New addition
        :
        :
    }
        
 }

After making these two changes, there won't be more than 1 trade at any one time.

Reason: