//+------------------------------------------------------------------+
//| GaussianRandomNumber1.mq4 |
//| Copyright © 2008, MetaQuotes Software Corp. |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net"
#property indicator_separate_window
//#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Yellow
#property indicator_color2 Red
#property indicator_color3 LightSeaGreen
#property indicator_level1 0.0
double Buffer1[];
double Buffer2[];
double Buffer3[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
MathSrand(TimeLocal());
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,Buffer1);
SetIndexStyle(1,DRAW_HISTOGRAM);
SetIndexBuffer(1,Buffer2);
SetIndexStyle(2,DRAW_LINE);
SetIndexBuffer(2,Buffer3);
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
//----
for(int i=0;i<3000;i++)
{
Buffer1[i]=0.0;
Buffer2[i]=0.0;
}
for(i=0;i<3000;i++)
{
int j=randn_trig(5.0,1.0)*2;
Buffer1[j]=Buffer1[j]+1;
}
for(i=0,j=0;i<3000;i++,j++)
{
Buffer2[i]=Buffer1[j];
}
//----
return(0);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
#define RAND_MAX 32767.0
double rand()
{ //range from 0.0 to 1.0
//return(MathRand()%1001/1000.0);
double r=MathRand();
return(r);
}
// Standard version with trigonometric calls
#define PI 3.14159265358979323846
double randn_trig(double mu=0.0, double sigma=1.0)
{
static bool deviateAvailable=false; //flag
static double storedDeviate; //deviate from previous calculation
double dist, angle;
// If no deviate has been stored, the standard Box-Muller transformation is
// performed, producing two independent normally-distributed random
// deviates. One is stored for the next round, and one is returned.
if (!deviateAvailable)
{
// choose a pair of uniformly distributed deviates, one for the
// distance and one for the angle, and perform transformations
dist=MathSqrt( -2.0 * MathLog(rand()/RAND_MAX));
angle=2.0 * PI * (rand()/RAND_MAX);
// calculate and store first deviate and set flag
storedDeviate=dist*MathCos(angle);
deviateAvailable=true;
// calcaulate return second deviate
return (dist * MathSin(angle) * sigma + mu);
}
// If a deviate is available from a previous call to this function, it is
// returned, and the flag is set to false.
else
{
deviateAvailable=false;
return (storedDeviate*sigma + mu);
}
}
/******************************************************************************/
/* randn()
*
* Normally (Gaussian) distributed random numbers, using the Box-Muller
* transformation. This transformation takes two uniformly distributed deviates
* within the unit circle, and transforms them into two independently
* distributed normal deviates. Utilizes the internal rand() function; this can
* easily be changed to use a better and faster RNG.
*
* The parameters passed to the function are the mean and standard deviation of
* the desired distribution. The default values used, when no arguments are
* passed, are 0 and 1 - the standard normal distribution.
*
*
* Two functions are provided:
*
* The first uses the so-called polar version of the B-M transformation, using
* multiple calls to a uniform RNG to ensure the initial deviates are within the
* unit circle. This avoids making any costly trigonometric function calls.
*
* The second makes only a single set of calls to the RNG, and calculates a
* position within the unit circle with two trigonometric function calls.
*
* The polar version is generally superior in terms of speed; however, on some
* systems, the optimization of the math libraries may result in better
* performance of the second. Try it out on the target system to see which
* works best for you. On my test machine (Athlon 3800+), the non-trig version
* runs at about 3x10^6 calls/s; while the trig version runs at about
* 1.8x10^6 calls/s (-O2 optimization).
*
*
* Example calls:
* randn_notrig(); //returns normal deviate with mean=0.0, std. deviation=1.0
* randn_notrig(5.2,3.0); //returns deviate with mean=5.2, std. deviation=3.0
*
*
* Dependencies - requires <cmath> for the sqrt(), sin(), and cos() calls, and a
* #defined value for PI.
*/
/*
// "Polar" version without trigonometric calls
double randn_notrig(double mu=0.0, double sigma=1.0) {
static bool deviateAvailable=false; // flag
static float storedDeviate; // deviate from previous calculation
double polar, rsquared, var1, var2;
// If no deviate has been stored, the polar Box-Muller transformation is
// performed, producing two independent normally-distributed random
// deviates. One is stored for the next round, and one is returned.
if (!deviateAvailable) {
// choose pairs of uniformly distributed deviates, discarding those
// that don't fall within the unit circle
do {
var1=2.0*( double(rand())/double(RAND_MAX) ) - 1.0;
var2=2.0*( double(rand())/double(RAND_MAX) ) - 1.0;
rsquared=var1*var1+var2*var2;
} while ( rsquared>=1.0 || rsquared == 0.0);
// calculate polar tranformation for each deviate
polar=sqrt(-2.0*log(rsquared)/rsquared);
// store first deviate and set flag
storedDeviate=var1*polar;
deviateAvailable=true;
// return second deviate
return var2*polar*sigma + mu;
}
// If a deviate is available from a previous call to this function, it is
// returned, and the flag is set to false.
else {
deviateAvailable=false;
return storedDeviate*sigma + mu;
}
}
// Standard version with trigonometric calls
#define PI 3.14159265358979323846
double randn_trig(double mu=0.0, double sigma=1.0) {
static bool deviateAvailable=false; // flag
static float storedDeviate; // deviate from previous calculation
double dist, angle;
// If no deviate has been stored, the standard Box-Muller transformation is
// performed, producing two independent normally-distributed random
// deviates. One is stored for the next round, and one is returned.
if (!deviateAvailable) {
// choose a pair of uniformly distributed deviates, one for the
// distance and one for the angle, and perform transformations
dist=sqrt( -2.0 * log(double(rand()) / double(RAND_MAX)) );
angle=2.0 * PI * (double(rand()) / double(RAND_MAX));
// calculate and store first deviate and set flag
storedDeviate=dist*cos(angle);
deviateAvailable=true;
// calcaulate return second deviate
return dist * sin(angle) * sigma + mu;
}
// If a deviate is available from a previous call to this function, it is
// returned, and the flag is set to false.
else {
deviateAvailable=false;
return storedDeviate*sigma + mu;
}
}
*/
Comments