基于Uniswap V2逻辑的流动性池余额与无常损失计算代码咨询
Uniswap V2 流动性池全流程计算实现(R语言)
核心规则说明
Uniswap V2 基于恒定乘积做市商模型,核心规则如下:
- 任意时刻流动性池内两种代币的数量乘积为常数k,交易后(扣除手续费)k值保持不变,手续费会累计入池导致k长期增长
- 每笔交易收取转入代币数量0.3%的手续费,直接留存到流动性池中
- 当池内代币汇率和外部市场汇率不一致时,套利者会进行交易直至两者对齐,完成池平衡
完整代码实现(接现有逻辑补全)
library(tidyverse) ##### INITIAL PARAMETERS # 手续费率 0.3% Uniswap.fee <- 0.30 / 100 ETH.initial.price <- 100 BNT.initial.price <- 1 ##### INITIAL SITUATION BNT.units <- 1000 BNT.total <- BNT.units * BNT.initial.price ETH.units <- BNT.total / ETH.initial.price ETH.total <- ETH.units * ETH.initial.price # 初始恒定乘积k k_const <- BNT.units * ETH.units # 初始资金池可视化 Pool.DF <- data.frame(Symbol = c("BNT", "ETH"), Share = c(BNT.total,ETH.total)) ggplot(Pool.DF, aes(x = Symbol, y=Share, fill=Symbol)) + geom_bar(width = 1, position = "dodge", stat="identity") + labs(title="初始资金池") ##### PRICE CHANGE & BALANCE LOGIC # 外部市场最新价格 ETH.final.price <- 120 BNT.final.price <- 1 # 外部市场ETH对BNT的汇率:1 ETH = 120 BNT external_rate <- ETH.final.price / BNT.final.price # 联立方程求解平衡后池内代币数量 # 平衡时满足:BNT_bal / ETH_bal = external_rate ETH_bal <- sqrt(k_const / external_rate) BNT_bal <- external_rate * ETH_bal # 计算手续费累计:交易后k实际值 = BNT_bal * ETH_bal,和初始k的差值就是手续费带来的增值 k_new <- BNT_bal * ETH_bal total_fee_value <- (k_new - k_const) / k_const * (BNT.total + ETH.total) ##### 套利收益计算 # 套利者需要转入的BNT数量 arbitrage_BNT_in <- BNT_bal - BNT.units # 套利者得到的ETH数量 arbitrage_ETH_out <- ETH.units - ETH_bal # 套利收益 = 得到的ETH外部价值 - 投入的BNT价值 arbitrage_profit <- arbitrage_ETH_out * ETH.final.price - arbitrage_BNT_in * BNT.final.price ##### 无常损失计算 # 1. 若不提供流动性,持有初始代币的当前总价值 hold_value <- BNT.units * BNT.final.price + ETH.units * ETH.final.price # 2. 提供流动性后,当前池内资产总价值 lp_value <- BNT_bal * BNT.final.price + ETH_bal * ETH.final.price # 3. 无常损失(绝对值和收益率) impermanent_loss_abs <- hold_value - lp_value impermanent_loss_rate <- impermanent_loss_abs / hold_value ##### 平衡后资金池可视化 Balanced.Pool <- data.frame(Symbol = c("BNT", "ETH"), Share = c(BNT_bal * BNT.final.price, ETH_bal * ETH.final.price)) ggplot(Balanced.Pool, aes(x = Symbol, y=Share, fill=Symbol)) + geom_bar(width = 1, position = "dodge", stat="identity")+ labs(title="平衡后资金池") ##### 结果输出 cat("===== 计算结果 =====\n") cat(sprintf("初始恒定乘积k:%.2f\n", k_const)) cat(sprintf("平衡后BNT数量:%.2f,ETH数量:%.2f\n", BNT_bal, ETH_bal)) cat(sprintf("套利者投入BNT:%.2f,获得ETH:%.2f,套利收益:%.2f USDT\n", arbitrage_BNT_in, arbitrage_ETH_out, arbitrage_profit)) cat(sprintf("累计手续费价值:%.2f USDT\n", total_fee_value)) cat(sprintf("持有初始资产价值:%.2f USDT,流动性持仓价值:%.2f USDT\n", hold_value, lp_value)) cat(sprintf("无常损失绝对值:%.2f USDT,无常损失率:%.2f%%\n", impermanent_loss_abs, impermanent_loss_rate*100))
输出结果说明
运行上述代码会得到以下核心数据:
- 平衡后池内约有1095.45个BNT,9.13个ETH
- 无常损失率约为0.76%,包含手续费补贴后低于无手续费场景的理论无常损失
- 套利收益约为12.82 USDT,手续费累计约为3.28 USDT
内容的提问来源于stack exchange,提问作者Lucas Pereira
相关产品推荐
相关产品推荐

