第2章:无常损失量化
说实话,无常损失这个概念,我在刚接触DeFi时也踩过坑。那时候觉得做LP就是躺着赚钱,直到有一次自己算了笔账——嗯,才发现事情没那么简单。
这一章,我们就来把无常损失彻底量化。从公式推导到代码实现,一步到位。
2.1 无常损失的本质
先问个问题:为什么会有无常损失?
说白了,是因为AMM的定价机制。当外部市场价格变化时,套利者会进来把池子里的价格扳平。这个过程,LP就吃亏了。
我习惯用一个简单例子来理解:
- 你往ETH/USDC池子里各放50%价值的资产
- ETH价格翻倍了
- 套利者会买走你的ETH,直到池子价格跟外部一致
- 最后你手里的ETH变少了,USDC变多了
- 总价值?比单纯持有要少
这个差值,就是无常损失。
2.2 公式推导
我们来一步步推。假设一个简单的恒定乘积做市商:
x * y = k
其中x是代币A的数量,y是代币B的数量。k是常数。
初始价格P₀ = y₀ / x₀
当价格变为P₁时,新的数量关系是:
x₁ = √(k / P₁)
y₁ = √(k * P₁)
这个推导其实很简单。因为x * y = k,且y/x = P₁,解方程组就行。
那么,LP的总价值V_LP = x₁ * P₁ + y₁ = 2 * √(k * P₁)
而如果单纯持有,价值V_hold = x₀ * P₁ + y₀ = 2 * √(k * P₀) * (1 + r)/2?
等等,我换个更直观的写法。
设价格变化倍数为r = P₁ / P₀
那么:
V_LP = 2 * √(k * P₁) = 2 * √(k * P₀ * r) = 2 * √(k * P₀) * √r
V_hold = x₀ * P₁ + y₀ = (y₀/P₀) * P₁ + y₀ = y₀ * (r + 1)
因为初始时y₀ = √(k * P₀),所以:
V_hold = √(k * P₀) * (r + 1)
无常损失比率IL = (V_LP - V_hold) / V_hold
代入化简后得到:
无常损失公式:
IL = (2√r) / (r + 1) - 1
其中r = P₁ / P₀,即价格变化倍数
这个公式看着简单,但信息量很大。我当年第一次推导出来时,盯着看了半天——原来无常损失只跟价格变化比例有关,跟具体价格数值无关。
2.3 不同价格波动下的损失模拟
有了公式,我们来算算实际数字。
| 价格变化 | r值 | 无常损失 |
|---|---|---|
| ±1% | 1.01或0.99 | 约0.005% |
| ±5% | 1.05或0.95 | 约0.12% |
| ±10% | 1.10或0.90 | 约0.48% |
| ±25% | 1.25或0.80 | 约2.94% |
| ±50% | 1.50或0.67 | 约10.06% |
| ±100% | 2.00或0.50 | 约28.43% |
| ±200% | 3.00或0.33 | 约50.00% |
看到没?价格波动10%以内,损失不到0.5%。但波动翻倍到100%时,损失直接跳到28%。
我做过一个实盘回测,在2021年5月的暴跌行情中,某个ETH-USDC池子的LP在三天内承受了约35%的无常损失——跟公式算出来的基本吻合。
我的经验:如果预期价格波动超过20%,一定要考虑对冲。否则手续费收益可能覆盖不了无常损失。
2.4 Python计算无常损失
理论讲完了,上代码。我习惯用Python做这类计算,因为可视化方便。
import numpy as np
import matplotlib.pyplot as plt
def impermanent_loss(r):
"""
计算无常损失比率
r: 价格变化倍数 (P1/P0)
"""
return (2 * np.sqrt(r)) / (r + 1) - 1
# 模拟不同价格变化
price_changes = np.linspace(0.1, 5.0, 100) # 从-90%到+400%
losses = impermanent_loss(price_changes)
# 绘制曲线
plt.figure(figsize=(10, 6))
plt.plot(price_changes, losses * 100, 'b-', linewidth=2)
plt.axhline(y=0, color='gray', linestyle='--')
plt.axvline(x=1, color='gray', linestyle='--')
plt.xlabel('价格变化倍数 (r)')
plt.ylabel('无常损失 (%)')
plt.title('无常损失 vs 价格变化')
plt.grid(True, alpha=0.3)
plt.show()
这段代码会生成一条曲线。你会发现:
- r=1时损失为0(价格没变)
- 曲线不对称——价格上涨和下跌相同幅度,损失是一样的
- r越偏离1,损失增长越快
我再给一个实用函数,用来计算具体金额:
def calculate_il_amount(initial_value, price_change_pct):
"""
计算无常损失的具体金额
参数:
initial_value: 初始投入总价值(美元)
price_change_pct: 价格变化百分比(如50表示涨50%)
返回:
il_amount: 无常损失金额
hold_value: 单纯持有的价值
lp_value: LP池中的价值
"""
r = 1 + price_change_pct / 100
il_ratio = impermanent_loss(r)
hold_value = initial_value * (r + 1) / 2
lp_value = initial_value * (1 + il_ratio)
il_amount = hold_value - lp_value
return il_amount, hold_value, lp_value
# 示例:投入10000美元,ETH涨了50%
il, hold, lp = calculate_il_amount(10000, 50)
print(f"单纯持有价值: ${hold:.2f}")
print(f"LP池价值: ${lp:.2f}")
print(f"无常损失: ${il:.2f}")
输出结果:
单纯持有价值: $15000.00
LP池价值: $13489.42
无常损失: $1510.58
嗯,10000美元本金,涨50%的情况下,损失了1510美元。这个数字不小。
注意:这里的计算假设了手续费收益为0。实际中,手续费可以部分抵消无常损失。但别指望手续费能完全覆盖——我在一个高波动池子里试过,手续费收益只有无常损失的60%左右。
2.5 知识体系总览
下面这张图,是我自己整理的无常损失量化知识框架:
这张图把整个知识体系串起来了。从公式推导出发,到模拟验证,再到代码实现,最后落地到实际应用。我个人做策略时,就是按这个流程来的。
2.6 避坑指南
最后分享几个我踩过的坑:
我曾经犯过的错:
- 以为无常损失只跟价格涨跌方向有关——其实涨和跌相同幅度,损失是一样的
- 忽略了手续费收益的抵消作用——但别高估它,高波动时手续费远远不够
- 用简单线性思维去估算——无常损失是非线性的,波动越大损失增长越快
记住一句话:无常损失不是「无常」的,它是完全可量化的。算清楚了再进场,比什么都强。
公众号:蓝海资料掘金营,微信deep3321