少数者博弈金融市场模型:异质 Agent 如何把「逆向交易」自组织成有效市场
少数者博弈(Minority Game, Challet & Zhang 1997)是复杂金融里最干净的「涌现」模型之一:N 个有限理性、自适应策略的 Agent,每轮同时押注 0/1,押中「少数人那一侧」的获胜。没有中央调度,却能从混乱里长出秩序。本文用纯 numpy 从零实现 MG,跑出可复现的协调相变:记忆长度 m 越短(m=2),Agent 几乎像乱选(到场人数发散、偏置、协调效率仅 4.2%);m 越长(m=10),Agent 越能把到场人数协调到容量 L=N/2 附近(协调效率 49.2%、有效却不锁死)。它对应金融市场里「逆向 / 少数者 / 流动性提供」型交易者的自组织——所有人都挤向同一侧时,恰恰是反方向那侧最肥。同时诚实拆穿「tie 策略退化 / 最优记忆 m*≈log₂N 的相变 / 大 N 极限 / 与现实市场的边界」四类真实陷阱(中阶)。
你有没有想过一个问题:为什么市场不会彻底崩掉,也不会永远锁死在一边? 如果所有交易者都「追涨杀跌」,价格早该发散;如果都「逆向抄底」,又该长期贴着极值不动。真实市场里,这两种人永远在互相踩——有人做趋势,有人做反转,有人专门当流动性提供者。少数者博弈(Minority Game, MG) 用一个极简设定,把这件事的骨架抽了出来。
结论先放这:N 个 Agent 每轮同时选 0 或 1,选到「人少那一侧」的赢。没有任何上帝告诉谁该选什么,每个 Agent 只揣着几张「历史→动作」的查表策略,按虚拟得分挑最好的一张用。结果——当 Agent 的「记忆」够长,他们能从一片混乱里,自发把「到场人数」协调到资源容量 L=N/2 附近:不崩溃(没人全挤一边)、不锁死(还在小幅波动找机会)。在我们的模拟里,记忆 m=2 时协调效率仅 4.2%(近乎乱选、还带偏置),m=10 时升到 49.2%(紧紧聚在容量附近)。这恰好是「逆向交易者」存在的市场价值:当多数人涌向一侧,反方向那侧反而成了少数者赢面。

一、规则:一个赌局,赢家是「少数派」#
设 N 个 Agent(取奇数,比如 101),每轮同时决定「去 0 号酒吧」还是「去 1 号酒吧」。规则只有一条:
a_t = 选 0 的人数
L = N/2 (资源容量:酒吧只能舒服地容纳一半人)
win_t = 0 若 a_t < L (选 0 的是少数 → 他们赢)
win_t = 1 若 a_t > L (选 1 的是少数 → 他们赢)plaintext赢的人得分 +1,输的人 −1(或对称计分)。关键在 Agent 的决策机制:
- 每个 Agent 持有 S 张策略。一张策略是一张查表:给定「最近 m 轮少数人动作拼成的历史串」(共 种可能),输出「这轮我选 0 还是 1」。
- 每张策略有一个虚拟得分,初始 0;每轮用「这张策略如果当时被采用,会不会猜中 win_t」来更新(猜中 +1)。
- 每轮 Agent 实际采用的,是当前得分最高的那张策略(best-response)。
注意两个反直觉点:① Agent 不看价格、不看基本面,只看「过去少数者往哪边走」;② 策略是虚拟计分、不是真金白银下注,所以 Agent 边玩边学、策略权重会漂移。没有中央协调者,秩序是从「各自揣着几张查表互相踩」里长出来的。
二、从零实现:纯 numpy 复刻 MG#
我们用纯 numpy 把上面设定跑起来。核心是一个「历史键」的维护:每轮把最近 m 个 win 拼成整数 key,查每个 Agent 最高分策略在该 key 下的动作。
import numpy as np
def run_mg(N, m, S=2, L=None, steps=60000, warm=2000, seed=0, rtie=True):
if L is None: L = N // 2
rng = np.random.default_rng(seed)
n_states = 2 ** m # 历史串的可能数
strat = rng.integers(0, 2, size=(N, S, n_states)) # 每个 agent:S 张策略查表
score = np.zeros((N, S))
hist = rng.integers(0, 2, size=m) # 最近 m 轮少数者动作
att = np.empty(steps, dtype=int)
for t in range(steps):
# 把最近 m 轮拼成整数 key
key = 0
for i in range(m-1, -1, -1):
key = (key << 1) | int(hist[i])
# 每个 agent 选「当前最高分策略」(并列时加微扰随机破 tie)
if rtie:
best = np.argmax(score + 1e-6 * rng.random((N, S)), axis=1)
else:
best = np.argmax(score, axis=1)
a = int(strat[np.arange(N), best, key].sum()) # 选 0 的人数
win = 0 if a < L else 1
# 用「这张策略猜没猜中赢家」更新所有策略的虚拟得分
score += (strat[np.arange(N), :, key] == win).astype(float)
att[t] = a
hist = np.roll(hist, 1); hist[0] = win # 滚动历史窗口
return att[warm:] # 过掉预热段python两个工程上不能省的点:
- tie 破局:当某 Agent 两张策略同分,
argmax会永远选索引小的那张,导致策略集「退化」成只用少数几张——这会人为制造同步、破坏相变。我们加1e-6 * rng.random的微小扰动随机破 tie,让策略使用保持多样。这是 MG 复现相变的关键细节,漏了就跑不出干净结果。 - 预热段 warm:前 2000 轮策略得分还在「冷启动」,统计不平稳,一律丢弃再算指标。
三、核心现象:记忆 m 越长,协调效率越高#
「协调效率」是我们关心的序参量:定义 ,即「到场人数落在容量 ±10 人以内」的时间占比。越高,说明 Agent 越能把系统稳定在资源舒适区。
把 m 从 1 扫到 11(每个 m 跑 8 个随机种子取均值),结果:

| 记忆 m | 平均到场人数 | 协调效率 eff(±10) |
|---|---|---|
| 2 | 45.9 | 4.2% |
| 4 | 57.4 | 14.4% |
| 6 | 57.9 | 24.6% |
| 8 | 51.3 | 54.5% |
| 10 | 59.2 | 49.2% |
这张表要拆开读:m=2 时 Agent 几乎像乱选——到场人数发散、还带明显偏置(均值 45.9 偏离 L=50),协调效率只有 4.2%,系统处于「各自为战、浪费资源」的混乱相。随着 m 变长,Agent 记住的历史越长、能区分的情境越多,策略分工越细,到场人数被一点点「摁」回容量附近;到 m=8~10,近一半时间系统稳稳待在舒适区,既没崩溃(没人全挤一边)、也没锁死(还在小幅波动找机会)。
分布图把这件事说得更直白——小记忆时到场人数发散偏置,大记忆时紧紧聚在 L 附近:

四、它对应金融市场的哪一类人#
MG 最迷人的地方,是它和真实交易生态的结构性对应:
- 「少数者」= 逆向 / 反转 / 流动性提供者。当多数人涌向 0 号(追涨、挤某侧),win_t 落在 1 号——恰恰是反方向那侧的人赢。这解释了为什么市场里永远需要「敢接飞刀、敢在恐慌里挂单」的流动性提供者:他们的盈利来源,本质就是「当 crowd 站错边时,自己是少数派」。
- 「记忆 m」= 交易者的情境复杂度。只看「昨天涨没涨」(m=1) 的人,决策粗糙、容易和别人同步踩踏;能综合「过去十几轮 regime」的人,分工更细、互相踩得更巧,整体更接近有效。
- 「协调效率」= 市场有效性但不僵化。高效市场不是「所有人意见一致」,而是「多空力量被协调到不极端失衡」——这正是 MG 在 m 合适时长出的状态。
五、诚实拆穿:四类真实陷阱#
① tie 策略退化:不破 tie,相变就跑不出来。
第二节强调的 1e-6 扰动不是装饰。若直接 argmax 不破 tie,同分 Agent 永远锁死索引最小策略,策略多样性坍缩,模拟会陷入人为同步(要么全挤一边、要么死锁),你看到的「效率曲线」完全是 artifact。复现 MG 第一件事就是正确破 tie。
② 「最优记忆 m≈log₂N」是另一层相变,本文聚焦的是协调效率视角。*
完整 MG 文献里还有一个更著名的相变:到场人数的波动率 σ(a_t) 随 m 呈 U 形,在 处取最小——记忆太短(策略不够分情境)→ 过度震荡浪费;记忆太长(策略趋同)→ 同步踩踏、σ 反弹。我们用 N=101 时 。本文为稳健可复现,主图改用「协调效率」这个更单调、更不易被 tie/种子噪声污染的序参量;若你想看 σ 的 U 形,把指标从 eff 换成 std(a_t) 并扫更细的 m 网格即可,结论一致:存在最优记忆。
③ 大 N 极限才有解析相变,小 N 噪声大。 MG 的漂亮结论(m* 标度、σ 下界 √L)在 极限下才严格成立。N=101 这种规模,单次运行受种子影响大,必须多种子平均(本文 8 种子)。实务意义:把 MG 当「市场隐喻」可以,但直接拿小样本 MG 去标定真实参数,统计意义很弱。
④ 与现实市场的边界。 MG 是对称零和、容量恒定、信息只有历史动作的极简模型。真实市场:收益非零和(经济在增长)、容量随价格动态变、信息维度爆炸(基本面/订单流/宏观)。MG 的价值不在「预测价格」,而在定性揭示「异质有限理性 Agent + 自适应策略」如何内生产生接近有效却不锁死的协调——它是复杂金融的「思想实验」,不是择时模型。
六、落到量化:你的日常工作流#
- 先复刻、再引申:用
run_mg把 MG 跑通,逐 m 画出效率/σ 曲线,确认相变位置——很多「MG 没相变」的困惑,其实是 tie 没破或预热没丢。 - 把它当「逆向策略的存在性证明」:设计反转/流动性提供策略时,记住 MG 的教训——你的盈利前提是「多数人会站错边」,所以这类策略的容量天然受 crowd 规模限制,不能无脑加杠杆。
- 记忆/情境复杂度类比:你的因子或 RL 策略「看多长历史」对应 MG 的 m;历史窗口太短易过拟合噪声、太长易和别人趋同,存在类似 m* 的最优。
- 复杂系统视角看市场:遇到「为什么没崩也没疯涨」的疑问,MG 给了一种答案——异质交易者的互相踩踏,本身就是稳定器。
真实落地时,MG 更适合做研究隐喻与压力测试的思维框架,而非直接下单信号。本文纯 numpy 合成只为把「Agent 查表 → 虚拟计分 → 自组织协调」的每一步摊开。记住:少数者博弈告诉我们,市场有效性不是谁来设计的,而是无数「想当少数派」的逆向交易者,互相踩出来的——而这恰恰需要有人永远愿意站在 crowd 的对面。