这是第九个实验。第 35 讲,我们用一个小银行,手算了 Diamond 和 Dybvig 的核心想法:借短放长、先到先得,让银行有两个均衡,一个平静,一个挤兑;两个均衡之间,只隔着一个很小的缓冲(正常的取钱比例 25%,到 30%,就开始挤兑)。第 35 讲结尾,留了一个承诺:让你亲手跑一个更完整的挤兑模型:很多个存款人、不同的信念、存款保险。 这就是这个实验。
这个实验里,用的仍然是第 35 讲的小银行:100 个存款人,每人存 1,银行把钱全部投进一个长期项目;提前清算,每 1 份只能变现 0.6;到期,每 1 份变成 1.4;急用钱的人占 25%。数字是我设的,不对应任何一家银行。 在这个小银行上,我们一步一步地加东西,看挤兑怎么变。
怎么用:和前面的实验一样,代码块是接着往下写的:后面的块会用到前面块里定义的东西。把它们依次拼成一个文件(比如 lab78.py),用 python lab78.py 运行,约 30 秒;也可以一段一段地在 Python 里依次运行。只需要 Python 3 和 NumPy。实验里有随机数(排队、网络),但种子都固定了,所以你跑出来的数字,会和下面的输出一模一样。
一、六个问题
先停一下:请先凭直觉,回答下面六个问题,写下来。
问题 1: 小银行里,不急的人,每人选"去取"还是"等下去",一共有几个均衡?
问题 2: 如果存款人对银行资产好坏的看法不一样,有人乐观,有人悲观,银行会更稳,还是更脆弱?
问题 3: 如果存款人不知道银行资产的真实收益,每人只收到一个带噪声的消息,“全部去取”,还会是一个均衡吗?
问题 4: 你只看得到身边 k 个人有没有去取钱。k 要多大,一个正常的银行,才不会被"邻居里偶然多了几个人去取"吓垮?
问题 5: 存款保险有限额:超过限额的部分,没有保险。限额要高到什么程度,才能消除坏的均衡?
问题 6: 暂停兑付,和最后贷款人,各有什么代价?
我们会一个一个回来。
二、实验的设计
2.1 小银行
- 100 个存款人,每人存 1。银行把 100 全部投进一个长期项目。
- 第 1 期提前清算:每 1 份只能变现 s = 0.6;第 2 期到期:每 1 份变成 R = 1.4。
- 银行承诺:第 1 期来取的人,付 1,先到先得,钱付完为止;留到第 2 期的人,平分剩下的资产。
- 25% 的存款人是急用钱的人,一定在第 1 期取;其余 75% 是不急的人,哪个更划算,选哪个。
2.2 两个收益
第 1 期,如果一共有 f 比例的人来取钱:
- 去取的人拿到的:银行最多能付出 s × 100 = 60。f ≤ 0.6 时,每人拿 1;f > 0.6 时,随机排队,前面的拿 1,后面的拿 0,期望 s ÷ f。
- 等下去的人拿到的:为了付给 f 比例的人,银行要变现 f ÷ s 的资产;剩下的资产,到期变成 R 倍,平分给没来取的人:R × (1 − f ÷ s) ÷ (1 − f)。f ≥ s 时,资产被变现光了,拿 0。
让"等下去"等于"去取"(等于 1),解出 f* = (R − 1) ÷ (R ÷ s − 1) = 30%:这是第 35 讲的临界值。
三、第一步:把均衡找全
import numpy as np
from statistics import NormalDist
# 第 35 讲的小银行:100 个存款人,每人存 1,银行把 100 全部投进一个长期项目。
# 第 1 期(提前)清算:每 1 份只能变现 s = 0.6;等到第 2 期(到期):每 1 份变成 R = 1.4。
# 银行承诺:第 1 期来取的人,付 1(先到先得,钱付完为止);留到第 2 期的人,平分剩下的资产。
# 25% 的存款人是「急用钱的人」,一定在第 1 期取;其余 75% 是「不急的人」,哪个更划算,选哪个。
N, S_LIQ, R_MAT, EARLY = 100, 0.6, 1.4, 0.25
def run_payoff(f, s=S_LIQ):
"""第 1 期,一共有 f 比例的人来取钱(f × N 个人)。银行最多能付出 s × N。来取钱的人,期望拿到多少?
钱够付(f ≤ s):每人 1;不够:随机排队,前面的拿 1,后面的拿 0,期望 s / f"""
return 1.0 if f <= s else s / f
def wait_value(f, r=R_MAT, s=S_LIQ):
"""f 比例的人在第 1 期取钱之后,留到第 2 期的人,每人能拿到多少"""
if f >= 1: return 0.0
sold = f / s # 为了付给 f 比例的人,要变现的资产(占全部资产的比例)
return 0.0 if sold >= 1 else (1 - sold) * r / (1 - f)
def threshold(r=R_MAT, s=S_LIQ):
"""等下去的价值,恰好等于现在去取:f* = (R - 1) / (R / s - 1)"""
return (r - 1) / (r / s - 1)
f_star = threshold()
print(f"临界值 f* = (R - 1) ÷ (R ÷ s - 1) = {f_star:.4f};正常取钱的比例 = {EARLY:.2f}")
# 不急的人里,有 p 的比例选择「去取」,总取钱比例 f = 0.25 + 0.75 p。每个不急的人,比较:去取,和等下去,哪个更好?
p_star = (f_star - EARLY) / (1 - EARLY) # 内部均衡处,不急的人里去取的比例
print("\n不急的人里,有 p 的比例去取钱:总取钱比例 f,去取的人拿多少,等下去的人拿多少")
print(" p f 去取 等下去 谁更划算")
for p in (0.0, 0.03, p_star, 0.10, 0.25, 0.5, 0.75, 1.0):
f = EARLY + (1 - EARLY) * p; a, b = run_payoff(f), wait_value(f)
print(f" {p:6.4f} {f:6.3f} {a:6.3f} {b:6.3f} {'等下去' if b > a + 1e-9 else ('一样' if abs(b - a) < 1e-9 else '去取')}")
# 均衡:没有人想单独改变。在 p 处,「等下去 - 去取」的差;差 > 0 时,等下去更好,所以 p 会变小;差 < 0 时,去取更好,p 会变大
gap = lambda p: wait_value(EARLY + (1 - EARLY) * p) - run_payoff(EARLY + (1 - EARLY) * p)
ps = np.linspace(0, 1, 100001); g = np.array([gap(p) for p in ps])
print("\n均衡有:")
if g[0] >= 0: print(f" p = 0(不急的人,全部等),f = {EARLY:.3f}:等下去更好({g[0]:+.3f}):好的均衡")
for i in range(len(ps) - 1):
if g[i] > 0 >= g[i + 1]: print(f" p = {ps[i]:.4f}(一部分人去取),f = {EARLY + (1 - EARLY) * ps[i]:.3f}:去取和等下去一样好:内部均衡")
if g[-1] <= 0: print(f" p = 1(不急的人,全部去取),f = 1.000:去取更好({g[-1]:+.3f}):坏的均衡")
print("内部均衡是「刀刃」:p 比它小一点,大家都想等,p 回到 0;p 比它大一点,大家都想去取,p 一路走到 1。")
# 用真正的排队,随机模拟,核对「去取的人,期望拿多少」(f > 0.6,钱不够付)
rng = np.random.default_rng(78)
print("\n随机排队的模拟(20000 次),去取钱的人,期望拿多少:")
for f in (0.7, 0.85, 1.0):
k = int(round(f * N)); capacity = int(round(S_LIQ * N)); mine = 0
for _ in range(20000):
position = rng.integers(k) # 我在 k 个去取的人里,排第几(0 是第一个)
mine += 1.0 if position < capacity else 0.0
print(f" f = {f:.2f}:模拟 {mine / 20000:.3f},公式 s / f = {run_payoff(f):.3f}")
输出:
临界值 f* = (R - 1) ÷ (R ÷ s - 1) = 0.3000;正常取钱的比例 = 0.25
不急的人里,有 p 的比例去取钱:总取钱比例 f,去取的人拿多少,等下去的人拿多少
p f 去取 等下去 谁更划算
0.0000 0.250 1.000 1.089 等下去
0.0300 0.273 1.000 1.050 等下去
0.0667 0.300 1.000 1.000 一样
0.1000 0.325 1.000 0.951 去取
0.2500 0.438 1.000 0.674 去取
0.5000 0.625 0.960 0.000 去取
0.7500 0.812 0.738 0.000 去取
1.0000 1.000 0.600 0.000 去取
均衡有:
p = 0(不急的人,全部等),f = 0.250:等下去更好(+0.089):好的均衡
p = 0.0667(一部分人去取),f = 0.300:去取和等下去一样好:内部均衡
p = 1(不急的人,全部去取),f = 1.000:去取更好(-0.600):坏的均衡
内部均衡是「刀刃」:p 比它小一点,大家都想等,p 回到 0;p 比它大一点,大家都想去取,p 一路走到 1。
随机排队的模拟(20000 次),去取钱的人,期望拿多少:
f = 0.70:模拟 0.854,公式 s / f = 0.857
f = 0.85:模拟 0.706,公式 s / f = 0.706
f = 1.00:模拟 0.601,公式 s / f = 0.600
逐段看:
- p 是不急的人里,去取的比例;总取钱比例 f = 0.25 + 0.75 p。p = 0:f = 25%,去取拿 1,等下去拿 1.089,等更好。p = 6.67%(f = 30%):一样。p = 10%(f = 32.5%):去取拿 1,等下去只拿 0.951,去取更好。p = 0.5(f = 62.5%):钱已经不够了,去取拿 0.960,等下去什么也拿不到。p = 1(f = 100%):去取拿 0.6,等下去拿 0。
- 三个均衡:
- p = 0(f = 25%):好的均衡:别人都等,我也等;
- p = 1(f = 100%):坏的均衡:别人都去取,我也去取;
- p = 0.0667(f = 30%):内部均衡:去取和等下去,一样好。
- 第三个均衡,是一把刀刃:p 比它小一点,大家都想等,p 回到 0;p 比它大一点,大家都想去取,p 一路走到 1。所以,真正稳定的,只有两个。
- 随机排队的模拟(每次 20000 场):f = 0.70、0.85、1.00 时,去取的人,期望拿到 0.854、0.706、0.601,和公式 s ÷ f(0.857、0.706、0.600)一致。
问题 1 的答案:三个,其中两个稳定(平静、挤兑),一个是刀刃。
四、第二步:大家对银行的看法不一样
第一步里,每个不急的人,都知道项目到期会变成 R = 1.4,所以大家的临界值一样,都是 30%。现实里,大家对银行资产好坏的看法不一样:第 i 个人相信的到期收益是 R_i,他的临界值 f_i* = (R_i − 1) ÷ (R_i ÷ s − 1)。我们让 R_i 在 [1.4 − w, 1.4 + w] 上均匀分布(取 1000 个等分位数,没有随机数):w 越大,大家的看法越分散。
这是 Granovetter 1978 年(American Journal of Sociology,83 卷 6 期,1420–1443 页;我只核对了出处)的门槛模型:每个人有自己的门槛,别人去的比例超过它,我就去;个人的门槛的分布,决定了整体的结局。动态很简单:大家预期这一期的取钱比例是 f;不急的人里,临界值低于 f 的人,会去取;于是下一期的总取钱比例,是急用钱的,加上这些人。一期一期地走,看最后停在哪里。
# 第二步:存款人的信念不一样。第一步里,每个不急的人,都知道项目到期会变成 R = 1.4,所以大家的临界值一样,都是 30%。
# 现实里,大家对银行资产好坏的看法不一样:第 i 个人相信的到期收益是 R_i。每个人的临界值:f_i* = (R_i - 1) / (R_i / s - 1)。
# R_i 在 [1.4 - w, 1.4 + w] 上均匀分布(取 1000 个等分位数,没有随机数):w 越大,大家的看法越分散。
def thresholds(w, n=1000):
r = R_MAT + w * (2 * (np.arange(n) + 0.5) / n - 1)
return (r - 1) / (r / S_LIQ - 1)
def next_f(f, thr):
"""如果大家预期,这一期的取钱比例是 f:不急的人里,临界值低于 f 的人,会去取。下一期的总取钱比例 = 急用钱的 + 去取的"""
return EARLY + (1 - EARLY) * np.mean(thr < f)
def settle(f0, thr, steps=300):
f = f0
for _ in range(steps): f = next_f(f, thr)
return f
print("看法的分散程度 w 不同:最悲观的人的临界值;平静时,会不会有人先跑,把大家拖进去?")
print(" w 最悲观的人 R_i 最悲观的人的临界值 平静时(f = 25%)最后的取钱比例 从「25% + 额外 x 的人先跑」出发,最后的取钱比例")
print(" x = 3% x = 6% x = 10% x = 20%")
het = {}
for w in (0.0, 0.05, 0.09, 0.10, 0.15, 0.25):
thr = thresholds(w); het[w] = thr
calm = settle(EARLY, thr)
cells = " ".join(f"{settle(EARLY + x, thr):6.3f}" for x in (0.03, 0.06, 0.10, 0.20))
print(f" {w:4.2f} {R_MAT - w:5.2f} {thr.min():6.3f} {calm:6.3f} {cells}")
# 均衡:f = 0.25 + 0.75 × F(f),F 是临界值的分布函数。在 f 的格子上,看曲线和 45 度线,穿过几次,哪些是稳定的
print("\n均衡(f = 急用钱的 + 不急的里临界值低于 f 的),以及稳定的(被推离一点,会回来):")
fs = np.linspace(0, 1, 4001)
for w in (0.0, 0.05, 0.10, 0.15, 0.25):
thr = het[w]; h = np.array([next_f(f, thr) - f for f in fs])
stable = [fs[i] for i in range(len(fs) - 1) if h[i] > 0 >= h[i + 1]]
unstable = [fs[i] for i in range(len(fs) - 1) if h[i] < 0 <= h[i + 1]]
print(f" w = {w:4.2f}:稳定的 f = " + "、".join(f"{x:.3f}" for x in stable) + ";不稳定的(刀刃)f = " + ("、".join(f"{x:.3f}" for x in unstable) if unstable else "没有"))
# 对照:如果信念是正态分布(没有上下界),尾巴里总有人悲观到「平时就去取」
thr_n = np.array([(r - 1) / (r / S_LIQ - 1) for r in np.maximum(R_MAT + 0.05 * np.array([NormalDist().inv_cdf((i + 0.5) / 1000) for i in range(1000)]), 1.0001)])
print(f"\n对照:R_i 服从正态分布(标准差 0.05),平静时最后的取钱比例 = {settle(EARLY, thr_n):.3f}:最悲观的几个人,平时就会去取,把一串临界值更高的人,一个一个地拖进来。")
输出:
看法的分散程度 w 不同:最悲观的人的临界值;平静时,会不会有人先跑,把大家拖进去?
w 最悲观的人 R_i 最悲观的人的临界值 平静时(f = 25%)最后的取钱比例 从「25% + 额外 x 的人先跑」出发,最后的取钱比例
x = 3% x = 6% x = 10% x = 20%
0.00 1.40 0.300 0.250 0.250 1.000 1.000 1.000
0.05 1.35 0.280 0.250 0.250 1.000 1.000 1.000
0.09 1.31 0.262 0.250 1.000 1.000 1.000 1.000
0.10 1.30 0.257 0.250 1.000 1.000 1.000 1.000
0.15 1.25 0.231 1.000 1.000 1.000 1.000 1.000
0.25 1.15 0.164 1.000 1.000 1.000 1.000 1.000
均衡(f = 急用钱的 + 不急的里临界值低于 f 的),以及稳定的(被推离一点,会回来):
w = 0.00:稳定的 f = 0.250、1.000;不稳定的(刀刃)f = 0.300
w = 0.05:稳定的 f = 0.250、1.000;不稳定的(刀刃)f = 0.282
w = 0.10:稳定的 f = 0.250、1.000;不稳定的(刀刃)f = 0.258
w = 0.15:稳定的 f = 1.000;不稳定的(刀刃)f = 没有
w = 0.25:稳定的 f = 1.000;不稳定的(刀刃)f = 没有
对照:R_i 服从正态分布(标准差 0.05),平静时最后的取钱比例 = 1.000:最悲观的几个人,平时就会去取,把一串临界值更高的人,一个一个地拖进来。
逐段看:
- w = 0(大家看法一样,第一步):平静时,稳定在 25%;额外有 3% 的人先跑,还稳得住(25% + 3% = 28% < 30%);额外有 6% 的人先跑,一路走到 100%。
- w = 0.05:最悲观的人,相信 R = 1.35,临界值 28.0%,比 30% 更低;刀刃,从 30.0% 移到了 28.2%:缓冲,从 5.0 个百分点,薄成了 3.2 个百分点。
- w = 0.10:最悲观的人,R = 1.30,临界值 25.7%,刀刃在 25.8%:缓冲只剩 0.8 个百分点。额外有 3% 的人先跑,就已经走到 100%(w = 0.09 时,也一样)。
- w = 0.15、0.25:最悲观的人的临界值(23.1%、16.4%),已经低于正常的 25%:平静,不再是均衡:平时,最悲观的几个人,就会去取,把临界值更高的人,一个一个地拖进来:最后 100%。
- 看法的分散,有一个分界:w ≈ 0.114。 低于它,平静还是一个均衡;高于它,没有。(练习 3 让你验证。)
- 对照:如果信念是正态分布(没有上下界,标准差 0.05),平静时,最后也是 100%:分布的尾巴里,总有人悲观到"平时就去取"。
问题 2 的答案:更脆弱。不是因为"大家都悲观",而是因为"大家看法不一致":最悲观的那一小撮人,把整个银行的缓冲,一点一点地吃掉。(要小心:我们假设的是,大家的信念,围绕真实值(R = 1.4)对称地分布,没有人更接近真相;如果悲观的人,恰好是对的,那就不是"恐慌",是"基本面",这个模型分不开,第 35 讲也说过。)
五、第三步:大家只收到带噪声的信号
第一步里,R 是公开的,所以"全部去取",在 R 是任何值的时候,都是一个均衡。现实里,没人确切知道银行的资产值多少。全局博弈(Morris 和 Shin 1998 年,American Economic Review,88 卷 3 期,587–597 页;用到挤兑上的,是 Goldstein 和 Pauzner 2005 年,Journal of Finance,60 卷 3 期,1293–1327 页;我只核对了摘要)的想法是:让每个人,各自收到一个带噪声的信号,这时,均衡会变得唯一,而且,由基本面决定。
设项目到期的真实收益 R(基本面),谁也不确定,先验是平的。每个不急的人,收到信号 x_i = R + 噪声(噪声是正态的,每人不同)。策略:信号低于门槛 x*,就去取。一个收到信号 x 的人,认为 R 服从以 x 为中心的正态分布,他比较等和取的期望收益;门槛 x*,就是他刚好觉得一样的信号。
# 第三步:如果存款人不知道 R 是多少,只能各自收到一个带噪声的消息,会怎样?(「全局博弈」:Morris 和 Shin 1998 年提出,
# Goldstein 和 Pauzner 2005 年用到了挤兑上。)
# 项目到期的真实收益 R(「基本面」),谁也不确定,先验是平的。每个不急的人,收到一个信号 x_i = R + sigma × 噪声(噪声是正态分布,每人不同)。
# 策略:信号低于某个门槛 x*,就去取钱。于是,真实收益是 R 时,不急的人里去取钱的比例是 Phi((x* - R) / sigma),总取钱比例 f(R) = 0.25 + 0.75 × 这个比例。
# 一个收到信号 x 的人,认为 R 服从 N(x, sigma²);他比较:等下去的期望收益,和去取的期望收益。门槛 x* 就是他刚好觉得一样的信号。
PHI = NormalDist().cdf
Z = np.linspace(-6, 6, 1201); WEIGHT = np.exp(-Z ** 2 / 2); WEIGHT /= WEIGHT.sum() # 标准正态的权重
def waiting_minus_running(x, x_star, sigma, s):
"""信号为 x 的人,等下去,比去取,期望多得多少(对 R ~ N(x, sigma²) 取平均)"""
r = x + sigma * Z
f = EARLY + (1 - EARLY) * np.array([PHI((x_star - ri) / sigma) for ri in r])
return float(WEIGHT @ np.array([wait_value(fi, ri, s) - run_payoff(fi, s) for fi, ri in zip(f, r)]))
def equilibrium_threshold(sigma, s, hi=12.0):
"""二分法:找 x*,让「信号刚好是 x* 的人」觉得,等和取一样好"""
lo = 1.0
for _ in range(40):
mid = (lo + hi) / 2
if waiting_minus_running(mid, mid, sigma, s) > 0: hi = mid # 等更好,说明门槛可以再低一点
else: lo = mid
return (lo + hi) / 2
def laplace_threshold(s, early=EARLY):
"""噪声趋于 0 的极限:每个人对「别人去取的比例」没有任何信息,认为它在 [早取的比例, 1] 上均匀分布(Laplace 信念);门槛 R*,让平均的「等 - 取」等于 0"""
ls = np.linspace(0, 1, 2001)
avg = lambda r: np.mean([wait_value(early + (1 - early) * l, r, s) - run_payoff(early + (1 - early) * l, s) for l in ls])
lo, hi = 1.0, 20.0
for _ in range(50):
mid = (lo + hi) / 2
if avg(mid) > 0: hi = mid
else: lo = mid
return (lo + hi) / 2
print("一、噪声趋于 0 的极限:银行到期收益低于 R*,就一定被挤兑;高于 R*,就不会。R* 取决于资产的变现能力 s(R = 1.4 时的 f* 也列出来)")
print(" s R* R = 1.4 时的 f*")
for s in (0.5, 0.6, 0.7, 0.8, 0.9, 0.95):
print(f" {s:4.2f} {laplace_threshold(s):5.2f} {threshold(1.4, s):.3f}")
print(f" (第一步的小银行,s = 0.6:R* = {laplace_threshold(0.6):.2f}。这个玩具里,银行承诺的「提前取,付 1」太慷慨,提前变现的损失又大,所以只有到期收益高到 4,才不会被挤兑;数字不要当成现实,要看的是:s 越大,R* 越低。)")
print("\n二、资产比较好变现的银行(s = 0.9),存款人只收到带噪声的信号:门槛 x*,以及真实收益 R 不同时,不急的人里去取的比例")
print(" 噪声 sigma 门槛 x* R = 1.1、1.3、1.5、1.7、1.9 时,不急的人里,去取的比例")
x_stars = {}
for sigma in (0.02, 0.05, 0.10):
xs = equilibrium_threshold(sigma, 0.9); x_stars[sigma] = xs
print(f" {sigma:5.2f} {xs:6.3f} " + "、".join(f"{PHI((xs - r) / sigma):5.3f}" for r in (1.1, 1.3, 1.5, 1.7, 1.9)))
print(f" 对照:噪声趋于 0 时的 R* = {laplace_threshold(0.9):.3f};噪声越小,门槛,越接近它。")
print(" 没有噪声时(第一步),R = 1.7 的银行,也有「全部去取」这个均衡;有噪声时,只有 R 低于门槛附近,才有人去取:均衡唯一,由基本面决定。")
输出:
一、噪声趋于 0 的极限:银行到期收益低于 R*,就一定被挤兑;高于 R*,就不会。R* 取决于资产的变现能力 s(R = 1.4 时的 f* 也列出来)
s R* R = 1.4 时的 f*
0.50 6.31 0.222
0.60 3.99 0.300
0.70 2.80 0.400
0.80 2.04 0.533
0.90 1.49 0.720
0.95 1.26 0.844
(第一步的小银行,s = 0.6:R* = 3.99。这个玩具里,银行承诺的「提前取,付 1」太慷慨,提前变现的损失又大,所以只有到期收益高到 4,才不会被挤兑;数字不要当成现实,要看的是:s 越大,R* 越低。)
二、资产比较好变现的银行(s = 0.9),存款人只收到带噪声的信号:门槛 x*,以及真实收益 R 不同时,不急的人里去取的比例
噪声 sigma 门槛 x* R = 1.1、1.3、1.5、1.7、1.9 时,不急的人里,去取的比例
0.02 1.486 1.000、1.000、0.240、0.000、0.000
0.05 1.473 1.000、1.000、0.293、0.000、0.000
0.10 1.451 1.000、0.934、0.312、0.006、0.000
对照:噪声趋于 0 时的 R* = 1.495;噪声越小,门槛,越接近它。
没有噪声时(第一步),R = 1.7 的银行,也有「全部去取」这个均衡;有噪声时,只有 R 低于门槛附近,才有人去取:均衡唯一,由基本面决定。
逐段看:
- 噪声趋于 0 的极限:每个人,对"别人去取的比例",没有任何信息,认为它在 [25%, 100%] 上均匀分布(Laplace 信念)。这时,银行的到期收益,低于 R*,就一定被挤兑;高于 R*,就不会。R* 取决于资产的变现能力 s:s = 0.5 要 6.31;s = 0.6(第一步的小银行)要 3.99;s = 0.7 要 2.80;s = 0.8 要 2.04;s = 0.9 要 1.49;s = 0.95 只要 1.26。资产越好变现,越不容易被挤兑。
- 第一步的小银行,R* = 3.99:这个玩具里,银行承诺"提前取,付 1",太慷慨,提前变现的损失又大,所以只有到期收益高到 4,才不会被挤兑。这个数字,不要当成现实;要看的,是 s 越大,R* 越低。
- s = 0.9 的银行,只收到带噪声的信号:噪声 0.02、0.05、0.10 时,门槛 x* = 1.486、1.473、1.451,越来越接近噪声为 0 时的 R* = 1.495。真实收益 R = 1.1 或 1.3 时(远低于门槛),不急的人几乎全去取(100%、100%,噪声 0.10 时 93.4%);R = 1.7 或 1.9 时(远高于门槛),几乎没有人去取(0%);只有在门槛附近(R = 1.5),才是一部分人去取(24% 到 31%)。
- 均衡由基本面决定: 没有噪声时(第一步),R = 1.7 的银行,也有"全部去取"这个均衡;有噪声时,R = 1.7,几乎没有人去取。
问题 3 的答案:不再是。有噪声时,R 远高于门槛,没有人去取;“全部去取”,只在基本面确实不好时,才发生。这个结论,是"基本面决定挤兑"的一个版本:挤兑,不是纯粹的恐慌,是有基本面的门槛的。
要小心:这是我们自己写的、简化的版本(在每个门槛策略里找均衡,不是严格证明唯一);Goldstein 和 Pauzner 的模型,更完整(合约更一般,项目的收益是随机的),他们还借此算出了挤兑的概率,并比较了不同的合约。这里的 R* = 3.99,也说明了,我们的玩具合约,和他们的有多不同。
六、第四步:谁看见谁
第二步里,每个人都能看到全体的取钱比例。现实里,你只看得到身边的人:同事、邻居、群里的朋友。现在:
- 1000 个存款人,放在一个社交网络上;每个人,看得到 k 个邻居有没有取钱。
- 急用钱的人(25%),第 0 轮一定去取;不急的人,如果看到的邻居里,取钱的比例,高于自己的临界值(信念 R_i 在 [R − 0.05, R + 0.05] 上均匀分布),下一轮就去取,取了就不回头。
- 两种网络:随机网络(朋友的朋友,未必是朋友);小世界(先排成一圈,每人和左右邻居相连,朋友的朋友也是朋友,再把 5% 的连接,随机改接到别处)。
# 第五步:谁看见谁。第二步里,每个人都能看到全体的取钱比例。现实里,你只看得到身边的人:同事、邻居、群里的朋友。
# 1000 个存款人,放在一个社交网络上;每个人看得到 k 个「邻居」有没有取钱。急用钱的人(25%)第 0 轮一定去取;
# 不急的人,如果看到的邻居里,取钱的比例,高于自己的临界值(信念 R_i 在 [1.35, 1.45] 上均匀分布),下一轮就去取(取了就不回头)。
def make_network(kind, n=1000, k=8, rewire=0.05, rng=None):
"""返回每个人的邻居列表。random:随机网络(每人平均 k 个邻居);ring:先排成一圈,每人和左右各 k/2 个人相连(朋友的朋友也是朋友),再把一部分连接,随机改接到别处(rewire 是比例)"""
nbrs = [set() for _ in range(n)]
if kind == "random":
for i in range(n):
while len(nbrs[i]) < k // 2:
j = int(rng.integers(n))
if j != i: nbrs[i].add(j); nbrs[j].add(i)
else:
for i in range(n):
for d in range(1, k // 2 + 1): nbrs[i].add((i + d) % n); nbrs[(i + d) % n].add(i)
for i in range(n):
for j in list(nbrs[i]):
if j > i and rng.random() < rewire:
new = int(rng.integers(n))
if new != i and new not in nbrs[i]: nbrs[i].discard(j); nbrs[j].discard(i); nbrs[i].add(new); nbrs[new].add(i)
return [np.array(sorted(s)) for s in nbrs]
def cascade(nbrs, thr, early, seeds, rng):
"""返回最后取钱的比例,和用了几轮"""
n = len(nbrs); out = early.copy(); out[seeds] = True # 第 0 轮:急用钱的,加上被吓跑的「种子」
for rnd in range(1, 100):
seen = np.array([out[nb].mean() if len(nb) else 0.0 for nb in nbrs]) # 每个人看到的,邻居里取钱的比例
new = (~out) & (seen > thr)
if not new.any(): return out.mean(), rnd - 1
out = out | new
return out.mean(), 99
def experiment(kind, k, rbar, seeds_n=0, reps=20, w=0.05, n=1000, rewire=0.05):
"""reps 个不同的网络,每个网络上,银行的真实到期收益是 rbar(存款人的信念 R_i 在 [rbar - w, rbar + w] 上均匀分布)。
返回:最后取钱比例的平均,和「把银行拖垮(取钱比例 > 60%)」的网络所占的比例"""
rng = np.random.default_rng(78); res = []
for _ in range(reps):
nbrs = make_network(kind, n, k, rewire, rng)
early = rng.random(n) < EARLY
r = rbar - w + 2 * w * rng.random(n); thr = (r - 1) / (r / S_LIQ - 1)
seeds = rng.choice(np.flatnonzero(~early), seeds_n, replace=False) if seeds_n else np.array([], dtype=int)
res.append(cascade(nbrs, thr, early, seeds, rng)[0])
return float(np.mean(res)), float(np.mean(np.array(res) > 0.6))
print("一、平静时(没有人先被吓跑):每个人看到 k 个邻居,被局部的偶然波动,拖垮的网络占多少?(每格 20 个随机网络)")
print(" 银行真实到期收益 R: 1.4(f* = 30.0%) 1.6(f* = 36.0%) 2.0(f* = 42.9%)")
print(" 看到的邻居数 k 随机网络 小世界 随机网络 小世界 随机网络 小世界")
collapse = {}
for k in (8, 40, 100, 300, 600):
row = []
for rbar in (1.4, 1.6, 2.0):
a, b = experiment("random", k, rbar)[1], experiment("ring", k, rbar)[1]; collapse[(k, rbar)] = (a, b); row += [a, b]
print(f" {k:>5} " + " ".join(f"{x:5.0%}" for x in row))
print("(「拖垮」= 最后取钱的比例 > 60%。小世界 = 先排成一圈、每人和左右邻居相连,再把 5% 的连接随机改接;随机网络里,朋友的朋友,未必是朋友。)")
print("\n二、R = 1.6,每人看到 k = 300 个邻居:平静时没事。如果一开始,有 m 个不急的人(占 1000 人里的 m ‰)被吓跑,会怎样?")
print(" m 拖垮的网络占多少 最后取钱比例的平均")
seed_res = {}
for m in (0, 20, 50, 100, 150):
f, c = experiment("random", 300, 1.6, seeds_n=m); seed_res[m] = (f, c)
print(f" {m:>3} {c:5.0%} {f:6.3f}")
输出:
一、平静时(没有人先被吓跑):每个人看到 k 个邻居,被局部的偶然波动,拖垮的网络占多少?(每格 20 个随机网络)
银行真实到期收益 R: 1.4(f* = 30.0%) 1.6(f* = 36.0%) 2.0(f* = 42.9%)
看到的邻居数 k 随机网络 小世界 随机网络 小世界 随机网络 小世界
8 100% 100% 100% 100% 100% 100%
40 100% 100% 100% 100% 20% 90%
100 100% 100% 75% 70% 0% 0%
300 100% 55% 0% 0% 0% 0%
600 55% 15% 0% 0% 0% 0%
(「拖垮」= 最后取钱的比例 > 60%。小世界 = 先排成一圈、每人和左右邻居相连,再把 5% 的连接随机改接;随机网络里,朋友的朋友,未必是朋友。)
二、R = 1.6,每人看到 k = 300 个邻居:平静时没事。如果一开始,有 m 个不急的人(占 1000 人里的 m ‰)被吓跑,会怎样?
m 拖垮的网络占多少 最后取钱比例的平均
0 0% 0.252
20 10% 0.344
50 85% 0.892
100 100% 1.000
150 100% 1.000
逐段看:
- 看到的人越少,越容易被偶然吓垮:R = 1.4(f* = 30%):k = 8、40、100、300,随机网络,100% 被拖垮,k = 600 也有 55%。原因:你看到 k 个邻居,邻居里取钱的比例,本身就有随机的波动(急用钱的人,随机地分布);k 越小,波动越大;一旦有人,因为偶然多看到几个取钱的邻居,而决定去取,他的邻居们,就多看到一个取钱的人……一串连锁反应。
- 银行越好,需要的 k 越小:R = 1.6(f* = 36%):k = 100 时,75% 被拖垮,k = 300 时 0%;R = 2.0(f* = 42.9%):k = 40 时,20%(小世界 90%),k = 100 时 0%。
- 两种网络,没有一致的方向:R = 1.4、k = 300:随机网络 100%,小世界 55%;R = 2.0、k = 40:随机 20%,小世界 90%。朋友的朋友也是朋友,有时帮忙(把恐慌,困在一个小圈子里),有时添乱(小圈子里,大家互相印证),取决于参数。
- 一小撮恐慌,就是一道门槛(R = 1.6,k = 300,平静时 0% 被拖垮):一开始有 20 个不急的人(占 1000 人的 2%)被吓跑,10% 的网络被拖垮;50 个,85%;100 个,100%。
问题 4 的答案:看银行有多好。R = 1.6:k 到 300;R = 1.4(离挤兑只有 5 个百分点):k 到 600,也不够稳。你看到的信息越少,一个正常的银行,越容易被局部的、偶然的波动,吓成一个系统性的挤兑。
证据:Rajkamal Iyer 和 Manju Puri 2012 年(American Economic Review,102 卷 4 期,1414–1445 页)用印度古吉拉特邦的一家合作银行的存款人数据(2001 年,该地区最大的合作银行因贷款欺诈倒闭之后,别的合作银行,遭遇了挤兑;他们研究的这家,和倒闭的银行没有关系,自身是偿付能力充足的),发现:没有保险的存款人,最容易去取钱;社交网络,很重要,但存款人和银行的关系越长、越深(比如,有过贷款),越不容易去取。(我只核对了摘要。)这和我们的模拟,方向一致:谁看见谁,很重要。
七、第五步:办法
同一个小银行,看几种办法,能不能把"坏的均衡"去掉,代价是什么。
# 第五步:办法。同一个小银行(N = 100,s = 0.6,R = 1.4,急用钱的 25%),看几种办法,能不能把「坏的均衡」去掉,代价是什么。
print("一、不同的办法,对「银行能承受的取钱比例」的影响(这个比例,超过了,坏均衡就出现)")
print(" 办法 银行能承受的取钱比例 坏均衡还在吗")
print(f" 什么也不做 {threshold():6.1%} 在(只比正常的 25% 多 {threshold() - EARLY:.1%})")
# 1. 存款保险(全额):政府保证,不管别人怎么做,每个人该拿的都拿到。
print(" 全额存款保险 不再取决于别人 不在(在这个模型里)")
# 2. 有限额的存款保险:每个账户,保到 cap;超过的部分,没有保险,这部分的存款人,才会参与挤兑
sigma, mu = 2.0, 0.0 # 账户余额 ~ 对数正态;平均余额 = e^(mu + sigma²/2)
mean_bal = np.exp(mu + sigma ** 2 / 2)
def uninsured_share(cap):
"""没有被保险保住的余额,占全部余额的比例:E[(X - cap)+] / E[X]"""
d2 = (mu - np.log(cap)) / sigma; d1 = d2 + sigma
return PHI(d1) - cap / mean_bal * PHI(d2)
u_star = (threshold() - EARLY) / (1 - EARLY)
print(f"\n二、有限额的存款保险:保险保到 cap(账户余额服从对数正态,平均余额 {mean_bal:.1f},大账户很多)。没保住的余额占 u;")
print(f" 最坏的情形:没保住的余额全去取,总取钱比例 = 0.25 + 0.75 × u。坏均衡可能出现,当且仅当 0.25 + 0.75 × u > f* = {threshold():.3f},也就是 u > {u_star:.1%}")
print(" 保险的限额 cap 没保住的余额占比 u 最坏的取钱比例 坏均衡还可能出现吗")
for cap in (1, 5, 20, 50, 200, 1000):
u = uninsured_share(cap); worst = EARLY + (1 - EARLY) * u
print(f" {cap:>5}(平均余额的 {cap / mean_bal:5.2f} 倍) {u:6.1%} {worst:6.3f} {'可能' if worst > threshold() else '不可能'}")
# 3. 暂停兑付:银行宣布,第 1 期,最多只付给 K 比例的人(K 略低于 f*)。
print("\n三、暂停兑付:第 1 期,最多只付给 K 比例的存款人,其余的,等到第 2 期。急用钱的比例,其实是随机的(15% 到 35% 均匀分布)")
rng = np.random.default_rng(78); early_draw = rng.uniform(0.15, 0.35, 200000)
print(" K 等下去(f = K)比去取(1)好多少 急用钱,却没拿到钱的存款人:占全部存款人的比例")
for K in (0.28, 0.29, 0.30, 0.32):
print(f" {K:.2f} {wait_value(K) - 1:+.3f} {np.mean(np.maximum(early_draw - K, 0)):.2%}")
print(f" (不暂停、又发生了挤兑:每个人平均只拿到 0.6;而 K = 0.29 时,平均有 {np.mean(np.maximum(early_draw - 0.29, 0)):.2%} 的存款人,在急用钱的时候,拿不到钱。)")
# 4. 最后贷款人:央行愿意按 s' 的比例,替银行把资产「变现」(按一个比市场价更高的价格,借出钱来,银行不用甩卖)
print("\n四、最后贷款人:央行愿意按每 1 份资产 s' 的价格,借钱给银行(银行不用以 0.6 甩卖):")
print(" s' 银行能承受的取钱比例 f* 坏均衡")
for sp in (0.6, 0.7, 0.8, 0.9, 1.0):
fs = threshold(R_MAT, sp)
print(f" {sp:.1f} {min(fs, 1.0):6.1%} " + ("还在" if fs < 1 - 1e-9 else "不在(资产随时能按 1 变现)"))
输出:
一、不同的办法,对「银行能承受的取钱比例」的影响(这个比例,超过了,坏均衡就出现)
办法 银行能承受的取钱比例 坏均衡还在吗
什么也不做 30.0% 在(只比正常的 25% 多 5.0%)
全额存款保险 不再取决于别人 不在(在这个模型里)
二、有限额的存款保险:保险保到 cap(账户余额服从对数正态,平均余额 7.4,大账户很多)。没保住的余额占 u;
最坏的情形:没保住的余额全去取,总取钱比例 = 0.25 + 0.75 × u。坏均衡可能出现,当且仅当 0.25 + 0.75 × u > f* = 0.300,也就是 u > 6.7%
保险的限额 cap 没保住的余额占比 u 最坏的取钱比例 坏均衡还可能出现吗
1(平均余额的 0.14 倍) 91.0% 0.932 可能
5(平均余额的 0.68 倍) 74.2% 0.806 可能
20(平均余额的 2.71 倍) 51.1% 0.633 可能
50(平均余额的 6.77 倍) 34.7% 0.510 可能
200(平均余额的 27.07 倍) 14.9% 0.362 可能
1000(平均余额的 135.34 倍) 3.6% 0.277 不可能
三、暂停兑付:第 1 期,最多只付给 K 比例的存款人,其余的,等到第 2 期。急用钱的比例,其实是随机的(15% 到 35% 均匀分布)
K 等下去(f = K)比去取(1)好多少 急用钱,却没拿到钱的存款人:占全部存款人的比例
0.28 +0.037 1.23%
0.29 +0.019 0.90%
0.30 +0.000 0.63%
0.32 -0.039 0.23%
(不暂停、又发生了挤兑:每个人平均只拿到 0.6;而 K = 0.29 时,平均有 0.90% 的存款人,在急用钱的时候,拿不到钱。)
四、最后贷款人:央行愿意按每 1 份资产 s' 的价格,借钱给银行(银行不用以 0.6 甩卖):
s' 银行能承受的取钱比例 f* 坏均衡
0.6 30.0% 还在
0.7 40.0% 还在
0.8 53.3% 还在
0.9 72.0% 还在
1.0 100.0% 不在(资产随时能按 1 变现)
逐段看:
- 全额存款保险:政府保证,不管别人怎么做,每个人该拿的都拿到:等下去的收益,不再取决于别人,坏均衡消失(在这个模型里)。代价,是第 35 讲 6.1 节说的:银行可能冒更大的风险(道德风险);这个模型里,没有算它。
- 有限额的存款保险:只有没被保险保住的余额,才参与挤兑。最坏的情形,没保住的余额,全部去取:总取钱比例 = 0.25 + 0.75 × u(u 是没保住的余额的占比)。要想不超过 f* = 30%,需要 u 低于 6.7%。
- 假设账户余额服从对数正态(很不平均:大账户很多,平均余额 7.4):限额是平均余额的 0.14、0.68、2.7、6.8、27 倍时,没保住的余额占 91%、74%、51%、35%、15%,坏均衡都可能出现;要到限额是平均余额的 135 倍(u = 3.6%),才不可能。(练习 6:不平均的程度,一变,数字就变;余额分布不那么不平均时,只要保到平均余额的 4 倍左右。)
- 所以,限额的作用,不是"保住小存款人",而是"让没保住的余额,不够多":如果大账户占了存款的大头,限额再高,也不够。
- 暂停兑付:银行宣布,第 1 期,最多只付给 K 比例的存款人。K = 0.29:等下去,比去取还好 0.019,没有人想抢先去取,坏均衡消失;代价:急用钱的比例,其实是随机的(15% 到 35%),超过 K 的,那部分真急用钱的人,拿不到钱:K = 0.29 时,平均 0.90% 的存款人。K = 0.30:刚好一样;K = 0.32:等下去更差,又会有人想去取。(对照:不暂停,又发生挤兑,每个人平均只拿到 0.6。)
- 最后贷款人:央行愿意按每 1 份资产 s’ 的价格,借钱给银行(银行不用以 0.6 甩卖):s’ = 0.6:门槛 30.0%;0.7:40.0%;0.8:53.3%;0.9:72.0%;1.0:资产随时能按 1 变现,不会挤兑。越慷慨,门槛越高。 代价,在这个模型之外:央行借出去的钱,如果银行其实资不抵债,就变成了救助(第 35 讲 6.1 节讨论过);而且,银行知道央行会救,可能冒更大的风险。
问题 5 的答案:要保到"没保住的余额,不超过 6.7%",用限额的话,取决于账户余额有多不平均:很不平均的时候,限额要非常高。
问题 6 的答案:暂停兑付的代价,是真急用钱的人,拿不到钱(0.9% 的存款人);最后贷款人的代价,是道德风险和救助的风险,在模型之外。
八、这个实验说明了什么,没说明什么
说明了:
- 银行有三个均衡,其中一个是刀刃,缓冲很薄(5 个百分点)。
- 看法的分歧,让银行更脆弱:最悲观的人,把缓冲一点一点吃掉,超过一个分界,平静就不再是均衡。
- 有噪声、有基本面,挤兑就不是纯粹的恐慌:均衡由基本面决定,资产越好变现,越不容易挤兑。
- 信息的结构,很重要:你看到的人越少,越容易被局部的偶然波动,吓成系统性的挤兑;一小撮恐慌,就能越过门槛。
- 每种办法,都有代价:存款保险(道德风险;限额要够高)、暂停兑付(真急用钱的人拿不到钱)、最后贷款人(救助)。
没说明:
- 这是一个小银行的玩具:一个银行,一次性;没有银行之间的联系(传染),没有银行主动选择资产的风险(道德风险),没有真实的资产定价。
- 现代的挤兑,不只是零售存款人的挤兑:第 35 讲提过,2007 到 2008 年的恐慌,主要是批发融资(回购市场)的挤兑;硅谷银行 2023 年,是大额存款人,在社交网络里,一两天内的集体撤离。
- “急用钱"是外生的、固定的;现实里,它自己也会变。
- “基本面"和"恐慌”,很难分开:悲观的人,可能是对的。
九、和前面、后面的联系
- 第 17 讲:临界规模、自我实现的预期,是同一类结构;挤兑,是它的反面(“大家都撤”)。
- 第 18 讲:纳什均衡、多重均衡、协调博弈。
- 第 20 讲:存款人看不清银行的资产,是信息不对称。
- 第 30 讲:银行的资产负债表,借短放长。
- 第 35 讲:这个实验,是它 2.3 节的承诺;硅谷银行 2023 年,和包商银行 2019 年的案例,在那里。
- 实验 73、76:格子和网络上的集体行为,一个看不见的"门槛”,决定了结局。
- 实验 79:用真实数据检验有效市场(随机游走)。
十、练习
下面的练习,都可以在上面的代码上改几个数字做出来。提示里的数字,都是我跑过的。
练习 1(资产好坏)。 第一步里,R 改成 1.2 和 1.6,临界值 f* 分别是多少?平静(f = 25%)还是不是一个均衡?
提示:R = 1.2:f* = 20.0%,低于正常的 25%;平静时,等下去只拿 0.933,不如去取:平静不是均衡,只有挤兑。R = 1.6:f* = 36.0%,平静时,等下去拿 1.244,缓冲有 11 个百分点。
练习 2(急用钱的人更多)。 第一步里,急用钱的比例(EARLY),从 25% 改成 40%(R = 1.4)。平静还是均衡吗?
提示:f* 不变(30%),但正常的取钱比例,已经是 40%,高于它:f = 40% 时,等下去只拿 0.778,不如去取,平静不是均衡。银行的缓冲,不只取决于资产(f*),还取决于"正常情况下,有多少人需要钱"。
练习 3(看法的分界)。 第二步里,w = 0.11 和 w = 0.12,平静时,最后的取钱比例各是多少?最悲观的人的临界值各是多少?分界在哪里?
提示:w = 0.11:最悲观的人的临界值 0.2522(高于 25%),平静稳定在 0.250;w = 0.12:0.2471(低于 25%),一路走到 1.000。分界是 f*(R) = 25% 时的 R:R = 1.2857,也就是 w = 1.4 − 1.2857 ≈ 0.114。
练习 4(噪声和变现能力)。 第三步里,s = 0.8、噪声 0.05 的银行,门槛 x* 是多少,和噪声为 0 时的 R*(2.04)比怎么样?s = 0.9、噪声 0.2 呢?
提示:
equilibrium_threshold(0.05, 0.8)= 2.007,比 R* = 2.04 略低;equilibrium_threshold(0.2, 0.9)= 1.407,离 R* = 1.495 更远。噪声越大,门槛离噪声为 0 时的 R* 越远(越低)。
练习 5(谁看见谁)。 第四步里,R = 1.6,k = 100 和 k = 200,随机网络和小世界,被拖垮的比例各是多少?R = 1.8、k = 150 呢?
提示:
experiment("random", k, R)和experiment("ring", k, R)(每格 20 个网络):R = 1.6,k = 100:随机 75%,小世界 70%;k = 200:随机 15%,小世界 5%;R = 1.8,k = 150:随机 0%,小世界 5%。差别不大,也没有稳定的方向。
练习 6(账户有多不平均)。 第五步里,账户余额的对数标准差 sigma,从 2.0 改成 1.0。限额要保到平均余额的多少倍,没保住的余额,才低于 6.7%?
提示:σ = 2.0:限额要到约 529(平均余额的 71.6 倍);σ = 1.0:只要约 6.7(平均余额的 4.1 倍)。(第五步表里,限额 1000 才让 u 降到 3.6%,是 σ = 2.0 的数;σ 越大,大账户占存款的比例越大,限额越要高。)
十一、局限
- 一个银行、一次性;没有银行之间的联系、没有银行选择资产风险、没有真实的价格。
- 存款人的行为规则(第二步的"看上一期的取钱比例",第四步的"看邻居")是我们假设的;真实的存款人,会用更多的信息。
- 全局博弈:我们只在"信号低于门槛,就去取"的策略里,找了均衡;玩具合约的 R* = 3.99,不是现实。
- 网络:随机网络和小世界,只是两种简单的结构;真实的社交网络,有中心人物(比如几个有影响力的投资人,在一个群里发消息),这里没有。
- 没有:存款人之间的借贷关系、银行的资本(第 35 讲 6.2 节)、政策的反应速度。
参考
- Diamond, D. W., & Dybvig, P. H. (1983). Bank runs, deposit insurance, and liquidity. Journal of Political Economy, 91(3), 401–419.
- Morris, S., & Shin, H. S. (1998). Unique equilibrium in a model of self-fulfilling currency attacks. American Economic Review, 88(3), 587–597.
- Goldstein, I., & Pauzner, A. (2005). Demand-deposit contracts and the probability of bank runs. Journal of Finance, 60(3), 1293–1327.
- Granovetter, M. (1978). Threshold models of collective behavior. American Journal of Sociology, 83(6), 1420–1443.
- Iyer, R., & Puri, M. (2012). Understanding bank runs: The importance of depositor-bank relationships and networks. American Economic Review, 102(4), 1414–1445.