Limiting the opening of multiple orders on new bar - page 2

 

Keelan, Your idea works fine. I have it running on a demo account. I used the following for generating the random delay:

x+(y-x)*MathRand()/32767, x and y being the lower and upper limits of the random number generated. I found this elsewhere in this forum.

Thanks for your help, once again 

 
You random just reduces the race conditions. Eliminate it with a mutex.
Not compiled, not tested.
input string GV_Mutex = "Mutex"; 

class Mutex{ 
 Public: 
   void                 Mutex()                     : mName(GV_Mutex), 
                                                      mLocked(false){   Lock();} 
   void                 Mutex(const string& aName)  : mName(aName), 
                                                      mLocked(false){   Lock();} 
   void                ~Mutex(){                                     Release();} 
   void                 Lock(void){ 
      if(mLocked) return 
      SECONDS     startWaitingTime  = 0; 
      if(!GlobalVariableTemp(mName){                     // Attempt to create 
      && _LastError != ERR_GLOBAL_VARIABLES_PROCESSING)  DisableTrading( 
         StringFormat("Mutex: GVSet('%s') Failed: %i",s, _LastError) ); return;} 
      while(true){ 
         if(!IsTradeContextBusy() 
         && GlobalVariableSetOnCondition(mName, 0, 1) ){ 
            if(startWaitingTime != 0){ 
               Comment(WindowExpertName(),": ", VERSION);   WindowRedraw(); 
               SetNeedToRefresh();  // I slept 
            } 
            RefreshIf();   // RefreshRates if slept or previous OrderSend/Modify 
            SetNeedToRefresh();     // Assume will do a OrderSend/Modify/Close. 
            mLocked = true; 
            return; 
         } 
         if(IsStopped() ){ 
            Alert("Mutex: The expert was terminated by the user!");  return;  } 
         if(startWaitingTime == 0) 
            startWaitingTime  = GetTickCount(); // Remember start time. 
         else{ 
            SECONDS  delay = GetTickCount() - startWaitingTime; 
   #define MUTEX_TIMEOUT_MSEC    60000 // Trade context busy maximum delay 
            if(delay > MUTEX_TIMEOUT_MSEC){              // Abort. 
               DisableTrading(StringFormat("Wait time (%i sec) exceeded!", 
                              MUTEX_TIMEOUT_MSEC / 1000) ); return; 
            } 
            Comment(WindowExpertName(), ": ", 
            "Wait until another expert finishes trading... ", delay / 1000.); 
            WindowRedraw(); 
         } 
         Sleep(1000); 
      }  // while 
      //NOT REACHED 
   }  // Lock 
   void                 Release(void){ 
      if(mLocked){ 
         if(!GlobalVariableSet(mName, 0) ) 
            Alert("Mutex: GlobalVariableSet('%s',!LOCK): Error #", 
                  mName, _LastError); 
         mLocked=false; 
      } 
   } 
   void                 IsLocked(void)             const{return mLocked;    } 
 Private: 
   string               mName; 
   bool                 mLocked; 
}; // Mutex 
Not compiled, not tested.
 
Thank you. I will have a go sometime.
 

The same Mutex, compiled and tested, without need for external functions

class Mutex
  {
#ifndef MUTEX_TIMEOUT_MSEC
   #define MUTEX_TIMEOUT_MSEC    60000 // Trade context busy maximum delay 
#endif

public:
   void                 Mutex()                     : mName("GV_Mutex"), mLocked(false) {Lock();}
   void                 Mutex(const string& aName)  : mName(aName), mLocked(false) {Lock();}
   void                ~Mutex() {Release();}
   void                 Lock(void)
     {
      if(mLocked)
         return;
      uint startWaitingTime  = 0;
      if(!GlobalVariableTemp(mName))
        {
         int err = GetLastError();
         if(err != ERR_GLOBAL_VARIABLES_PROCESSING)
           {
            PrintFormat("Mutex: GVSet Failed: %i", err);
           }
         return;
        }

      while(true)
        {
         if(!IsTradeContextBusy()&& GlobalVariableSetOnCondition(mName, 1, 0))
           {
            if(startWaitingTime != 0)
              {
               RefreshRates();
              }
            mLocked = true;
            return;
           }
         if(IsStopped())
           {
            Print("Mutex: The expert was terminated by the user!");
            return;
           }

         if(startWaitingTime == 0)
           {
            startWaitingTime  = GetTickCount(); // Remember start time.
           }
         else
           {
            uint delay = GetTickCount() - startWaitingTime;

            if(delay > MUTEX_TIMEOUT_MSEC)      // Abort.
              {
               PrintFormat("Wait time (%i sec) exceeded!", MUTEX_TIMEOUT_MSEC / 1000);
               return;
              }

            Sleep(1000);
           }
        }// while
     }  // Lock

   void              Release(void)
     {
      if(mLocked)
        {
         if(!GlobalVariableSet(mName, 0))
           {
            PrintFormat("Mutex: GlobalVariableSet(UNLOCK): Error #", _LastError);
           }

         mLocked=false;
        }
     }

   bool                 IsLocked(void)             const {return mLocked;}

private:
   string               mName;
   bool                 mLocked;
  }; // Mutex
//+------------------------------------------------------------------+