diff --git a/matlab/default_option_values.m b/matlab/default_option_values.m
index 9422d030165c1b6e5d7714cc1fdd7db7f2c9ef65..a1d501d980702871ec3c5b698f2e98cda5b330e1 100644
--- a/matlab/default_option_values.m
+++ b/matlab/default_option_values.m
@@ -289,9 +289,6 @@ particle.resampling.number_of_partitions = 200;
 particle.mixture_state_variables = 5 ;
 particle.mixture_structural_shocks = 1 ;
 particle.mixture_measurement_shocks = 1 ;
-% Online approach
-particle.liu_west_delta = 0.99 ;
-particle.liu_west_max_resampling_tries = 5000;
 % Options for setting the weights in conditional particle filters.
 particle.cpf_weights_method.amisanotristani = true;
 particle.cpf_weights_method.murrayjonesparslow = false;
@@ -517,6 +514,11 @@ options_.posterior_sampler_options.dsmh.particles = 20000 ;
 options_.posterior_sampler_options.dsmh.alpha0 = 0.2 ;
 options_.posterior_sampler_options.dsmh.alpha1 = 0.3 ;
 options_.posterior_sampler_options.dsmh.tau = 10 ;
+% Liu and West online Sampler
+options_.posterior_sampler_options.online.particles= 5000 ;
+options_.posterior_sampler_options.online.liu_west_delta = 0.99 ;
+options_.posterior_sampler_options.online.liu_west_max_resampling_tries = 5000 ;
+options_.posterior_sampler_options.online.second_resampling = false;
 
 options_.trace_plot_ma = 200;
 options_.mh_autocorrelation_function_size = 30;
@@ -660,6 +662,12 @@ particleswarm.UseParallel = false;
 particleswarm.UseVectorized = false;
 options_.particleswarm = particleswarm;
 
+% One step
+one_step.gradient = [] ;
+one_step.hessian = [] ;
+one_step.outer_product = 0 ;
+options_.one_step= one_step ;
+
 % prior analysis
 options_.prior_mc = 20000;
 
diff --git a/matlab/dynare_config.m b/matlab/dynare_config.m
index 5b2f208c85d563087a0011c48df2302b77b827a9..8d44e1caaa2756125d7f5d7fbc3b279cfe53d778 100644
--- a/matlab/dynare_config.m
+++ b/matlab/dynare_config.m
@@ -53,6 +53,7 @@ p = {'/../contrib/ms-sbvar/TZcode/MatlabFiles/' ; ...
      '/ep/' ; ...
      '/estimation/'; ...
      '/estimation/smc/'; ...
+     '/estimation/online/'; ...
      '/estimation/resampler/'; ...
      '/kalman/' ; ...
      '/kalman/likelihood' ; ...
diff --git a/matlab/estimation/GetAllPosteriorDraws.m b/matlab/estimation/GetAllPosteriorDraws.m
index 5c1847cf0283ecf87da59089dd78f843a7306ab4..fdea14c93f56029116a2a2887379f0d34a63a3e2 100644
--- a/matlab/estimation/GetAllPosteriorDraws.m
+++ b/matlab/estimation/GetAllPosteriorDraws.m
@@ -51,6 +51,18 @@ if issmc(options_)
         else
             draws = posterior.tlogpostkernel;
         end
+    elseif isonline(options_)
+        % Load draws from the posterior distribution
+        posterior = load(sprintf('%s/online/parameters_particles_final.mat', dname));
+        if column>0 || strcmp(column,'all')
+            if strcmp(column,'all')
+                draws = transpose(posterior.param);
+            else
+                draws = transpose(posterior.param(column,:));
+            end
+        else
+            draws=NaN(size(posterior.param,2),1);
+        end
     elseif isdime(options_)
         posterior = load(sprintf('%s%s%s%schains.mat', dname, filesep(), 'dime', filesep()));
         tune = posterior.tune;
diff --git a/matlab/estimation/GetPosteriorMeanVariance.m b/matlab/estimation/GetPosteriorMeanVariance.m
index 9a1c1205129f6cc24b7a0745b15e92ec94db039b..7f73899cc863c5b8d51f88a388f5fa755cc816aa 100644
--- a/matlab/estimation/GetPosteriorMeanVariance.m
+++ b/matlab/estimation/GetPosteriorMeanVariance.m
@@ -36,6 +36,12 @@ if issmc(options_)
         mean = sum(posterior.particles, 2)/length(posterior.tlogpostkernel);
         % Compute the posterior covariance
         variance = (posterior.particles-mean)*(posterior.particles-mean)'/length(posterior.tlogpostkernel);
+    elseif isonline(options_)
+        posterior = load(sprintf('%s/online/parameters_particles_final.mat', M_.dname));
+        % Compute the posterior mean
+        mean = sum(posterior.param, 2)/size(posterior.param, 2);
+        % Compute the posterior covariance
+        variance = (posterior.param-mean)*(posterior.param-mean)'/size(posterior.param, 2);
     elseif isdime(options_)
         posterior = load(sprintf('%s%s%s%schains.mat', M_.dname, filesep(), 'dime', filesep()));
         tune = posterior.tune;
diff --git a/matlab/estimation/GetPosteriorParametersStatistics.m b/matlab/estimation/GetPosteriorParametersStatistics.m
index 208a37779290ca18a3daa690cfb706c9f7e419b8..ebaf93666523353a3a2df5c5d54f5f594743395d 100644
--- a/matlab/estimation/GetPosteriorParametersStatistics.m
+++ b/matlab/estimation/GetPosteriorParametersStatistics.m
@@ -55,9 +55,11 @@ skipline(2)
 disp('ESTIMATION RESULTS')
 skipline()
 
-if ishssmc(options_)
+if ishssmc(options_) 
     dprintf('Log data density is %f.', oo_.MarginalDensity.hssmc);
     hpd_draws = round((1-options_.mh_conf_sig)*num_draws);
+elseif isonline(options_)
+    hpd_draws = num_draws;
 elseif isdime(options_)
     hpd_draws = round((1-options_.mh_conf_sig)*num_draws);
 else
@@ -87,7 +89,7 @@ if np
     disp(tit2)
     ip = nvx+nvn+ncx+ncn+1;
     for i=1:np
-        if options_.mh_replic || (options_.load_mh_file && ~options_.load_results_after_load_mh) || ishssmc(options_)
+        if options_.mh_replic || (options_.load_mh_file && ~options_.load_results_after_load_mh) || ishssmc(options_) || isonline(options_)
             draws = getalldraws(ip);
             [post_mean, post_median, post_var, hpd_interval, post_deciles, density] = posterior_moments(draws, options_.mh_conf_sig);
             name = bayestopt_.name{ip};
diff --git a/matlab/estimation/check_posterior_analysis_data.m b/matlab/estimation/check_posterior_analysis_data.m
index 6de65d2de26ed4380f63f3785b3ddc4dc5f5a467..6b9008d4422899c063c90cb77b20a86ab5d467cf 100644
--- a/matlab/estimation/check_posterior_analysis_data.m
+++ b/matlab/estimation/check_posterior_analysis_data.m
@@ -45,6 +45,8 @@ if ~issmc(options_)
 else
     if ishssmc(options_)
         [MetropolisFolder, info] = CheckPath('hssmc',M_.dname);
+    elseif isonline(options_)
+        [MetropolisFolder, info] = CheckPath('online',M_.dname);
     elseif isdime(options_)
         [MetropolisFolder, info] = CheckPath('dime',M_.dname);
     else
@@ -76,6 +78,10 @@ else
             % Load draws from the posterior distribution
             pfiles = dir(sprintf('%s/hssmc/particles-*.mat', M_.dname));
             mhdate = get_date_of_a_file(sprintf('%s/hssmc/particles-%u-%u.mat', M_.dname, length(pfiles), length(pfiles)));
+        elseif isonline(options_)
+            % Load draws from the posterior distribution
+            pfiles = dir(sprintf('%s/online/parameters_particles_final.mat', M_.dname));
+            mhdate = get_date_of_a_file(sprintf('%s/online/parameters_particles_final.mat', M_.dname, length(pfiles), length(pfiles)));
         elseif isdime(options_)
             mhdate = get_date_of_a_file(sprintf('%s%s%s%schains.mat', M_.dname, filesep(), 'dime', filesep()));
         end
diff --git a/matlab/estimation/check_posterior_sampler_options.m b/matlab/estimation/check_posterior_sampler_options.m
index e93510075baf1f6956c47beb1a5c148f9eefc3a7..fe93f77a69ec5436c5ee84ed80b28f28c25e25e3 100644
--- a/matlab/estimation/check_posterior_sampler_options.m
+++ b/matlab/estimation/check_posterior_sampler_options.m
@@ -374,125 +374,150 @@ if init
                 posterior_sampler_options.WR=[];
             end
 
-          case 'hssmc'
+      case 'hssmc'
 
-            % default options
-            posterior_sampler_options = add_fields_(posterior_sampler_options, options_.posterior_sampler_options.hssmc);
+          % default options
+          posterior_sampler_options = add_fields_(posterior_sampler_options, options_.posterior_sampler_options.hssmc);
 
-            % user defined options
-            if ~isempty(options_.posterior_sampler_options.sampling_opt)
-                options_list = read_key_value_string(options_.posterior_sampler_options.sampling_opt);
-                for i=1:rows(options_list)
-                    switch options_list{i,1}
+          % user defined options
+          if ~isempty(options_.posterior_sampler_options.sampling_opt)
+              options_list = read_key_value_string(options_.posterior_sampler_options.sampling_opt);
+              for i=1:rows(options_list)
+                  switch options_list{i,1}
                       case 'target'
-                        posterior_sampler_options.target = options_list{i,2};
+                          posterior_sampler_options.target = options_list{i,2};
                       case 'steps'
-                        posterior_sampler_options.steps = options_list{i,2};
+                          posterior_sampler_options.steps = options_list{i,2};
                       case 'scale'
-                        posterior_sampler_options.scale = options_list{i,2};
+                          posterior_sampler_options.scale = options_list{i,2};
                       case 'particles'
-                        posterior_sampler_options.particles = options_list{i,2};
+                          posterior_sampler_options.particles = options_list{i,2};
                       case 'lambda'
-                        posterior_sampler_options.lambda = options_list{i,2};
+                          posterior_sampler_options.lambda = options_list{i,2};
                       otherwise
-                        warning(['hssmc: Unknown option (' options_list{i,1} ')!'])
-                    end
-                end
-            end
-
-            options_.mode_compute = 0;
-            options_.cova_compute = 0;
-            options_.mh_replic = 0;
-            options_.mh_posterior_mode_estimation = false;
-
-          case 'dime_mcmc'
-
-            % default options
-            posterior_sampler_options = add_fields_(posterior_sampler_options, options_.posterior_sampler_options.dime);
-
-            % user defined options
-            if ~isempty(options_.posterior_sampler_options.sampling_opt)
-                options_list = read_key_value_string(options_.posterior_sampler_options.sampling_opt);
-                for i=1:rows(options_list)
-                    switch options_list{i,1}
+                          warning(['hssmc: Unknown option (' options_list{i,1} ')!'])
+                  end
+              end
+          end
+          
+          options_.mode_compute = 0;
+          options_.cova_compute = 0;
+          options_.mh_replic = 0;
+          options_.mh_posterior_mode_estimation = false;
+          
+      case 'dime_mcmc'
+          
+          % default options
+          posterior_sampler_options = add_fields_(posterior_sampler_options, options_.posterior_sampler_options.dime);
+
+          if ~isempty(options_.posterior_sampler_options.sampling_opt)
+              options_list = read_key_value_string(options_.posterior_sampler_options.sampling_opt);
+              for i=1:rows(options_list)
+                  switch options_list{i,1}
                       case 'nchain'
-                        posterior_sampler_options.nchain = options_list{i,2};
+                          posterior_sampler_options.nchain = options_list{i,2};
                       case 'niter'
-                        posterior_sampler_options.niter = options_list{i,2};
+                          posterior_sampler_options.niter = options_list{i,2};
                       case 'parallel'
-                        posterior_sampler_options.parallel = options_list{i,2};
+                          posterior_sampler_options.parallel = options_list{i,2};
                       case 'tune'
-                        posterior_sampler_options.tune = options_list{i,2};
+                          posterior_sampler_options.tune = options_list{i,2};
                       case 'aimh_prob'
-                        posterior_sampler_options.aimh_prob = options_list{i,2};
+                          posterior_sampler_options.aimh_prob = options_list{i,2};
                       case 'sigma'
-                        posterior_sampler_options.sigma = options_list{i,2};
+                          posterior_sampler_options.sigma = options_list{i,2};
                       case 'gamma'
-                        posterior_sampler_options.gamma = options_list{i,2};
+                          posterior_sampler_options.gamma = options_list{i,2};
                       case 'df_proposal_dist'
-                        posterior_sampler_options.df_proposal_dist = options_list{i,2};
+                          posterior_sampler_options.df_proposal_dist = options_list{i,2};
                       case 'rho'
-                        posterior_sampler_options.rho = options_list{i,2};
+                          posterior_sampler_options.rho = options_list{i,2};
                       otherwise
-                        warning(['dime: Unknown option (' options_list{i,1} ')!'])
-                    end
-                end
-            end
-
-            if ~isfield(posterior_sampler_options,'tune')
-                posterior_sampler_options.tune = ceil(50000 / posterior_sampler_options.nchain);
-                dprintf('dime: setting number of ensemble iterations to keep (`tune`) to %d.', posterior_sampler_options.tune)
-            end
-            options_.mode_compute = 0;
-            options_.cova_compute = 0;
-            options_.mh_replic = 0;
-            options_.mh_posterior_mode_estimation = false;
+                          warning(['dime: Unknown option (' options_list{i,1} ')!'])
+                  end
+              end
+          end
+
+          if ~isfield(posterior_sampler_options,'tune')
+              posterior_sampler_options.tune = ceil(50000 / posterior_sampler_options.nchain);
+              dprintf('dime: setting number of ensemble iterations to keep (`tune`) to %d.', posterior_sampler_options.tune)
+          end
+
+      case 'online'
+
+          % default options
+          posterior_sampler_options = add_fields_(posterior_sampler_options, options_.posterior_sampler_options.online);
+
+          % user defined options
+          if ~isempty(options_.posterior_sampler_options.sampling_opt)
+              options_list = read_key_value_string(options_.posterior_sampler_options.sampling_opt);
+              for i=1:rows(options_list)
+                  switch options_list{i,1}
+                      case 'particles'
+                          posterior_sampler_options.particles = options_list{i,2};
+                      case 'liu_west_delta'
+                          posterior_sampler_options.liu_west_delta = options_list{i,2};
+                      case 'liu_west_max_resampling_tries'
+                          posterior_sampler_options.liu_west_max_resampling_tries = options_list{i,2};
+                      case 'second_resampling'
+                          posterior_sampler_options.second_resampling = options_list{i,2};
+                      otherwise
+                          warning(['online: Unknown option (' options_list{i,1} ')!'])
+                  end
+              end
+          end
+          
+          options_.mode_compute = 0;
+          options_.cova_compute = 0;
+          options_.mh_replic = 0;
+          options_.mh_posterior_mode_estimation = false;
 
       case 'dsmh'
 
-        % default options
-        posterior_sampler_options = add_fields_(posterior_sampler_options, options_.posterior_sampler_options.dsmh);
-
-        % user defined options
-        if ~isempty(options_.posterior_sampler_options.sampling_opt)
-            options_list = read_key_value_string(options_.posterior_sampler_options.sampling_opt);
-            for i=1:rows(options_list)
-                switch options_list{i,1}
-                  case 'proposal_distribution'
-                    if ~(strcmpi(options_list{i,2}, 'rand_multivariate_student') || ...
-                         strcmpi(options_list{i,2}, 'rand_multivariate_normal'))
-                        error(['initial_estimation_checks:: the proposal_distribution option to estimation takes either ' ...
-                               'rand_multivariate_student or rand_multivariate_normal as options']);
-                    else
-                        posterior_sampler_options.proposal_distribution=options_list{i,2};
-                    end
-                  case 'student_degrees_of_freedom'
-                    if options_list{i,2} <= 0
-                        error('initial_estimation_checks:: the student_degrees_of_freedom takes a positive integer argument');
-                    else
-                        posterior_sampler_options.student_degrees_of_freedom=options_list{i,2};
-                    end
-                  case 'save_tmp_file'
-                    posterior_sampler_options.save_tmp_file = options_list{i,2};
-                  case 'number_of_particles'
-                    posterior_sampler_options.particles = options_list{i,2};
-                  otherwise
-                    warning(['rwmh_sampler: Unknown option (' options_list{i,1} ')!'])
-                end
-            end
-        end
-
-        options_.mode_compute = 0;
-        options_.cova_compute = 0;
-        options_.mh_replic = 0;
-        options_.mh_posterior_mode_estimation = true;
+          % default options
+          posterior_sampler_options = add_fields_(posterior_sampler_options, options_.posterior_sampler_options.dsmh);
+
+          % user defined options
+          if ~isempty(options_.posterior_sampler_options.sampling_opt)
+              options_list = read_key_value_string(options_.posterior_sampler_options.sampling_opt);
+              for i=1:rows(options_list)
+                  switch options_list{i,1}
+                      case 'proposal_distribution'
+                          if ~(strcmpi(options_list{i,2}, 'rand_multivariate_student') || ...
+                               strcmpi(options_list{i,2}, 'rand_multivariate_normal'))
+                              error(['initial_estimation_checks:: the proposal_distribution option to estimation takes either ' ...
+                                         'rand_multivariate_student or rand_multivariate_normal as options']);
+                          else
+                              posterior_sampler_options.proposal_distribution=options_list{i,2};
+                          end
+                      case 'student_degrees_of_freedom'
+                          if options_list{i,2} <= 0
+                              error('initial_estimation_checks:: the student_degrees_of_freedom takes a positive integer argument');
+                          else
+                              posterior_sampler_options.student_degrees_of_freedom=options_list{i,2};
+                          end
+                      case 'save_tmp_file'
+                          posterior_sampler_options.save_tmp_file = options_list{i,2};
+                      case 'number_of_particles'
+                          posterior_sampler_options.particles = options_list{i,2};
+                      otherwise
+                          warning(['rwmh_sampler: Unknown option (' options_list{i,1} ')!'])
+                  end
+                  end
+          end
+          
+          options_.mode_compute = 0;
+          options_.cova_compute = 0;
+          options_.mh_replic = 0;
+          options_.mh_posterior_mode_estimation = true;
+              
+      otherwise
+          error('check_posterior_sampler_options:: Unknown posterior_sampling_method option %s ',posterior_sampler_options.posterior_sampling_method);
+    end
 
-          otherwise
-            error('check_posterior_sampler_options:: Unknown posterior_sampling_method option %s ',posterior_sampler_options.posterior_sampling_method);
-        end
+    return
 
-        return
-end
+end % if init
 
 % here are all samplers requiring a proposal distribution
 if ~strcmp(posterior_sampler_options.posterior_sampling_method,'slice')
diff --git a/matlab/estimation/dynare_estimation_1.m b/matlab/estimation/dynare_estimation_1.m
index 6e2bd2bee0d2b881644be389f367d46fb99acd8e..12c0444b5aa1c1b18960e95752a7ff28d83ce1ef 100644
--- a/matlab/estimation/dynare_estimation_1.m
+++ b/matlab/estimation/dynare_estimation_1.m
@@ -237,11 +237,7 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation &
     optimizer_vec = [options_.mode_compute;num2cell(options_.additional_optimizer_steps)];
     for optim_iter = 1:length(optimizer_vec)
         current_optimizer = optimizer_vec{optim_iter};
-        if current_optimizer~=11  
-          [xparam1, fval, ~, hh, options_, Scale, new_rat_hess_info] = dynare_minimize_objective(objective_function,xparam1,current_optimizer,options_,[bounds.lb bounds.ub],bayestopt_.name,bayestopt_,hh,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,bounds,oo_.dr, oo_.steady_state,oo_.exo_steady_state,oo_.exo_det_steady_state);
-        else 
-          [xparam1, fval, ~, hh, options_, Scale, new_rat_hess_info] = dynare_minimize_objective(objective_function,xparam1,current_optimizer,options_,[bounds.lb bounds.ub],bayestopt_.name,bayestopt_,hh,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,bounds,oo_);
-        end
+        [xparam1, fval, ~, hh, options_, Scale, new_rat_hess_info] = dynare_minimize_objective(objective_function,xparam1,current_optimizer,options_,[bounds.lb bounds.ub],bayestopt_.name,bayestopt_,hh,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,bounds,oo_.dr, oo_.steady_state,oo_.exo_steady_state,oo_.exo_det_steady_state);
         fprintf('\nFinal value of minus the log posterior (or likelihood):%f \n', fval);
 
         if isnumeric(current_optimizer)
@@ -271,7 +267,7 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation &
                         hh = hessian(penalized_objective_function, xparam1, options_.gstep, objective_function, fval, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, bounds,oo_.dr,oo_.steady_state,oo_.exo_steady_state,oo_.exo_det_steady_state);
                     else
                         hh = hessian(objective_function, xparam1, options_.gstep, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, bounds,oo_.dr,oo_.steady_state,oo_.exo_steady_state,oo_.exo_det_steady_state);
-                    end
+                    end 
                     hh = reshape(hh, nx, nx);
                 elseif isnumeric(current_optimizer) && isequal(current_optimizer,5)
                     % other numerical hessian options available with optimizer
@@ -398,7 +394,11 @@ end
 % Run SMC sampler.
 %
 
-if ishssmc(options_)
+if isonline(options_)
+    [posterior_sampler_options, options_, bayestopt_] = check_posterior_sampler_options([], M_.fname, M_.dname, options_, bounds, bayestopt_);
+    options_.posterior_sampler_options.current_options = posterior_sampler_options;
+    online_auxiliary_filter(xparam1, dataset_, options_, M_, estim_params_, bayestopt_, oo_);
+elseif ishssmc(options_)
     [posterior_sampler_options, options_, bayestopt_] = check_posterior_sampler_options([], M_.fname, M_.dname, options_, bounds, bayestopt_);
     options_.posterior_sampler_options.current_options = posterior_sampler_options;
     oo_.MarginalDensity.hssmc = hssmc(objective_function, bounds, dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, oo_);
@@ -471,7 +471,7 @@ if issmc(options_) || (any(bayestopt_.pshape>0) && options_.mh_replic) ||  (any(
             oo_.lprob = trace_plot_dime(options_, M_);
         end
         % Estimation of the marginal density from the Mh draws:
-        if ishssmc(options_) || isdime(options_) || options_.mh_replic || (options_.load_mh_file && ~options_.load_results_after_load_mh)
+        if ishssmc(options_) || isonline(options_) || isdime(options_) || options_.mh_replic || (options_.load_mh_file && ~options_.load_results_after_load_mh)
             if ~issmc(options_)
                 [~, oo_] = marginal_density(M_, options_, estim_params_, oo_, bayestopt_);
             end
diff --git a/matlab/estimation/get_posterior_folder_name.m b/matlab/estimation/get_posterior_folder_name.m
index 25b86f1c8b6375b691dfff125cbee03b0752aafd..fc0fd0b8e463d03b60347dc27fc6f5b1a95112d6 100644
--- a/matlab/estimation/get_posterior_folder_name.m
+++ b/matlab/estimation/get_posterior_folder_name.m
@@ -36,6 +36,8 @@ else
         folder_name='hssmc';
     elseif isdime(options_)
         folder_name='dime';
+    elseif isonline(options_)
+        folder_name='online';
     else
         error('get_posterior_folder_name:: case should not happen. Please contact the developers')
     end
diff --git a/matlab/estimation/online/isonline.m b/matlab/estimation/online/isonline.m
new file mode 100644
index 0000000000000000000000000000000000000000..b44670ea524b57d299f6d4349180e99c94a0fdf6
--- /dev/null
+++ b/matlab/estimation/online/isonline.m
@@ -0,0 +1,25 @@
+function bool = isonline(options_)
+
+% Copyright © 2024 Dynare Team
+%
+% This file is part of Dynare.
+%
+% Dynare is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <https://www.gnu.org/licenses/>.
+
+bool = false;
+if isfield(options_, 'posterior_sampler_options')
+    if strcmp(options_.posterior_sampler_options.posterior_sampling_method, 'online')
+        bool = true;
+    end
+end
diff --git a/matlab/nonlinear-filters/online_auxiliary_filter.m b/matlab/estimation/online/online_auxiliary_filter.m
similarity index 80%
rename from matlab/nonlinear-filters/online_auxiliary_filter.m
rename to matlab/estimation/online/online_auxiliary_filter.m
index e392474ea5681c7e6bc319aec860cfb0ef88d87c..ebe1394ff1d2e18c98bfd4e4e69aa3f5f848e7f9 100644
--- a/matlab/nonlinear-filters/online_auxiliary_filter.m
+++ b/matlab/estimation/online/online_auxiliary_filter.m
@@ -1,5 +1,5 @@
-function [pmean, pmode, pmedian, pstdev, p025, p975, covariance] = online_auxiliary_filter(xparam1, dataset_, options_, M_, estim_params_, bayestopt_, oo_)
-% [pmean, pmode, pmedian, pstdev, p025, p975, covariance] = online_auxiliary_filter(xparam1, dataset_, options_, M_, estim_params_, bayestopt_, oo_)
+function online_auxiliary_filter(xparam1, dataset_, options_, M_, estim_params_, bayestopt_, oo_)
+% online_auxiliary_filter(xparam1, dataset_, options_, M_, estim_params_, bayestopt_, oo_)
 % Liu & West particle filter = auxiliary particle filter including Liu & West filter on parameters.
 %
 % INPUTS
@@ -12,16 +12,7 @@ function [pmean, pmode, pmedian, pstdev, p025, p975, covariance] = online_auxili
 % - bayestopt_               [struct]    Prior definition.
 % - oo_                      [struct]    Results.
 %
-% OUTPUTS
-% - pmean                    [double]    n×1 vector, mean of the particles at the end of the sample (for the parameters).
-% - pmode                    [double]    n×1 vector, mode of the particles at the end of the sample (for the parameters).
-% - pmedian                  [double]    n×1 vector, median of the particles at the end of the sample (for the parameters).
-% - pstdev                   [double]    n×1 vector, st. dev. of the particles at the end of the sample (for the parameters).
-% - p025                     [double]    n×1 vector, 2.5 percent of the particles are below p025(i) for i=1,…,n.
-% - p975                     [double]    n×1 vector, 97.5 percent of the particles are below p975(i) for i=1,…,n.
-% - covariance               [double]    n×n matrix, covariance of the particles at the end of the sample.
-
-% Copyright © 2013-2023 Dynare Team
+% Copyright © 2013-2024 Dynare Team
 %
 % This file is part of Dynare.
 %
@@ -41,8 +32,11 @@ function [pmean, pmode, pmedian, pstdev, p025, p975, covariance] = online_auxili
 % Set seed for randn().
 options_ = set_dynare_seed_local_options(options_,'default');
 pruning = options_.particle.pruning;
-second_resample = options_.particle.resampling.status.systematic;
 variance_update = true;
+online_opt = options_.posterior_sampler_options.current_options;
+
+% Set location for the simulated particles.
+SimulationFolder = CheckPath('online', M_.dname);
 
 bounds = prior_bounds(bayestopt_, options_.prior_trunc); % Reset bounds as lb and ub must only be operational during mode-finding
 
@@ -52,13 +46,13 @@ bounds = prior_bounds(bayestopt_, options_.prior_trunc); % Reset bounds as lb an
 order = options_.order;
 mf0 = ReducedForm.mf0;
 mf1 = ReducedForm.mf1;
-number_of_particles = options_.particle.number_of_particles;
+number_of_particles = online_opt.particles;
 number_of_parameters = size(xparam1,1);
 Y = dataset_.data;
 sample_size = size(Y,1);
 number_of_observed_variables = length(mf1);
 number_of_structural_innovations = length(ReducedForm.Q);
-liu_west_delta = options_.particle.liu_west_delta;
+liu_west_delta = online_opt.liu_west_delta;
 
 % Get initial conditions for the state particles
 StateVectorMean = ReducedForm.StateVectorMean;
@@ -99,7 +93,6 @@ weights = ones(1,number_of_particles)/number_of_particles;
 % Initialization of the likelihood.
 const_lik = log(2*pi)*number_of_observed_variables;
 mean_xparam = zeros(number_of_parameters,sample_size);
-mode_xparam = zeros(number_of_parameters,sample_size);
 median_xparam = zeros(number_of_parameters,sample_size);
 std_xparam = zeros(number_of_parameters,sample_size);
 lb95_xparam = zeros(number_of_parameters,sample_size);
@@ -194,7 +187,6 @@ for t=1:sample_size
             % Replace Gaussian density with a Student density with 3 degrees of freedom for fat tails.
             z = sum(PredictionError.*(ReducedForm.H\PredictionError), 1) ;
             ddl = 3 ;
-            %tau_tilde(i) = weights(i).*(tpdf(z,3*ones(size(z)))+1e-99) ;
             tau_tilde(i) = weights(i)*(exp(gammaln((ddl + 1) / 2) - gammaln(ddl/2))/(sqrt(ddl*pi)*(1 + (z^2)/ddl)^((ddl + 1)/2))+1e-99) ;
         else
             tau_tilde(i) = 0 ;
@@ -202,7 +194,7 @@ for t=1:sample_size
     end
     % particles selection
     tau_tilde = tau_tilde/sum(tau_tilde);
-    indx = resample(0, tau_tilde', options_.particle);
+    indx = kitagawa(tau_tilde');
     StateVectors = StateVectors(:,indx);
     xparam = fore_xparam(:,indx);
     if pruning
@@ -214,7 +206,7 @@ for t=1:sample_size
     for i=1:number_of_particles
         info = 12042009;
         counter=0;
-        while info(1) && counter <options_.particle.liu_west_max_resampling_tries
+        while info(1) && counter <online_opt.liu_west_max_resampling_tries
             counter=counter+1;
             candidate = xparam(:,i) + chol_sigma_bar*randn(number_of_parameters, 1);
             if all(candidate>=bounds.lb) && all(candidate<=bounds.ub)
@@ -298,12 +290,12 @@ for t=1:sample_size
                     wtilde(i) = w_stage1(i)*exp(-.5*(const_lik+log(det(ReducedForm.H))+sum(PredictionError.*(ReducedForm.H\PredictionError), 1)));
                 end
             end
-            if counter==options_.particle.liu_west_max_resampling_tries
-                fprintf('\nLiu & West particle filter: I haven''t been able to solve the model in %u tries.\n',options_.particle.liu_west_max_resampling_tries)
-                fprintf('Liu & West particle filter: The last error message was: %s\n',get_error_message(info))
-                fprintf('Liu & West particle filter: You can try to increase liu_west_max_resampling_tries, but most\n')
-                fprintf('Liu & West particle filter: likely there is an issue with the model.\n')
-                error('Liu & West particle filter: unable to solve the model.')
+            if counter==online_opt.liu_west_max_resampling_tries
+                fprintf('\nLiu & West online filter: I haven''t been able to solve the model in %u tries.\n',online_opt.liu_west_max_resampling_tries)
+                fprintf('Liu & West online filter: The last error message was: %s\n',get_error_message(info))
+                fprintf('Liu & West online filter: You can try to increase liu_west_max_resampling_tries, but most\n')
+                fprintf('Liu & West online filter: likely there is an issue with the model.\n')
+                error('Liu & West online filter: unable to solve the model.')
             end
         end
     end
@@ -313,10 +305,8 @@ for t=1:sample_size
         variance_update = false;
     end
     % final resampling (not advised)
-    if second_resample
-        [~, idmode] = max(weights);
-        mode_xparam(:,t) = xparam(:,idmode);
-        indx = resample(0, weights,options_.particle);
+    if online_opt.second_resampling
+        indx = kitagawa(weights);
         StateVectors = StateVectors(:,indx) ;
         if pruning
             StateVectors_ = StateVectors_(:,indx);
@@ -333,10 +323,11 @@ for t=1:sample_size
             median_xparam(i,t) = temp(0.5*number_of_particles);
             ub95_xparam(i,t) = temp(0.975*number_of_particles);
         end
-    end
-    if second_resample
-        [~, idmode] = max(weights);
-        mode_xparam(:,t) = xparam(:,idmode);
+        if t==sample_size
+            param = xparam ;
+            save(sprintf('%s%sparameters_particles_final.mat', SimulationFolder, filesep()), 'param');
+        end 
+    else
         mean_xparam(:,t) = xparam*(weights');
         mat_var_cov = bsxfun(@minus, xparam,mean_xparam(:,t));
         mat_var_cov = mat_var_cov*(bsxfun(@times, mat_var_cov, weights)');
@@ -362,22 +353,21 @@ for t=1:sample_size
                 end
             end
         end
+        if t==sample_size
+            param = xparam(:,kitagawa(weights));
+            save(sprintf('%s%sparameters_particles_final.mat', SimulationFolder, filesep()), 'param');
+        end 
     end
+    save(sprintf('%s%sparameters_particles-%u.mat', SimulationFolder, filesep(), t), 'xparam');
+
     str = sprintf(' Lower Bound (95%%) \t Mean \t\t\t Upper Bound (95%%)');
     for l=1:size(xparam,1)
         str = sprintf('%s\n %5.4f \t\t %7.5f \t\t %5.4f', str, lb95_xparam(l,t), mean_xparam(l,t), ub95_xparam(l,t));
     end
     disp(str)
     disp('')
-end
 
-pmean = xparam(:,sample_size);
-pmode = mode_xparam(:,sample_size);
-pstdev = std_xparam(:,sample_size) ;
-p025 = lb95_xparam(:,sample_size) ;
-p975 = ub95_xparam(:,sample_size) ;
-pmedian = median_xparam(:,sample_size) ;
-covariance = mat_var_cov;
+end
 
 %% Plot parameters trajectory
 TeX = options_.TeX;
@@ -395,7 +385,7 @@ end
 
 for plt = 1:nbplt
     hh_fig = dyn_figure(options_.nodisplay,'Name','Parameters Trajectories');
-    for k=1:length(pmean)
+    for k=1:number_of_parameters
         subplot(nr,nc,k)
         [name,texname] = get_the_name(k,TeX,M_,estim_params_,options_.varobs);
         % Draw the surface for an interval containing 95% of the particles.
@@ -426,38 +416,3 @@ for plt = 1:nbplt
     end
 end
 
-% Plot Parameter Densities
-number_of_grid_points = 2^9;      % 2^9 = 512 !... Must be a power of two.
-bandwidth = 0;                    % Rule of thumb optimal bandwidth parameter.
-kernel_function = 'gaussian';     % Gaussian kernel for Fast Fourier Transform approximation.
-for plt = 1:nbplt
-    hh_fig = dyn_figure(options_.nodisplay,'Name','Parameters Densities');
-    for k=1:length(pmean)
-        subplot(nr,nc,k)
-        [name,texname] = get_the_name(k,TeX,M_,estim_params_,options_.varobs);
-        optimal_bandwidth = mh_optimal_bandwidth(xparam(k,:)',number_of_particles,bandwidth,kernel_function);
-        [density(:,1),density(:,2)] = kernel_density_estimate(xparam(k,:)', number_of_grid_points, ...
-                                                          number_of_particles, optimal_bandwidth, kernel_function);
-        plot(density(:,1), density(:,2));
-        hold on
-        if TeX
-            title(texname,'interpreter','latex')
-        else
-            title(name,'interpreter','none')
-        end
-        hold off
-        axis tight
-        drawnow
-    end
-    dyn_saveas(hh_fig,[ M_.fname '_param_density' int2str(plt) ],options_.nodisplay,options_.graph_format);
-    if TeX && any(strcmp('eps',cellstr(options_.graph_format)))
-        % TeX eps loader file
-        fprintf(fidTeX, '\\begin{figure}[H]\n');
-        fprintf(fidTeX,'\\centering \n');
-        fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%_param_density%s}\n',min(k/nc,1),M_.fname,int2str(plt));
-        fprintf(fidTeX,'\\caption{Parameter densities based on the Liu/West particle filter.}');
-        fprintf(fidTeX,'\\label{Fig:ParameterDensities:%s}\n',int2str(plt));
-        fprintf(fidTeX,'\\end{figure}\n');
-        fprintf(fidTeX,' \n');
-    end
-end
diff --git a/matlab/estimation/set_number_of_subdraws.m b/matlab/estimation/set_number_of_subdraws.m
index c6dcf6911d635903353e46e964907fdcc218f070..0241b32050e50376e00b3f4570f7c1cbb9ec13aa 100644
--- a/matlab/estimation/set_number_of_subdraws.m
+++ b/matlab/estimation/set_number_of_subdraws.m
@@ -57,6 +57,11 @@ else
         posterior = load(sprintf('%s/hssmc/particles-%u-%u.mat', M_.dname, length(pfiles), length(pfiles)));
         NumberOfDraws = size(posterior.particles,2);
         NumberOfDrawsPerChain=NumberOfDraws;
+    elseif isonline(options_)
+        % Load draws from the posterior distribution
+        posterior = load(sprintf('%s/online/parameters_particles_final.mat', M_.dname));
+        NumberOfDraws = size(posterior.param,2);
+        NumberOfDrawsPerChain=NumberOfDraws;
     elseif isdime(options_)
         posterior = load(sprintf('%s%s%s%schains.mat', M_.dname, filesep(), 'dime', filesep()));
         tune = posterior.tune;
diff --git a/matlab/issmc.m b/matlab/issmc.m
index 0f80730a55635be528e9fc6cf648921ff57b5957..45080a164049e1e9f671ae4dd8842e1d4a7b5934 100644
--- a/matlab/issmc.m
+++ b/matlab/issmc.m
@@ -17,4 +17,4 @@ function bool = issmc(options_)
 % You should have received a copy of the GNU General Public License
 % along with Dynare.  If not, see <https://www.gnu.org/licenses/>.
 
-bool = ishssmc(options_) || isdsmh(options_) || isdime(options_);
+bool = ishssmc(options_) || isonline(options_) || isdsmh(options_) || isdime(options_);
diff --git a/matlab/nonlinear-filters/solve_model_for_online_filter.m b/matlab/nonlinear-filters/solve_model_for_online_filter.m
index ca8d9fe08b305fca4640005be3ffea249384723d..6305f214e613ac8c5ee63a055e9bc9297ed12dfe 100644
--- a/matlab/nonlinear-filters/solve_model_for_online_filter.m
+++ b/matlab/nonlinear-filters/solve_model_for_online_filter.m
@@ -127,7 +127,6 @@ M_.H = H;
 warning('off', 'MATLAB:nearlySingularMatrix')
 [oo_.dr, info, M_.params] = ...
     compute_decision_rules(M_, options_, oo_.dr, oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state);
-%    resol(0,M_, options_, oo_.dr, oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state);
 warning('on', 'MATLAB:nearlySingularMatrix')
 
 if info(1)~=0
diff --git a/matlab/optimization/dynare_minimize_objective.m b/matlab/optimization/dynare_minimize_objective.m
index 990f9b146e08310cd2dc72077bb60a7800bcd32b..0452ca29559a56cbc2e7f68fbf4a4eadc0b51359 100644
--- a/matlab/optimization/dynare_minimize_objective.m
+++ b/matlab/optimization/dynare_minimize_objective.m
@@ -496,9 +496,11 @@ switch minimizer_algorithm
     [LB, UB]=set_bounds_to_finite_values(bounds, options_.huge_number);
     [opt_par_values, fval, exitflag] = simpsa(func2str(objective_function),start_par_value,LB,UB,simpsaOptions,varargin{:});
   case 11
-    options_.cova_compute = 0;
-    subvarargin = [varargin(1), varargin(3:6), varargin(8)];
-    opt_par_values = online_auxiliary_filter(start_par_value, subvarargin{:});
+    % waiting for validation 
+    %    options_.cova_compute = 0;
+    %    subvarargin = [varargin(1), varargin(3:6), varargin(8)];
+    %    opt_par_values = online_auxiliary_filter(start_par_value, subvarargin{:});
+    warning('Online particle filter is no more available with mode_compute=11; use posterior_sampler with option online')
   case 12
     if isoctave
         error('Option mode_compute=12 is not available under Octave')
diff --git a/tests/particle/dsge_base2.mod b/tests/particle/dsge_base2.mod
index f07148e9f890408f5c946169220bcc8beed630ff..473e9366e750f8426650e30a4ae1544dad7ffa68 100644
--- a/tests/particle/dsge_base2.mod
+++ b/tests/particle/dsge_base2.mod
@@ -8,7 +8,7 @@
 @#endif
 
 @#ifndef ALGO_SIR
-    @#define ALGO_SIR = 1
+    @#define ALGO_SIR = 0
 @#endif
 
 @#ifndef ALGO_APF
@@ -24,7 +24,7 @@
 @#endif
 
 @#ifndef ALGO_ONLINE
-    @#define ALGO_ONLINE = 0
+    @#define ALGO_ONLINE = 1
 @#endif
 
 @#ifndef MCMC
@@ -150,9 +150,12 @@ estimation(order=3,nograph,filter_algorithm=gf,proposal_approximation=montecarlo
 @#endif
 
 @#if ALGO_ONLINE
-  estimation(order=1,nograph,mode_compute=11,mh_replic=0,particle_filter_options=('liu_west_delta',0.9));
-  estimation(order=2,nograph,number_of_particles=10000,mode_compute=11,mh_replic=0,particle_filter_options=('liu_west_delta',0.9));
-  estimation(order=3,nograph,number_of_particles=10000,mode_compute=11,mh_replic=0,particle_filter_options=('liu_west_delta',0.9));
+%  estimation(order=1,nograph,mode_compute=11,mh_replic=0,particle_filter_options=('liu_west_delta',0.9));
+%  estimation(order=2,nograph,number_of_particles=10000,mode_compute=11,mh_replic=0,particle_filter_options=('liu_west_delta',0.9));
+%  estimation(order=3,nograph,number_of_particles=10000,mode_compute=11,mh_replic=0,particle_filter_options=('liu_west_delta',0.9));
+  estimation(order=1,posterior_sampling_method='online',posterior_sampler_options=('particles',1000));
+  estimation(order=2,posterior_sampling_method='online',posterior_sampler_options=('particles',1000));
+  estimation(order=3,posterior_sampling_method='online',filter_algorithm=nlkf,proposal_approximation=montecarlo,number_of_particles=500,posterior_sampler_options=('particles',500));
 @#endif
 
 @#if MCMC
@@ -187,9 +190,7 @@ estimation(order=3,filter_algorithm=nlkf,number_of_particles=10000,proposal_appr
 @#endif
 
 @#if SMC
-%  estimation(order=1,nograph,posterior_sampling_method='hssmc');
-%  estimation(order=2,nograph,posterior_sampling_method='hssmc',filter_algorithm=nlkf,proposal_approximation=montecarlo);
-%  estimation(order=2,nograph,posterior_sampling_method='hssmc',number_of_particles=10000);
-%  estimation(order=3,nograph,posterior_sampling_method='hssmc',number_of_particles=10000,filter_algorithm=apf,resampling=none);%,posterior_sampler_options=('particles',1000));
-  estimation(order=3,nograph,posterior_sampling_method='hssmc',filter_algorithm=nlkf,proposal_approximation=montecarlo);
+  estimation(order=1,posterior_sampling_method='hssmc',posterior_sampler_options=('particles',1000));
+  estimation(order=2,posterior_sampling_method='hssmc',posterior_sampler_options=('particles',1000));
+  estimation(order=3,posterior_sampling_method='hssmc',filter_algorithm=nlkf,proposal_approximation=montecarlo,number_of_particles=500,posterior_sampler_options=('particles',500));
 @#endif