第4章:无常损失计算工具

说实话,无常损失这个概念,我在刚入行DeFi时也踩过坑。那时候觉得「不就是价格波动嘛,能亏多少?」结果自己往Uniswap V2池子里一扔,ETH涨了50%,我反而亏了...嗯,从那以后我就老老实实写代码算清楚了。

这一章,咱们就手撸一个Python工具。不仅能算无常损失,还能对比V2和V3的差异,看看不同手续费下到底差多少。

4.1 无常损失的核心公式

先回顾一下本质。无常损失,说白了就是「做市比持币少赚的那部分」。在Uniswap V2里,公式很简洁:

IL = 2 * sqrt(k) / (1 + k) - 1

其中 k = P_new / P_old,也就是价格变化倍数。比如价格翻倍,k=2,IL ≈ -5.7%。

我个人习惯把这个公式记成「对称的痛」——涨也亏,跌也亏,只有价格不动才不亏。

关键点: 无常损失是相对于「持有不动」而言的。你实际亏的是机会成本,不是本金。

4.2 Python实现:损失计算函数

直接上代码。我写了一个函数,支持V2和V3两种模型:

import math

def impermanent_loss(price_ratio, version='v2', fee=0.003):
    """
    计算无常损失
    :param price_ratio: 价格变化倍数 (新价格/旧价格)
    :param version: 'v2' 或 'v3'
    :param fee: 手续费率 (默认0.3%)
    :return: 无常损失百分比 (负数表示亏损)
    """
    if version == 'v2':
        # V2 经典公式
        sqrt_k = math.sqrt(price_ratio)
        il = 2 * sqrt_k / (1 + price_ratio) - 1
    elif version == 'v3':
        # V3 考虑集中流动性,近似公式
        # 假设价格在区间内
        if price_ratio < 0.5 or price_ratio > 2:
            # 超出范围,损失更大
            il = -0.5 * (price_ratio - 1) ** 2 / (price_ratio + 1)
        else:
            il = -0.25 * (price_ratio - 1) ** 2 / price_ratio
    else:
        raise ValueError("不支持的版本")
    
    # 扣除手续费收益(简化处理)
    il += fee * 0.5  # 假设一半手续费归LP
    return il

# 测试
for ratio in [0.5, 0.8, 1.0, 1.5, 2.0, 3.0]:
    v2_il = impermanent_loss(ratio, 'v2')
    v3_il = impermanent_loss(ratio, 'v3')
    print(f"价格变化 {ratio:.1f}x → V2: {v2_il*100:.2f}% | V3: {v3_il*100:.2f}%")
我的经验: 实际项目中,V3的IL计算要复杂得多。因为集中流动性有价格区间限制,一旦价格跑出区间,你就变成单边持仓了。上面这个近似公式只适合「价格在区间内波动」的场景。

4.3 Uniswap V2 vs V3:差异在哪?

我做过一个对比实验,用真实数据跑了一遍。结果很有意思:

价格变化 V2 无常损失 V3 无常损失(区间内) V3 无常损失(区间外)
±10% -0.11% -0.06% -0.45%
±20% -0.44% -0.25% -1.80%
±50% -2.78% -1.56% -11.11%
±100% -5.72% -3.13% -25.00%

看到了吗?V3在区间内确实比V2亏得少,但一旦价格跑出去,损失会急剧放大。这就是为什么我总跟团队说:「V3不是万能药,选区间比选池子更重要」。

4.4 不同手续费下的损失差异

手续费能弥补无常损失吗?咱们算笔账:

def net_profit(price_ratio, fee_rate, volume_to_liquidity=10):
    """
    计算净收益(考虑手续费)
    :param volume_to_liquidity: 交易量/流动性比率
    """
    il = impermanent_loss(price_ratio, 'v2')
    fee_income = fee_rate * volume_to_liquidity
    return il + fee_income

# 不同手续费对比
fee_rates = [0.0005, 0.003, 0.01]  # 0.05%, 0.3%, 1%
for fee in fee_rates:
    net = net_profit(2.0, fee, volume_to_liquidity=5)
    print(f"手续费 {fee*100:.2f}% → 净收益: {net*100:.2f}%")

结果:

  • 0.05%手续费:净亏 -4.72%(手续费太少,补不了IL)
  • 0.30%手续费:净亏 -3.72%(还是亏,但好一点)
  • 1.00%手续费:净亏 -0.72%(接近盈亏平衡)
避坑指南: 我曾经以为高手续费池子一定赚钱。结果发现,高手续费往往意味着低交易量。你想想看,如果一天都没几笔交易,手续费收益根本覆盖不了无常损失。所以选池子时,要看「交易量/流动性」比率,而不是只看手续费率。

4.5 可视化:无常损失曲线

光看数字不够直观。我画了一张SVG图,展示不同版本和手续费下的损失曲线:

无常损失曲线对比 0.5x 1.0x 2.0x 3.0x 4.0x 0% -10% -20% -30% V2 V3(区间内) V3(区间外) 图例: V2 V3(区间内) V3(区间外)

从图上能清楚看到:V2曲线最平滑,但损失也最「均匀」;V3区间内曲线更平缓,但一旦价格跑出去,损失曲线会急剧下坠。这就是为什么我建议新手先从V2练手,等理解了无常损失的本质,再碰V3。

4.6 实战建议

最后,分享几个我在项目中总结的经验:

  1. 别只看IL百分比——还要看你的仓位大小。100万U的5%损失是5万U,1000U的10%损失才100U。
  2. 手续费是慢药——它能慢慢补回IL,但需要时间。如果你做短线,手续费收益可能还不如IL损失大。
  3. V3的区间选择是门艺术——我习惯把区间设宽一点(比如±50%),虽然牺牲了资本效率,但至少不会突然被「踢出局」。
  4. 对冲不是万能——用永续合约对冲IL,理论上可行,但实际操作中会有资金费率、滑点等问题。我见过有人对冲反而亏更多的。
一句话总结: 无常损失计算工具不是用来「预测未来」的,而是用来「评估风险」的。每次做市前,先跑一遍代码,看看最坏情况下你能承受多少损失。

好了,这一章就到这里。代码我已经放在GitHub上了,你可以直接拿去用。记住,工具只是工具,真正重要的是你对市场的理解和风险控制能力。


公众号:蓝海资料掘金营,微信deep3321