Convert rest of calcuate file to generic multi contracts
This commit is contained in:
parent
26717295b8
commit
58afde2772
|
@ -28,7 +28,7 @@ export function getProbabilityAfterBet(
|
||||||
const shares = calculateShares(totalShares, bet, outcome)
|
const shares = calculateShares(totalShares, bet, outcome)
|
||||||
|
|
||||||
const prevShares = totalShares[outcome] ?? 0
|
const prevShares = totalShares[outcome] ?? 0
|
||||||
const newTotalShares = { ...totalShares, outcome: prevShares + shares }
|
const newTotalShares = { ...totalShares, [outcome]: prevShares + shares }
|
||||||
|
|
||||||
return getOutcomeProbability(newTotalShares, outcome)
|
return getOutcomeProbability(newTotalShares, outcome)
|
||||||
}
|
}
|
||||||
|
@ -48,54 +48,49 @@ export function calculateShares(
|
||||||
return Math.sqrt(bet ** 2 + shares ** 2 + c) - shares
|
return Math.sqrt(bet ** 2 + shares ** 2 + c) - shares
|
||||||
}
|
}
|
||||||
|
|
||||||
export function calculateEstimatedWinnings(
|
|
||||||
totalShares: { YES: number; NO: number },
|
|
||||||
shares: number,
|
|
||||||
betChoice: 'YES' | 'NO'
|
|
||||||
) {
|
|
||||||
const ind = betChoice === 'YES' ? 1 : 0
|
|
||||||
|
|
||||||
const yesShares = totalShares.YES + ind * shares
|
|
||||||
const noShares = totalShares.NO + (1 - ind) * shares
|
|
||||||
|
|
||||||
const estPool = Math.sqrt(yesShares ** 2 + noShares ** 2)
|
|
||||||
const total = ind * yesShares + (1 - ind) * noShares
|
|
||||||
|
|
||||||
return ((1 - FEES) * (shares * estPool)) / total
|
|
||||||
}
|
|
||||||
|
|
||||||
export function calculateRawShareValue(
|
export function calculateRawShareValue(
|
||||||
totalShares: { YES: number; NO: number },
|
totalShares: {
|
||||||
|
[outcome: string]: number
|
||||||
|
},
|
||||||
shares: number,
|
shares: number,
|
||||||
betChoice: 'YES' | 'NO'
|
betChoice: string
|
||||||
) {
|
) {
|
||||||
const [yesShares, noShares] = [totalShares.YES, totalShares.NO]
|
const currentValue = Math.sqrt(
|
||||||
const currentValue = Math.sqrt(yesShares ** 2 + noShares ** 2)
|
_.sumBy(Object.values(totalShares), (shares) => shares ** 2)
|
||||||
|
)
|
||||||
|
|
||||||
const postSaleValue =
|
const postSaleValue = Math.sqrt(
|
||||||
betChoice === 'YES'
|
_.sumBy(Object.keys(totalShares), (outcome) =>
|
||||||
? Math.sqrt(Math.max(0, yesShares - shares) ** 2 + noShares ** 2)
|
outcome === betChoice
|
||||||
: Math.sqrt(yesShares ** 2 + Math.max(0, noShares - shares) ** 2)
|
? Math.max(0, totalShares[outcome] - shares) ** 2
|
||||||
|
: totalShares[outcome] ** 2
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return currentValue - postSaleValue
|
return currentValue - postSaleValue
|
||||||
}
|
}
|
||||||
|
|
||||||
export function calculateMoneyRatio(
|
export function calculateMoneyRatio<T extends 'BINARY' | 'MULTI'>(
|
||||||
contract: Contract,
|
contract: Contract<T>,
|
||||||
bet: Bet,
|
bet: Bet<T>,
|
||||||
shareValue: number
|
shareValue: number
|
||||||
) {
|
) {
|
||||||
const { totalShares, pool } = contract
|
const { totalShares, totalBets, pool } = contract
|
||||||
|
const { outcome, amount } = bet
|
||||||
|
|
||||||
const p = getProbability(totalShares)
|
const p = getOutcomeProbability(totalShares, outcome)
|
||||||
|
|
||||||
const actual = pool.YES + pool.NO - shareValue
|
const actual = pool.YES + pool.NO - shareValue
|
||||||
|
|
||||||
const betAmount =
|
const betAmount = p * amount
|
||||||
bet.outcome === 'YES' ? p * bet.amount : (1 - p) * bet.amount
|
|
||||||
|
|
||||||
const expected =
|
const expected =
|
||||||
p * contract.totalBets.YES + (1 - p) * contract.totalBets.NO - betAmount
|
_.sumBy(
|
||||||
|
Object.keys(totalBets),
|
||||||
|
(outcome) =>
|
||||||
|
getOutcomeProbability(totalShares, outcome) *
|
||||||
|
(totalBets as { [outcome: string]: number })[outcome]
|
||||||
|
) - betAmount
|
||||||
|
|
||||||
if (actual <= 0 || expected <= 0) return 0
|
if (actual <= 0 || expected <= 0) return 0
|
||||||
|
|
||||||
|
@ -103,14 +98,13 @@ export function calculateMoneyRatio(
|
||||||
}
|
}
|
||||||
|
|
||||||
export function calculateShareValue(contract: Contract, bet: Bet) {
|
export function calculateShareValue(contract: Contract, bet: Bet) {
|
||||||
const shareValue = calculateRawShareValue(
|
const { pool, totalShares } = contract
|
||||||
contract.totalShares,
|
const { shares, outcome } = bet
|
||||||
bet.shares,
|
|
||||||
bet.outcome
|
const shareValue = calculateRawShareValue(totalShares, shares, outcome)
|
||||||
)
|
|
||||||
const f = calculateMoneyRatio(contract, bet, shareValue)
|
const f = calculateMoneyRatio(contract, bet, shareValue)
|
||||||
|
|
||||||
const myPool = contract.pool[bet.outcome]
|
const myPool = pool[outcome]
|
||||||
const adjShareValue = Math.min(Math.min(1, f) * shareValue, myPool)
|
const adjShareValue = Math.min(Math.min(1, f) * shareValue, myPool)
|
||||||
return adjShareValue
|
return adjShareValue
|
||||||
}
|
}
|
||||||
|
@ -133,10 +127,11 @@ export function calculatePayout(
|
||||||
}
|
}
|
||||||
|
|
||||||
export function calculateCancelPayout(contract: Contract, bet: Bet) {
|
export function calculateCancelPayout(contract: Contract, bet: Bet) {
|
||||||
const totalBets = contract.totalBets.YES + contract.totalBets.NO
|
const { totalBets, pool } = contract
|
||||||
const pool = contract.pool.YES + contract.pool.NO
|
const betTotal = _.sum(Object.values(totalBets))
|
||||||
|
const poolTotal = _.sum(Object.values(pool))
|
||||||
|
|
||||||
return (bet.amount / totalBets) * pool
|
return (bet.amount / betTotal) * poolTotal
|
||||||
}
|
}
|
||||||
|
|
||||||
export function calculateStandardPayout(
|
export function calculateStandardPayout(
|
||||||
|
@ -152,7 +147,8 @@ export function calculateStandardPayout(
|
||||||
|
|
||||||
const pool = _.sum(Object.values(totalShares))
|
const pool = _.sum(Object.values(totalShares))
|
||||||
|
|
||||||
const total = totalShares[outcome] - phantomShares[outcome]
|
const total =
|
||||||
|
totalShares[outcome] - (phantomShares ? phantomShares[outcome] : 0)
|
||||||
|
|
||||||
const winnings = (shares / total) * pool
|
const winnings = (shares / total) * pool
|
||||||
// profit can be negative if using phantom shares
|
// profit can be negative if using phantom shares
|
||||||
|
@ -161,45 +157,55 @@ export function calculateStandardPayout(
|
||||||
|
|
||||||
export function calculatePayoutAfterCorrectBet(contract: Contract, bet: Bet) {
|
export function calculatePayoutAfterCorrectBet(contract: Contract, bet: Bet) {
|
||||||
const { totalShares, pool, totalBets } = contract
|
const { totalShares, pool, totalBets } = contract
|
||||||
|
const { shares, amount, outcome } = bet
|
||||||
const ind = bet.outcome === 'YES' ? 1 : 0
|
|
||||||
const { shares, amount } = bet
|
|
||||||
|
|
||||||
const newContract = {
|
const newContract = {
|
||||||
...contract,
|
...contract,
|
||||||
totalShares: {
|
totalShares: {
|
||||||
YES: totalShares.YES + ind * shares,
|
...totalShares,
|
||||||
NO: totalShares.NO + (1 - ind) * shares,
|
[outcome]: totalShares[outcome] + shares,
|
||||||
},
|
},
|
||||||
pool: {
|
pool: {
|
||||||
YES: pool.YES + ind * amount,
|
...pool,
|
||||||
NO: pool.NO + (1 - ind) * amount,
|
[outcome]: pool[outcome] + amount,
|
||||||
},
|
},
|
||||||
totalBets: {
|
totalBets: {
|
||||||
YES: totalBets.YES + ind * amount,
|
...totalBets,
|
||||||
NO: totalBets.NO + (1 - ind) * amount,
|
[outcome]: totalBets[outcome] + amount,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return calculateStandardPayout(newContract, bet, bet.outcome)
|
return calculateStandardPayout(newContract, bet, outcome)
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculateMktPayout(contract: Contract, bet: Bet) {
|
function calculateMktPayout(contract: Contract, bet: Bet) {
|
||||||
const p =
|
const { resolutionProbability, totalShares, pool, phantomShares } = contract
|
||||||
contract.resolutionProbability !== undefined
|
|
||||||
? contract.resolutionProbability
|
|
||||||
: getProbability(contract.totalShares)
|
|
||||||
|
|
||||||
const pool = contract.pool.YES + contract.pool.NO
|
const totalPool = _.sum(Object.values(pool))
|
||||||
|
const squareSum = _.sumBy(Object.values(totalShares), (shares) => shares ** 2)
|
||||||
|
|
||||||
const weightedShareTotal =
|
let weightedShareTotal = _.sumBy(Object.keys(totalShares), (outcome) => {
|
||||||
p * (contract.totalShares.YES - contract.phantomShares.YES) +
|
const shareTotals = totalShares as { [outcome: string]: number }
|
||||||
(1 - p) * (contract.totalShares.NO - contract.phantomShares.NO)
|
|
||||||
|
// Avoid O(n^2) by reusing squareSum for prob.
|
||||||
|
const prob = shareTotals[outcome] ** 2 / squareSum
|
||||||
|
const shares =
|
||||||
|
shareTotals[outcome] -
|
||||||
|
(phantomShares ? phantomShares[outcome as 'YES' | 'NO'] : 0)
|
||||||
|
return prob * shares
|
||||||
|
})
|
||||||
|
|
||||||
|
// Compute binary case if resolutionProbability provided.
|
||||||
|
if (resolutionProbability !== undefined) {
|
||||||
|
weightedShareTotal =
|
||||||
|
resolutionProbability * (totalShares.YES - phantomShares.YES) +
|
||||||
|
(1 - resolutionProbability) * (totalShares.NO - phantomShares.NO)
|
||||||
|
}
|
||||||
|
|
||||||
const { outcome, amount, shares } = bet
|
const { outcome, amount, shares } = bet
|
||||||
|
|
||||||
const betP = outcome === 'YES' ? p : 1 - p
|
const betP = getOutcomeProbability(totalShares, outcome)
|
||||||
const winnings = ((betP * shares) / weightedShareTotal) * pool
|
const winnings = ((betP * shares) / weightedShareTotal) * totalPool
|
||||||
|
|
||||||
return deductFees(amount, winnings)
|
return deductFees(amount, winnings)
|
||||||
}
|
}
|
||||||
|
@ -210,15 +216,6 @@ export function resolvedPayout(contract: Contract, bet: Bet) {
|
||||||
throw new Error('Contract was not resolved')
|
throw new Error('Contract was not resolved')
|
||||||
}
|
}
|
||||||
|
|
||||||
// deprecated use MKT payout
|
|
||||||
export function currentValue(contract: Contract, bet: Bet) {
|
|
||||||
const prob = getProbability(contract.pool)
|
|
||||||
const yesPayout = calculatePayout(contract, bet, 'YES')
|
|
||||||
const noPayout = calculatePayout(contract, bet, 'NO')
|
|
||||||
|
|
||||||
return prob * yesPayout + (1 - prob) * noPayout
|
|
||||||
}
|
|
||||||
|
|
||||||
export const deductFees = (betAmount: number, winnings: number) => {
|
export const deductFees = (betAmount: number, winnings: number) => {
|
||||||
return winnings > betAmount
|
return winnings > betAmount
|
||||||
? betAmount + (1 - FEES) * (winnings - betAmount)
|
? betAmount + (1 - FEES) * (winnings - betAmount)
|
||||||
|
|
|
@ -67,15 +67,15 @@ export const getNewMultiBetInfo = (
|
||||||
const { pool, totalShares, totalBets } = contract
|
const { pool, totalShares, totalBets } = contract
|
||||||
|
|
||||||
const prevOutcomePool = pool[outcome] ?? 0
|
const prevOutcomePool = pool[outcome] ?? 0
|
||||||
const newPool = { ...pool, outcome: prevOutcomePool + amount }
|
const newPool = { ...pool, [outcome]: prevOutcomePool + amount }
|
||||||
|
|
||||||
const shares = calculateShares(contract.totalShares, amount, outcome)
|
const shares = calculateShares(contract.totalShares, amount, outcome)
|
||||||
|
|
||||||
const prevShares = totalShares[outcome] ?? 0
|
const prevShares = totalShares[outcome] ?? 0
|
||||||
const newTotalShares = { ...totalShares, outcome: prevShares + shares }
|
const newTotalShares = { ...totalShares, [outcome]: prevShares + shares }
|
||||||
|
|
||||||
const prevTotalBets = totalBets[outcome] ?? 0
|
const prevTotalBets = totalBets[outcome] ?? 0
|
||||||
const newTotalBets = { ...totalBets, outcome: prevTotalBets + amount }
|
const newTotalBets = { ...totalBets, [outcome]: prevTotalBets + amount }
|
||||||
|
|
||||||
const probBefore = getOutcomeProbability(totalShares, outcome)
|
const probBefore = getOutcomeProbability(totalShares, outcome)
|
||||||
const probAfter = getOutcomeProbability(newTotalShares, outcome)
|
const probAfter = getOutcomeProbability(newTotalShares, outcome)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user