function [yprogn,masdtparam]=MarkovPrognozOptimize(y,masdtparam1);
%главная функция прогнозирования. Принимает массив значений, дополнительные параметры и производит
%прогноз.
%y - входной ряд.

N=length(y);
% Определяем наиболее оптимальную длину ряда при заданной иерархии.
%[N1,masm,masdt]=getbestlength(N*3/4,[2,3,5,7,11,13,17,19,23,29]);
%Возможно использование простой иерархии - степени двоек.
ndt=length(masdtparam1);
N1=masdtparam1(ndt).dt;
y_urez=y;
% Обрезаем входной ряд, убирая лишние начальные точки.
tbeg=ceil(N1/3);
nprognoz=N1;
s=4;
dtmanual=3; % Количество слоев иерархии, задаваемых вручную
%masiv_s=[1,1,2,2,14,3,3,2,2,2,10,3,3,5,2,5,2,6];
%masiv_s=[8,8,8,7,7,7,6,6,6,5,5,5,4,4,4,3,3,3];
%masiv_s=[3,3,3,3,7,8,5,12,2,8,2,4,8,13,14,2]; % масив, одержаний на оптимизации по данным Грн-евро НБУ
%masiv_s=[2,2,2,2,3,8,10,2,13,15,2,13,5,2,11,11]; % масив, одержаний на оптимизации по данным sp500new

% 252-3,210-8, 180-10,140-2,126-13, 105-15,90-2,84-13,70-5,63-2, 60-11,45-11 - сп500
%sin30 :168-14,140-10,120-2,105-8,84-6,70-9,60-5,56-9,42-3,40-3,35-4,30-4, 28-9,24-15,21-4,20-3,15-7,14-15,12-7,10-2,8-10,7-9,6-8,5-6,4-4,3-9,2-5
xx=1:length(y);
if (size(y,1)>size(y,2))
    y=transpose(y);
end

skleenoe=0; 
first_r_min=-10;
lin_aprox=polyfit(xx,y,1);
xx=1:nprognoz*3+1;
aa=ones(1,length(xx))*lin_aprox(1);
bb=ones(1,length(xx))*y_urez(nprognoz+1);
skleenoe=aa.*xx+bb;

masdtparam =[];
for dtparam=masdtparam1(dtmanual+1:length(masdtparam1))
    r_max=dtparam.rmax;
    r_max_ot_s=7;
    % сюда нужно вставить подсчет максимальной степени цепи в зависимости от количества уровней квантования.
    % s^r=k*N1->log<s>(s^r)=log<s>(k*N1)-> r=ln(k*N1)/ln(s)
    k=5;
    %r_max_ot_s=round(log(k*(N1-dt))/log(s));
    %if r_max<1
    %    continue;
    %end
    %if r_max>r_max_ot_s 
    %    r_max=r_max_ot_s;
    %end
    dtparam.r=r_max;
    dt=dtparam.dt;
    s=dtparam.s;
    smax=dtparam.smax;
    smin=dtparam.smin;
    k=dtparam.k;
    kmax=dtparam.kmax;
    kmin=dtparam.kmin;
    r=dtparam.r;
    rmax=dtparam.rmax;
    rmin=dtparam.rmin;
    rmax_usr=dtparam.rmax;
    rmin_usr=dtparam.rmin;
    tbeg=dtparam.tbeg;
    tend=dtparam.tend;
    tbeg_sost=dtparam.tbeg_sost;
    tend_sost=dtparam.tend_sost;
    
    %dtparam.s=s_best;
    %dtparam.r=r_best;
    best_err=99999999;
    best_r=0;
    best_s=2;
    best_k=1;    
    r=10;
    s_max=smax;
    s=s_max;
    %if s_max>dt^(1/2)
    %    s_max=dt^(1/2);
    %end
    if (dtparam.testk==0)
        kmax=k;
        kmin=k;
    end
    for k=kmin:kmax
        sum_err=0;
        ntest=0;
        if (dtparam.tests==0)
            smax=s;
            smin=s;
        end
        for s=smin:smax
            if (dtparam.testr==0)
                rmax=r;
                rmin=r;
            end
            for r=rmin:rmax
                step=floor(((N-dt-1)-(tbeg-dt+1))/20);
                if step<=0
                    -9999
                end
                abs_r_min=99999;
                abs_r_max=0;
                abs_r_avg=0;
                abs_r_sum=0;
                abs_r_count=0;
                for curtbeg=tbeg+1:step:N-dt-1 % curtbeg+dt: koordinata nachala prognozirowaniya pri teste
                    %tbeg=ceil(iii);
                    dtparam.r=r;
                    dtparam.s=s;
                    dtparam.k=k;
                    ycopy=y_urez(curtbeg-tbeg:length(y_urez));
                    %[yprogn,res_r_min,res_r_max,res_r_avg]=prognoztest(ycopy(1:tbeg),[dtparam,masdtparam],tbeg,nprognoz);
                    smeshenie=floor(dt/2);
                    tbeg_progn=curtbeg;
                    if (~isempty(skleenoe))
                        y_all_prognoz=[ycopy(1:length(y_urez)-1),skleenoe];
                        y_all_zglazh=sglazh(y_all_prognoz,dt,0); % в конце уменьшение окна
                        len1=tbeg_progn-smeshenie;%length(y_urez)
                        y_zglazh=y_all_zglazh(1:length(ycopy));
                        len_yzgl=length(y_all_zglazh);
                        sglazhskl=y_all_zglazh(len1+1:len_yzgl);%sglazh(y_urez,dt);
                    else
                        y_zglazh=sglazh(y_copy,dt,1); % уменьшение окна в начале (в конце прогнозироваться будет)
                        if tbeg_progn>length(y_zglazh)
                            tbeg_progn=length(y_zglazh);
                        end
                        sglazhskl=sglazh(skleenoe,dt,0); % уменьшение окна в конце - там прогноз менее точен
                    end
                    %y_zglazh
                    
                    [mas_newsost,mas_sredn,res_r_min,res_r_max,res_r_avg,s,errors]=prognoz_maxr(y_zglazh,dt,rmin_usr, rmax_usr,s,nprognoz/dt*3+1,tbeg_progn-smeshenie+1,k,tbeg,tend,tbeg_sost,tend_sost);
                    
                    nresseries=size(mas_newsost,1);
                    for nser=1:nresseries
                        mas_newsost1=mas_newsost(nser,:);
                        mas_newy=sost2val(y_zglazh(tbeg_progn-smeshenie+1),mas_newsost1,mas_sredn,dt);
                        %plot(mas_newy);
                    end
                    yprogn=mas_newy;
                    if (res_r_min<abs_r_min)
                        abs_r_min=res_r_min;
                    end
                    if (res_r_max>abs_r_max)
                        abs_r_max=res_r_max;
                    end
                    abs_r_sum=abs_r_sum+res_r_avg;
                    abs_r_count=abs_r_count+1;
                    %figure;
                    %plot(ycopy,'b');
                    %hold on; 
                    %plot(yprogn,'r');
                    lsr=tbeg+dt;%min(length(y_urez),length(yprogn))/4;
                    %lycopy=length(ycopy)
                    diff=ycopy(tbeg:dt:lsr)-yprogn(tbeg:dt:lsr);
                    err=(diff*transpose(diff))/length(diff);
                    sum_err=sum_err+err;
                    ntest=ntest+1;
                    %fprintf(1,'dt=\t%d\t r=\t%d\t s=\t%d\t, err=\t%d\n',dt,dtparam.r,dtparam.s,err);
                    fprintf(1,'*');
                end 
                abs_r_avg=abs_r_sum/abs_r_count;
                sum_err=sum_err/ntest;
                fprintf(1,'\ndt=\t%d\t s=\t%d\tk=\t%d\t srednee_err=\t%d\t',dt,dtparam.s,dtparam.k,sum_err);
                fprintf(1,'r_min=\t%d\tr_max=\t%d\tr_avg=\t%d\n',abs_r_min,abs_r_max,abs_r_avg);
                if (sum_err<best_err)
                    best_err=sum_err;
                    best_s=s;
                    best_r=r;
                    best_k=k;
                end
            end
        end
    end
    fprintf(1,'For dt=\t%d\t bests=\t%d\tbestk=\t%d\t best_err=\t%d\n',dt,best_s,best_k,best_err);
    dtparam.s=best_s;    
    dtparam.k=best_k;
    dtparam.r=best_r;
    masdtparam=[dtparam,masdtparam];
end
yprogn=prognoztest(y_urez,masdtparam,N-1,nprognoz);
%figure;
%plot(y_urez,'b');
%hold on;
%plot(yprogn,'r');

