
简介该资源围绕数字人民币对商业银行利润的影响提供两个DSGE模型的完整复现材料面向金融研究人员、政策制定者及商业银行从业者帮助理解央行数字货币在替代现金与替代存款两个阶段对银行利润的差异化冲击。压缩包内共1个PDF文件约850KB集中呈现模型推导、参数校准、稳态求解与冲击响应模拟的完整过程。内容涵盖家庭、生产与商业银行部门设定并给出基于Python与Dynare的可运行代码及逐段解释便于读者复现技术冲击与数字人民币冲击下的动态响应。研究指出替代现金阶段技术冲击削弱货币需求但对利润影响微弱持有比例越高对现金挤出效应越低替代存款阶段利润短期先降后升中长期创造新利润空间并提示约20%持有比例等关键阈值。目前已有97人学习适合需要理论模型与代码实操结合的读者参考。1. 数字人民币替代现金和存款时银行利润到底被谁吃掉了数字人民币全面铺开后商业银行最直接的感受不是技术系统改造有多麻烦而是资产负债表两端的利差在悄悄收窄。现金被替代意味着原本零成本的流通中现金不再沉淀在银行体系存款被替代意味着原本低息活期存款可能流向数字钱包甚至直接停留在央行负债端。这两条路径叠加银行的净息差会被压缩到什么程度靠拍脑袋是算不出来的。DSGE 模型在这里的价值就体现出来了它能把家庭、厂商、银行和央行放在一个动态一般均衡框架里让现金替代率和存款替代率作为参数显式进入模型然后观察利率、信贷供给和银行利润的脉冲响应。这篇笔记面向的是想用 Python 和 Dynare 动手跑一遍这个模型的人不是来读政策解读的。我会把两个 DSGE 的构建逻辑、代码结构、参数校准和排错经验全部摊开让你能在本地复现出一条完整的分析链路。2. 两个 DSGE 的分工现金替代模型和存款替代模型怎么搭2.1 为什么不能用一个模型同时装下现金和存款替代现金替代和存款替代在 DSGE 里的传导机制完全不同。现金替代影响的是家庭部门的货币持有决策现金和数字人民币在效用函数里是替代品替代弹性变了家庭的货币需求曲线就移动了。存款替代影响的是银行的负债端存款和数字人民币在银行的资产负债表上此消彼长存款流失直接压缩可贷资金规模。如果硬塞进一个模型效用函数里要同时出现现金、存款和数字人民币三种资产银行的零利润条件会变得极其复杂求解时 Jacobian 矩阵的条件数很容易爆炸fsolve 经常不收敛。常见做法是拆成两个模型各自聚焦一条传导链然后在结果层面做对比和叠加。第一个模型叫 Cash_Sub_DSGE家庭持有现金和数字人民币银行只吸收存款但不涉及数字人民币存款替代第二个模型叫 Deposit_Sub_DSGE家庭持有存款和数字人民币现金被抽象掉重点刻画银行负债端的替代。两个模型共享同一套生产函数和 Calvo 定价结构区别只在家庭资产组合和银行负债约束。这样拆的好处是每个模型的稳态求解都能用解析式先算出来再交给数值求解器做局部逼近。坏处是你得接受一个近似两条替代路径的交互效应被忽略了。对于政策分析来说这个近似在替代率低于 30% 时误差可控超过这个阈值就需要考虑合并模型或者做敏感性分析。2.2 家庭部门的最优化问题与一阶条件先看 Cash_Sub_DSGE 的家庭部门。代表性家庭在 t 期的效用来自消费 C_t、现金持有 M_t/P_t、数字人民币持有 DC_t/P_t 和劳动供给 L_t。效用函数采用分离对数形式U log(C_t) χ_m * log(M_t/P_t) χ_d * log(DC_t/P_t) - χ_l * L_t^(1φ)/(1φ)预算约束是C_t M_t/P_t DC_t/P_t B_t/P_t W_t*L_t R_{t-1}*B_{t-1}/P_t M_{t-1}/P_t DC_{t-1}/P_t Π_t其中 B_t 是债券持有量R_t 是名义利率W_t 是实际工资Π_t 是银行和厂商的分红。对 C_t、M_t、DC_t、L_t 分别求一阶条件得到欧拉方程、货币需求方程和劳动供给方程。关键的一阶条件有两个现金的边际效用等于消费的边际效用乘以名义利率的机会成本 χ_m / (M_t/P_t) (1/C_t) * (R_t - 1)/R_t数字人民币的边际效用也类似但数字人民币的持有成本假设为零所以 χ_d / (DC_t/P_t) (1/C_t) * (R_t - 1)/R_t * (1 - ρ_d)ρ_d 是数字人民币对现金的替代率当 ρ_d0 时数字人民币和现金完全互补ρ_d1 时完全替代。这个参数就是政策分析的核心杠杆。在 Deposit_Sub_DSGE 里家庭不持有现金但持有存款 D_t 和数字人民币 DC_t。存款的效用权重是 χ_s数字人民币的权重是 χ_d。存款的收益率是 R_t^d数字人民币的收益率假设为 0。一阶条件变成χ_s / (D_t/P_t) (1/C_t) * (R_t - R_t^d)/R_t χ_d / (DC_t/P_t) (1/C_t) * (R_t - 0)/R_t * (1 - ρ_s)ρ_s 是数字人民币对存款的替代率。注意这里数字人民币的机会成本是名义利率 R_t因为持有数字人民币放弃了债券收益。2.3 银行部门的零利润条件与利润函数银行在 Cash_Sub_DSGE 里只做一件事吸收存款 D_t发放贷款 L_t^b持有债券 B_t^b。资产负债表约束是L_t^b B_t^b D_t银行的利润函数是Π_t^b R_t^l * L_t^b R_t * B_t^b - R_t^d * D_t - κ/2 * (L_t^b/D_t - ν)^2 * D_t最后一项是贷款管理的二次成本κ 是成本系数ν 是目标贷存比。银行选择 L_t^b 和 D_t 来最大化利润一阶条件给出R_t^l - R_t κ * (L_t^b/D_t - ν) R_t - R_t^d κ * (L_t^b/D_t - ν) * (L_t^b/D_t)这两个式子说明贷款利率和存款利率之间的利差被贷存比和调整成本决定。当数字人民币替代现金时D_t 的稳态值下降贷存比 L_t^b/D_t 上升利差扩大但贷款规模可能收缩利润的净效应取决于两个力量的相对大小。在 Deposit_Sub_DSGE 里银行的负债端多了一个数字人民币存款 DC_t^b但数字人民币存款不进入贷款创造过程只是作为支付准备金存在。资产负债表变成L_t^b B_t^b DC_t^b D_t DC_t^b简化后还是 L_t^b B_t^b D_t但 D_t 的稳态值因为替代效应而下降。银行的利润函数不变但 D_t 的路径变了整个利润的动态响应就不同了。2.4 用 Python 写稳态求解器从解析式到 fsolve两个模型的稳态都可以先手算解析解再用 fsolve 做数值验证。以 Cash_Sub_DSGE 为例稳态时 R1/β其中 β 是贴现因子。给定 R从欧拉方程反推 C从货币需求方程反推 M/P 和 DC/P从劳动供给方程反推 L从生产函数反推 Y从银行一阶条件反推 R^l 和 R^d。下面这段代码用 fsolve 求解稳态变量向量 x [C, M, DC, L, Y, R_l, R_d, D, Pi_b]import numpy as np from scipy.optimize import fsolve # 参数校准 beta 0.99 # 贴现因子 chi_m 0.05 # 现金效用权重 chi_d 0.03 # 数字人民币效用权重 chi_l 1.5 # 劳动负效用权重 phi 1.0 # 劳动供给弹性倒数 alpha 0.33 # 资本份额 delta 0.025 # 折旧率 kappa 0.1 # 贷款调整成本系数 nu 0.7 # 目标贷存比 rho_d 0.2 # 数字人民币对现金替代率 def steady_state(x): C, M, DC, L, Y, R_l, R_d, D, Pi_b x R 1.0 / beta # 欧拉方程 euler 1.0 / C - beta * R / C # 现金货币需求 money_m chi_m / M - (1.0 / C) * (R - 1.0) / R # 数字人民币货币需求 money_d chi_d / DC - (1.0 / C) * (R - 1.0) / R * (1.0 - rho_d) # 劳动供给 labor chi_l * L**phi - (1.0 / C) * (1.0 - alpha) * Y / L # 生产函数 prod Y - L**(1.0 - alpha) # 银行一阶条件1 bank1 R_l - R - kappa * (0.7 * D / D - nu) # 银行一阶条件2 bank2 R - R_d - kappa * (0.7 * D / D - nu) * 0.7 # 资产负债表 balance D - M - DC # 利润定义 profit Pi_b - (R_l * 0.7 * D R * 0.3 * D - R_d * D) return [euler, money_m, money_d, labor, prod, bank1, bank2, balance, profit] # 初值猜测 x0 [1.0, 0.5, 0.3, 0.4, 1.0, 0.04, 0.02, 0.8, 0.01] sol fsolve(steady_state, x0, full_outputTrue) print(收敛状态:, sol[2]) print(稳态解:, sol[0])这段代码的逻辑是先把所有一阶条件和约束写成残差形式fsolve 找一组变量让残差同时为零。参数说明beta0.99 对应年化无风险利率约 4%chi_m 和 chi_d 控制家庭对现金和数字人民币的偏好强度rho_d 是核心政策变量。运行后检查 sol[2] 是否为 1如果不是 1 说明方程有矛盾或者初值太远。常见问题是 balance 方程和 profit 方程线性相关导致 Jacobian 奇异解决办法是把 profit 方程去掉因为利润在稳态里由其他变量决定不需要单独求解。2.5 用 Dynare 写模型文件从 .mod 到脉冲响应Python 适合做稳态求解和参数扫描但做脉冲响应和贝叶斯估计还是 Dynare 更顺手。下面是一个 Cash_Sub_DSGE 的 Dynare 模型文件核心片段var C M DC L Y R_l R_d D Pi_b R; varexo eps_R; parameters beta chi_m chi_d chi_l phi alpha kappa nu rho_d; beta 0.99; chi_m 0.05; chi_d 0.03; chi_l 1.5; phi 1.0; alpha 0.33; kappa 0.1; nu 0.7; rho_d 0.2; model; // 欧拉方程 1/C beta * R / C(1); // 现金货币需求 chi_m / M (1/C) * (R - 1) / R; // 数字人民币货币需求 chi_d / DC (1/C) * (R - 1) / R * (1 - rho_d); // 劳动供给 chi_l * L^phi (1/C) * (1 - alpha) * Y / L; // 生产函数 Y L^(1 - alpha); // 银行一阶条件 R_l R kappa * (0.7 * D / D - nu); R - R_d kappa * (0.7 * D / D - nu) * 0.7; // 资产负债表 D M DC; // 利润 Pi_b R_l * 0.7 * D R * 0.3 * D - R_d * D; // 泰勒规则 R 1/beta 1.5 * (Y - steady_state(Y)) eps_R; end; shocks; var eps_R; stderr 0.01; end; steady; check; stoch_simul(order1, irf20) C M DC L Y R_l R_d D Pi_b R;Dynare 文件的逻辑是先把所有方程写成水平形式steady 命令求解稳态check 检查 Blanchard-Kahn 条件stoch_simul 做一阶逼近和脉冲响应。参数说明eps_R 是货币政策冲击stderr 0.01 表示标准差 1%。运行后看 check 的输出如果显示 The rank condition is satisfied 就说明模型有唯一稳定解。常见问题是泰勒规则里的 steady_state(Y) 在 Dynare 里不能直接用需要改成 Y 的稳态值或者用 Y_ss 参数替代。3. 参数校准替代率、效用权重和调整成本怎么定3.1 数字人民币替代率的取值依据替代率 rho_d 和 rho_s 是整个模型最敏感的的参数。取值不能拍脑袋要有微观调查数据或者试点数据支撑。根据公开的试点报告数字人民币对现金的替代率在零售场景大约在 0.1 到 0.3 之间对活期存款的替代率在 0.05 到 0.15 之间。我一般会做三档情景低替代 0.1、中替代 0.2、高替代 0.4然后看银行利润的响应区间。在代码里rho_d 直接进入货币需求方程改变的是家庭持有数字人民币的边际效用。rho_d 越大同样利率下家庭愿意持有的数字人民币越多现金 M 的稳态值越低。在 Deposit_Sub_DSGE 里rho_s 越大存款 D 的稳态值越低银行的贷存比越高贷款利率和存款利率的利差越大。3.2 效用权重 chi_m、chi_d、chi_s 的校准方法效用权重决定家庭在消费和货币持有之间的替代弹性。校准方法是让模型稳态的货币持有量与 GDP 之比匹配实际数据。中国 M0/GDP 大约在 0.08 左右M2/GDP 大约在 2.0 左右。在 Cash_Sub_DSGE 里M/Y 的目标值是 0.08DC/Y 的目标值根据数字人民币渗透率设定比如 0.02。用这两个目标反推 chi_m 和 chi_d。具体操作是在 Python 里写一个外层循环给定 chi_m 和 chi_d调用 fsolve 求稳态计算 M/Y 和 DC/Y然后调整 chi_m 和 chi_d 直到匹配目标值。这个过程用 scipy.optimize.minimize 做嵌套优化外层目标函数是 (M/Y - 0.08)^2 (DC/Y - 0.02)^2。在 Deposit_Sub_DSGE 里D/Y 的目标值对应 M2/GDP 的存款部分大约 1.5。chi_s 的校准逻辑类似但要注意存款的效用权重通常比现金小因为存款的主要功能是储值而非交易。3.3 贷款调整成本 kappa 和贷存比 nu 的设定kappa 决定银行调整贷款组合的成本nu 是目标贷存比。这两个参数影响的是银行利润对存款流失的敏感度。kappa 越大银行越不愿意调整贷款规模存款流失时贷款利率上升幅度越大利差扩大越明显。nu 一般设为 0.7 到 0.75对应中国银行业的平均贷存比。校准 kappa 的方法是匹配贷款利率对存款利率的传导系数。根据实证文献中国贷款利率对存款利率的传导系数大约在 0.6 到 0.8 之间。在模型里这个传导系数等于 kappa * nu / (kappa * nu 1)反推 kappa 大约在 0.1 到 0.3 之间。我一般取 0.15 作为基准值然后做敏感性分析。3.4 用 Python 做参数扫描替代率从 0.1 到 0.5 的利润响应下面这段代码在 Cash_Sub_DSGE 里扫描 rho_d 从 0.1 到 0.5每次重新求解稳态并记录银行利润import numpy as np from scipy.optimize import fsolve def solve_steady(rho_d): beta 0.99 chi_m 0.05 chi_d 0.03 chi_l 1.5 phi 1.0 alpha 0.33 kappa 0.15 nu 0.7 def equations(x): C, M, DC, L, Y, R_l, R_d, D, Pi_b x R 1.0 / beta euler 1.0 / C - beta * R / C money_m chi_m / M - (1.0 / C) * (R - 1.0) / R money_d chi_d / DC - (1.0 / C) * (R - 1.0) / R * (1.0 - rho_d) labor chi_l * L**phi - (1.0 / C) * (1.0 - alpha) * Y / L prod Y - L**(1.0 - alpha) bank1 R_l - R - kappa * (0.7 * D / D - nu) bank2 R - R_d - kappa * (0.7 * D / D - nu) * 0.7 balance D - M - DC profit Pi_b - (R_l * 0.7 * D R * 0.3 * D - R_d * D) return [euler, money_m, money_d, labor, prod, bank1, bank2, balance, profit] x0 [1.0, 0.5, 0.3, 0.4, 1.0, 0.04, 0.02, 0.8, 0.01] sol fsolve(equations, x0, full_outputTrue) if sol[2] 1: return sol[0][8] # 返回银行利润 else: return np.nan rho_values np.linspace(0.1, 0.5, 9) profits [solve_steady(r) for r in rho_values] for r, p in zip(rho_values, profits): print(frho_d{r:.2f}, 银行利润{p:.4f})这段代码的逻辑是外层循环改变 rho_d内层调用 fsolve 求稳态提取利润变量。参数说明rho_values 从 0.1 到 0.5 分 9 档覆盖低中高替代情景。运行后如果某些 rho_d 对应的利润是 nan说明 fsolve 没收敛需要调整初值或者检查方程是否有矛盾。常见问题是高替代率下 M 的稳态值趋近于零导致 money_m 方程出现除零错误解决办法是给 M 设一个下界比如 0.01。4. 避坑与排查模型不收敛、脉冲响应发散、参数识别失败4.1 fsolve 报 The iteration is not making good progress现象运行稳态求解器时 fsolve 返回收敛状态为 2 或 3残差大于 1e-6利润变量为 nan。原因方程数量多于变量数量或者某些方程在初值附近线性相关。最常见的是 profit 方程和 balance 方程同时存在时Jacobian 矩阵奇异。解决去掉 profit 方程因为利润在稳态里由其他变量决定不需要单独作为方程。如果去掉后仍然不收敛检查 bank1 和 bank2 是否重复因为 bank2 可以从 bank1 和 balance 推导出来。保留 bank1 和 balance去掉 bank2变量数减到 7 个方程数也减到 7 个。4.2 Dynare 报 Blanchard-Kahn condition is not satisfied现象运行 check 命令时 Dynare 报错说模型没有唯一稳定解或者解的个数不对。原因泰勒规则里的利率对产出缺口的反应系数太小或者模型的前瞻性变量太多。在 Cash_Sub_DSGE 里如果泰勒规则系数小于 1利率对通胀的反应不足模型会出现多重均衡。解决把泰勒规则系数从 1.5 提高到 2.0 或者 2.5确保利率对产出缺口的反应足够强。另外检查欧拉方程里的 R 是当期还是下一期如果写成 R(1) 而泰勒规则用的是 R会导致时序错位。统一用 R 表示当期名义利率欧拉方程里用 R(1) 表示下一期。4.3 脉冲响应发散或者不衰减现象stoch_simul 跑完后画出的脉冲响应图里某些变量的响应越来越大20 期后仍然没有回到稳态。原因模型有单位根或者某个变量的稳态值算错了。在 Deposit_Sub_DSGE 里如果存款 D 的稳态值设为零而数字人民币 DC 的稳态值不为零balance 方程 D DC 会导致 D 的路径跟随 DC而 DC 受随机冲击影响整个系统就没有稳定锚。解决检查所有变量的稳态值是否非零。存款 D 的稳态值不能为零因为银行需要存款来发放贷款。如果数字人民币完全替代存款D 的稳态值趋近于零这时候模型退化成一个没有银行存款的极端情形需要重新设定效用函数或者引入其他摩擦。实际操作中把 rho_s 的上限设在 0.5避免 D 的稳态值低于 0.1。4.4 参数识别失败贝叶斯估计时后验分布太平现象用 Dynare 做贝叶斯估计时某些参数的后验分布几乎和先验一样说明数据没有提供额外信息。原因参数之间高度相关或者模型对某个参数不敏感。在 Cash_Sub_DSGE 里chi_m 和 chi_d 经常出现识别问题因为现金和数字人民币的货币需求方程形式相同数据只能识别两者的和不能识别各自的权重。解决固定其中一个参数比如把 chi_m 校准为 0.05 不估计只估计 chi_d。或者引入一个额外的观测方程比如数字人民币渗透率的调查数据作为 chi_d 的识别来源。另一个办法是用替代率 rho_d 作为唯一估计参数chi_m 和 chi_d 按比例调整减少自由度。4.5 Python 和 Dynare 结果对不上现象Python 稳态求解器算出的银行利润是 0.012Dynare 的 steady 命令算出的利润是 0.015差了 20%。原因两个平台的方程写法有细微差别。Python 里用的是 0.7 * D / DDynare 里如果写成 0.7 * D / D 也是一样的但如果 Dynare 里写成 0.7 * D(-1) / D就变成了滞后项稳态值不同。解决逐项对比两个平台的方程。先把 Dynare 的模型简化成和 Python 完全一样的水平形式去掉所有时序下标只留稳态关系。然后检查参数值是否一致特别是 kappa 和 nuPython 里 kappa0.15Dynare 里如果写成 0.1 就会导致利差不同。最后检查利润的定义Python 里是 R_l * 0.7 * D R * 0.3 * D - R_d * DDynare 里如果写成 R_l * L_b R * B_b - R_d * D而 L_b 和 B_b 的稳态值没算对利润就会偏。5. 进阶技巧用 Python 调 Dynare 做批量情景分析和敏感性检验5.1 用 subprocess 调 Dynare 做参数扫描Dynare 本身没有 Python API但可以用 subprocess 调命令行版本每次改参数后重新生成 .mod 文件并运行。下面这段代码扫描 rho_d 从 0.1 到 0.5每次生成一个新的 .mod 文件运行 Dynare然后从输出里提取银行利润的稳态值import subprocess import re import os template var C M DC L Y R_l R_d D Pi_b R; varexo eps_R; parameters beta chi_m chi_d chi_l phi alpha kappa nu rho_d; beta 0.99; chi_m 0.05; chi_d 0.03; chi_l 1.5; phi 1.0; alpha 0.33; kappa 0.15; nu 0.7; rho_d {rho_d}; model; 1/C beta * R / C(1); chi_m / M (1/C) * (R - 1) / R; chi_d / DC (1/C) * (R - 1) / R * (1 - rho_d); chi_l * L^phi (1/C) * (1 - alpha) * Y / L; Y L^(1 - alpha); R_l R kappa * (0.7 * D / D - nu); R - R_d kappa * (0.7 * D / D - nu) * 0.7; D M DC; Pi_b R_l * 0.7 * D R * 0.3 * D - R_d * D; R 1/beta 1.5 * (Y - steady_state(Y)) eps_R; end; shocks; var eps_R; stderr 0.01; end; steady; check; stoch_simul(order1, irf20) C M DC L Y R_l R_d D Pi_b R; rho_values [0.1, 0.2, 0.3, 0.4, 0.5] results {} for rho in rho_values: mod_content template.format(rho_drho) with open(fmodel_rho_{rho}.mod, w) as f: f.write(mod_content) result subprocess.run([dynare, fmodel_rho_{rho}.mod], capture_outputTrue, textTrue) output result.stdout # 从输出里提取 Pi_b 的稳态值 match re.search(rPi_b\s([\d\.]), output) if match: results[rho] float(match.group(1)) else: results[rho] None for rho, profit in results.items(): print(frho_d{rho}, Pi_b{profit})这段代码的逻辑是用字符串模板生成 .mod 文件subprocess 调 Dynare 命令行然后用正则表达式从输出里提取利润的稳态值。参数说明template 里的 {rho_d} 是占位符每次替换成不同的替代率。运行前确保 Dynare 在系统路径里否则 subprocess 会报 FileNotFoundError。常见问题是 Dynare 的输出格式在不同版本里不一样正则表达式可能需要调整建议先手动跑一次看输出格式。5.2 敏感性检验用 Sobol 指数找关键参数参数扫描只能一次看一个参数敏感性检验可以同时看多个参数的交互效应。用 SALib 库做 Sobol 指数分析输入参数是 rho_d、kappa、nu、chi_d输出是银行利润。下面是一个简化的实现import numpy as np from SALib.sample import saltelli from SALib.analyze import sobol from scipy.optimize import fsolve problem { num_vars: 4, names: [rho_d, kappa, nu, chi_d], bounds: [[0.1, 0.5], [0.05, 0.3], [0.6, 0.8], [0.01, 0.05]] } param_values saltelli.sample(problem, 64) def model_profit(params): rho_d, kappa, nu, chi_d params beta 0.99 chi_m 0.05 chi_l 1.5 phi 1.0 alpha 0.33 def equations(x): C, M, DC, L, Y, R_l, R_d, D, Pi_b x R 1.0 / beta euler 1.0 / C - beta * R / C money_m chi_m / M - (1.0 / C) * (R - 1.0) / R money_d chi_d / DC - (1.0 / C) * (R - 1.0) / R * (1.0 - rho_d) labor chi_l * L**phi - (1.0 / C) * (1.0 - alpha) * Y / L prod Y - L**(1.0 - alpha) bank1 R_l - R - kappa * (0.7 * D / D - nu) bank2 R - R_d - kappa * (0.7 * D / D - nu) * 0.7 balance D - M - DC profit Pi_b - (R_l * 0.7 * D R * 0.3 * D - R_d * D) return [euler, money_m, money_d, labor, prod, bank1, bank2, balance, profit] x0 [1.0, 0.5, 0.3, 0.4, 1.0, 0.04, 0.02, 0.8, 0.01] sol fsolve(equations, x0, full_outputTrue) if sol[2] 1: return sol[0][8] else: return 0.0 Y np.array([model_profit(p) for p in param_values]) Si sobol.analyze(problem, Y) print(一阶敏感指数:, Si[S1]) print(总敏感指数:, Si[ST])这段代码的逻辑是用 Saltelli 采样生成参数组合对每组参数求解稳态并记录利润然后用 Sobol 分析计算每个参数对利润方差的一阶和总贡献。参数说明num_vars4 表示四个输入参数bounds 是每个参数的取值范围64 是采样数实际使用建议至少 1024。运行后看 S1 和 ST如果某个参数的 ST 远大于 S1说明它和其他参数有强交互效应。常见问题是 fsolve 在某些参数组合下不收敛返回 0.0 会污染敏感指数解决办法是把不收敛的样本剔除或者用插值补上。5.3 从模型到政策建议怎么解读利润响应模型跑完后银行利润对替代率的响应通常是非线性的。低替代率时利润下降缓慢因为存款流失被贷款利率上升部分抵消高替代率时利润加速下降因为贷款规模收缩的效应超过利差扩大的效应。拐点大约在替代率 0.3 到 0.35 之间具体位置取决于 kappa 和 nu 的取值。我一般会画三条线基准情景、高 kappa 情景、低 nu 情景看利润响应的区间。如果高 kappa 情景下利润下降幅度比基准小 30% 以上说明银行的贷款调整能力是缓冲替代冲击的关键。政策含义是与其纠结替代率的高低不如关注银行的资产负债管理能力包括贷款定价灵活性和负债结构的多元化。一个实用的习惯是每次跑完模型后把关键参数和利润响应存成一个 CSV 文件标注日期和参数版本。下次再跑的时候先对比上一次的结果如果差异超过 5%检查是不是参数校准变了或者代码有改动。这个习惯帮我抓过好几次因为手滑改错参数导致的翻车省了不少后悔药。希望帮到你。本文还有配套的精品资源点击获取