Random order functionality

 

Hello, 

I'm trying to create an Expert Advisor (EA) that can generate random BUY or SELL orders, and I'm using the following for this:

   // Generate random number (0 or 1)
   MathSrand((int)TimeLocal());
   int randomChoice = MathRand() % 2;

So far, the EA has only placed 15 consecutive BUY orders and not a single SELL order. I'm therefore wondering if there's something wrong with the code, or if "chance" has simply been 100% on the BUY side so far.

Thank you for your help in advance.

 

Nice question — I ran into the same gotcha before. A few practical points that should help:

  1. Don’t reseed every time. Call MathSrand((int)TimeLocal()) once (for example in OnInit() ), not immediately before every MathRand() call. Reseeding on every tick can produce repeated or correlated values, especially if TimeLocal() hasn’t changed much.

  2. Log the raw values. Add Print() s to see MathRand() outputs and randomChoice (e.g. Print("rand=", MathRand(), " choice=", randomChoice); ). That will show whether the RNG is biased or if your trading logic later forces BUYs.

  3. Check order-selection logic. If your EA uses additional checks (filters, margin, symbol state) it may skip SELL attempts—so 15 BUYs could be a logic/condition issue, not RNG.

  4. Example (safe and simple):

int OnInit() { MathSrand((int)TimeLocal()); // seed once return INIT_SUCCEEDED; } void OnTick() { int randomChoice = MathRand() % 2; // 0 or 1 Print("MathRand=", MathRand(), " choice=", randomChoice); if(randomChoice==0) OpenBuy(); else OpenSell(); }

  1. If you want stronger randomness, collect MathRand() into a larger integer or combine several calls, and always separate RNG from trade-execution so you can reproduce/diagnose behavior.

Moderator's notes:

  • Don't use "Artificial Intelligence" to generate automated answers.
  • Please EDIT your post and use the CODE button (Alt-S) when inserting code.

    Code button in editor

 
Doflixindia Doflixindia #:
collect MathRand() into a larger integer

Thank you. I'll try that out. I just read the following.

"To increase the randomness of MathRand() in MQL5, you can use a better pseudorandom number generator (PRNG) library, such as Alglib or xoshiro256."

 
ch0sen:

Hello, 

I'm trying to create an Expert Advisor (EA) that can generate random BUY or SELL orders, and I'm using the following for this:

So far, the EA has only placed 15 consecutive BUY orders and not a single SELL order. I'm therefore wondering if there's something wrong with the code, or if "chance" has simply been 100% on the BUY side so far.

Thank you for your help in advance.

MathSRand() should only be used once.

It's not possibly to get 15 consecutive 0 (or 1) with MathRand() if properly used. You have a bug in your code.

 
Alain Verleyen #:
It's not possibly to get 15 consecutive 0 (or 1) with MathRand() if properly used. You have a bug in your code.

The odds are 1 in 16384😁

The probability of a bug in the code tends to 1😁

 

So I tried to implement Xoshiro256 because it's supposed to offer better randomness and speed, which works so far, but now I have the following problem: no SELL orders are being executed (at least not in StrategyTester). I can't test it live right now because it's the weekend.


// Xoshiro256** random number generator state
ulong xoshiro_state[4];

//+------------------------------------------------------------------+
//| Initialize Xoshiro256** RNG                                      |
//+------------------------------------------------------------------+
void InitXoshiro256()
{
   // Seed using current time and tick count for better randomness
   ulong seed = (ulong)TimeLocal() + (ulong)GetTickCount();
   
   // Simple SplitMix64 to initialize state from seed
   for(int i = 0; i < 4; i++)
   {
      seed += 0x9e3779b97f4a7c15;
      ulong z = seed;
      z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
      z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
      xoshiro_state[i] = z ^ (z >> 31);
   }
}

//+------------------------------------------------------------------+
//| Rotate left operation for 64-bit integer                        |
//+------------------------------------------------------------------+
ulong RotateLeft64(ulong x, int k)
{
   return (x << k) | (x >> (64 - k));
}

//+------------------------------------------------------------------+
//| Generate next random number using Xoshiro256**                   |
//+------------------------------------------------------------------+
ulong Xoshiro256Next()
{
   ulong result = RotateLeft64(xoshiro_state[1] * 5, 7) * 9;
   ulong t = xoshiro_state[1] << 17;
   
   xoshiro_state[2] ^= xoshiro_state[0];
   xoshiro_state[3] ^= xoshiro_state[1];
   xoshiro_state[1] ^= xoshiro_state[2];
   xoshiro_state[0] ^= xoshiro_state[3];
   
   xoshiro_state[2] ^= t;
   xoshiro_state[3] = RotateLeft64(xoshiro_state[3], 45);
   
   return result;
}

//+------------------------------------------------------------------+
//| Generate random integer in range [0, max)                        |
//+------------------------------------------------------------------+
int XoshiroRandRange(int max)
{
   if(max <= 0) return 0;
   ulong randValue = Xoshiro256Next();
   // Use upper bits for better distribution
   return (int)((randValue >> 32) % (ulong)max);
}

//+------------------------------------------------------------------+
//| Place random buy or sell order                                   |
//+------------------------------------------------------------------+
void PlaceRandomOrder()
{
   // Generate random number (0 or 1) using Xoshiro256**
   int randomChoice = XoshiroRandRange(2);
   
   Print("Random choice generated: ", randomChoice, " (0=BUY, 1=SELL)");
   
   string symbol = _Symbol;
   double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
   double price = 0;
   double sl = 0;
   double tp = 0;
   double lotSize = 0;
   
   // Calculate lot size based on risk
   lotSize = CalculateLotSize(StopLossPoints);
   
   if(randomChoice == 0)
   {
      // Place BUY order
      price = SymbolInfoDouble(symbol, SYMBOL_ASK);
      sl = price - (StopLossPoints * point);
      tp = price + (TakeProfitPoints * point);
      
      // Normalize price levels
      int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
      sl = NormalizeDouble(sl, digits);
      tp = NormalizeDouble(tp, digits);
      
      if(trade.Buy(lotSize, symbol, price, sl, tp, "Random Buy"))
      {
         Print("BUY order placed: Lots=", lotSize, " Price=", price, " SL=", sl, " TP=", tp);
      }
      else
      {
         Print("Failed to place BUY order. Error: ", GetLastError());
      }
   }
   else
   {
      // Place SELL order
      price = SymbolInfoDouble(symbol, SYMBOL_BID);
      sl = price + (StopLossPoints * point);
      tp = price - (TakeProfitPoints * point);
      
      // Normalize price levels
      int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
      sl = NormalizeDouble(sl, digits);
      tp = NormalizeDouble(tp, digits);
      
      if(trade.Sell(lotSize, symbol, price, sl, tp, "Random Sell"))
      {
         Print("SELL order placed: Lots=", lotSize, " Price=", price, " SL=", sl, " TP=", tp);
      }
      else
      {
         Print("Failed to place SELL order. Error: ", GetLastError());
      }
   }
}
 
ch0sen #So I tried to implement Xoshiro256 because it's supposed to offer better randomness and speed, which works so far, but now I have the following problem: no SELL orders are being executed (at least not in StrategyTester). I can't test it live right now because it's the weekend.

Why are you ignoring the simplest solution and the advice given to you?

  • "Don’t reseed every time."
  • "MathSRand() should only be used once."
 
Fernando Carreiro #:

Why are you ignoring the simplest solution and advice given to you?

  • "Don’t reseed every time."
  • "MathSRand() should only be used once."

Yes, I moved MathSrand to OnInit(), but that didn't solve the problem either. In any case, I'd now like to use Xoshiro256 instead of MQL5's built-in functionality, as this seems like a fundamentally better choice, but that's not working either. It's only generating BUY orders.

 
ch0sen #:

Yes, I moved MathSrand to OnInit(), but that didn't solve the problem either. In any case, I'd now like to use Xoshiro256 instead of MQL5's built-in functionality, as this seems like a fundamentally better choice, but that's not working either. It's only generating BUY orders.

Am I the only one here who thinks you generate code using AI?

ch0sen #:

Print("Failed to place SELL order. Error: ", GetLastError());

If you (and not an AI) had written this code, the first thing you would do would be to look at the error code.

 
Vladislav Boyko #:
Print("Failed to place SELL order. Error: ", GetLastError());

There are no errors. It's just that no BUY orders are being generated/executed.

 
ch0sen #:

There are no errors. It's just that no BUY orders are being generated/executed.

Don't request help for A.I. generated code. It generates horrible invalid code. Research the Documentation, Articles and Codebase, or use the Freelance section for such requests.