Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save kangchihlun/74e6c241bf7f81bb7b1ee51e88803316 to your computer and use it in GitHub Desktop.
Save kangchihlun/74e6c241bf7f81bb7b1ee51e88803316 to your computer and use it in GitHub Desktop.
UniswapV3 +作空永續對沖 -- 收益曲面預估
# coding=utf-8
import os,sys
import time
import math
import random
def getLowerFromUpper(
P, # 當前幣價
Pu, # 上界
amountX,
amountY
):
pa_1 = amountY/(math.sqrt(Pu)*amountX) + math.sqrt(P) - amountY/(math.sqrt(P)*amountX)
return pa_1*pa_1
def getTokenAmountsFromDepositAmounts(
P, # 當前幣價
Pl, # 下界
Pu, # 上界
priceUSDX, # 幣種1對美元
priceUSDY, # 幣種2對美元
targetAmounts # 投入資金美金計價
):
deltaL = targetAmounts / ((math.sqrt(P) - math.sqrt(Pl)) * priceUSDY +
(1 / math.sqrt(P) - 1 / math.sqrt(Pu)) * priceUSDX)
deltaY = deltaL * (math.sqrt(P) - math.sqrt(Pl))
if (deltaY * priceUSDY < 0):
deltaY = 0
if (deltaY * priceUSDY > targetAmounts):
deltaY = targetAmounts / priceUSDY
deltaX = deltaL * (1 / math.sqrt(P) - 1 / math.sqrt(Pu))
if (deltaX * priceUSDX < 0):
deltaX = 0;
if (deltaX * priceUSDX > targetAmounts):
deltaX = targetAmounts / priceUSDX
return deltaX,deltaY
def getILPriceChange(
price,
newPrice,
upper,
lower,
amountX,
amountY
):
Lx = amountX * (math.sqrt(price) * math.sqrt(upper)) / (math.sqrt(upper)-math.sqrt(price))
Ly = amountY / (math.sqrt(price)-math.sqrt(lower))
L = min(Lx,Ly)
Lx2 = L * (math.sqrt(upper)-math.sqrt(newPrice)) / (math.sqrt(newPrice) * math.sqrt(upper))
Ly2 = L * (math.sqrt(newPrice)-math.sqrt(lower))
newAssetValue = Lx2 * newPrice + Ly2
# 回傳當時價格手上的資產總額,幣種1剩餘數量,幣種2剩餘數量
return newAssetValue,Lx2,Ly2
# ######################
# ## 參數
# ######################
# 初始資金
initialCapital = 6888
# 進場價
initialPrice = 4000
USD_Price = 1
# 上界
upper = 5000
# 下界
lower = 1333
# 池費率
fee_rate = 0.3
# 初始TVL(預估)
initTVL = 159.27 * 1000000
# TVL 成長率(月)(預估)
TVLGrowRate = 0.05
# 成交量上界(預估)
tradevol_upper = 4702.59 * 1000000
# 成交量下界(預估)
tradevol_lower = 551.57 * 1000000
# 空單開倉位置,從下界起算比例
hedge_rto = 0.05
# 資金費率(天)--參考幣安(較穩定)
# 資金費率上界
fundrate_upper = 0.03*0.01*3
# 資金費率下界
fundrate_lower = 0.01*0.01*3
# ######## 參數 End ########
# 決定當前價格跟下界哪個是開倉點(減少做空成本)
low_price = max(initialPrice,lower)
# 依照比例決定開空單的位置
hedge_price = low_price + (upper-low_price) * hedge_rto
# 根據開空單的位置和上下界找出實際需要 hedge 的 eth 數量
h_eth,h_usd = getTokenAmountsFromDepositAmounts(hedge_price,lower,upper,hedge_price,USD_Price,initialCapital)
# 進入資金池內的資金 = 所有資金 - 空單部位資金
poolAsset = initialCapital - h_eth*hedge_price
# 再次使用當前價位計算需要提供的數量
initialAmtEth,initialAmtUsd = getTokenAmountsFromDepositAmounts(initialPrice,lower,upper,initialPrice,USD_Price,poolAsset)
# 初始流動量(你提供的)
initialLq = math.sqrt(initialAmtEth * initialAmtUsd)
# 散點圖座標,不包含手續費(必賠)
scatter_points_noFee = []
# 散點圖座標,不包含手續費+空單避險
scatter_points_hdeged = []
# 散點圖座標,包含手續費+空單避險
scatter_points = []
# 預測範圍 : 幣價歸0 -> 幣價漲1倍
for k in range(1,initialPrice*2,10):
# 手續費累加
feeIncome_accu = 0
# 資金費率累加
fundrate_income_accu = 0
for d in range(1,366):
curp = k
if(k>upper):
curp = upper
newAssetValue,_x,_y = getILPriceChange(initialPrice,curp,upper,lower,initialAmtEth,initialAmtUsd)
if(newAssetValue<0):newAssetValue=0
# 賺取手續費使用單利計算(Todo:每月再投入複利)
# 今日的 tvl
nthDay_tvl = initTVL * (1+TVLGrowRate/30*d)
# 今日的成交量預估 隨機從成交量高低區間取
todayVolEstimation = tradevol_lower + random.uniform(0, 1) * (tradevol_upper - tradevol_lower)
# 今日的手續費 = 流動量(自己) / 今日的流動量 * 今日的成交量 * 手續費率
feeIncome = (initialLq / nthDay_tvl) * todayVolEstimation * (1+TVLGrowRate/30*d) * fee_rate * 0.01
# 手續費累加
feeIncome_accu += feeIncome
# 空單損益含本金(低於0當作已爆倉,不列入計算)
uPnL = max( h_eth*hedge_price + (hedge_price - k)*h_eth , 0 )
# 資金費率
fundrate = fundrate_lower + random.uniform(0, 1) * (fundrate_upper - fundrate_lower)
fundrate_income = h_eth * fundrate * hedge_price
if(uPnL>0.001):
fundrate_income_accu += fundrate_income
# 原始無常損失資產價值
scatter_points_noFee.append([d,k,newAssetValue])
# 避險總資產
hedged_asset = newAssetValue + uPnL + fundrate_income_accu
scatter_points_hdeged.append([d,k,hedged_asset])
# 資產+避險+資金費率+已賺手續費
curCapital = hedged_asset + feeIncome_accu
scatter_points.append([d,k,curCapital])
print('day '+str(d)+ ' price $' + str(k)+ ' asset = '+ str(newAssetValue) +' fee='+ str(feeIncome_accu) +' heg='+str(uPnL+fundrate_income_accu) +' total='+str(curCapital) )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment