Why my order auto open twice in the same time

 

I am new to MQL5 and I am using Fractal and SAR signal, and my expectation is:

  1. close previous sell order when new buy order opening 
  2. close previous buy order when new sell order opening
  3. only have one order opening on the same time

The unexpected buy doesn't print expected stuff like before printing "Performing Buy" and "Buy Completed". Result:

#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <Trade/Trade.mqh>

CTrade trade;
int barsTotal;
ulong posTicket;
bool hasPosition = false;
ulong prevOrderNumber = 1; 
int prevOrderType = 0;  // 0 sell 1 buy
bool closepreviousorder = false;
int totalOrders = HistoryOrdersTotal();
int latestTicket = 0;
int magic = 777777;

int handleFractals;
int handleSar;


int OnInit(){
   handleFractals = iFractals(_Symbol, PERIOD_CURRENT);
   if(handleFractals == INVALID_HANDLE){
      Print("Error creating Fractals indicator!");
      return(INIT_FAILED);
   }
   handleSar = iSAR(_Symbol, PERIOD_CURRENT, 0.04, 0.9);
   if (handleSar == INVALID_HANDLE) {
      Print("Error creating SAR indicator!");
      return(INIT_FAILED);
   }
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason){
}
void OnTick()
{
   int bars = iBars(_Symbol, PERIOD_CURRENT);
   if (barsTotal != bars){
      if (HistorySelect(0, TimeCurrent()) != -1){
          latestTicket = HistoryOrderGetTicket(0);
      }
      Print("Last Order: ", latestTicket, "|", prevOrderNumber, " - ", prevOrderType, " | ", closepreviousorder);
      barsTotal = bars;
      bool isFracSell = false;
      bool isFracBuy = false;
      bool isSARSell = false;
      bool isSARBuy = false;
      bool isSell = false;
      bool isBuy = false;
    
      // Fractals
      double fracUpper[];
      double fracLower[];
      int copiedUpper = CopyBuffer(handleFractals, UPPER_LINE, 0, 10, fracUpper);
      int copiedLower = CopyBuffer(handleFractals, LOWER_LINE, 1, 10, fracLower);
      if (copiedUpper == 10 && copiedLower == 10){
         double upperChange1 = fracUpper[0] - fracUpper[1];
         double upperChange2 = fracUpper[1] - fracUpper[2];
         double upperChange3 = fracUpper[2] - fracUpper[3];
         double upperChange4 = fracUpper[3] - fracUpper[4];
         double upperChange5 = fracUpper[4] - fracUpper[5];
         double upperChange6 = fracUpper[5] - fracUpper[6];
         double upperChange7 = fracUpper[6] - fracUpper[7];
         double upperChange8 = fracUpper[7] - fracUpper[8];
         double upperChange9 = fracUpper[8] - fracUpper[9];
         double lowerChange1 = fracLower[0] - fracLower[1];
         double lowerChange2 = fracLower[1] - fracLower[2];
         double lowerChange3 = fracLower[2] - fracLower[3];
         double lowerChange4 = fracLower[3] - fracLower[4];
         double lowerChange5 = fracLower[4] - fracLower[5];
         double lowerChange6 = fracLower[5] - fracLower[6];
         double lowerChange7 = fracLower[6] - fracLower[7];
         double lowerChange8 = fracLower[7] - fracLower[8];
         double lowerChange9 = fracLower[8] - fracLower[9];
         //Print(upperChange1, " | ", upperChange2, " | ", upperChange3, " | ", upperChange4, " | ", upperChange5, " | ", upperChange6, " | ",upperChange7, " | ",upperChange8, " | ",upperChange9);
         //Print(upperChange1, " | ", lowerChange2, " | ", lowerChange3, " | ", lowerChange4, " | ", lowerChange5, " | ", lowerChange6, " | ",lowerChange7, " | ",lowerChange8, " | ",lowerChange9);
         if (upperChange1 < 0 || upperChange2 < 0 || upperChange3 < 0 || upperChange4 < 0 || upperChange5 < 0 ||
             upperChange6 < 0 || upperChange7 < 0 || upperChange8 < 0 || upperChange9 < 0){
            isFracSell = true;
         }else if (lowerChange1 > 0 || lowerChange2 > 0 || lowerChange3 > 0 || lowerChange4 > 0 || lowerChange5 > 0 ||
                  lowerChange6 > 0 || lowerChange7 > 0 || lowerChange8 > 0 || lowerChange9 > 0){
            isFracBuy = true;
         }
      }

      //SAR
      double previousHigh = iHigh(_Symbol, PERIOD_CURRENT, 1);
      double previousLow = iLow(_Symbol, PERIOD_CURRENT, 1);
      double previousSar = 0;
      double currentSar = 0;
      double sarBuffer[];
      int copiedBars = CopyBuffer(handleSar, 0, 0, 2, sarBuffer);  
      if (copiedBars > 0) {
          previousSar = sarBuffer[0];
          currentSar = sarBuffer[1];  
          //Print(currentSar, " | ", previousSar);
          //Print(previousHigh, " | ", previousLow);
      }
      
      if (currentSar < previousLow && currentSar > previousSar) {
          isSARBuy = true;
      } else if (currentSar > previousLow && currentSar < previousSar) {
          isSARSell = true;
      }
      Print("Signal: ", isFracBuy, isSARBuy, " B|S ", isFracSell, isSARSell);
      if (isSARSell && isFracSell) {
         bool closepreviousorder = ClosePreviousBuyOrder(prevOrderNumber, prevOrderType);
         if (closepreviousorder == true) {
            prevOrderNumber = executeSell(prevOrderNumber, prevOrderType);
            prevOrderType = 0;
            Print("SELL Finish: ", prevOrderNumber, " | ", prevOrderType);
         }
      }else if (isSARBuy && isFracBuy) {
         bool closepreviousorder = ClosePreviousSellOrder(prevOrderNumber, prevOrderType);
         if (closepreviousorder == true) {
            prevOrderNumber = executeBuy(prevOrderNumber, prevOrderType);
            prevOrderType = 1;
            Print("BUY Finish: ", prevOrderNumber, " | ", prevOrderType);
         }
      }
   }
}


int executeSell(int prevOrderNumber, int prevOrderType){
   Print("Performing SELL");
   trade.Sell(0.1);
   prevOrderType = 0;
   prevOrderNumber = prevOrderNumber + 1;
   Print("SELL COMPLETED: ", prevOrderNumber, " | ", prevOrderType);
   return prevOrderNumber;
}

int executeBuy(int prevOrderNumber, int prevOrderType){
   Print("Performing BUY");
   trade.Buy(0.1);
   prevOrderType = 1;
   prevOrderNumber = prevOrderNumber + 1;
   Print("BUY COMPLETED: ", prevOrderNumber, " | ", prevOrderType);
   return prevOrderNumber;
}


bool ClosePreviousSellOrder(int prevOrderNumber, int prevOrderType) {
   bool result = false; 
   if (prevOrderNumber > 1) {
      if (PositionSelectByTicket(prevOrderNumber)) {
         int currentOrderType = PositionGetInteger(POSITION_TYPE);
         if (currentOrderType == POSITION_TYPE_SELL) {
            Print("Closing Sell Order: ", prevOrderNumber);
            bool closepreviousorder = trade.PositionClose(prevOrderNumber);
            if (closepreviousorder == true) {
               result = true; 
            } else {
               Print("Closed Failed");
               result = false;
            }
         }
      }
   } else if (prevOrderNumber < 2) {
      result = true; 
   }
   return result;
}

bool ClosePreviousBuyOrder(int prevOrderNumber, int prevOrderType) {
   bool result = false;
   if (prevOrderNumber > 1) {
      if (PositionSelectByTicket(prevOrderNumber)) {
         int currentOrderType = PositionGetInteger(POSITION_TYPE);
         if (currentOrderType == POSITION_TYPE_BUY) {
            Print("Closing Buy Order: ", prevOrderNumber);
            bool closepreviousorder = trade.PositionClose(prevOrderNumber);
            if (closepreviousorder == true) {
               result = true; 
            } else {
               Print("Closed Failed");
               result = false; 
            }
         }
      }
   } else if (prevOrderNumber < 2) {
      result = true; 
   }
   return result;
}

//+------------------------------------------------------------------+
 
Your topic has been moved to the section: Expert Advisors and Automated Trading
Please consider which section is most appropriate — https://www.mql5.com/en/forum/172166/page6#comment_49114893