Random values in a loop

 

Greatings MQL coders,

I would like to generate multiple unique random numbers between 0 and 1 within a loop. The problem is that every loop returns the same range of 'random' values (yes, I know this is because the MathSrand uses the same iteration id, over and over again, but I know no better alternative).

How can I generate 'true' random numbers, for example based on the time in milliseconds?

Thanks in advance for any feedback!

- Jim


Here's my code:

int I;
for(I=1;I<=25;I++)
   {
   MathSrand(I);//'TimeLocal()' won't work in my case because the time between the loops is very short
   Print(MathRand()%10001/10000.0);//Get a random value between 0 and 1
   }
 

is this helping?

//+------------------------------------------------------------------+
//|                                                        32679.mq4 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
int start()
{
  int I;
  MathSrand(GetTickCount());
  for(I=1;I<=25;I++)
     {
     //MathSrand(I);//'TimeLocal()' won't work in my case because the time between the loops is very short
     Print(MathRand()%10001/10000.0);//Get a random value between 0 and 1
     }
  return;
}

/* ORIG code
2010.06.05 15:08:40     32679 EURGBP,M15: removed
2010.06.05 15:08:40     32679 EURGBP,M15: uninit reason 0
2010.06.05 15:08:40     32679 EURGBP,M15: 0.012
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0116
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0113
2010.06.05 15:08:40     32679 EURGBP,M15: 0.011
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0107
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0103
2010.06.05 15:08:40     32679 EURGBP,M15: 0.01
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0097
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0094
2010.06.05 15:08:40     32679 EURGBP,M15: 0.009
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0087
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0084
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0081
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0077
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0074
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0071
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0068
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0064
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0061
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0058
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0054
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0051
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0048
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0045
2010.06.05 15:08:40     32679 EURGBP,M15: 0.0041
2010.06.05 15:08:40     32679 EURGBP,M15: loaded successfully

--------------------

WITH GetTickCount() as seed 'b4 loop entry'
2010.06.05 15:11:31     32679 EURGBP,M15: removed
2010.06.05 15:11:31     32679 EURGBP,M15: uninit reason 0
2010.06.05 15:11:31     32679 EURGBP,M15: 0.4268
2010.06.05 15:11:31     32679 EURGBP,M15: 0.3061
2010.06.05 15:11:31     32679 EURGBP,M15: 0.097
2010.06.05 15:11:31     32679 EURGBP,M15: 0.3392
2010.06.05 15:11:31     32679 EURGBP,M15: 0.8844
2010.06.05 15:11:31     32679 EURGBP,M15: 0.0029
2010.06.05 15:11:31     32679 EURGBP,M15: 0.8836
2010.06.05 15:11:31     32679 EURGBP,M15: 0.7305
2010.06.05 15:11:31     32679 EURGBP,M15: 0.9041
2010.06.05 15:11:31     32679 EURGBP,M15: 0.3061
2010.06.05 15:11:31     32679 EURGBP,M15: 0.8526
2010.06.05 15:11:31     32679 EURGBP,M15: 0.6889
2010.06.05 15:11:31     32679 EURGBP,M15: 0.2064
2010.06.05 15:11:31     32679 EURGBP,M15: 0.9896
2010.06.05 15:11:31     32679 EURGBP,M15: 0.9517
2010.06.05 15:11:31     32679 EURGBP,M15: 0.7827
2010.06.05 15:11:31     32679 EURGBP,M15: 0.9267
2010.06.05 15:11:31     32679 EURGBP,M15: 0.7442
2010.06.05 15:11:31     32679 EURGBP,M15: 0.1118
2010.06.05 15:11:31     32679 EURGBP,M15: 0.5577
2010.06.05 15:11:31     32679 EURGBP,M15: 0.68
2010.06.05 15:11:31     32679 EURGBP,M15: 0.4302
2010.06.05 15:11:31     32679 EURGBP,M15: 0.9845
2010.06.05 15:11:31     32679 EURGBP,M15: 0.0565
2010.06.05 15:11:31     32679 EURGBP,M15: 0.5505
2010.06.05 15:11:31     32679 EURGBP,M15: loaded successfully
*/
 

How about:

int I;
for(I=1;I<=25;I++)
   {
   MathSrand(TimeLocal()*I);
   Print(MathRand()%10001/10000.0);//Get a random value between 0 and 1
   }
 
fbj:

is this helping?



Yup it does, thanks (again) fbj!

- Jim

 
1005phillip:

How about:


Nope, that was one of the failing alternatives I'v tried.

Thanks anyway!

- Jim

 
fbj:

is this helping?


Would this also help with a problem I found trying to use random data in Strategy Tester.

The seed "TimeLocal()" comes from the database, not the server, so it always leads to the same random data, which defeats the purpose of the test.

The MQL4 Reference states "At the testing, local time is modelled and is the same as the modelled last known server time."

The function "GetTickCount()" might not even work on a weekend when the system is shut down?

Thank you, Helmut

 
1005phillip:

How about [...]

TimeLocal() (or TimeCurrent()) have a resolution of 1 second only, but the loop obviously runs much faster than that... So most iterations will get the same seed.
 

VirtualReal:

I would like to generate multiple unique random numbers between 0 and 1 within a loop. The problem is that every loop returns the same range of 'random' values (yes, I know this is because the MathSrand uses the same iteration id, over and over again, but I know no better alternative).

How can I generate 'true' random numbers, for example based on the time in milliseconds?

Here's my code:

int I;
for(I=1;I<=25;I++)
   {
   MathSrand(TimeLocal()*I);
   Print(MathRand()%10001/10000.0);//Get a random value between 0 and 1
   }

Never, EVER, use the low bits of random numbers, they are very NON-RANDOM. Initialize the random generator ONLY once.

init() {
   MathSrand(LocalTime());  // Comment this out for testing or use if (IsTesting())
}
for(int I=1;I<=25;I++) {
   double aRand = MathRand()/32768.0; // MathRand=0-32767, aRand=0-0.999969
   Print(aRand);//Get a random value between 0 and 1
}
 
engcomp:

The function "GetTickCount()" might not even work on a weekend when the system is shut down?


I've tried this function on a Saturday in my test environment (no connected account) and it works fine.

HTH,

Jim

 
WHRoeder:

Never, EVER, use the low bits of random numbers, they are very NON-RANDOM. Initialize the random generator ONLY once.

I wasn't aware of this, thanks for insight :)

- Jim

 
WHRoeder:

Never, EVER, use the low bits of random numbers, they are very NON-RANDOM. Initialize the random generator ONLY once.

Can you please explain or give a reference for your claim (I asked u this before -> https://www.mql5.com/en/forum/125208, u probably didn't notice it).
Reason: