简介该资源围绕数字人民币对商业银行利润的影响构建了替代现金与替代存款两个DSGE模型面向金融研究人员、政策制定者及商业银行从业者帮助理解央行数字货币对金融体系的短期与中长期冲击。压缩包内共1个PDF文件约850KB完整呈现论文复现思路、模型推导与实证分析。内容涵盖参数校准、稳态求解、动态方程构建及冲击响应模拟并给出基于Python与Dynare的可运行代码及逐段解释便于读者复现实验结果。研究指出数字人民币技术冲击在替代现金阶段对银行利润影响微弱持有比例越高对现金挤出效应越低在替代存款阶段利润短期先降后升中长期创造新利润空间并提示20%持有比例等关键阈值。目前已有97人学习适合需要理论模型与代码实操结合的读者参考。1. 数字人民币冲击下的商业银行利润两个 DSGE 模型能算什么数字人民币全面铺开后商业银行最直接的感受不是“支付方式变了”而是资产负债表两端的结构在悄悄位移。现金被替代意味着流通中现金M0向数字钱包迁移存款被替代意味着部分活期存款可能分流到数字人民币钱包银行的低成本负债来源被削弱。这两条路径对利润的影响方向并不一致甚至可能相反——现金替代降低银行的现金管理成本存款替代却抬高付息成本。要在一个统一框架里把这两种效应拆开DSGE动态随机一般均衡是目前宏观金融领域最常用的工具。这篇笔记围绕“现金替代”和“存款替代”两个阶段构建两个可运行的 DSGE 模型用 Python 和 Dynare 做求解与脉冲响应分析。适合有宏观经济学基础、想用代码把数字人民币对银行利润的影响量化出来的研究者或银行资产负债管理人员。全文不依赖任何特定项目源码所有模型方程和求解步骤都可以照着复现。2. 两个 DSGE 模型的方程系统与参数校准2.1 为什么拆成“现金替代”和“存款替代”两个模型把数字人民币对银行的影响塞进一个模型里参数会互相污染。现金替代主要影响家庭的货币需求函数和银行的现金持有成本存款替代则直接改写家庭的资产配置决策和银行的负债端定价。两者作用的传导链条不同混在一起校准脉冲响应的符号都可能翻车。常见做法是分两阶段建模。第一阶段模型只引入“现金-数字人民币”替代家庭在现金和数字钱包之间做选择银行侧的现金管理成本随替代率下降。第二阶段模型在家庭资产组合里加入“活期存款-数字人民币”替代银行需要为流失的存款支付更高的边际融资成本。两个模型共享家庭效用函数和厂商生产函数的基本结构但货币和存款的进入方式不同。这样拆的好处是每个模型的参数都有明确的校准依据脉冲响应的解释不会含糊。代价是需要跑两次求解但 Dynare 的代码结构可以复用实际工作量增加有限。2.2 家庭部门货币效用函数与替代弹性家庭效用函数采用货币效用MIU形式这是 DSGE 里处理货币需求的经典做法。第一阶段模型的效用函数写成U ln(C_t) χ_m * ln(M_t/P_t) χ_d * ln(D_t/P_t) - φ * N_t^(1η)/(1η)其中 C_t 是消费M_t/P_t 是实际现金余额D_t/P_t 是实际数字人民币余额N_t 是劳动供给。χ_m 和 χ_d 分别衡量家庭对现金和数字人民币的偏好权重。替代弹性通过 χ_d/χ_m 的比值间接体现——比值上升家庭更愿意持有数字人民币。第二阶段模型把 D_t/P_t 替换为活期存款的实际余额同时保留现金项。家庭的预算约束里多了一个存款利率 r_d,t银行通过调整这个利率来应对数字人民币的竞争。参数校准方面贴现因子 β 取 0.99劳动供给弹性 η 取 1.5消费替代弹性取 1对数效用。χ_m 校准为 0.05χ_d 在第一阶段从 0.01 逐步提高到 0.05模拟数字人民币渗透率上升。这些数值不是拍脑袋而是参照了国内货币需求实证文献的常见区间。2.3 银行部门利润函数与成本项拆解银行的利润函数是整篇分析的核心。第一阶段模型里银行利润写成Π_t r_l,t * L_t - r_d,t * D_t - r_m,t * M_t - c_m * M_t - c_d * D_t其中 r_l,t 是贷款利率L_t 是贷款余额r_d,t 是存款利率r_m,t 是现金管理的机会成本率c_m 和 c_d 分别是现金和数字人民币的单位管理成本。数字人民币替代现金后c_m * M_t 这一项下降因为银行不需要再处理实物现金的押运、清分和保管。第二阶段模型里存款替代导致 D_t 下降银行为了维持负债规模要么提高 r_d,t要么转向同业负债。同业负债的边际成本高于活期存款所以利润函数里多了一项c_f * (D_target - D_t)c_f 是存款流失后的边际融资成本溢价。这个溢价参数是第二阶段模型最敏感的校准对象取值在 0.002 到 0.008 之间做敏感性分析。2.4 用 Dynare 写模型文件从方程到 .mod 文件Dynare 的 .mod 文件是模型求解的入口。下面给出第一阶段模型的核心代码块包含变量声明、参数校准和模型方程。// 第一阶段现金-数字人民币替代模型 var C N M D L Y r_l r_d pi; varexo e_m e_d; parameters beta eta chi_m chi_d phi alpha delta c_m c_d rho_m rho_d; beta 0.99; eta 1.5; chi_m 0.05; chi_d 0.03; phi 1.2; alpha 0.6; delta 0.025; c_m 0.008; c_d 0.003; rho_m 0.9; rho_d 0.85; model; // 欧拉方程 1/C beta * (1/C(1)) * (r_l(1) - pi(1) 1); // 劳动供给 phi * N^eta (1/C) * (1 - alpha) * Y / N; // 货币需求现金 chi_m / (M/P) (1/C) * (1 - 1/(1 r_m)); // 货币需求数字人民币 chi_d / (D/P) (1/C) * (1 - 1/(1 r_d)); // 生产函数 Y exp(e_m) * (N^alpha) * (K(-1)^(1-alpha)); // 银行利润恒等式 Pi r_l * L - r_d * D - r_m * M - c_m * M - c_d * D; // 市场出清 Y C delta * K; // 利率规则 r_l 0.02 0.5 * pi 0.3 * Y; // 外生冲击 r_m rho_m * r_m(-1) e_m; r_d rho_d * r_d(-1) e_d; end; initval; C 1; N 1; M 0.5; D 0.2; L 1; Y 1.2; r_l 0.03; r_d 0.01; pi 0.02; end; steady; check; stoch_simul(order1, irf20);这段代码的逻辑是先声明内生变量和外生冲击再校准参数然后写模型方程。欧拉方程决定消费跨期选择劳动供给方程决定就业两个货币需求方程分别决定现金和数字人民币的持有量。银行利润恒等式把利率和成本项串起来。steady命令求稳态check检查 Blanchard-Kahn 条件stoch_simul做一阶脉冲响应。参数说明chi_d从 0.01 调到 0.05 可以模拟数字人民币渗透率上升c_m和c_d的差值决定现金替代对银行成本的净效应rho_m和rho_d是冲击的持久性参数越接近 1 冲击越持久。如果check报错说特征值不满足条件先检查欧拉方程的符号和贴现因子的取值。2.5 第二阶段模型的增量方程与代码改动第二阶段模型在家庭预算约束里把数字人民币换成活期存款同时加入存款流失的融资成本溢价。核心改动有三处家庭效用函数里的 D 改为存款余额银行利润函数加入 c_f 项存款利率的调整规则改为对数字人民币渗透率冲击做反应。// 第二阶段存款-数字人民币替代模型增量部分 parameters c_f D_target; c_f 0.005; D_target 0.4; model; // 存款利率反应函数 r_d 0.01 0.4 * (D_target - D) 0.2 * pi; // 银行利润加入融资成本溢价 Pi r_l * L - r_d * D - r_m * M - c_m * M - c_d * D - c_f * (D_target - D); end;c_f是存款流失的边际融资成本取值 0.005 意味着存款每流失 1 个单位银行额外承担 0.5% 的融资成本。D_target是银行的目标存款规模设为 0.4 是为了让稳态存款高于数字人民币替代后的水平。存款利率反应函数里的系数 0.4 和 0.2 分别对应存款缺口的调整速度和通胀反应这两个参数决定了脉冲响应的形状。跑完两个模型后把脉冲响应数据导出到 CSV用 Python 做对比图。下面是用 pandas 和 matplotlib 画图的代码import pandas as pd import matplotlib.pyplot as plt # 读取 Dynare 输出的脉冲响应数据 irf_cash pd.read_csv(irf_cash_replacement.csv) irf_deposit pd.read_csv(irf_deposit_replacement.csv) fig, axes plt.subplots(1, 2, figsize(12, 4)) # 左图现金替代对银行利润的影响 axes[0].plot(irf_cash[period], irf_cash[Pi], label现金替代) axes[0].axhline(y0, colorgray, linestyle--) axes[0].set_title(现金替代阶段银行利润脉冲响应) axes[0].set_xlabel(期数) axes[0].set_ylabel(利润偏离稳态百分比) # 右图存款替代对银行利润的影响 axes[1].plot(irf_deposit[period], irf_deposit[Pi], label存款替代, colororange) axes[1].axhline(y0, colorgray, linestyle--) axes[1].set_title(存款替代阶段银行利润脉冲响应) axes[1].set_xlabel(期数) axes[1].set_ylabel(利润偏离稳态百分比) plt.tight_layout() plt.savefig(bank_profit_irf.png, dpi150) plt.show()这段代码读取 Dynare 导出的 CSV画两个子图对比两个阶段的利润响应。axhline画零线方便看方向dpi150保证出图清晰。如果 CSV 列名不对先检查 Dynare 的stoch_simul输出格式常见的是period和变量名两列。3. 参数校准的敏感性分析与常见翻车点3.1 替代弹性取值对利润方向的影响替代弹性是决定利润响应符号的关键参数。在现金替代阶段χ_d/χ_m 从 0.2 升到 1.0 时银行利润的脉冲响应从正转负。原因不复杂替代率低的时候现金管理成本下降的效应占主导替代率高到一定程度数字人民币钱包对存款的分流效应开始压过成本节约。我一般会做三档敏感性低替代χ_d/χ_m 0.3、中替代0.6、高替代1.0。每档跑一次stoch_simul把利润的脉冲响应峰值记下来。如果三档的符号不一致说明模型对参数太敏感需要重新检查货币需求函数的设定。3.2 存款流失溢价 c_f 的校准边界c_f 的取值直接决定第二阶段模型里利润下降的幅度。取值太小存款替代的效应被淹没取值太大脉冲响应爆炸。根据国内银行同业负债和活期存款的利差数据c_f 的合理区间在 0.002 到 0.008 之间。超过 0.01 会导致check报错因为融资成本溢价太高银行的利润函数在稳态附近不满足二阶条件。校准方法是先取 0.005 跑基准然后上下各调 0.002 做敏感性。如果利润响应的方向不变但幅度变化超过 50%说明模型对 c_f 过于敏感需要在利润函数里加入调整成本项来平滑。3.3 稳态求解不收敛时的排查顺序Dynare 的steady命令不收敛是高频翻车点。排查顺序是先看initval里的初值是否合理特别是利率和通胀的初值不要设得太离谱再检查欧拉方程的符号贴现因子和利率的乘积如果大于 1稳态可能不存在最后看市场出清条件Y C delta * K里的 delta 如果太大资本存量会吃掉全部产出。如果steady报错说“无法找到稳态”把initval里的 C 和 Y 调成接近 1 的值利率调成 0.02 到 0.04 之间。还不行就在steady后面加solve_algo2换一个求解算法。4. 避坑与排查跑通两个 DSGE 模型的 5 条血泪经验现象一check报错“Blanchard-Kahn 条件不满足”。原因通常是前定变量和跳变量的数量不匹配。解决方法是数一遍模型里的内生变量确认哪些是当期决定、哪些是预期决定。欧拉方程里的 C(1) 是跳变量资本存量 K(-1) 是前定变量两者数量要对上。现象二脉冲响应图全是零。原因可能是冲击的方差没设或者stoch_simul的irf参数设成了 0。检查shocks块里有没有var e_m 0.01^2这样的语句irf20表示跑 20 期。如果冲击方差太小响应会接近零把方差调到 0.01 量级再试。现象三两个模型的稳态利润水平差太多。原因通常是参数校准不一致。两个模型共享的参数β、η、α、δ必须完全相同只有货币和存款相关的参数可以不同。如果第一阶段稳态利润是 0.05第二阶段变成 0.15先检查 c_f 和 D_target 的取值是否合理。现象四Python 画图时中文显示成方框。原因是 matplotlib 的默认字体不支持中文。在代码开头加两行plt.rcParams[font.sans-serif] [SimHei]和plt.rcParams[axes.unicode_minus] False。如果系统没有 SimHei 字体换成Microsoft YaHei或Arial Unicode MS。现象五Dynare 和 Python 的数据对接出错。Dynare 导出的 CSV 默认没有表头或者列名是Pi_e_m这种带冲击名的格式。用 pandas 读取时加headerNone和names[period, Pi]手动指定列名。如果列数不对先打开 CSV 看前几行确认 Dynare 的输出格式。5. 用 Python 做脉冲响应的批量对比与结果验证跑通单个模型只是第一步真正有价值的是把两个阶段的脉冲响应放在一起对比看利润的净效应在什么条件下由正转负。我一般会写一个批量脚本自动改参数、跑 Dynare、读结果、画图省去手动改 .mod 文件的麻烦。import subprocess import pandas as pd import matplotlib.pyplot as plt import numpy as np # 批量跑不同替代弹性下的模型 chi_d_values [0.01, 0.03, 0.05] results {} for chi_d in chi_d_values: # 用 sed 替换 .mod 文件里的 chi_d 值 subprocess.run([sed, -i, fs/chi_d .*/chi_d {chi_d};/, model_stage1.mod]) # 跑 Dynare subprocess.run([dynare, model_stage1.mod, noclearall], capture_outputTrue) # 读取脉冲响应 irf pd.read_csv(model_stage1/Output/model_stage1_irf.csv, headerNone) results[chi_d] irf.iloc[:, 1].values # 假设第二列是利润 # 画对比图 plt.figure(figsize(8, 5)) for chi_d, irf_data in results.items(): plt.plot(range(len(irf_data)), irf_data, labelfchi_d{chi_d}) plt.axhline(y0, colorgray, linestyle--) plt.xlabel(期数) plt.ylabel(银行利润偏离稳态) plt.legend() plt.title(不同数字人民币替代弹性下的银行利润响应) plt.savefig(chi_d_comparison.png, dpi150) plt.show()这段脚本的核心是subprocess调用 Dynare 和sed替换参数。noclearall选项保留工作区变量方便连续跑多个模型。results字典按 chi_d 存利润的脉冲响应序列最后画在一张图上对比。如果sed替换失败检查 .mod 文件里 chi_d 的写法是否和正则匹配。验证结果是否合理看三个点第一chi_d 越大利润响应的峰值应该越负因为替代效应增强第二响应的持久性应该和 rho_d 一致rho_d 越接近 1响应衰减越慢第三两个阶段的利润响应在 chi_d 相同时存款替代阶段的负效应应该更大因为多了融资成本溢价。如果结果不符合预期先检查steady是否收敛再看脉冲响应的符号是否和理论一致。我踩过最深的坑是sed替换后忘了重新跑steady导致脉冲响应基于旧的稳态结果完全对不上。后来养成习惯每次改参数后先跑steady和check确认通过再跑stoch_simul。这套流程跑下来两个 DSGE 模型的求解和对比大概需要 10 到 15 分钟大部分时间花在 Dynare 的编译和求解上。如果只是做参数敏感性可以把stoch_simul的irf期数从 20 降到 10速度会快不少。希望帮到你。本文还有配套的精品资源点击获取