/* ML Estimation and Forecasting of Binomial Multi-Fractal Models */ 
//NSW
cls; 


fname1 = "out_residelec1.xlsx"; 
rname1 = "a1:clo1399"$|"a1:chm1506"$|"a1:chr1501"$|"a1:clo1400"$|"a1:cey1572";

        iij = 1;

		do while iij <= rows(rname1); //rows(rname1)

shname1 = iij;   vls1 = reshape(error(0),9,1);
           
residuals = xlsReadM(fname1, rname1[iij], shname1, vls1[1]);  residuals = packr(residuals);

library pgraph,cml;

k = 8; 
gk = seqm(2^-(k-1),2,k);
forcsam = 1 ~ 5 ~ seqa(10,10,2)'; 	
mm1 = matrixA(k);  
xx1 = xxm(mm1,gk);  


//T1 = 2355; // T2 = 2249; //T3 = 2254; //T4 = 2355;
            //T5 = 2183;  
TT = 2355|2249|2254|2355|2183;
            
elec_bmsm1 = zeros(TT[iij],4); 

tt = 1; do while tt <= TT[iij]; 
	
test1 = residuals[.,tt]; n1 = rows(test1);    

xres = test1; 
    
start = 1.2|stdc(xres); 
    
format /rd 1,4; 
_output = 1; 
_cml_algorithm = 3; _cml_dirTol = 0.000000001; _cml_maxIters = 100;
_cml_Switch = 1|0.01|3;
_cml_bounds = {1 2, 0 1e256 }; _cml_Diagnostic = 2;

{  x,functi,grad,cov,retcode } = cmlprt(cml(xres,0,&multfrac_H,start));

forecast_msm = mfbin2_forcast(xres,mm1,x,forcsam,xx1);
    
    elec_bmsm1[tt,.] = forecast_msm[1,.]; 

  tt = tt + 1;
 
endo;

vls = reshape(error(0),9,1);
oret = xlsWriteM(elec_bmsm1,"elec_BMSM_revision.xls","a1",iij,vls[4]);
        
iij = iij + 1; 

endo;  


/* Likelihood function */

proc multfrac_H(pars,xres); 
	
local m0,s0,pitlg,omeg,piter,pit,iter;

m0 = pars[1]; s0 = stdc(xres); /*pars[2]*/

pitlg = zeros(rows(xres),1); pit = (2^(-k)).* ones(1,2^k); 

    iter = 1; do while iter <= rows(xres);

	omeg = omega(mm1,xres[iter],s0,m0); 

	piter = pit*xx1;

	pitlg[iter] = ln(omeg'*(piter)'); 

	pit = (omeg'.*(piter))/sumc((omeg'.*(piter))'); 

   iter = iter + 1; endo;

retp(sumc(pitlg));

endp;


/* Filtering of probabilities and use for forecasts over various horizons */

proc mfbin2_forcast(ret1,mm1,x,forcsam,xx1);
  local n1,j,jj,lg,ret,
         mm10,multis,iter,pit,pit1,omeg,piter,result;


mm10 = (mm1 .== 0).*x[1] + (mm1 .== 1).*(2-x[1]);

multis = prodc(mm10');


pit = (2^(-k)).* ones(1,2^k); 

    iter = 1; do while iter <= rows(ret1);
        
	   omeg = omega(mm1,ret1[iter],x[2],x[1]); 

	   piter = pit*xx1;

	   pit = (omeg'.*(piter))/sumc((omeg'.*(piter))'); 

   iter = iter + 1; endo;
 
/*  forecasts over a sample of different horizons*/ 

result = zeros(1,cols(forcsam)); 

    j = 1; do while j <= maxc(forcsam');

	if j == 1; pit1 = pit*xx1; else; pit1 = pit1*xx1; endif;
  
		 jj = 1; do while jj <= cols(forcsam);

		if j == forcsam[jj]; result[1,jj] = ((pit1*multis).*x[2]^2); endif;

			jj = jj + 1; endo;

    j = j + 1; endo;

  	   omeg = omega(mm1,ret1[rows(ret1)],x[2],x[1]); 

	   piter = pit*xx1;

	   pit = (omeg'.*(piter))/sumc((omeg'.*(piter))'); 

retp(result); 
endp;


proc matrixA(k);
local bins,j,i,kk,binaer;

bins = zeros(2^k,1); binaer = zeros(2^k,k);
j = 0; do while j <= 2^k - 1;
	i = j; 
	kk = k-1; do while kk >= 0;
		if i/(2^kk) >= 1; binaer[j+1,k-kk] = 1; i = i - 2^kk; endif;
	kk = kk - 1; endo;
j = j + 1; endo;
retp(binaer);
endp;


proc omega(mm1,x,s0,m0);
local multis,omeg;
	mm1 = (mm1 .== 0).*m0 + (mm1 .== 1).*(2-m0);
	multis = prodc(mm1');
 	omeg = pdfn(x/(s0*sqrt(multis)))./(s0*sqrt(multis));
retp(omeg);
endp;

/*
proc xx(mm1,gk);
local wegm,z,xx2,j;
	wegm = (rev(mm1) .== 1).*(1 - 0.5*gk') + (rev(mm1) .== 0).*0.5.*gk'; wegm = prodc(wegm');  
	z = seqa(1,1,2^k);
	xx2 = wegm~wegm[z+seqm(1,-1,2^k)];
		j = 2; do while j <= k;
		   xx2 = xx2~xx2[z+reshape(seqm(2^(j-1),-1,2^(k-j+1))*ones(1,2^(j-1)),2^k,1),.];
	j = j + 1; endo;
retp(xx2);
endp; */

proc xxm(mm1,gk);
local wegm,z,xx2,j;
	wegm = (rev(mm1) .== 1).*(1 - 0.5*gk') + (rev(mm1) .== 0).*0.5.*gk'; wegm = prodc(wegm');  
	z = seqa(1,1,2^k);
	xx2 = wegm~wegm[z+seqm(1,-1,2^k)];
		j = 2; do while j <= k;
		   xx2 = xx2~xx2[z+reshape(seqm(2^(j-1),-1,2^(k-j+1))*ones(1,2^(j-1)),2^k,1),.];
	j = j + 1; endo;
retp(xx2);
endp;


