Created
October 25, 2021 05:18
-
-
Save kangchihlun/74e6c241bf7f81bb7b1ee51e88803316 to your computer and use it in GitHub Desktop.
UniswapV3 +作空永續對沖 -- 收益曲面預估
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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