新闻详情

新闻详情

首页 / 资讯中心 / 详情

数字人民币对商业银行利润影响:两个DSGE模型的Python复现与代码解析

发布时间:2026/10/1 19:51:52来源:尧图网络
数字人民币对商业银行利润影响:两个DSGE模型的Python复现与代码解析
简介该资源围绕数字人民币对商业银行利润的影响提供基于DSGE模型的完整研究复现材料面向金融研究人员、政策制定者及商业银行从业者帮助理解央行数字货币在替代现金与替代存款两个阶段对银行利润的差异化冲击。压缩包内仅含1个PDF文件约850KB集中呈现论文复现说明、模型推导与Python及Dynare代码解释便于读者按图索骥地理解建模思路与实验流程。内容涵盖参数校准、稳态求解、动态方程构建与冲击响应模拟并给出20%持有比例等关键阈值结论可帮助读者掌握数字人民币技术冲击下货币需求变化、银行利润短期先降后升及中长期新利润空间的机制。已有97人学习适合具备宏观经济建模基础、希望快速复现并拓展相关研究的学习者参考。1. 数字人民币冲击银行利润这件事用两个 DSGE 模型能算清吗数字人民币到底会不会把商业银行的利润打穿这个问题在 2020 年深圳试点之后就一直在被讨论但多数讨论停留在定性层面——有人说存款会搬家有人说银行多了数据资产吵来吵去没有量化结论。石建勋、江鸿那篇《数字人民币对商业银行利润的影响研究》做了一件很具体的事把数字人民币的推广拆成「替代现金」和「替代存款」两个阶段各建一个 DSGE 模型分别算冲击响应。替代现金阶段数字人民币技术冲击削弱货币需求但银行利润几乎不动而且持有比例越高对现金的挤出反而越低替代存款阶段银行利润短期先降后升中长期反而多出一块新利润空间。这套代码用 Python 把两个模型的稳态、动态方程、冲击模拟和可视化全串起来了适合做宏观建模、央行数字货币政策评估、银行资产负债表分析的从业者直接跑起来验证。下面我按「模型怎么搭 → 代码怎么跑 → 参数怎么调 → 哪里容易翻车」的顺序拆一遍。2. 两个 DSGE 模型的骨架从家庭效用函数到银行利润方程2.1 为什么拆成两个阶段而不是一个模型数字人民币对银行的冲击不是一条直线。替代现金阶段数字人民币抢的是 M0也就是流通中的现金这部分本来就不在银行体系内生息挤出去对银行利润表的影响很小。替代存款阶段就不一样了数字人民币直接和活期存款竞争存款是银行负债端的核心来源一旦搬家贷款投放能力、利差收入、准备金规模全跟着动。用一个模型硬套两个阶段参数含义会打架——替代弹性 ε 在现金阶段小于 1在存款阶段大于 1符号方向都不一样。所以论文的做法是建两个独立模型共享家庭部门和生产部门的基础设定但在货币需求函数和银行利润方程上分叉。这个设计思路在代码里体现得很清楚Parameters类里同时放了theta_c现金持有比例初始值、theta_d替代现金阶段的数字人民币持有比例、theta_d_prime替代存款阶段的持有比例三个参数各管一个场景互不干扰。steady_state函数里也分别算了pi_b_ss和pi_b_prime_ss两个稳态利润。2.2 家庭部门消费欧拉方程和劳动供给怎么进模型家庭部门是整个 DSGE 的微观基础。代表性家庭在预算约束下最大化一生效用效用函数里消费和劳动分开风险规避系数 σ 控制跨期替代弹性劳动供给弹性倒数 φ 控制劳动意愿对工资的反应。代码里对应的两个核心方程是# 消费欧拉方程当期边际效用 贴现后的下期边际效用 × 资本回报 eq2 c**(-params.sigma) - params.beta * c**(-params.sigma) * (1 r_k - params.delta) # 劳动供给工资的边际效用 劳动的边际负效用 eq3 w * c**(-params.sigma) - n**params.varphibeta 0.99是季度贴现因子对应年化约 4% 的无风险利率这是 RBC/DSGE 文献里的标准取值。sigma 2意味着家庭相对风险规避系数为 2跨期替代弹性 0.5属于中等偏保守的设定。varphi 3表示劳动供给弹性倒数Frisch 弹性约 0.33和国内宏观计量文献的常见估计接近。这两个方程的逻辑是家庭在当期多消费一单位损失的是下期多消费带来的效用均衡时两者相等。劳动供给方程则是工资带来的边际效用正好补偿多工作一单位带来的负效用。参数改动会直接影响稳态附近的动态响应幅度——σ 越大消费对利率变化越不敏感冲击传导越弱。2.3 货币需求函数替代弹性的方向决定结论货币需求是这篇论文的核心机制。代码里现金需求、替代现金阶段的数字人民币需求、替代存款阶段的数字人民币需求分别写成# 现金需求稳态 m_c_ss params.theta_c * (params.r_d - params.r_c)**(-params.epsilon) # 数字人民币需求替代现金阶段 m_d_ss params.theta_d * (params.r_d - params.r_e)**(-params.epsilon) # 数字人民币需求替代存款阶段 m_d_prime_ss params.theta_d_prime * (params.r_d - params.r_e)**(-params.epsilon)这里的关键参数是epsilon 0.8替代弹性小于 1。含义是数字人民币利率 r_e 和存款利率 r_d 之间的利差变化对货币需求的影响是递减的——利差扩大 1%需求增加不到 1%。这个设定在替代现金阶段是合理的因为现金本来就没有利息数字人民币利率再高能替代的现金量也有限。但到了替代存款阶段论文认为替代弹性应该大于 1因为存款和数字人民币之间的转换成本更低、便利性更高。代码里没有直接改 epsilon而是通过提高theta_d_prime到 0.5 来体现替代强度的跃升。注意如果你要复现论文里「替代弹性 ε1」的设定需要手动把epsilon改成 1.2 或更高同时观察稳态利润是否出现符号反转。这是论文结论的敏感点之一。2.4 银行利润方程利差收入加准备金收益银行利润的稳态表达式在代码里是两行# 替代现金阶段 pi_b_ss (params.r_l - params.r_d) * (1 - params.phi) * (1 - m_d_ss) params.r_d * params.phi * (1 - m_d_ss) # 替代存款阶段 pi_b_prime_ss (params.r_l - params.r_e) * (1 - params.phi) * (1 - m_d_prime_ss) params.r_e * params.phi * (1 - m_d_prime_ss)拆开看第一项是贷款利差收入(r_l - r_d)是存贷利差(1 - phi)是可贷资金比例(1 - m_d_ss)是扣除数字人民币分流后的存款基数。第二项是准备金收益r_d * phi是准备金利率乘以准备金规模。替代存款阶段把r_d换成r_e因为数字人民币计息后银行负债端成本参照的是数字人民币利率而不是存款利率。phi 0.15是存款准备金率r_d 0.015是存款利率r_l 0.045是贷款利率r_e 0.03是数字人民币利率。这几个参数直接决定利润水平。利差 3 个百分点、准备金率 15%算出来的稳态利润大概在什么量级跑一遍steady_state就能看到。3. 把代码跑起来从参数校准到冲击响应模拟3.1 环境准备和依赖安装代码依赖 numpy、scipy、matplotlib、pandas 四个库。如果你用的是干净的 Python 环境先装依赖pip install numpy scipy matplotlib pandasPython 版本建议 3.8 以上scipy 的fsolve在 1.5 之后的版本对初值敏感度有优化。如果你用 vscode 配 Python 环境记得选对解释器路径不然pip install装到系统 Python 里、vscode 用的是虚拟环境跑起来会报ModuleNotFoundError。这是新手最常翻车的地方。3.2 参数校准哪些值可以改、哪些最好别动Parameters类里的参数分三组家庭部门、数字人民币相关、商业银行部门。我的建议是参数默认值可调范围调整影响beta0.990.96–0.995影响稳态利率和资本回报sigma21–5影响消费跨期替代弹性varphi31–5影响劳动供给弹性alpha0.330.3–0.4资本产出弹性对应劳动收入份额delta0.0250.02–0.03季度折旧率年化约 10%theta_c0.20.1–0.3现金持有比例初始值theta_d0.30.1–0.5替代现金阶段数字人民币份额theta_d_prime0.50.3–0.9替代存款阶段数字人民币份额epsilon0.80.5–1.5替代弹性跨 1 时结论可能反转phi0.150.1–0.2存款准备金率r_d0.0150.01–0.02存款利率r_l0.0450.03–0.06贷款利率r_e0.030.01–0.04数字人民币利率alpha 0.33对应资本收入份额约三分之一和中国宏观数据里劳动收入份额偏低的特征一致。delta 0.025是季度折旧率年化 10%比发达国家略高符合国内资本折旧较快的现实。rho_tech 0.9和rho_digital 0.7是冲击持续性参数技术冲击衰减慢、数字人民币冲击衰减快这个设定在文献里常见。3.3 稳态求解先看数字合不合理再跑动态稳态计算是steady_state函数干的活。跑完ss steady_state(params)之后打印ss字典重点看几个数ss steady_state(params) for key, value in ss.items(): print(f{key}: {value:.6f})r_k_ss应该在 0.01–0.02 之间对应年化 4%–8% 的资本回报。w_ss是工资稳态量级取决于生产函数标定。pi_b_ss和pi_b_prime_ss是两个阶段的银行利润正常情况下pi_b_prime_ss应该低于pi_b_ss因为数字人民币替代存款后银行负债成本上升、可贷资金减少。如果跑出来pi_b_prime_ss反而更高检查r_e是不是设得太低或者theta_d_prime是不是太小。提示稳态求解不涉及动态迭代秒出结果。如果这一步就报错大概率是参数导致分母为零或负数比如r_d - r_c在r_c 0时没问题但如果你把r_c改成大于r_d的值(r_d - r_c)**(-epsilon)就会出复数。3.4 冲击模拟fsolve 逐期求解的坑simulate_shock函数用fsolve逐期解非线性方程组。核心逻辑是第 t 期用第 t-1 期的解作为初值求解 11 个方程组成的系统。代码里for t in range(1, periods): guess history[t-1, :] solution fsolve(lambda x: model_equations(x, params, shock_type), guess) history[t, :] solution if shock_type tech: history[t, 10] params.rho_tech * history[t-1, 10] else: history[t, 11] params.rho_digital * history[t-1, 11]这里有两个容易翻车的点。第一fsolve对初值敏感如果第 t-1 期的解离真实解太远第 t 期可能不收敛solution会返回初值附近的一个局部解导致后续所有期都偏。第二冲击过程是手动叠加的——history[t, 10]和history[t, 11]在fsolve求解后被覆盖这意味着model_equations里的eq10和eq11实际上被绕过了。这种写法能跑出图形但严格来说不是标准的 DSGE 求解流程。常见做法是用 Dynare 的stoch_simul命令做一阶扰动求解或者用 Python 的linearsolve库做线性化。但论文给的代码是教学向的用fsolve逐期迭代更容易理解每一步在算什么。如果你要发论文建议把冲击过程写成外生 AR(1) 直接进方程而不是事后覆盖。3.5 可视化六宫格图怎么看plot_results画的是 3×2 的子图左边一列是技术冲击响应右边一列是数字人民币冲击响应。每列从上到下分别是产出、银行利润、数字人民币需求。技术冲击那列产出应该先上后下银行利润跟着产出走但幅度更小数字人民币需求变化不大——因为技术冲击不直接改变数字人民币和存款的相对吸引力。数字人民币冲击那列产出可能微降银行利润在替代现金阶段几乎不动在替代存款阶段先降后升。这个「先降后升」是论文的核心结论短期银行负债成本上升挤压利润中长期数字人民币带来的数据资产和精准放贷能力创造新利润来源。注意代码里plot_results只画了替代现金阶段的银行利润tech_shock[:,8]和digital_shock[:,8]替代存款阶段的利润动态没有单独画。如果你想看替代存款阶段的冲击响应需要把model_equations里的eq9改成pi_b_prime_ss的表达式重新跑一遍。4. 替代存款阶段的专项分析持有比例阈值到底在哪4.1 theta 扫描从 0.1 到 0.9 看利润曲线deposit_substitution_analysis函数做了一件很实用的事把theta_d_prime从 0.1 扫到 0.9每次算一遍稳态利润画出一条利润随持有比例变化的曲线。theta_values np.linspace(0.1, 0.9, 9) profits [] for theta in theta_values: params.theta_d_prime theta ss steady_state(params) profits.append(ss[pi_b_prime_ss])这条曲线如果是单调下降的说明数字人民币替代存款对银行利润是纯负面如果是先降后升的 U 型说明存在一个阈值超过之后数据资产的正面效应开始占主导。论文提到的「20% 持有比例临界点」大概对应曲线斜率由负转正的位置。你可以把np.linspace(0.1, 0.9, 9)改成np.linspace(0.05, 0.5, 46)步长缩到 0.01精确定位拐点。4.2 数据资产项怎么加进利润方程论文在替代存款阶段引入了数据资产但代码里的pi_b_prime_ss没有显式包含数据资产项。如果你要复现论文的完整设定需要在利润方程里加一项# 数据资产收益交易数据量 × 风险权重倒数 data_asset_yield theta * transactions_data * (risk_weight ** (-1)) pi_b_prime_ss (r_l - r_e) * (1 - phi) * (1 - m_d_prime_ss) r_e * phi * (1 - m_d_prime_ss) data_asset_yieldtransactions_data可以标定为稳态产出的一个比例risk_weight反映数据资产的风险调整系数。论文正文里给的data_assets θ·transactions_data·(risk_weight)^(-1)就是这个形式。加上这一项之后theta 扫描曲线会更明显地出现 U 型因为数据资产收益随 theta 线性增长而利差收入随 theta 线性下降两者叠加产生非线性。4.3 政策情景模拟利率和准备金率的组合论文的扩展建议里提到了政策情景模拟代码框架可以这样搭policy_scenarios { baseline: {r_e: 0.01, phi: 0.10}, interest_floor: {r_e: 0.00, phi: 0.15}, data_driven: {r_e: 0.005, phi: 0.12} } for name, policy in policy_scenarios.items(): params.r_e policy[r_e] params.phi policy[phi] ss steady_state(params) print(f{name}: pi_b_prime {ss[pi_b_prime_ss]:.6f})这个模拟能回答一个实际问题如果央行把数字人民币利率压到零、同时提高准备金率银行利润会掉多少如果反过来数字人民币利率设为正、准备金率下调银行能不能靠数据资产补回来跑一遍就知道。5. 避坑与排查跑这套 DSGE 代码最容易翻车的五个地方5.1 fsolve 不收敛输出全是初值现象simulate_shock跑完history矩阵里所有值都接近初始猜测图形是一条直线。原因fsolve默认的容差是 1.49e-8如果方程组在初值附近梯度很小或者方程之间有线性相关求解器会认为已经收敛。另一个可能是model_equations返回的列表长度和变量数不匹配——代码里vars解包了 12 个变量但return只返回了 11 个方程fsolve会报错或静默失败。解决把fsolve的full_output打开检查ier标志位。ier1表示收敛其他值都是异常。同时确认model_equations返回的方程数和vars长度一致。代码里n_vars 12但只返回 11 个方程这是一个隐藏 bug需要补一个方程或者把n_vars改成 11。5.2 稳态利润为负曲线画不出来现象pi_b_ss或pi_b_prime_ss算出负数plt.plot画出来在零轴以下。原因r_l - r_d利差太小或者phi准备金率太高导致(1 - phi) * (1 - m_d_ss)的可贷资金比例被压得过低。另一个可能是m_d_ss大于 1货币需求超过了总存款基数这在theta_d设得过大时会发生。解决检查r_l是否大于r_dphi是否在 0.1–0.2 之间theta_d是否小于 0.5。如果m_d_ss 1把epsilon调大或者theta_d调小。5.3 图形横坐标太密集看不清冲击路径现象periods 40时x 轴标签挤在一起matplotlib 自动旋转后还是重叠。原因默认的刻度间隔太密40 个点全标出来。解决用ax.set_xticks(range(0, periods, 5))手动设置刻度间隔或者用plt.xticks(rotation45)旋转标签。更彻底的做法是把periods降到 20冲击响应通常在 20 期内已经衰减到稳态附近。5.4 替代存款阶段的利润曲线不出现 U 型现象deposit_substitution_analysis画出来是一条单调下降的线没有拐点。原因利润方程里没有加数据资产项或者theta_d_prime的扫描范围太窄没覆盖到拐点。论文的 U 型依赖数据资产收益随 theta 增长如果只算利差收入利润必然随 theta 单调下降。解决在pi_b_prime_ss里加上data_asset_yield项把theta_values范围扩到 0.05–0.95步长缩到 0.01。5.5 Dynare 和 Python 版本不兼容现象如果你试图用 PyDynare 接口跑这套代码报ImportError: cannot import name dynare。原因Dynare 的 Python 接口需要单独安装而且对 Python 版本有要求。Dynare 5.x 支持 Python 3.7–3.9Dynare 6.x 支持 3.9–3.11。如果你用的是 Python 3.12PyDynare 可能还没适配。解决论文代码实际上没有依赖 Dynare纯 numpy scipy 就能跑。如果你要用 Dynare 做一阶扰动求解建议单独建一个 conda 环境装 Python 3.10 Dynare 6.x。或者直接用 Python 的linearsolve库替代安装pip install linearsolve用linearsolve.model做线性化。6. 进阶技巧用 linearsolve 替代 fsolve 做一阶扰动fsolve逐期迭代的写法适合教学但做政策分析时不够稳。我一般会用linearsolve库把模型线性化然后算脉冲响应。步骤是先把model_equations写成linearsolve要求的equations字典格式指定变量名和方程然后调model.solve()和model.impulse()。import linearsolve as ls # 定义变量和方程 equations { y: y - a * k**alpha * n**(1-alpha), c: c**(-sigma) - beta * c**(-sigma) * (1 r_k - delta), n: w * c**(-sigma) - n**varphi, k: k - (1-delta)*k - i, r_k: r_k - alpha * y / k, w: w - (1-alpha) * y / n, m_c: m_c - theta_c * (r_d - r_c)**(-epsilon) * c, m_d: m_d - theta_d * (r_d - r_e)**(-epsilon) * c, pi_b: pi_b - ((r_l - r_d) * (1 - phi) * (1 - m_d) r_d * phi * (1 - m_d)), a: a - rho_tech * a(-1), epsilon_d: epsilon_d - rho_digital * epsilon_d(-1) } # 指定稳态值 ss_values { y: 1.0, c: 0.8, n: 0.5, k: 5.0, r_k: 0.015, w: 1.2, m_c: 0.1, m_d: 0.15, pi_b: 0.02, a: 1.0, epsilon_d: 0.0 } model ls.model(equationsequations, n_states2, n_controls9) model.assign_ss_values(ss_values) model.solve() model.impulse(T40, t00, shocks{a: 0.01}) model.plot_impulse()linearsolve的好处是自动做一阶泰勒展开求解线性理性预期模型比fsolve逐期迭代快一个数量级而且不会出现不收敛的问题。n_states2对应两个外生冲击状态变量a和epsilon_dn_controls9是其余内生变量。impulse函数直接算脉冲响应plot_impulse出图。我自己的习惯是先用论文的fsolve代码跑一遍确认稳态和冲击方向对得上再用linearsolve做正式的政策模拟。两套结果如果差异很大说明模型设定有问题——通常是方程线性化后丢掉了非线性项或者稳态值标定不一致。从那以后我每次复现 DSGE 论文都强制走一遍「fsolve 验证 linearsolve 正式跑」的流程省得在审稿人那里翻车。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

ESP32 改个 WiFi 密码还得重刷固件?这个浏览器工具能直接改 NVS 键值 2026/10/1 21:31:35

ESP32 改个 WiFi 密码还得重刷固件?这个浏览器工具能直接改 NVS 键值

设备装到客户现场了。客户换了路由器,WiFi 密码变了;或者 MQTT 服务器迁移,broker 地址要换。设备在墙上、在配电箱里,或者干脆在两百公里外的仓库。这时候你的选项其实很少:固件做了配网功能,教客户重新配…

阅读更多 →
WhatsApp 无法登录时如何查阅已有记录?本地归档的检索与排查方法 2026/10/1 21:31:29

WhatsApp 无法登录时如何查阅已有记录?本地归档的检索与排查方法

账号暂时无法访问时,首先要确认的不是“重新登录多少次”,而是手头已经保留了哪些资料。一个可阅读的 HTML 文件、一份消息表格,以及只能由原客户端打开的本地记录,使用条件并不相同。 本文以 WABak 已保存的记录为客户端示例&am…

阅读更多 →
一文读懂OpenAI Privacy Filter:本地部署的开源PII脱敏模型5分钟全解 2026/10/1 21:31:29

一文读懂OpenAI Privacy Filter:本地部署的开源PII脱敏模型5分钟全解

一文读懂OpenAI Privacy Filter:本地部署的开源PII脱敏模型5分钟全解 【免费下载链接】privacy-filter OpenAI Privacy Filter 项目地址: https://gitcode.com/gh_mirrors/pr/privacy-filter OpenAI Privacy Filter 是一个可本地部署的开源 PII 脱敏模型&…

阅读更多 →
HTML学习笔记2 2026/10/1 21:31:23

HTML学习笔记2

1VSCode的Live Server插件有什么作用:我们无法在没有任何插件的情况下直接用VSCode打开自己写的代码,Live Server通过对网页注入一段JS脚本实现了这个功能,使我们在使用VSCode时更方便,同时可以让网页显示的内容根据我们对html文…

阅读更多 →
AMC8数学竞赛十年考点分布与备考时间线(结构化整理) 2026/10/1 21:31:23

AMC8数学竞赛十年考点分布与备考时间线(结构化整理)

下面用结构化的方式,把「AMC8 备考」的核心信息整理清楚,方便快速对照和备查。 本文要点:AMC8 到底是什么,几年级开始合适2026 年考点分布(按题型占比)一条可用的备考时间线最有效的练习方式关于…

阅读更多 →
智慧园区规划的系统性难点与工程要点:基于制造运营视角的深度剖析 2026/10/1 21:31:23

智慧园区规划的系统性难点与工程要点:基于制造运营视角的深度剖析

在制造业数字化转型进程中,智慧园区作为承载智能工厂的物理与数字底座,其规划质量直接决定了生产运营的效率、合规性及投资回报。然而,在实际工程落地中,智慧园区往往陷入“重展示、轻应用”、“重硬件、轻数据”、“重建设、轻运…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉