Implement buy YES calculation
This commit is contained in:
parent
17ae9d953d
commit
06c49be05b
|
@ -89,6 +89,7 @@ export function calculateLPCost(
|
||||||
deltaL: number
|
deltaL: number
|
||||||
) {
|
) {
|
||||||
// TODO: this is subtly wrong, because of rounding between curTick and sqrtPrice
|
// TODO: this is subtly wrong, because of rounding between curTick and sqrtPrice
|
||||||
|
// Also below in buyYES
|
||||||
const upperTick = Math.min(maxTick, Math.max(minTick, curTick))
|
const upperTick = Math.min(maxTick, Math.max(minTick, curTick))
|
||||||
const costN = toRatio(upperTick) ** 0.5 - toRatio(minTick) ** 0.5
|
const costN = toRatio(upperTick) ** 0.5 - toRatio(minTick) ** 0.5
|
||||||
|
|
||||||
|
@ -101,6 +102,62 @@ export function calculateLPCost(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns a preview of the new pool + number of YES shares purchased.
|
||||||
|
// Does NOT modify the pool
|
||||||
|
// Hm, logic is pretty complicated. Let's see if we can simplify this.
|
||||||
|
export function buyYes(
|
||||||
|
pool: Swap3Pool,
|
||||||
|
amount: number // In M$
|
||||||
|
) {
|
||||||
|
const tickStates = sortedTickStates(pool)
|
||||||
|
let tick = pool.tick
|
||||||
|
let stateIndex = 0
|
||||||
|
let amountLeft = amount
|
||||||
|
let yesPurchased = 0
|
||||||
|
while (amountLeft > 0) {
|
||||||
|
// Find the current tick state
|
||||||
|
while (tick >= tickStates[stateIndex + 1].tick) {
|
||||||
|
stateIndex++
|
||||||
|
if (stateIndex > tickStates.length - 2) {
|
||||||
|
// We've reached the end of the tick states...
|
||||||
|
throw new Error('Ran out of tick states')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const state = tickStates[stateIndex]
|
||||||
|
const nextState = tickStates[stateIndex + 1]
|
||||||
|
|
||||||
|
// Copied from above; TODO extract to common function
|
||||||
|
const noCost = toRatio(nextState.tick) ** 0.5 - toRatio(tick) ** 0.5
|
||||||
|
const yesCost =
|
||||||
|
1 / toRatio(tick) ** 0.5 - 1 / toRatio(nextState.tick) ** 0.5
|
||||||
|
|
||||||
|
if (noCost * state.liquidityGross <= amountLeft) {
|
||||||
|
// We can fully purchase up until the next tick state
|
||||||
|
amountLeft -= noCost * state.liquidityGross
|
||||||
|
yesPurchased += yesCost * state.liquidityGross
|
||||||
|
tick = nextState.tick
|
||||||
|
} else {
|
||||||
|
// Buy as much as we can at the current tick state. Derivation:
|
||||||
|
// noCostLeft = toRatio(upTick) ** 0.5 - toRatio(tick) ** 0.5
|
||||||
|
// (noCostLeft + toRatio(tick) ** 0.5) ** 2 = toRatio(upTick)
|
||||||
|
// TODO check flooring done here
|
||||||
|
const noCostLeft = amountLeft / state.liquidityGross
|
||||||
|
const finalTick = fromRatio((noCostLeft + toRatio(tick) ** 0.5) ** 2)
|
||||||
|
const yesCostLeft =
|
||||||
|
1 / toRatio(tick) ** 0.5 - 1 / toRatio(finalTick) ** 0.5
|
||||||
|
|
||||||
|
amountLeft = 0
|
||||||
|
yesPurchased += yesCostLeft * state.liquidityGross
|
||||||
|
tick = finalTick
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
newPoolTick: tick,
|
||||||
|
yesPurchased,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Currently, this mutates the pool. Should it return a new object instead?
|
// Currently, this mutates the pool. Should it return a new object instead?
|
||||||
export function addPosition(
|
export function addPosition(
|
||||||
pool: Swap3Pool,
|
pool: Swap3Pool,
|
||||||
|
@ -165,5 +222,9 @@ export function toProb(tick: number) {
|
||||||
// Returns the tick for a given probability from 0 to 1
|
// Returns the tick for a given probability from 0 to 1
|
||||||
export function fromProb(prob: number) {
|
export function fromProb(prob: number) {
|
||||||
const ratio = prob / (1 - prob)
|
const ratio = prob / (1 - prob)
|
||||||
|
return fromRatio(ratio)
|
||||||
|
}
|
||||||
|
|
||||||
|
function fromRatio(ratio: number) {
|
||||||
return Math.floor(Math.log(ratio) / Math.log(1.0001))
|
return Math.floor(Math.log(ratio) / Math.log(1.0001))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import {
|
import {
|
||||||
addPosition,
|
addPosition,
|
||||||
|
buyYes,
|
||||||
calculateLPCost,
|
calculateLPCost,
|
||||||
fromProb,
|
fromProb,
|
||||||
getSwap3Probability,
|
getSwap3Probability,
|
||||||
|
@ -136,11 +137,14 @@ export default function Swap() {
|
||||||
tickStates: [],
|
tickStates: [],
|
||||||
}
|
}
|
||||||
INIT_POOL = addPosition(INIT_POOL, -(2 ** 23), 2 ** 20, 100)
|
INIT_POOL = addPosition(INIT_POOL, -(2 ** 23), 2 ** 20, 100)
|
||||||
|
INIT_POOL = addPosition(INIT_POOL, fromProb(0.32), fromProb(0.35), 100)
|
||||||
INIT_POOL = grossLiquidity(INIT_POOL)
|
INIT_POOL = grossLiquidity(INIT_POOL)
|
||||||
|
|
||||||
const [pool, setPool] = useState(INIT_POOL)
|
const [pool, setPool] = useState(INIT_POOL)
|
||||||
|
|
||||||
const [minTick, setMinTick] = useState(0)
|
const [minTick, setMinTick] = useState(0)
|
||||||
const [maxTick, setMaxTick] = useState(0)
|
const [maxTick, setMaxTick] = useState(0)
|
||||||
|
const [buyAmount, setBuyAmount] = useState(0)
|
||||||
|
|
||||||
const { requiredN, requiredY } = calculateLPCost(
|
const { requiredN, requiredY } = calculateLPCost(
|
||||||
pool.tick,
|
pool.tick,
|
||||||
|
@ -149,6 +153,8 @@ export default function Swap() {
|
||||||
100 // deltaL
|
100 // deltaL
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const { newPoolTick, yesPurchased } = buyYes(pool, buyAmount)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Col className="mx-auto max-w-2xl gap-10 p-4">
|
<Col className="mx-auto max-w-2xl gap-10 p-4">
|
||||||
{/* <BalanceTable /> */}
|
{/* <BalanceTable /> */}
|
||||||
|
@ -200,10 +206,20 @@ export default function Swap() {
|
||||||
<Col>
|
<Col>
|
||||||
Bob: Buy Tokens
|
Bob: Buy Tokens
|
||||||
{/* <input className="input" placeholder="User" type="text" /> */}
|
{/* <input className="input" placeholder="User" type="text" /> */}
|
||||||
<input className="input" placeholder="Amount" type="number" />
|
<input
|
||||||
|
className="input"
|
||||||
|
placeholder="Amount"
|
||||||
|
type="number"
|
||||||
|
onChange={(e) => setBuyAmount(parseFloat(e.target.value))}
|
||||||
|
/>
|
||||||
|
<Row className="gap-2 py-2">
|
||||||
|
<div>Y shares purchaseable: {yesPurchased.toFixed(2)}</div>
|
||||||
|
<div>New Tick: {newPoolTick}</div>
|
||||||
|
<div>New prob: {formatPercent(toProb(newPoolTick))}</div>
|
||||||
|
</Row>
|
||||||
<Row className="gap-2">
|
<Row className="gap-2">
|
||||||
<button className="btn">Buy YES</button>
|
<button className="btn">Buy YES</button>
|
||||||
<button className="btn">Buy NO</button>
|
{/* <button className="btn">Buy NO</button> */}
|
||||||
</Row>
|
</Row>
|
||||||
</Col>
|
</Col>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user