【
】
此文内容为《动态随机一般均衡(DSGE)模型》的笔记,李向阳老师著,清华大学出版社出版。
我只将个人会用到的知识作了笔记,并对教材较难理解的部分做了进一步阐述。为了更易于理解,我还对教材上的一些部分(包括代码和正文)做了修改。
仅供学习参考,请勿转载,侵删!
上一篇有关Dyanre的文章为大家介绍了有关log-level
、Dynare解的表示
、计算结果的保存
等一系列内容。在这篇文章,我会总结有关DSGE的确定性模拟
技术。
3.8 确定性模拟
确定性模拟
和随机模拟
是模型分析的重要内容和方法,是在参数估计和模型求解之后必须要进行的操作。不论是确定性模拟还是随机模拟,都必须是模型结构参数已知并且模型已经被求解的基础上才能进行的。
在开始模拟之前,还有一些准备工作:
- 首先,在大多数情况下,不论是确定性模拟还是随机模拟,都需要提供
初始条件
(Initial Condition),某些情况下还需要提供终止条件
(Terminal Condition)。
初始条件和终止条件一般是指内生变量和外生变量的
初值
和终值
。
- 另外,根据问题分析的需要,指定外生冲击的变化特征包括外生冲击的大小、外生冲击的方差、外生冲击的持续周期等。
3.8.1 初始条件
和终止条件
一般来说,初值设定的目标有两个:
- 为随机模拟和确定性模拟的计算提供稳态值,提供一个初始的出发点
通常,如果模型的内生变量稳态很容易求出,则可以直接将稳态值作为初值,这样会提升计算效率
- 为确定性模拟提供初值
终值的设定并不是专指设定模拟后各期的值。如果设置终值,它会覆盖初值的部分设定
在Dynare中,模拟始于第1期
,在模拟开始之前的一期为第0期
,模型开始之前的第2期为负1期
,以此类推。初值就是第0期
及以前各期的值,终止即T+1
期及以后各期的值。
假设总模拟期数是 ,模拟期是指
到
期,模拟后的第一期是指
期。一般情况下,Dynare在储存模拟结果(确定性模拟)时,不仅考虑模拟器,而且考虑模拟前和模拟后各一期,因此一共有
期。所以,如果画此模拟路径,则往往会首尾出现跳跃的情况。这是因为设定值通常和模拟计算的结果存在较大的差异。
在Dynare中,设定初值和终值分别使用关键字 initval
和 endval
,并使用 end
关键字结束初值和终值的设定,如下表3.5所示。一般来说,所有内生变量和外生变量都要设定初值,否则默认为0;而终值设定则不是必须的。
在确定性模拟中,使用 initval
模块设定初值是对 第0期
及其之前的各期设定取值。没有使用 endval
模块时, initval
模块设定的初值将作为模拟后各期的取值,同时也作为模拟计算的初值。理解这一点非常重要!
如果 initval
模块后紧接着 steady
命令,那么 initval
模块的作用将发生变化:
首先,
steady
命令将使用initval
模块提供的初值作为初始猜测值以计算稳态然后,Dynare将刚刚计算的稳态值作为模拟的初值
如果使用 endval
模块设定终值,将会覆盖部分 initval
的功能:终值优先用于设定模拟后各期的值,而不管 initval
的初始如何设定。如果某些变量在 endval
中没有设定,那么其取值于上一个 initval
模块或 steady
命令稳态值。
此外,当 steady
命令结合 initval
和 endval
同时使用时,Dynare输出两个稳态值,这是分别给予初始和终值的设定计算出来的。如果两个模块中的外生变量的值有差异,那么两个稳态值一般不同。initval
模块对应的稳态值被设定为初值,endval
模块对应的稳态值被设定为终值。
3.8.2 稳态求解命令:steady
计算稳态值是非线性模型求解的一个非常具有挑战性的问题。在Dynare中,steady
命令被用来求解模型的稳态值。
具体来说,
steady
命令使用一个非线性的牛顿递归算法,以initval
或endval
模块中声明的内生和外生变量的值作为初始值来求解稳态。
通常来说,较为复杂(甚至简单)的模型,Dynare都无法准确地求出稳态值,这可能是因为初始值离稳态值太远,或默认求解的递归算法并不合适。经验表明,完全依靠Dyanre来计算模型的稳态值,几乎行不通。所以,求解模型的稳态值,大部分只能靠手动编程实现。
在Dynare具体编程时,稳态求解通常采取以下几种常见的模式:
-
方法一:自定义稳态参数
这是最常用的方法,特别合适中小规模的模型,而且要求稳态值能够方便地计算,具有解析解。使用这种处理方式,允许方便地循环调用模型文件来进行某个或某些参数的敏感性测试。其基本逻辑是:
对每一个内生变量定义一个稳态参数,比如消费
,定义稳态参数为
Css
。然后编程计算
Css
的值,这要求内生变量的稳态值具有解析式。然后
initval
模块直接将Css
的值赋给即可
直接将稳态值赋给内生变量,省去了Dynare自行求解稳态值的繁琐过程。在
源代码 20
中,甚至直接省去了steady
命令,直接使用stoch_simul
命令来计算稳态值:var C ...; varexo epsA; parameters alpha beta ...; model; ...; end; initval; C = Css; ...; end; stoch_simul;
-
方法二:内置模块命令
steady_state_model
稳态计算的内置模块命令提供了更加灵活、可靠的稳态值计算方式,这是计算稳态的第二个办法。相比于第一种方法,此方法更为便捷,甚至不需要自行定义任何稳态参数。在某些情况下,此命令十分有用。
这种方法的局限性在于,该方法同样要求内生变量稳态值具有解析解的形式或数值求解。也即同样只适用于中小模型。对于不具有解析解或求解稳态非常困难的模型,不推荐使用。
-
方法三:外部M文件
对于复杂的模型,通常使用自定义的外部稳态计算文件是一种选择,也是稳态计算的第3种方法。使用外部M文件,通常需要遵循一定的约定:
首先,外部M文件的名称必须满足形式
filename_steadystate.m
M文件的书写必须遵循一定的格式
在教材的 5.8 金融加速器与随机波动模型示例 会对外部M文件技术进行讲解。
3.8.3 确定性模拟
确定性模拟()具体而言就是说:通过外生冲击的确定性变化过程来考察系统的变化。即,系统是如何返回原来的均衡的或者如何达到另外一个新均衡的。
比如,在某一期或第几期突然施加一个外生冲击来考察各内生变量在外生冲击发生后的变化路径和趋势,画出脉冲响应图,以直观观测外生冲击的影响。
1 确定性「模型」和随机「模型」
确定性模型是指(1)模型中不存在随机的外生冲击 (2)存在外生冲击,但其实完全可见。也就是所说的完全信息。
随机模型是值模型中存在随机的外生冲击,形式上模型不仅存在期望算子和外生冲击的概率分布,而且外生冲击的方差不能为0。
区别确定性模型和随机模型的一个关键的判断标准就是对外生冲击的定义。以下举例说明:假设模型中存在一个外生的技术冲击变量, 满足独立同分布,
第一,如果
,此时完全没有外生冲击,是确定性模型;
第二,如果
,外生冲击被完全预期,是确定性模型
第三,如果
,则外生冲击不能被完全预期,是随机模型
2 确定性模拟的4种类型
根据外生冲击的:
可预期性
变化长短类型
可以将确定性模拟分成4个类型,这需要通过Dyanre的几个命令:
初值命令
initval
终值命令
endval
冲击命令
shocks
模拟命令
simul
的组合才能实现。见表3.6:
3 外生冲击模块设定:shocks
在Dynare中,外生冲击是指由 varexo
定义的变量。确定性模拟使用外生冲击模块设定外生冲击的暂时性变化,而永久性变化则需要 endval
模块来定义。
确定性模拟和随机模拟的外生冲击设定方式在Dyanre中不完全相同,如表3.7所示:
从语法看,也可以悟出随机模拟的内在含义:由于没有 periods
关键字以指定外生冲击出现的时间,所以外生冲击每一期都存在,而且是随机抽取。
这有别于脉冲响应函数。因为脉冲响应函数计算时,虽然也要随机模拟,但外生冲击仅发生在第一期,以后各期为0。
4 Dynare确定性模拟命令:Simul
Simul
命令根据既定设置,求解非线性联立方程,得到模拟值。首先分析simul
的求解逻辑,然后再分析simul
命令的语法。
(1) 求解逻辑
一般来说,确定性模型具有以下的一般形式:
其中, 为内生变量(向量),
为外生冲击(向量)。假设模型具有稳态
,满足:
其中, 为外生变量的稳态值;Dynare使用
steady
命令来计算模型的稳态值。
通常情况下, 在模拟开始前即第0期
,通常假设系统处于稳态。在接下来的第1期
即模拟的开始,外生冲击已经完全确定。模拟的基本目的就在于分析系统在外生冲击下的变化路径,是回归原始均衡还是达到一个新的均衡。
确定性模拟事实上是基于两个边界的数值求解问题。Dynare实际上是使用了一个有限期模型来近似逼近无限期模型,从而实现数值求解。具体来说,Dynare求解如下的非线性联立方程(Stack System)来确定模拟计算:
其中, 为模拟的总期数。Dynare将使用牛顿算法来求解该联立方程组。
(2) simul
的语法
相比于随机模拟的命令 stoch_simul
,确定性模拟命令 simul
要简单得多,使用的选项很少。
simul (options) ...;
确定性模拟的 options
只有6个,但最常用的只有 periods
一个。
3.8.4 介绍一个完整的例子
我们来看一个完整的例子:带有投资的新古典增长模型。
(1)建模
假设家庭选择消费、劳动和资本存量来最大化终身贴现效用;
-
生产函数和效用函数方面。
生产函数为
形式:
效用函数为消费和劳动不可分函数:
-
变量方面
、
、
、
分别为消费、劳动、资本存量、产出,属内生变量
为技术冲击,属外生变量
-
参数方面
为折现率
为效用函数中消费的权重
为风险厌恶参数
为资本存量的产出份额
为生产函数中资本存量和劳动的替代弹性参数
为折旧率
为技术冲击的自回归系数
为资技术冲击的方差
(2)求解消费者行为
-
采用
方法求解,对三个
决策变量
求导,有::
:
:
(3)总结
消去,最终得出系统的动力学方程由5个内生变量
、
、
、
、
以及5个均衡条件:
(4)敲代码
为了便于编程,把偏导数的部分先计算出来:
完整的代码示例如下所示(可以直接复制运行)
/*
* 教材源代码24 确定性模拟(预期的永久性冲击)
* Modified by 爱吃汉堡薯条 based on Xiangyang Li@SCC, 2020/3/30
* 与书本上的不同,本代码更加直观
*/
close all; % 关掉所有现存的figures
%---- 定义变量部分 ----%
// 定义内生变量
var
C, // 消费
N, // 劳动
Y, // 总产出
K, // 资本存量
A // 技术水平
;
// 定义外生变量
varexo
epsA // 技术扰动
;
// 定义参数
parameters
beta,
delta,
rho,
sigma,
theta,
tau,
alpha,
psi,
tech_s
;
// 参数校准
beta = 0.99; // 折现率
delta = 0.025; // 折旧率
rho = 0.85; // 自回归系数
sigma = 0.01; // 冲击的方差
theta = 0.35; // 消费在效用函数中的权重
tau = 2; // 风险规避系数
alpha = 0.35; // 资本占生产中的比例
psi = -0.1; // 资本和劳动的替代弹性
tech_s = 1; // 技术的稳态
%---- 模型定义部分 ----%
model;
// 首先定义便于编程的局部变量
# U_Ct = theta * ( C^theta * (1-N)^(1-theta) )^(-tau) * C^(theta-1);
# U_Ct1 = theta * ( C(+1)^theta * (1-N(+1))^(1-theta) )^(-tau) * C(+1)^(theta-1);
# U_Nt = -(1-theta)* ( C^theta * (1-N)^(1-theta) )^(-tau) * (1-N)^(-theta);
# F_Nt = (1-alpha) * ( alpha*K(-1)^psi + (1-alpha) * N^psi )^(1/psi-1) * N^(psi-1);
# F_Kt1 = alpha * ( alpha*K^psi + (1-alpha) * N(+1)^psi )^(1/psi-1) * K^(psi-1);
% (1) 欧拉方程
U_Ct = beta * U_Ct1 * (A(+1) * F_Kt1 + 1 - delta);
% (2) 劳动供给方程
A * F_Nt = -1 * U_Nt / U_Ct;
% (3) 生产函数
Y = A * (alpha * K^psi + (1-alpha) * N^psi)^(1/psi);
% (4) 资源约束条件
K = Y - C + (1-delta)*K(-1);
% (5) 水平技术冲击AR(1)过程
log(A) = log(tech_s) + rho*log(A(-1)) + epsA;
end;
%---- 初值设定部分 ----%
% 教材的代码是使用 `steady_state_model;` 命令计算的稳态
% 我这里是直接把教材代码算出来的稳态值作为初值了
initval;
K = 6.93619;
Y = 0.857369;
N = 0.325829;
C = 0.683964;
A = 1;
end;
%---- 设置终值 ----%
endval;
epsA = (1-rho)*log(0.5);
end;
%---- 计算稳态 ----%
steady;
%---- 设置冲击 ----%
shocks;
var epsA;
periods 40;
values 0.3;
end;
%---- 确定性模拟 ----%
simul(periods=150);
rplot C;
rplot K;
我在这里设置的是技术水平发生永久性变化(减小),并在第40期发生一次正的一次性技术冲击,产出、消费
和资本存量
的变化如下脉冲响应图所示:
对于不同的冲击类型和预期,只需要参考表3.6进行修改即可!