MobinMQL/Include/Math/Stat/Binomial.mqh

875 lines
34 KiB
MQL5
Raw Permalink Normal View History

2025-07-22 14:47:41 +03:00
//+------------------------------------------------------------------+
//| Binomial.mqh |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#include "Math.mqh"
#include "Beta.mqh"
//+------------------------------------------------------------------+
//| Binomial probability mass function (PDF) |
//+------------------------------------------------------------------+
//| The function returns the Binomial probability mass function |
//| with parameters n and p at x. |
//| |
//| f(x,n,p)= C(n,x)*(p^x)*(1-p)^(n-x) |
//| |
//| where binomial coefficient C(n,k)=n!/(k!*(n-k)!) |
//| |
//| Arguments: |
//| x : Integer random variable |
//| n : Number of trials |
//| p : Probability of success for each trial |
//| log_mode : Logarithm mode flag, if true it returns Log values |
//| error_code : Variable for error code |
//| |
//| Return value: |
//| The probability mass function evaluated at x. |
//+------------------------------------------------------------------+
double MathProbabilityDensityBinomial(const double x,const double n,const double p,const bool log_mode,int &error_code)
{
//--- check NaN
if(!MathIsValidNumber(x) || !MathIsValidNumber(n) || !MathIsValidNumber(p))
{
error_code=ERR_ARGUMENTS_NAN;
return QNaN;
}
//--- check n
if(n<0 || n!=MathRound(n))
{
error_code=ERR_ARGUMENTS_INVALID;
return QNaN;
}
//--- check p range
if(p<0.0 || p>1.0)
{
error_code=ERR_ARGUMENTS_INVALID;
return QNaN;
}
error_code=ERR_OK;
//--- case p=0
if(p==0.0 || p==1.0)
return TailLog0(true,log_mode);
//--- check x range
if(x<0 || x>n)
return TailLog0(true,log_mode);
double log_result=MathGammaLog(n+1.0)-MathGammaLog(x+1.0)-MathGammaLog(n-x+1.0)+x*MathLog(p)+(n-x)*MathLog(1.0-p);
if(log_mode==true)
return log_result;
//--- return probability mass
return MathExp(log_result);
}
//+------------------------------------------------------------------+
//| Binomial probability mass function (PDF) |
//+------------------------------------------------------------------+
//| The function returns the Binomial probability mass function |
//| with parameters n and p at x. |
//| |
//| f(x,n,p)= C(n,x)*(p^x)*(1-p)^(n-x) |
//| |
//| where binomial coefficient C(n,k)=n!/(k!*(n-k)!) |
//| |
//| Arguments: |
//| x : Integer random variable |
//| n : Number of trials |
//| p : Probability of success for each trial |
//| error_code : Variable for error code |
//| |
//| Return value: |
//| The probability mass function evaluated at x. |
//+------------------------------------------------------------------+
double MathProbabilityDensityBinomial(const double x,const double n,const double p,int &error_code)
{
return MathProbabilityDensityBinomial(x,n,p,false,error_code);
}
//+------------------------------------------------------------------+
//| Binomial probability mass function (PDF) |
//+------------------------------------------------------------------+
//| The function calculates the Binomial probability mass function |
//| with parameters n and p for values in x[] array. |
//| |
//| Arguments: |
//| x : Array with integer random variables |
//| n : Number of trials |
//| p : Probability of success for each trial |
//| log_mode : Logarithm mode flag,if true it calculates Log values|
//| result : Array with calculated values |
//| |
//| Return value: |
//| true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathProbabilityDensityBinomial(const double &x[],const double n,const double p,const bool log_mode,double &result[])
{
//--- check NaN
if(!MathIsValidNumber(n) || !MathIsValidNumber(p))
return false;
//--- check n
if(n<0 || n!=MathRound(n))
return false;
//--- check p range
if(p<0.0 || p>1.0)
return false;
int data_count=ArraySize(x);
if(data_count==0)
return false;
int error_code=0;
ArrayResize(result,data_count);
//--- case p=0 or p=1
if(p==0.0 || p==1.0)
{
for(int i=0; i<data_count; i++)
result[i]=TailLog0(true,log_mode);
return true;
}
for(int i=0; i<data_count; i++)
{
double x_arg=x[i];
if(MathIsValidNumber(x_arg) && x_arg==MathRound(x_arg))
{
//--- check x range
if(x_arg<0 || x_arg>n)
result[i]=TailLog0(true,log_mode);
else
{
double log_result=MathGammaLog(n+1.0)-MathGammaLog(x_arg+1.0)-MathGammaLog(n-x_arg+1.0)+x_arg*MathLog(p)+(n-x_arg)*MathLog(1.0-p);
if(log_mode==true)
result[i]=log_result;
else
result[i]=MathExp(log_result);
}
}
else
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| Binomial probability mass function (PDF) |
//+------------------------------------------------------------------+
//| The function calculates the Binomial probability mass function |
//| with parameters n and p for values in x[] array. |
//| |
//| Arguments: |
//| x : Array with integer random variables |
//| n : Number of trials |
//| p : Probability of success for each trial |
//| result : Array with calculated values |
//| |
//| Return value: |
//| true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathProbabilityDensityBinomial(const double &x[],const double n,const double p,double &result[])
{
return MathProbabilityDensityBinomial(x,n,p,false,result);
}
//+------------------------------------------------------------------+
//| Binomial cumulative distribution function (CDF) |
//+------------------------------------------------------------------+
//| The function returns the value of the Binomial cumulative |
//| distribution function with given n and p at the desired x. |
//| |
//| Arguments: |
//| x : Integer random variable |
//| n : Number of trials |
//| p : Probability of success for each trial |
//| tail : Flag to calculate lower tail |
//| log_mode : Logarithm mode flag,if true it calculates Log values|
//| error_code : Variable for error code |
//| |
//| Return value: |
//| The cumulative distribution function evaluated at x. |
//+------------------------------------------------------------------+
double MathCumulativeDistributionBinomial(const double x,const double n,double p,const bool tail,const bool log_mode,int &error_code)
{
//--- check NaN
if(!MathIsValidNumber(x) || !MathIsValidNumber(n) || !MathIsValidNumber(p))
{
error_code=ERR_ARGUMENTS_NAN;
return QNaN;
}
//--- check n
if(n<0 || n!=MathRound(n))
{
error_code=ERR_ARGUMENTS_INVALID;
return QNaN;
}
//--- check probability
if(p<0.0 || p>1.0)
{
error_code=ERR_ARGUMENTS_INVALID;
return QNaN;
}
error_code=ERR_OK;
//--- case p==0
if(p==0.0)
{
if(x>=0)
return TailLog1(tail,log_mode);
else
return TailLog0(tail,log_mode);
}
//--- case p==1
if(p==1.0)
{
if(x>n)
return TailLog1(tail,log_mode);
else
return TailLog0(tail,log_mode);
}
//--- x must be>=0
if(x<0)
return TailLog0(tail,log_mode);
//--- check x
if(x>n)
return TailLog1(tail,log_mode);
int err_code=0;
//--- calculate using Beta distribution and correct round-off errors
double result=MathMin(1.0-MathCumulativeDistributionBeta(p,x+1.0,n-x,err_code),1.0);
//--- return result depending on arguments
return TailLogValue(result,tail,log_mode);
}
//+------------------------------------------------------------------+
//| Binomial cumulative distribution function (CDF) |
//+------------------------------------------------------------------+
//| The function returns the value of the Binomial cumulative |
//| distribution function with given n and p at the desired x. |
//| |
//| Arguments: |
//| x : Integer random variable |
//| n : Number of trials |
//| p : Probability of success for each trial |
//| error_code : Variable for error code |
//| |
//| Return value: |
//| The cumulative distribution function evaluated at x. |
//+------------------------------------------------------------------+
double MathCumulativeDistributionBinomial(const double x,const double n,double p,int &error_code)
{
return MathCumulativeDistributionBinomial(x,n,p,true,false,error_code);
}
//+------------------------------------------------------------------+
//| Binomial cumulative distribution function (CDF) |
//+------------------------------------------------------------------+
//| The function returns the value of the Binomial cumulative |
//| distribution function with given n and p at the desired x. |
//| |
//| Arguments: |
//| x : Array with integer random variables |
//| n : Number of trials |
//| p : Probability of success for each trial |
//| tail : Flag to calculate lower tail |
//| log_mode : Logarithm mode flag,if true it calculates Log values|
//| error_code : Variable for error code |
//| |
//| Return value: |
//| true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathCumulativeDistributionBinomial(const double &x[],const double n,double p,const bool tail,const bool log_mode,double &result[])
{
//--- check NaN
if(!MathIsValidNumber(n) || !MathIsValidNumber(p))
return false;
//--- check n
if(n<0 || n!=MathRound(n))
return false;
//--- check probability
if(p<0.0 || p>1.0)
return false;
int data_count=ArraySize(x);
if(data_count==0)
return false;
int error_code=0;
ArrayResize(result,data_count);
//--- case p=0 and p==1
if(p==0.0 || p==1.0)
{
if(p==0.0)
{
for(int i=0; i<data_count; i++)
{
if(x[i]>=0)
result[i]=TailLog1(tail,log_mode);
else
result[i]=TailLog0(tail,log_mode);
}
}
else
//--- p==1.0
{
for(int i=0; i<data_count; i++)
{
if(x[i]>n)
result[i]=TailLog1(tail,log_mode);
else
result[i]=TailLog0(tail,log_mode);
}
}
return true;
}
int err_code=0;
for(int i=0; i<data_count; i++)
{
double x_arg=x[i];
if(MathIsValidNumber(x_arg))
{
if(x_arg<0)
result[i]=TailLog0(tail,log_mode);
else
if(x_arg>n)
result[i]=TailLog1(tail,log_mode);
else
{
double value=MathMin(1.0-MathCumulativeDistributionBeta(p,x_arg+1.0,n-x_arg,err_code),1.0);
//--- calculate result depending on arguments
result[i]=TailLogValue(value,tail,log_mode);
}
}
else
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| Binomial cumulative distribution function (CDF) |
//+------------------------------------------------------------------+
//| The function returns the value of the Binomial cumulative |
//| distribution function with given n and p for values |
//| from x[] array. |
//| |
//| Arguments: |
//| x : Array with integer random variables |
//| n : Number of trials |
//| p : Probability of success for each trial |
//| error_code : Variable for error code |
//| |
//| Return value: |
//| true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathCumulativeDistributionBinomial(const double &x[],const double n,double p,double &result[])
{
return MathCumulativeDistributionBinomial(x,n,p,true,false,result);
}
//+------------------------------------------------------------------+
//| Binomial distribution quantile function (inverse CDF) |
//+------------------------------------------------------------------+
//| The function returns the value of the inverse Binomial cumulative|
//| distribution function with parameters n and p for the desired |
//| probability. |
//| |
//| Arguments: |
//| probability : The desired probability |
//| n : Number of trials |
//| p : Probability of success for each trial |
//| tail : Lower tail flag (lower tail of probability used) |
//| log_mode : Logarithm mode flag (log probability used) |
//| error_code : Variable for error code |
//| |
//| Return value: |
//| The value of the inverse cumulative distribution function |
//| of the Binomial distribution with parameters n and p. |
//+------------------------------------------------------------------+
double MathQuantileBinomial(const double probability,const double n,const double p,const bool tail,const bool log_mode,int &error_code)
{
//--- check NaN
if(!MathIsValidNumber(probability) || !MathIsValidNumber(n) || !MathIsValidNumber(p))
{
error_code=ERR_ARGUMENTS_NAN;
return QNaN;
}
//--- check n
if(n<0 || n!=MathRound(n))
{
error_code=ERR_ARGUMENTS_INVALID;
return QNaN;
}
//--- check p range
if(p<0.0 || p>1.0)
{
error_code=ERR_ARGUMENTS_INVALID;
return QNaN;
}
//--- calculate real probability
double prob=TailLogProbability(probability,tail,log_mode);
//--- check probability range
if(prob<0.0 || prob>1.0)
{
error_code=ERR_ARGUMENTS_INVALID;
return QNaN;
}
error_code=ERR_OK;
int iterations=0;
const int max_iterations=1000;
//--- direct cdf calculation
double sum=MathProbabilityDensityBinomial(0,n,p,false,error_code);
while(sum<prob && iterations<max_iterations)
{
sum+=MathProbabilityDensityBinomial(iterations,n,p,false,error_code);
iterations++;
}
//--- check convergence
if(iterations<max_iterations)
{
if(iterations==0)
return 0.0;
else
return iterations-1;
}
else
{
error_code=ERR_RESULT_INFINITE;
return QPOSINF;
}
}
//+------------------------------------------------------------------+
//| Binomial distribution quantile function (inverse CDF) |
//+------------------------------------------------------------------+
//| The function returns the value of the inverse Binomial cumulative|
//| distribution function with parameters n and p for the desired |
//| probability. |
//| |
//| Arguments: |
//| probability : The desired probability |
//| n : Number of trials |
//| p : Probability of success for each trial |
//| error_code : Variable for error code |
//| |
//| Return value: |
//| The value of the inverse cumulative distribution function |
//| of the Binomial distribution with parameters n and p. |
//+------------------------------------------------------------------+
double MathQuantileBinomial(const double probability,const double n,const double p,int &error_code)
{
return MathQuantileBinomial(probability,n,p,true,false,error_code);
}
//+------------------------------------------------------------------+
//| Binomial distribution quantile function (inverse CDF) |
//+------------------------------------------------------------------+
//| The function calculates the value of the inverse Binomial |
//| cumulative distribution function with parameters n and p for |
//| the probability values from probability[] array. |
//| |
//| Arguments: |
//| probability : Array with probability values |
//| n : Number of trials |
//| p : Probability of success for each trial |
//| tail : Lower tail flag (lower tail of probability used) |
//| log_mode : Logarithm mode flag (log probability used) |
//| result : Output array with quantile values |
//| |
//| Return value: |
//| true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathQuantileBinomial(const double &probability[],const double n,const double p,const bool tail,const bool log_mode,double &result[])
{
//--- check NaN
if(!MathIsValidNumber(n) || !MathIsValidNumber(p))
return false;
//--- check n
if(n<0 || n!=MathRound(n))
return false;
//--- check p range
if(p<0.0 || p>1.0)
return false;
int data_count=ArraySize(probability);
if(data_count==0)
return false;
int error_code=0;
ArrayResize(result,data_count);
const int max_iterations=1000;
for(int i=0; i<data_count; i++)
{
//--- calculate real probability
double prob=TailLogProbability(probability[i],tail,log_mode);
if(MathIsValidNumber(prob))
{
//--- check probability range
if(prob<0.0 || prob>1.0)
return false;
int iterations=0;
//--- direct cdf calculation
double sum=MathProbabilityDensityBinomial(0,n,p,false,error_code);
while(sum<prob && iterations<max_iterations)
{
sum+=MathProbabilityDensityBinomial(iterations,n,p,false,error_code);
iterations++;
}
//--- check convergence
if(iterations<max_iterations)
{
if(iterations==0)
result[i]=0;
else
result[i]=iterations-1;
}
else
return false;
}
else
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| Binomial distribution quantile function (inverse CDF) |
//+------------------------------------------------------------------+
//| The function returns the value of the inverse Binomial cumulative|
//| distribution function with parameters n and p for the desired |
//| probability values from probability[] array. |
//| |
//| Arguments: |
//| probability : Array with probability values |
//| n : Number of trials |
//| p : Probability of success for each trial |
//| result : Output array with quantile values |
//| |
//| Return value: |
//| true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathQuantileBinomial(const double &probability[],const double n,const double p,double &result[])
{
return MathQuantileBinomial(probability,n,p,true,false,result);
}
//+------------------------------------------------------------------+
//| Random variate from Binomial distribution |
//+------------------------------------------------------------------+
//| This procedure generates a single random deviate from Binomial |
//| distribution whose number of trials is N and whose probability |
//| of an event in each trial is p. |
//| |
//| Input parameters: |
//| n : Number of binomial trials from which a random deviate |
//| will be generated. |
//| p : The probability of an event in each trial of the binomial |
//| distribution from which a random deviate is to be generated. |
//| |
//| Return value: |
//| The random value with Binomial distribution. |
//| |
//| Reference: |
//| Voratas Kachitvichyanukul, Bruce Schmeiser, |
//| "Binomial Random Variate Generation", Communications of the ACM, |
//| Volume 31, Number 2, February 1988, pages 216-222. |
//| |
//| Original FORTRAN77 version by Barry Brown, James Lovato. |
//| C version by John Burkardt. |
//+------------------------------------------------------------------+
double MathRandomBinomial(const double n,const double p)
{
int ix,ix1,mp;
double f,g,qn,r,t,u,v,w,w2,x,z;
int value=0;
int n1=(int)n;
double pp= MathMin(p,1.0-p);
double q = 1.0-pp;
double xnp=(double)(n1)*pp;
if(xnp<30.0)
{
qn= MathPow(q,n1);
r = pp/q;
g = r*(double)(n1+1);
for(;;)
{
ix= 0;
f = qn;
u = MathRandomNonZero();
for(;;)
{
if(u<f)
{
if(0.5<p)
{
ix=n1-ix;
}
value=ix;
return value;
}
if(110<ix)
break;
u=u-f;
ix=ix+1;
f=f*(g/(double)(ix)-r);
}
}
}
double ffm=xnp+pp;
int m=int(ffm);
double fm=m;
double xnpq=xnp*q;
double p1 = (int)(2.195*MathSqrt(xnpq)-4.6*q)+0.5;
double xm = fm + 0.5;
double xl = xm - p1;
double xr = xm + p1;
double c=0.134+20.5/(15.3+fm);
double al=(ffm-xl)/(ffm-xl*pp);
double xll=al*(1.0+0.5*al);
al=(xr-ffm)/(xr*q);
double xlr= al*(1.0 + 0.5*al);
double p2 = p1*(1.0 + c + c);
double p3 = p2 + c/xll;
double p4 = p3 + c/xlr;
//--- generate a variate
for(;;)
{
u = MathRandomNonZero()*p4;
v = MathRandomNonZero();
//--- triangle
if(u<p1)
{
ix=int(xm-p1*v+u);
if(0.5<p)
ix=n1-ix;
value=ix;
return value;
}
//--- parallelogram
if(u<=p2)
{
x = xl+(u - p1)/c;
v = v*c + 1.0 - MathAbs(xm-x)/p1;
if(v<=0.0 || 1.0<v)
continue;
ix=int(x);
}
else
if(u<=p3)
{
ix=int(xl+MathLog(v)/xll);
if(ix<0)
continue;
v=v*(u-p2)*xll;
}
else
{
ix=int(xr-MathLog(v)/xlr);
if(n1<ix)
continue;
v=v*(u-p3)*xlr;
}
int k=MathAbs(ix-m);
if(k<=20 || xnpq/2.0-1.0<=k)
{
f = 1.0;
r = pp/q;
g = (n1+1)*r;
if(m<ix)
{
mp=m+1;
for(int i=mp; i<=ix; i++)
f=f*(g/i-r);
}
else
if(ix<m)
{
ix1=ix+1;
for(int i=ix1; i<=m; i++)
f=f/(g/i-r);
}
if(v<=f)
{
if(0.5<p)
ix=n1-ix;
value=ix;
return value;
}
}
else
{
double amaxp=(k/xnpq)*((k*(k/3.0+0.625)+0.1666666666666)/xnpq+0.5);
double ynorm=-double((k*k)/(2.0*xnpq));
double alv=MathLog(v);
if(alv<ynorm-amaxp)
{
if(0.5<p)
ix=n1-ix;
value=ix;
return value;
}
if(ynorm+amaxp<alv)
continue;
double x1 = double(ix+1);
double f1 = fm + 1.0;
z = (double)(n1+1) - fm;
w = (double)(n1-ix+1);
double z2 = z * z;
double x2 = x1 * x1;
double f2 = f1 * f1;
w2=w*w;
t=xm*MathLog(f1/x1)+(n1-m+0.5)*MathLog(z/w)+(double)(ix-m)*MathLog(w*pp/(x1*q))
+(13860.0 -(462.0 -(132.0 -(99.0-140.0/f2)/f2)/f2)/f2)/f1/166320.0
+(13860.0 -(462.0 -(132.0 -(99.0-140.0/z2)/z2)/z2)/z2)/z/166320.0
+(13860.0 -(462.0 -(132.0 -(99.0-140.0/x2)/x2)/x2)/x2)/x1/166320.0
+(13860.0 -(462.0 -(132.0 -(99.0-140.0/w2)/w2)/w2)/w2)/w/166320.0;
if(alv<=t)
{
if(0.5<p)
ix=n1-ix;
value=ix;
return value;
}
}
}
return value;
}
//+------------------------------------------------------------------+
//| Random variate from Binomial distribution |
//+------------------------------------------------------------------+
//| The function returns random deviate from Binomial distribution |
//| with parameters n and p. |
//| |
//| Arguments: |
//| n : Number of trials |
//| p : Probability of success for each trial |
//| error_code : Variable for error code |
//| |
//| Return value: |
//| The random value with Binomial distribution. |
//+------------------------------------------------------------------+
double MathRandomBinomial(const double n,const double p,int &error_code)
{
//--- check NaN
if(!MathIsValidNumber(n) || !MathIsValidNumber(p))
{
error_code=ERR_ARGUMENTS_NAN;
return QNaN;
}
//--- check n
if(n<=0 || n!=MathRound(n))
{
error_code=ERR_ARGUMENTS_INVALID;
return QNaN;
}
//--- check probability
if(p<=0 || p>=1.0)
{
error_code=ERR_ARGUMENTS_INVALID;
return QNaN;
}
error_code=ERR_OK;
//--- return binomial random value
return MathRandomBinomial(n,p);
}
//+------------------------------------------------------------------+
//| Random variate from Binomial distribution |
//+------------------------------------------------------------------+
//| The function generates random variables from Binomial |
//| distribution with parameters n and p. |
//| |
//| Arguments: |
//| n : Number of trials |
//| p : Probability of success for each trial |
//| data_count : Number of values needed |
//| result : Output array with random values |
//| |
//| Return value: |
//| true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathRandomBinomial(const double n,const double p,const int data_count,double &result[])
{
if(data_count<=0)
return false;
//--- check NaN
if(!MathIsValidNumber(n) || !MathIsValidNumber(p))
return false;
//--- check n
if(n<=0 || n!=MathRound(n))
return false;
//--- check probability
if(p<=0 || p>=1.0)
return false;
//--- prepare output array and calculate random values
ArrayResize(result,data_count);
for(int i=0; i<data_count; i++)
result[i]=MathRandomBinomial(n,p);
return true;
}
//+------------------------------------------------------------------+
//| Binomial distriburion moments |
//+------------------------------------------------------------------+
//| The function calculates 4 first moments of the Binomial |
//| distribution with parameters n and p. |
//| |
//| Arguments: |
//| n : Number of trials |
//| p : Probability of success for each trial |
//| mean : Variable for mean value (1st moment) |
//| variance : Variable for variance value (2nd moment) |
//| skewness : Variable for skewness value (3rd moment) |
//| kurtosis : Variable for kurtosis value (4th moment) |
//| error_code : Variable for error code |
//| |
//| Return value: |
//| true if moments calculated successfully, otherwise false. |
//+------------------------------------------------------------------+
bool MathMomentsBinomial(const double n,const double p,double &mean,double &variance,double &skewness,double &kurtosis,int &error_code)
{
//--- default values
mean =QNaN;
variance=QNaN;
skewness=QNaN;
kurtosis=QNaN;
//--- check NaN
if(!MathIsValidNumber(n) || !MathIsValidNumber(p))
{
error_code=ERR_ARGUMENTS_NAN;
return false;
}
//--- check n
if(n<0 || n!=MathRound(n))
{
error_code=ERR_ARGUMENTS_INVALID;
return false;
}
//--- check p range
if(p<=0.0 || p>=1.0)
{
error_code=ERR_ARGUMENTS_INVALID;
return false;
}
error_code=ERR_OK;
//--- prepare factors
double np=n*p;
double one_mp=(1.0-p);
//--- calculate moments
mean =np;
variance=np*one_mp;
skewness=(1-2*p)/MathSqrt(variance);
kurtosis=(1-6*p*one_mp)/variance;
//--- successful
return true;
}
//+------------------------------------------------------------------+