diff --git a/doc/manual/source/the-model-file.rst b/doc/manual/source/the-model-file.rst
index 38d43c3281e6a681b65031b6dbbf4509b0a29bac..062114c2f44965f5db67f0b5976e879ef8240f2b 100644
--- a/doc/manual/source/the-model-file.rst
+++ b/doc/manual/source/the-model-file.rst
@@ -1996,6 +1996,13 @@ in this case ``initval`` is used to specify the terminal conditions.
 	file as the only dates necessary for initialization are before
 	that date.
 
+    .. option:: last_simulation_period = {INTEGER | DATE}
+
+	The observation number in the file or the date (see
+	:ref:`dates <dates-members>`) at which the simulation (or the forecast) is
+	ending. This option avoids to have to compute the maximum
+	number of leads in the model.
+
     .. option:: last_obs = {INTEGER | DATE}
 
         The observaton number or the date (see
@@ -2265,6 +2272,13 @@ in this case ``initval`` is used to specify the terminal conditions.
 	file as the only dates necessary for initialization are before
 	that date.
 
+    .. option:: last_simulation_period = {INTEGER | DATE}
+
+	The observation number in the file or the date (see
+	:ref:`dates <dates-members>`) at which the simulation (or the forecast) is
+	ending. This option avoids to have to compute the maximum
+	number of leads in the model.
+
     .. option:: last_obs = {INTEGER | DATE}
 
         The observation number or the date (see :ref:`dates-members`) of the
diff --git a/matlab/histvalf_initvalf.m b/matlab/histvalf_initvalf.m
index ac0b251688248282d8585ab1f25416deba961667..4ce0da3cb08f300b9b2a49962fd8eced8a4d2ad5 100644
--- a/matlab/histvalf_initvalf.m
+++ b/matlab/histvalf_initvalf.m
@@ -1,18 +1,17 @@
-function series = histvalf_initvalf(caller, M, options) 
-% function initvalf(M)
-%
-% handles options for histvalf_initvalf() and initvalf()
+function [series, p] = histvalf_initvalf(caller, DynareModel, options)
+
+% Handles options for histvalf() and initvalf()
 %
 % INPUTS
-%    caller:           string, name of calling function
-%    M:                model structure
-%    options:          options specific to initivalf
+% - caller           [char]      row array, name of calling function
+% - DynareModel      [struct]    model description, a.k.a M_
+% - options          [struct]    options specific to initivalf
 %
 % OUTPUTS
-%    series:           dseries containing selected data from a file or a dseries
-%
+% - series           [dseries]   selected data from a file or a dseries
+% - p                [integer]   number of periods (excluding the initial and terminal conditions)
 
-% Copyright (C) 2003-2021 Dynare Team
+% Copyright © 2003-2022 Dynare Team
 %
 % This file is part of Dynare.
 %
@@ -80,23 +79,23 @@ end
 
 % checking that all variable are present
 error_flag = false;
-for i = 1:M.orig_endo_nbr
-    if ~series.exist(M.endo_names{i})
-        dprintf('%s_FILE: endogenous variable %s is missing', caller, M.endo_names{i})
+for i = 1:DynareModel.orig_endo_nbr
+    if ~series.exist(DynareModel.endo_names{i})
+        dprintf('%s_FILE: endogenous variable %s is missing', caller, DynareModel.endo_names{i})
         error_flag = true;
     end
 end
 
-for i = 1:M.exo_nbr
-    if ~series.exist(M.exo_names{i})
-        dprintf('%s_FILE: exogenous variable %s is missing', caller, M.exo_names{i})
+for i = 1:DynareModel.exo_nbr
+    if ~series.exist(DynareModel.exo_names{i})
+        dprintf('%s_FILE: exogenous variable %s is missing', caller, DynareModel.exo_names{i})
         error_flag = true;
     end
 end
 
-for i = 1:M.exo_det_nbr
-    if ~series.exist(M.exo_det_names{i})
-        dprintf('%s_FILE: exo_det variable %s is missing', caller, M.exo_det_names{i})
+for i = 1:DynareModel.exo_det_nbr
+    if ~series.exist(DynareModel.exo_det_names{i})
+        dprintf('%s_FILE: exo_det variable %s is missing', caller, DynareModel.exo_det_names{i})
         error_flag = true;
     end
 end
@@ -105,8 +104,8 @@ if error_flag
     error('%s_FILE: some variables are missing', caller)
 end
 
-if exist(sprintf('+%s/dynamic_set_auxiliary_series.m', M.fname), 'file')
-    series = feval(sprintf('%s.dynamic_set_auxiliary_series', M.fname), series, M.params);
+if exist(sprintf('+%s/dynamic_set_auxiliary_series.m', DynareModel.fname), 'file')
+    series = feval(sprintf('%s.dynamic_set_auxiliary_series', DynareModel.fname), series, DynareModel.params);
 end
 
 % selecting observations
@@ -130,18 +129,18 @@ if isfield(options, 'first_obs') && ~isempty(options.first_obs)
         error('%s_FILE: first_obs = %d is larger than the number of observations in the data file (%d)', ...
                       caller, options.first_obs, nobs0)
     elseif isfield(options, 'first_simulation_period')
-        if  options.first_obs == options.first_simulation_period - M.orig_maximum_lag
+        if  options.first_obs == options.first_simulation_period - DynareModel.orig_maximum_lag
             first_obs = periods(options.first_obs);
         else
             error('%s_FILE: first_obs = %d and first_simulation_period = %d have values inconsistent with a maximum lag of %d periods', ...
-                          caller, options.first_obs, options.first_simulation_period, M.orig_maximum_lag)
+                  caller, options.first_obs, options.first_simulation_period, DynareModel.orig_maximum_lag)
         end
     elseif isfield(options, 'firstsimulationperiod')
-        if  periods(options.first_obs) == options.firstsimulationperiod - M.orig_maximum_lag
+        if  periods(options.first_obs) == options.firstsimulationperiod - DynareModel.orig_maximum_lag
             first_obs = periods(options.first_obs);
         else
             error('%s_FILE: first_obs = %d and first_simulation_period = %s have values inconsistent with a maximum lag of %d periods', ...
-                          caller, options.first_obs, options.firstsimulationperiod, M.orig_maximum_lag)
+                  caller, options.first_obs, options.firstsimulationperiod, DynareModel.orig_maximum_lag)
         end
     else
         first_obs = periods(options.first_obs);
@@ -151,18 +150,18 @@ end
 
 if isfield(options, 'firstobs') && ~isempty(options.firstobs)
     if isfield(options, 'first_simulation_period')
-        if  options.firstobs == periods(options.first_simulation_period) - M.orig_maximum_lag
+        if  options.firstobs == periods(options.first_simulation_period) - DynareModel.orig_maximum_lag
             first_obs = options.firstobs;
         else
             error('%s_FILE: first_obs = %s and first_simulation_period = %d have values inconsistent with a maximum lag of %d periods', ...
-                          caller, options.firstobs, options.first_simulation_period, M.orig_maximum_lag)
+                  caller, options.firstobs, options.first_simulation_period, DynareModel.orig_maximum_lag)
         end
     elseif isfield(options, 'firstsimulationperiod')
-        if  options.firstobs == options.firstsimulationperiod - M.orig_maximum_lag
+        if  options.firstobs == options.firstsimulationperiod - DynareModel.orig_maximum_lag
             first_obs = options.firstobs;
         else
             error('%s_FILE: firstobs = %s and first_simulation_period = %s have values inconsistent with a maximum lag of %d periods', ...
-                          caller, options.firstobs, options.firstsimulationperiod, M.orig_maximum_lag)
+                  caller, options.firstobs, options.firstsimulationperiod, DynareModel.orig_maximum_lag)
         end
     else
         first_obs = options.firstobs;
@@ -172,26 +171,25 @@ end
 
 if ~first_obs_ispresent
     if isfield(options, 'first_simulation_period')
-        if options.first_simulation_period < M.orig_maximum_lag
+        if options.first_simulation_period < DynareModel.orig_maximum_lag
             error('%s_FILE: first_simulation_period = %d must be larger than the maximum lag (%d)', ...
-                          caller, options.first_simulation_period, M.orig_maximum_lag)
+                  caller, options.first_simulation_period, DynareModel.orig_maximum_lag)
         elseif options.first_simulation_period > nobs0
             error('%s_FILE: first_simulations_period = %d is larger than the number of observations in the data file (%d)', ...
                           caller, options.first_obs, nobs0)
         else
-            first_obs = periods(options.first_simulation_period) - M.orig_maximum_lag;
+            first_obs = periods(options.first_simulation_period) - DynareModel.orig_maximum_lag;
         end
         first_obs_ispresent = true;
     elseif isfield(options, 'firstsimulationperiod')
-        first_obs = options.firstsimulationperiod - M.orig_maximum_lag;
+        first_obs = options.firstsimulationperiod - DynareModel.orig_maximum_lag;
         first_obs_ispresent = true;
     end
 end
 
 if isfield(options, 'last_obs')
     if options.last_obs > nobs0
-        error('%s_FILE: last_obs = %d is larger than the number of observations in the dataset (%d)', ...
-                      caller, options.last_obs, nobs0)
+        error('%s_FILE: last_obs = %d is larger than the number of observations in the dataset (%d)', caller, options.last_obs, nobs0)
     elseif first_obs_ispresent
         if nobs > 0 && (periods(options.last_obs) ~= first_obs + nobs - 1)
             error('%s_FILE: FIST_OBS, LAST_OBS and NOBS contain inconsistent information. Use only two of these options.', caller)
@@ -208,8 +206,7 @@ if isfield(options, 'last_obs')
     end
 elseif isfield(options, 'lastobs')
     if options.lastobs > series.last
-        error('%s_FILE: last_obs = %s is larger than the number of observations in the dataset (%s)', ...
-                      caller, options.lastobs, series.last)
+        error('%s_FILE: last_obs = %s is larger than the number of observations in the dataset (%s)', caller, options.lastobs, series.last)
     elseif first_obs_ispresent
         if nobs > 0 && (options.lastobs ~= first_obs + nobs - 1)
             error('%s_FILE: FIST_OBS, LAST_OBS and NOBS contain inconsistent information. Use only two of these options.', caller)
@@ -230,4 +227,31 @@ else
     last_obs = series.last;
 end
 
-series = series(first_obs:last_obs);
+if isfield(options, 'last_simulation_period')
+    lastsimulationperiod = periods(options.last_simulation_period);
+end
+
+if isfield(options, 'lastsimulationperiod')
+    lastsimulationperiod = options.lastsimulationperiod;
+end
+
+
+if exist('lastsimulationperiod', 'var')
+    if lastsimulationperiod<=last_obs-DynareModel.orig_maximum_lead
+        last_obs = lastsimulationperiod+DynareModel.orig_maximum_lead;
+    else
+        error('%s_FILE: LAST_SIMULATION_PERIOD is too large compared to the available data.', caller)
+    end
+end
+
+if exist('lastsimulationperiod', 'var') && exist('firstsimulationperiod', 'var')
+    p = lastsimulationperiod-firstsimulationperiod+1;
+elseif exist('lastsimulationperiod', 'var')
+    p = lastsimulationperiod-(first_obs+DynareModel.orig_maximum_lag)+1;
+elseif exist('firstsimulationperiod', 'var')
+    p = (last_obs-DynareModel.orig_maximum_lead)-firstsimulationperiod+1;
+else
+    p = (last_obs-DynareModel.orig_maximum_lead)-(first_obs+DynareModel.orig_maximum_lag)+1;
+end
+
+series = series(first_obs:last_obs);
\ No newline at end of file
diff --git a/matlab/initvalf.m b/matlab/initvalf.m
index 707d349e17b901838e2580ec866956270850e6e7..c40009738f079d6979019ec64939ad0194852d44 100644
--- a/matlab/initvalf.m
+++ b/matlab/initvalf.m
@@ -1,18 +1,17 @@
-function series = initvalf(M, options) 
-% function initvalf(M)
-%
-% handles options for histvalf() and initvalf()
+function [series, p] = initvalf(DynareModel, options)
+
+% Handles options for histvalf() and initvalf()
 %
 % INPUTS
-%    caller:           string, name of calling function
-%    M:                model structure
-%    options:          options specific to initivalf
+% - caller           [char]      row array, name of calling function
+% - DynareModel      [struct]    model description, a.k.a M_
+% - options          [struct]    options specific to initivalf
 %
 % OUTPUTS
-%    series:           dseries containing selected data from a file or a dseries
-%
+% - series           [dseries]   selected data from a file or a dseries
+% - p                [integer]   number of periods (excluding the initial and terminal conditions)
 
-% Copyright (C) 2003-2020 Dynare Team
+% Copyright © 2003-2022 Dynare Team
 %
 % This file is part of Dynare.
 %
@@ -29,4 +28,4 @@ function series = initvalf(M, options)
 % You should have received a copy of the GNU General Public License
 % along with Dynare.  If not, see <https://www.gnu.org/licenses/>.
 
-series = histvalf_initvalf('INITVALF', M, options);
\ No newline at end of file
+[series, p] = histvalf_initvalf('INITVALF', DynareModel, options);
\ No newline at end of file
diff --git a/matlab/perfect-foresight-models/perfect_foresight_solver.m b/matlab/perfect-foresight-models/perfect_foresight_solver.m
index d303d59db43642f0c0b8b50a814577849ea8ce2b..3f1049925f6b385a7fb23138d988752b4a77a82b 100644
--- a/matlab/perfect-foresight-models/perfect_foresight_solver.m
+++ b/matlab/perfect-foresight-models/perfect_foresight_solver.m
@@ -228,14 +228,23 @@ end
 
 dyn2vec(M_, oo_, options_);
 
-if ~isdates(options_.initial_period) && isnan(options_.initial_period)
+if isfield(oo_, 'initval_series') && ~isempty(oo_.initval_series)
+    initial_period = oo_.initval_series.dates(1)+(M_.orig_maximum_lag-1);
+elseif ~isdates(options_.initial_period) && isnan(options_.initial_period)
     initial_period = dates(1,1);
 else
     initial_period = options_.initial_period;
 end
 
 ts = dseries([transpose(oo_.endo_simul(1:M_.orig_endo_nbr,:)), oo_.exo_simul], initial_period, [M_.endo_names(1:M_.orig_endo_nbr); M_.exo_names]);
+
+if isfield(oo_, 'initval_series') && ~isempty(oo_.initval_series)
+    names = ts.name;
+    ts = merge(oo_.initval_series{names{:}}, ts);
+end
+
 assignin('base', 'Simulated_time_series', ts);
+
 if oo_.deterministic_simulation.status
     oo_.gui.ran_perfect_foresight = true;
-end
+end
\ No newline at end of file
diff --git a/preprocessor b/preprocessor
index 5e8b478ccf795b4b4684b3c89e305cc083e3f0a3..c56d58822e6c581926ac765b7604b29e1ecdf557 160000
--- a/preprocessor
+++ b/preprocessor
@@ -1 +1 @@
-Subproject commit 5e8b478ccf795b4b4684b3c89e305cc083e3f0a3
+Subproject commit c56d58822e6c581926ac765b7604b29e1ecdf557
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 750ca5af64277732b47298f763add0231bc52874..c4e4371db307993d85dc1af1e64fdbe66b866f6a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -152,6 +152,7 @@ MODFILES = \
 	discretionary_policy/Gali_2015_chapter_3.mod \
 	discretionary_policy/Gali_2015_chapter_3_nonlinear.mod \
 	histval_initval_file/ramst_initval_file.mod \
+	histval_initval_file/ramst_initval_file_with_dseries.mod \
 	histval_initval_file/ramst_data_generate.mod \
 	histval_initval_file/ramst_datafile.mod \
 	histval_initval_file/sim_exo_lead_lag.mod \
diff --git a/tests/histval_initval_file/ramst_initval_file_with_dseries.mod b/tests/histval_initval_file/ramst_initval_file_with_dseries.mod
new file mode 100644
index 0000000000000000000000000000000000000000..e777d091ace753424166ea0097434d4ef9d4a8d9
--- /dev/null
+++ b/tests/histval_initval_file/ramst_initval_file_with_dseries.mod
@@ -0,0 +1,36 @@
+var c k;
+varexo x;
+
+parameters alph gam delt bet aa;
+alph=0.5;
+gam=0.5;
+delt=0.02;
+bet=0.05;
+aa=0.5;
+
+
+model;
+c + k - aa*x*k(-1)^alph - (1-delt)*k(-1);
+(c/c(-2))^(-gam) - (1+bet)^(-1)*(aa*alph*x(+2)*k^(alph-1) + 1 - delt)*(c(+1)/c(-1))^(-gam);
+end;
+
+kstar = ((delt+bet)/(1.0*aa*alph))^(1/(alph-1));
+cstar = aa*kstar^alph-delt*kstar;
+
+initval;
+x = 1;
+k = kstar;
+c = cstar;
+end;
+
+steady;
+
+// Instantiate dseries object with paths for the endogenous and exogenous variables
+baseline= dseries([.81*kstar, .81*cstar, .81; .9*kstar, .9*cstar, .9; repmat([kstar, cstar, 1], 998, 1)], 2000Q1, {'k', 'c', 'x'});
+
+initval_file(series=baseline, first_simulation_period=2000Q3, last_simulation_period=2050Q2);
+
+perfect_foresight_setup;
+perfect_foresight_solver;
+
+Simulated_time_series(2000Q3:2050Q2)
diff --git a/tests/histval_initval_file_unit_tests.m b/tests/histval_initval_file_unit_tests.m
index 34f558b6b39e8cf99b7c142665cde412020ecf2c..e2f6e514eadc5bc1876f386d2fca588b591ccc79 100644
--- a/tests/histval_initval_file_unit_tests.m
+++ b/tests/histval_initval_file_unit_tests.m
@@ -17,6 +17,7 @@ M.exo_nbr = 1;
 M.exo_names = {'Variable_4'};
 M.exo_det_nbr = 0;
 M.orig_maximum_lag = 2;
+M.orig_maximum_lead = 0;
 
 caller = 'INITVAL';