MQL Code Snippet for random number generation

This post is a suggestion how to generate an integer random number with the same randomness as the market itself. It is assumed, that market data series are more or less random. The function suggested below can be used in MetaTrader 4/5 Expert Advisors,Scripts or Indicators. The trick is simple: Just build the sum over a series of bars of the past, like:

s=sum(n,close-open)

 

, where n is the # of bars. Then divide the sum by minimal price movement to get a number which can be converted to an integer. Now scale this integer sum down buy the module of random number range.

s = s mod range

That’s it. This random number has the same distribution as the market itself (scaled to its range).

        

Function Code:

int random_int(MqlRates& rates[], double symbol_point,int range=2, bool use_tickcount=true)
{
     if(range > 0)
     {
        int len=ArraySize(rates);
        if(len > 0)
        {
           double bar_sum=0.0;
           for(int i=0;i < len;++i)
               bar_sum +=(rates[i].high - rates[i].low + MathAbs(rates[i].close - rates[i].open));
           // bar_sum has the same randomness as the market
           
           // make it integer convertable
           bar_sum /= symbol_point;
                      
           // add tickcount, to put random behaviour on backtest (where always the same rates selected)
           if(use_tickcount == true)
               bar_sum += GetTickCount();
               
           // scale random number to range
           int rnd=((int) bar_sum % range);
           
           //PrintFormat("rnd=%d bs=%.2f tc=%d dt=%s",rnd,bar_sum,GetTickCount(),TimeToStr(__rates_dyn[0].time));
           return rnd;
        }
     }
     return 0;
}

An application could be be to create random buy/sell orders for test purpose.

void test_random(void)
{
   int rnd=00;
   string sb_sequence;
   double point;
   MqlRates         rates_array[];
   
   // get point for symbol
   SymbolInfoDouble(_Symbol,SYMBOL_POINT,point);

   // make 100 random runs
   for(int i=0;i < 100;++i)
   {
      // get 10 bars in the past, with a moving offset 
      // (the order is not importent here)
      if(CopyRates(_Symbol ,PERIOD_CURRENT,i,10,rates_array) > 0)
      {
         // get a random number 0 or 1.
         // 0=OP_BUY,1=OP_SELL
         rnd=random_int(rates_array,point, 2,false);
         if(rnd == OP_BUY)
            sb_sequence += " buy";
         else
            sb_sequence += " sell";
            
      }
   }
   
   // print out sequence to Experts log
   Print(sb_sequence);
}

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.