computed bases

This commit is contained in:
tim
2025-10-25 18:18:18 -04:00
parent 2972152e58
commit ba08da2fca
14 changed files with 93 additions and 98 deletions

View File

@@ -7,7 +7,6 @@ import numpy as np
log = logging.getLogger(__name__)
LMSR_FEE = 0.0025
# UNISWAP_GAS=0
# LMSR_GAS=0
UNISWAP_GAS=115_000
@@ -180,31 +179,66 @@ def lmsr_marginal_price(balances, base_index, quote_index, kappa):
def compare(file, tvl, kappa):
def compare(file, tvl, fee, kappa):
d = pd.read_csv(file)
d.columns = ['block', 'price0', 'price1', 'in0', 'out0', 'rate']
# Calibrate LMSR balances so that exp((q1 - q0)/b) equals the initial price
# New approach: derive bases from initial external balances (assuming equal-valued deposits)
# This matches the Solidity implementation and eliminates the κ·ln(price) constraint
p0 = float(d.iloc[0].price0)
S = float(tvl) # choose the LMSR size metric
b = kappa * S
delta = b * math.log(p0) # q1 - q0
q0 = 0.5 * (S - delta)
q1 = 0.5 * (S + delta)
if q0 <= 0.0 or q1 <= 0.0:
raise ValueError("Invalid LMSR calibration: choose kappa such that kappa * ln(price0) < 1.")
# Set external balances assuming equal values: if token0 = B0 and token1 = B1,
# and they have equal value, then B0 * price0 = B1 * price1 = V (value per asset)
# For simplicity, choose B0 such that the total value is tvl, then B1 = B0 * price0
total_value = float(tvl)
# Since B0 * price0 + B1 = total_value and B1 = B0 * price0, we get:
# B0 * price0 + B0 * price0 = total_value, so B0 = total_value / (2 * price0)
B0 = total_value / (2.0 * p0) # external balance of token 0
B1 = B0 * p0 # external balance of token 1 (equal value)
external_balances = [B0, B1]
# Derive bases: set base_i = B_i so that q_i = B_i / base_i = 1.0 internally
bases = [B0, B1]
# Internal balances: q_i = external_balance_i / base_i ≈ 1.0
q0 = B0 / bases[0] # ≈ 1.0
q1 = B1 / bases[1] # ≈ 1.0
balances = [q0, q1]
print(balances)
print(f"External balances: {external_balances}")
print(f"Bases: {bases}")
print(f"Internal balances: {balances}")
# Convert external input amounts to internal for LMSR calculations, then convert results back
X = np.geomspace(1, 1_000_000, 100)
orig_price = lmsr_marginal_price(balances, 0, 1, kappa)
in_out = [(float(amount_in), lmsr_swap_amount_out(balances, float(amount_in), 0, 1, LMSR_FEE, kappa)) for amount_in in X]
print(in_out)
# Convert X to internal amounts, compute swap, then convert back to external
in_out = []
for amount_in_external in X:
# Convert external input to internal units
amount_in_internal = amount_in_external / bases[0] # input token 0
# Compute swap in internal units
amount_out_internal = lmsr_swap_amount_out(balances, amount_in_internal, 0, 1, fee, kappa)
# Convert output back to external units
amount_out_external = amount_out_internal * bases[1] # output token 1
in_out.append((float(amount_in_external), float(amount_out_external)))
print(f"Sample internal/external conversions: {in_out[:3]}")
# Compute initial marginal price in external units
# Internal price is exp((q1 - q0)/b), external price needs conversion by bases[1]/bases[0]
orig_price_external = orig_price * (bases[1] / bases[0])
# Relative execution price deviation from the initial marginal price:
# slippage = |(amount_out/amount_in)/orig_price - 1|
# slippage = |(amount_out/amount_in)/orig_price_external - 1|
eps = 1e-12
Y = [max(eps, abs((amount_out / amount_in) / orig_price - 1.0))
Y = [max(eps, abs((amount_out / amount_in) / orig_price_external - 1.0))
for amount_in, amount_out in in_out]
plt.plot(X, Y, label=f'LMSR {LMSR_FEE:.2%} κ={kappa:.2f}', color='cornflowerblue')
plt.plot(X, Y, label=f'LMSR {fee:.2%} κ={kappa:.2g}', color='cornflowerblue')
# Uniswap execution price deviation from its initial quoted price:
# slippage = |(out/in)/initial_price - 1|
@@ -257,6 +291,6 @@ def plot_kappa():
if __name__ == '__main__':
# compare('uni4_quotes/swap_results_block_23640998.csv')
# compare('uni4_quotes/ETH-USDC-30.csv', 53_000_000, 0.1)
compare('uni4_quotes/ETH-USDC-30.csv', 1_00_000, .1)
compare('uni4_quotes/ETH-USDC-30.csv', 53_000_000, 0.0025, 0.00025)
# compare('uni4_quotes/ETH-USDC-30.csv', 100_000, 0.0025, 0.00025)
# plot_kappa()