//+------------------------------------------------------------------+ //| ljung.mqh | //| Copyright 2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com" #include"acf.mqh" //+------------------------------------------------------------------+ //| Ljung-Box test of autocorrelation in residuals. //+------------------------------------------------------------------+ matrix ljungboxtest(vector& x, ulong lags=0, ulong model_df=0, ulong period = 0, bool demean=false,bool boxpierce=false, bool autolag=false) { if(period==1) { Print(__FUNCTION__, " period must be >= 2"); return matrix::Zeros(0,0); } ulong nobs = x.Size(); vector laggs; if(autolag) { ulong maxlag = nobs-1; ACFResult sacf = acf(x,maxlag,0.05,false,demean,false); if(!sacf.acf.Size()) return matrix::Zeros(0,0); vector ssacf(maxlag); vector r(maxlag); for(ulong i = 1;i<(maxlag+1);ssacf[i-1]=sacf.acf[i],++i); for(ulong i = 0;i<(maxlag);r[i] = double(i+1),++i); vector qsacf; if(!boxpierce) { vector n = pow(ssacf,2.)/(double(nobs)-r); qsacf = nobs*(nobs+2.)*n.CumSum(); } else { vector n = pow(ssacf,2.); qsacf = nobs*n.CumSum(); } double q = 2.4; double threshold = sqrt(q*log(nobs)); double threshold_metric = MathAbs(sacf.acf).Max()*sqrt(nobs); r = vector::Zeros(nobs-1); for(ulong i = 0;i0) pval[i] = 1. - MathCumulativeDistributionChiSquare(qljungbox[i],adj_lags[i],e); matrix out; out = matrix::Zeros(adj_lags.Size(),2); out.Col(qljungbox,0); out.Col(pval,1); if(boxpierce) { out.Resize(out.Rows(),4); temp = pow(ssacf,2.0); temp = temp.CumSum(); vector qboxpierce = temp; for(ulong i = 0; i0) pval[i] = 1. - MathCumulativeDistributionChiSquare(qboxpierce[i],adj_lags[i],e); out.Col(qboxpierce,2); out.Col(pval,3); } return out; } //+------------------------------------------------------------------+