diff --git a/doc/manual.xml b/doc/manual.xml
index 3eaf70f3dd376ad6295cd5106566834927793213..5281c40cc1e09b2d2d81532fcdeb87d6499c43ef 100644
--- a/doc/manual.xml
+++ b/doc/manual.xml
@@ -378,6 +378,7 @@ In the description of Dynare commands, the following conventions are observed:
 <listitem><para><xref linkend='varexo_det'/></para></listitem>
 <listitem><para><xref linkend='parameters'/></para></listitem>
 <listitem><para><xref linkend='change_type'/></para></listitem>
+<listitem><para><xref linkend='predetermined_variables'/></para></listitem>
 </itemizedlist>
 
 <refentry id="var">
@@ -610,6 +611,81 @@ change_type(parameters) y, w;
 </refsect1>
 </refentry>
 
+<refentry id="predetermined_variables">
+  <refmeta>
+    <refentrytitle>predetermined_variables</refentrytitle>
+  </refmeta>
+
+  <refnamediv>
+    <refname>predetermined_variables</refname>
+    <refpurpose>declare some endogenous variables as predetermined</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>predetermined_variables</command>
+      <arg choice="plain"><replaceable>VARIABLE_NAME</replaceable></arg>
+      <arg rep="repeat"><replaceable>VARIABLE_NAME</replaceable></arg>
+      <arg choice="plain">;</arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+<refsect1><title>Description</title>
+<para>
+In Dynare, the default convention is that the timing of a variable reflects when this variable is decided. The typical example is for capital stock: since the capital stock used at current period is actually decided at the previous period, then the capital stock entering the production function is <literal>k(-1)</literal>, and the law of motion of capital must be written:
+<programlisting>
+k = i + (1-delta)*k(-1)
+</programlisting>
+</para>
+
+<para>Put another way, for stock variables, the default in Dynare is to use a
+“stock at the end of the period” concept, instead of a “stock at the beginning of the period”
+convention.</para>
+
+
+<para>The <command>predetermined_variables</command> is used to change that convention. The endogenous variables declared as predetermined variables are supposed to be decided one period ahead of all other endogenous variables. For stock variables, they are supposed
+to follow a “stock at the beginning of the period”
+convention.</para>
+
+</refsect1>
+
+<refsect1><title>Example</title>
+<informalexample>
+
+<para>The following two program snippets are strictly equivalent.</para>
+
+<formalpara><title>Using default Dynare timing convention:</title>
+<para>
+<programlisting>
+var y, k, i;
+...
+model;
+y = k(-1)^alpha;
+k = i + (1-delta)*k(-1);
+...
+end;
+</programlisting>
+</para>
+</formalpara>
+
+<formalpara><title>Using the alternative timing convention:</title>
+<para>
+<programlisting>
+var y, k, i;
+predetermined_variables k;
+...
+model;
+y = k^alpha;
+k(+1) = i + (1-delta)*k;
+...
+end;
+</programlisting>
+</para>
+</formalpara>
+</informalexample>
+</refsect1>
+</refentry>
+
 </sect1>
 
 <sect1 id="expressions"><title>Expressions</title>
diff --git a/preprocessor/DynamicModel.cc b/preprocessor/DynamicModel.cc
index 5a97ef2a55dc628410f66dbc790b26b9b388bd4a..532261f9b6868b9ccbed07b1dfae67803e03272c 100644
--- a/preprocessor/DynamicModel.cc
+++ b/preprocessor/DynamicModel.cc
@@ -1995,15 +1995,6 @@ DynamicModel::writeDynamicModel(ostream &DynamicOutput, bool use_dll) const
 void
 DynamicModel::writeOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll) const
   {
-    // Write list of predetermined variables in M_.predetermined_variables
-    if (predetermined_variables_vec.size() > 0)
-      {
-        output << "M_.predetermined_variables = '';" <<  endl;
-        for(vector <string>::const_iterator it = predetermined_variables_vec.begin();
-            it != predetermined_variables_vec.end(); it++)
-          output << "M_.predetermined_variables = strvcat(M_.predetermined_variables, '" << *it << "');" << endl;
-      }
-
     /* Writing initialisation for M_.lead_lag_incidence matrix
        M_.lead_lag_incidence is a matrix with as many columns as there are
        endogenous variables and as many rows as there are periods in the
@@ -3090,34 +3081,11 @@ DynamicModel::substituteExpectation(bool partial_information_model)
 void
 DynamicModel::transformPredeterminedVariables()
 {
-  for(vector <string>::const_iterator it = predetermined_variables_vec.begin();
-      it != predetermined_variables_vec.end(); it++)
+  for(int i = 0; i < (int) equations.size(); i++)
     {
-      try
-        {
-          if(symbol_table.getType(*it)!=eEndogenous)
-            {
-              cerr << "Error: You must declare predetermined variable " << *it << " as an endogenous variable." << endl;
-              exit(EXIT_FAILURE);
-            }
-        }
-      catch(SymbolTable::UnknownSymbolNameException &e)
-        {
-          cerr << "Error: predetermind variable " << *it << " has not been declared." << endl;
-          exit(EXIT_FAILURE);
-        }
-      catch(...)
-        {
-          cerr << "error in DynamicModel::transformPredeterminedVariables(), should not arrive here" << endl;
-          exit(EXIT_FAILURE);
-        }
-
-      for(int i = 0; i < (int) equations.size(); i++)
-        {
-          BinaryOpNode *substeq = dynamic_cast<BinaryOpNode *>(equations[i]->decreaseLeadsLagsPredeterminedVariables(*it));
-          assert(substeq != NULL);
-          equations[i] = substeq;
-        }
+      BinaryOpNode *substeq = dynamic_cast<BinaryOpNode *>(equations[i]->decreaseLeadsLagsPredeterminedVariables());
+      assert(substeq != NULL);
+      equations[i] = substeq;
     }
 }
 
diff --git a/preprocessor/DynamicModel.hh b/preprocessor/DynamicModel.hh
index 785f06e61b6756832ba20cbcf26afbe2d142926a..8edd7153a50640c4b8eb12f5c9d445dd27448e66 100644
--- a/preprocessor/DynamicModel.hh
+++ b/preprocessor/DynamicModel.hh
@@ -165,8 +165,6 @@ public:
   int mfs;
   //! the file containing the model and the derivatives code
   ofstream code_file;
-  //! Stores variables declared to be predetermined by "predetermined_variables" statement
-  vector<string> predetermined_variables_vec;
   //! Execute computations (variable sorting + derivation)
   /*!
     \param jacobianExo whether derivatives w.r. to exo and exo_det should be in the Jacobian (derivatives w.r. to endo are always computed)
diff --git a/preprocessor/ExprNode.cc b/preprocessor/ExprNode.cc
index 7715ca5e4389312088d52634a8220561f4d040e6..0a861ec0fdddbb686ef06bef5349abfaf932dd59 100644
--- a/preprocessor/ExprNode.cc
+++ b/preprocessor/ExprNode.cc
@@ -319,9 +319,9 @@ NumConstNode::decreaseLeadsLags(int n) const
 }
 
 NodeID
-NumConstNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
+NumConstNode::decreaseLeadsLagsPredeterminedVariables() const
 {
-  return decreaseLeadsLags(1);
+  return const_cast<NumConstNode *>(this);
 }
 
 NodeID
@@ -831,9 +831,9 @@ VariableNode::decreaseLeadsLags(int n) const
 }
 
 NodeID
-VariableNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
+VariableNode::decreaseLeadsLagsPredeterminedVariables() const
 {
-  if(datatree.symbol_table.getName(symb_id).compare(pv_name)==0)
+  if (datatree.symbol_table.isPredetermined(symb_id))
     return decreaseLeadsLags(1);
   else
     return const_cast<VariableNode *>(this);
@@ -1641,9 +1641,9 @@ UnaryOpNode::decreaseLeadsLags(int n) const
 }
 
 NodeID
-UnaryOpNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
+UnaryOpNode::decreaseLeadsLagsPredeterminedVariables() const
 {
-  NodeID argsubst = arg->decreaseLeadsLagsPredeterminedVariables(pv_name);
+  NodeID argsubst = arg->decreaseLeadsLagsPredeterminedVariables();
   return buildSimilarUnaryOpNode(argsubst, datatree);
 }
 
@@ -2626,10 +2626,10 @@ BinaryOpNode::decreaseLeadsLags(int n) const
 }
 
 NodeID
-BinaryOpNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
+BinaryOpNode::decreaseLeadsLagsPredeterminedVariables() const
 {
-  NodeID arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables(pv_name);
-  NodeID arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables(pv_name);
+  NodeID arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables();
+  NodeID arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables();
   return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree);
 }
 
@@ -3097,11 +3097,11 @@ TrinaryOpNode::decreaseLeadsLags(int n) const
 }
 
 NodeID
-TrinaryOpNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
+TrinaryOpNode::decreaseLeadsLagsPredeterminedVariables() const
 {
-  NodeID arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables(pv_name);
-  NodeID arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables(pv_name);
-  NodeID arg3subst = arg3->decreaseLeadsLagsPredeterminedVariables(pv_name);
+  NodeID arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables();
+  NodeID arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables();
+  NodeID arg3subst = arg3->decreaseLeadsLagsPredeterminedVariables();
   return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree);
 }
 
@@ -3309,7 +3309,7 @@ UnknownFunctionNode::decreaseLeadsLags(int n) const
 }
 
 NodeID
-UnknownFunctionNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
+UnknownFunctionNode::decreaseLeadsLagsPredeterminedVariables() const
 {
   cerr << "UnknownFunctionNode::decreaseLeadsLagsPredeterminedVariables: not implemented!" << endl;
   exit(EXIT_FAILURE);
diff --git a/preprocessor/ExprNode.hh b/preprocessor/ExprNode.hh
index 5ba198f9a90e4ced761e17a38e42f3fb30a38fc1..2bc611c4c4b60bc9bbe462b965b3c2f899920fca 100644
--- a/preprocessor/ExprNode.hh
+++ b/preprocessor/ExprNode.hh
@@ -304,7 +304,7 @@ public:
   */
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const = 0;
 
-  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const = 0;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables() const = 0;
 
 };
 
@@ -345,7 +345,7 @@ public:
   virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
-  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables() const;
 };
 
 //! Symbol or variable node
@@ -384,7 +384,7 @@ public:
   virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
-  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables() const;
 };
 
 //! Unary operator node
@@ -433,7 +433,7 @@ public:
   virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
-  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables() const;
 };
 
 //! Binary operator node
@@ -485,7 +485,7 @@ public:
   virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
-  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables() const;
 };
 
 //! Trinary operator node
@@ -531,7 +531,7 @@ public:
   virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
-  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables() const;
 };
 
 //! Unknown function node
@@ -569,7 +569,7 @@ public:
   virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
-  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables() const;
 };
 
 #endif
diff --git a/preprocessor/ModFile.cc b/preprocessor/ModFile.cc
index 125f193a38bea183db5c3830eda45573b2c3cb15..93cf96ff8dc23f283a4ac8178d6cf970951e3f53 100644
--- a/preprocessor/ModFile.cc
+++ b/preprocessor/ModFile.cc
@@ -134,7 +134,8 @@ ModFile::checkPass()
 void
 ModFile::transformPass()
 {
-  dynamic_model.transformPredeterminedVariables();
+  if (symbol_table.predeterminedNbr() > 0)
+    dynamic_model.transformPredeterminedVariables();
 
   if (mod_file_struct.stoch_simul_present
       || mod_file_struct.estimation_present
diff --git a/preprocessor/ParsingDriver.cc b/preprocessor/ParsingDriver.cc
index 0be4a6d5ab5f2db4a3a61da7fd9e11914c61af3d..e4b000827b5aa8144b7c0c221c5fd575afdf801d 100644
--- a/preprocessor/ParsingDriver.cc
+++ b/preprocessor/ParsingDriver.cc
@@ -147,7 +147,18 @@ ParsingDriver::declare_parameter(string *name, string *tex_name)
 void
 ParsingDriver::add_predetermined_variable(string *name)
 {
-  mod_file->dynamic_model.predetermined_variables_vec.push_back(*name);
+  try
+    {
+      int symb_id = mod_file->symbol_table.getID(*name);
+      if (mod_file->symbol_table.getType(symb_id) != eEndogenous)
+        error("Predetermined variables must be endogenous variables");
+
+      mod_file->symbol_table.markPredetermined(symb_id);
+    }
+  catch(SymbolTable::UnknownSymbolNameException &e)
+    {
+      error("Undeclared symbol name: " + *name);
+    }
   delete name;
 }
 
diff --git a/preprocessor/SymbolTable.cc b/preprocessor/SymbolTable.cc
index 16e68a2bc052dbfd9624619bebc953598c735b29..10b06a718fef7a7542ab11e238c46fe1ab541e92 100644
--- a/preprocessor/SymbolTable.cc
+++ b/preprocessor/SymbolTable.cc
@@ -20,6 +20,7 @@
 #include <algorithm>
 #include <sstream>
 #include <iostream>
+#include <cassert>
 
 #include "SymbolTable.hh"
 
@@ -218,6 +219,15 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException)
           break;
         }
     }
+
+  if (predeterminedNbr() > 0)
+    {
+      output << "M_.predetermined_variables = [ ";
+      for(set<int>::const_iterator it = predetermined_variables.begin();
+          it != predetermined_variables.end(); it++)
+        output << getTypeSpecificID(*it) << " ";
+      output << "];" << endl;
+    }
 }
 
 int
@@ -326,3 +336,31 @@ SymbolTable::addExpectationAuxiliaryVar(int arg1, int arg2) throw (FrozenExcepti
 
   return symb_id;
 }
+
+void
+SymbolTable::markPredetermined(int symb_id) throw (UnknownSymbolIDException, FrozenException)
+{
+  if (symb_id < 0 || symb_id >= size)
+    throw UnknownSymbolIDException(symb_id);
+  if (frozen)
+    throw FrozenException();
+
+  assert(getType(symb_id) == eEndogenous);
+
+  predetermined_variables.insert(symb_id);
+}
+
+bool
+SymbolTable::isPredetermined(int symb_id) const throw (UnknownSymbolIDException)
+{
+  if (symb_id < 0 || symb_id >= size)
+    throw UnknownSymbolIDException(symb_id);
+
+  return(predetermined_variables.find(symb_id) != predetermined_variables.end());
+}
+
+int
+SymbolTable::predeterminedNbr() const
+{
+  return(predetermined_variables.size());
+}
diff --git a/preprocessor/SymbolTable.hh b/preprocessor/SymbolTable.hh
index 461ae20c03299f14cb8d499edb209a2b64767100..4f11bb2ecc975e6870b25bf1eacfe3a7a1d1be82 100644
--- a/preprocessor/SymbolTable.hh
+++ b/preprocessor/SymbolTable.hh
@@ -25,6 +25,7 @@ using namespace std;
 #include <map>
 #include <string>
 #include <vector>
+#include <set>
 #include <ostream>
 
 #include "CodeInterpreter.hh"
@@ -92,6 +93,9 @@ private:
   //! Information about auxiliary variables
   vector<AuxVarInfo> aux_vars;
 
+  //! Stores the predetermined variables (by symbol IDs)
+  set<int> predetermined_variables;
+
 public:
   SymbolTable();
   //! Thrown when trying to access an unknown symbol (by name)
@@ -211,6 +215,12 @@ public:
   inline int maxID();
   //! Write output of this class
   void writeOutput(ostream &output) const throw (NotYetFrozenException);
+  //! Mark a symbol as predetermined variable
+  void markPredetermined(int symb_id) throw (UnknownSymbolIDException, FrozenException);
+  //! Test if a given symbol is a predetermined variable
+  bool isPredetermined(int symb_id) const throw (UnknownSymbolIDException);
+  //! Return the number of predetermined variables
+  int predeterminedNbr() const;
 };
 
 inline bool
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b2e6d1f14fdded6adba2e6b24281611f579b558a..c0aae98203fd80dc92a790cbb295f531e9bbe673 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -9,6 +9,7 @@ OCTAVE_MODS = \
 	ramsey.mod \
 	ramst_initval_file.mod \
 	example1_varexo_det.mod \
+	predetermined_variables.mod \
 	arima/mod1.mod \
 	arima/mod1a.mod \
 	arima/mod2.mod \
diff --git a/tests/predetermined_variables.mod b/tests/predetermined_variables.mod
new file mode 100644
index 0000000000000000000000000000000000000000..5f6a495436aeb4156797fd34e4082c9325668a89
--- /dev/null
+++ b/tests/predetermined_variables.mod
@@ -0,0 +1,41 @@
+var c k i;
+varexo x;
+
+parameters alph gam delt bet aa;
+alph=0.5;
+gam=0.5;
+delt=0.02;
+bet=0.05;
+aa=0.5;
+
+predetermined_variables k;
+
+model;
+c + i = aa*x*k^alph;
+c^(-gam) - (1+bet)^(-1)*(aa*alph*x(+1)*k(+1)^(alph-1) + 1 - delt)*c(+1)^(-gam);
+k(+1) = (1-delt)*k + i;
+end;
+
+initval;
+x = 1;
+k = ((delt+bet)/(1.0*aa*alph))^(1/(alph-1));
+c = aa*k^alph-delt*k;
+i = delt*k;
+end;
+
+write_latex_dynamic_model;
+
+steady;
+
+check;
+
+shocks;
+var x;
+periods 1;
+values 1.2;
+end;
+
+simul(periods=200);
+
+rplot c;
+rplot k;