rename contract properties
This commit is contained in:
parent
022caa4407
commit
756f31b1b7
|
@ -43,7 +43,7 @@ export const placeBet = functions.runWith({ minInstances: 1 }).https.onCall(
|
||||||
.collection(`contracts/${contractId}/bets`)
|
.collection(`contracts/${contractId}/bets`)
|
||||||
.doc()
|
.doc()
|
||||||
|
|
||||||
const { newBet, newPot, newDpmWeights, newBalance } = getNewBetInfo(
|
const { newBet, newPool, newDpmWeights, newBalance } = getNewBetInfo(
|
||||||
user,
|
user,
|
||||||
outcome,
|
outcome,
|
||||||
amount,
|
amount,
|
||||||
|
@ -52,7 +52,10 @@ export const placeBet = functions.runWith({ minInstances: 1 }).https.onCall(
|
||||||
)
|
)
|
||||||
|
|
||||||
transaction.create(newBetDoc, newBet)
|
transaction.create(newBetDoc, newBet)
|
||||||
transaction.update(contractDoc, { pot: newPot, dpmWeights: newDpmWeights })
|
transaction.update(contractDoc, {
|
||||||
|
pool: newPool,
|
||||||
|
dpmWeights: newDpmWeights,
|
||||||
|
})
|
||||||
transaction.update(userDoc, { balance: newBalance })
|
transaction.update(userDoc, { balance: newBalance })
|
||||||
|
|
||||||
return { status: 'success' }
|
return { status: 'success' }
|
||||||
|
@ -69,35 +72,37 @@ const getNewBetInfo = (
|
||||||
contract: Contract,
|
contract: Contract,
|
||||||
newBetId: string
|
newBetId: string
|
||||||
) => {
|
) => {
|
||||||
const { YES: yesPot, NO: noPot } = contract.pot
|
const { YES: yesPool, NO: noPool } = contract.pool
|
||||||
|
|
||||||
const newPot =
|
const newPool =
|
||||||
outcome === 'YES'
|
outcome === 'YES'
|
||||||
? { YES: yesPot + amount, NO: noPot }
|
? { YES: yesPool + amount, NO: noPool }
|
||||||
: { YES: yesPot, NO: noPot + amount }
|
: { YES: yesPool, NO: noPool + amount }
|
||||||
|
|
||||||
const dpmWeight =
|
const dpmWeight =
|
||||||
outcome === 'YES'
|
outcome === 'YES'
|
||||||
? (amount * noPot ** 2) / (yesPot ** 2 + amount * yesPot)
|
? (amount * noPool ** 2) / (yesPool ** 2 + amount * yesPool)
|
||||||
: (amount * yesPot ** 2) / (noPot ** 2 + amount * noPot)
|
: (amount * yesPool ** 2) / (noPool ** 2 + amount * noPool)
|
||||||
|
|
||||||
const { YES: yesWeight, NO: noWeight } = contract.dpmWeights
|
const { YES: yesWeight, NO: noWeight } = contract.dpmWeights || {
|
||||||
|| { YES: 0, NO: 0 } // only nesc for old contracts
|
YES: 0,
|
||||||
|
NO: 0,
|
||||||
|
} // only nesc for old contracts
|
||||||
|
|
||||||
const newDpmWeights =
|
const newDpmWeights =
|
||||||
outcome === 'YES'
|
outcome === 'YES'
|
||||||
? { YES: yesWeight + dpmWeight, NO: noWeight }
|
? { YES: yesWeight + dpmWeight, NO: noWeight }
|
||||||
: { YES: yesWeight, NO: noWeight + dpmWeight }
|
: { YES: yesWeight, NO: noWeight + dpmWeight }
|
||||||
|
|
||||||
const probBefore = yesPot ** 2 / (yesPot ** 2 + noPot ** 2)
|
const probBefore = yesPool ** 2 / (yesPool ** 2 + noPool ** 2)
|
||||||
|
|
||||||
const probAverage =
|
const probAverage =
|
||||||
(amount +
|
(amount +
|
||||||
noPot * Math.atan(yesPot / noPot) -
|
noPool * Math.atan(yesPool / noPool) -
|
||||||
noPot * Math.atan((amount + yesPot) / noPot)) /
|
noPool * Math.atan((amount + yesPool) / noPool)) /
|
||||||
amount
|
amount
|
||||||
|
|
||||||
const probAfter = newPot.YES ** 2 / (newPot.YES ** 2 + newPot.NO ** 2)
|
const probAfter = newPool.YES ** 2 / (newPool.YES ** 2 + newPool.NO ** 2)
|
||||||
|
|
||||||
const newBet: Bet = {
|
const newBet: Bet = {
|
||||||
id: newBetId,
|
id: newBetId,
|
||||||
|
@ -114,5 +119,5 @@ const getNewBetInfo = (
|
||||||
|
|
||||||
const newBalance = user.balance - amount
|
const newBalance = user.balance - amount
|
||||||
|
|
||||||
return { newBet, newPot, newDpmWeights, newBalance }
|
return { newBet, newPool, newDpmWeights, newBalance }
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,90 +11,98 @@ export const CREATOR_FEE = 0.01 // 1%
|
||||||
|
|
||||||
export const resolveMarket = functions
|
export const resolveMarket = functions
|
||||||
.runWith({ minInstances: 1 })
|
.runWith({ minInstances: 1 })
|
||||||
.https
|
.https.onCall(
|
||||||
.onCall(async (data: {
|
async (
|
||||||
outcome: string
|
data: {
|
||||||
contractId: string
|
outcome: string
|
||||||
}, context) => {
|
contractId: string
|
||||||
const userId = context?.auth?.uid
|
},
|
||||||
if (!userId) return { status: 'error', message: 'Not authorized' }
|
context
|
||||||
|
) => {
|
||||||
|
const userId = context?.auth?.uid
|
||||||
|
if (!userId) return { status: 'error', message: 'Not authorized' }
|
||||||
|
|
||||||
const { outcome, contractId } = data
|
const { outcome, contractId } = data
|
||||||
|
|
||||||
if (!['YES', 'NO', 'CANCEL'].includes(outcome))
|
if (!['YES', 'NO', 'CANCEL'].includes(outcome))
|
||||||
return { status: 'error', message: 'Invalid outcome' }
|
return { status: 'error', message: 'Invalid outcome' }
|
||||||
|
|
||||||
const contractDoc = firestore.doc(`contracts/${contractId}`)
|
const contractDoc = firestore.doc(`contracts/${contractId}`)
|
||||||
const contractSnap = await contractDoc.get()
|
const contractSnap = await contractDoc.get()
|
||||||
if (!contractSnap.exists)
|
if (!contractSnap.exists)
|
||||||
return { status: 'error', message: 'Invalid contract' }
|
return { status: 'error', message: 'Invalid contract' }
|
||||||
const contract = contractSnap.data() as Contract
|
const contract = contractSnap.data() as Contract
|
||||||
|
|
||||||
if (contract.creatorId !== userId)
|
if (contract.creatorId !== userId)
|
||||||
return { status: 'error', message: 'User not creator of contract' }
|
return { status: 'error', message: 'User not creator of contract' }
|
||||||
|
|
||||||
if (contract.resolution)
|
if (contract.resolution)
|
||||||
return { status: 'error', message: 'Contract already resolved' }
|
return { status: 'error', message: 'Contract already resolved' }
|
||||||
|
|
||||||
await contractDoc.update({
|
await contractDoc.update({
|
||||||
isResolved: true,
|
isResolved: true,
|
||||||
resolution: outcome,
|
resolution: outcome,
|
||||||
resolutionTime: Date.now()
|
resolutionTime: Date.now(),
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('contract ', contractId, 'resolved to:', outcome)
|
console.log('contract ', contractId, 'resolved to:', outcome)
|
||||||
|
|
||||||
const betsSnap = await firestore.collection(`contracts/${contractId}/bets`).get()
|
const betsSnap = await firestore
|
||||||
const bets = betsSnap.docs.map(doc => doc.data() as Bet)
|
.collection(`contracts/${contractId}/bets`)
|
||||||
|
.get()
|
||||||
|
const bets = betsSnap.docs.map((doc) => doc.data() as Bet)
|
||||||
|
|
||||||
const payouts = outcome === 'CANCEL'
|
const payouts =
|
||||||
? bets.map(bet => ({
|
outcome === 'CANCEL'
|
||||||
userId: bet.userId,
|
? bets.map((bet) => ({
|
||||||
payout: bet.amount
|
userId: bet.userId,
|
||||||
}))
|
payout: bet.amount,
|
||||||
|
}))
|
||||||
|
: getPayouts(outcome, contract, bets)
|
||||||
|
|
||||||
: getPayouts(outcome, contract, bets)
|
console.log('payouts:', payouts)
|
||||||
|
|
||||||
console.log('payouts:', payouts)
|
const groups = _.groupBy(payouts, (payout) => payout.userId)
|
||||||
|
const userPayouts = _.mapValues(groups, (group) =>
|
||||||
|
_.sumBy(group, (g) => g.payout)
|
||||||
|
)
|
||||||
|
|
||||||
const groups = _.groupBy(payouts, payout => payout.userId)
|
const payoutPromises = Object.entries(userPayouts).map(payUser)
|
||||||
const userPayouts = _.mapValues(groups, group => _.sumBy(group, g => g.payout))
|
|
||||||
|
|
||||||
const payoutPromises = Object
|
return await Promise.all(payoutPromises)
|
||||||
.entries(userPayouts)
|
.catch((e) => ({ status: 'error', message: e }))
|
||||||
.map(payUser)
|
.then(() => ({ status: 'success' }))
|
||||||
|
}
|
||||||
return await Promise.all(payoutPromises)
|
)
|
||||||
.catch(e => ({ status: 'error', message: e }))
|
|
||||||
.then(() => ({ status: 'success' }))
|
|
||||||
})
|
|
||||||
|
|
||||||
const firestore = admin.firestore()
|
const firestore = admin.firestore()
|
||||||
|
|
||||||
const getPayouts = (outcome: string, contract: Contract, bets: Bet[]) => {
|
const getPayouts = (outcome: string, contract: Contract, bets: Bet[]) => {
|
||||||
const [yesBets, noBets] = _.partition(bets, bet => bet.outcome === 'YES')
|
const [yesBets, noBets] = _.partition(bets, (bet) => bet.outcome === 'YES')
|
||||||
|
|
||||||
const [pot, winningBets] = outcome === 'YES'
|
const [pool, winningBets] =
|
||||||
? [contract.pot.NO - contract.seedAmounts.NO, yesBets]
|
outcome === 'YES'
|
||||||
: [contract.pot.YES - contract.seedAmounts.YES, noBets]
|
? [contract.pool.NO - contract.startPool.NO, yesBets]
|
||||||
|
: [contract.pool.YES - contract.startPool.YES, noBets]
|
||||||
|
|
||||||
const finalPot = (1 - PLATFORM_FEE - CREATOR_FEE) * pot
|
const finalPool = (1 - PLATFORM_FEE - CREATOR_FEE) * pool
|
||||||
const creatorPayout = CREATOR_FEE * pot
|
const creatorPayout = CREATOR_FEE * pool
|
||||||
console.log('final pot:', finalPot, 'creator fee:', creatorPayout)
|
console.log('final pool:', finalPool, 'creator fee:', creatorPayout)
|
||||||
|
|
||||||
const sumWeights = _.sumBy(winningBets, bet => bet.dpmWeight)
|
const sumWeights = _.sumBy(winningBets, (bet) => bet.dpmWeight)
|
||||||
|
|
||||||
const winnerPayouts = winningBets.map(bet => ({
|
const winnerPayouts = winningBets.map((bet) => ({
|
||||||
userId: bet.userId,
|
userId: bet.userId,
|
||||||
payout: bet.amount + (bet.dpmWeight / sumWeights * finalPot)
|
payout: bet.amount + (bet.dpmWeight / sumWeights) * finalPool,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
return winnerPayouts
|
return winnerPayouts.concat([
|
||||||
.concat([{ userId: contract.creatorId, payout: creatorPayout }]) // add creator fee
|
{ userId: contract.creatorId, payout: creatorPayout },
|
||||||
|
]) // add creator fee
|
||||||
}
|
}
|
||||||
|
|
||||||
const payUser = ([userId, payout]: [string, number]) => {
|
const payUser = ([userId, payout]: [string, number]) => {
|
||||||
return firestore.runTransaction(async transaction => {
|
return firestore.runTransaction(async (transaction) => {
|
||||||
const userDoc = firestore.doc(`users/${userId}`)
|
const userDoc = firestore.doc(`users/${userId}`)
|
||||||
const userSnap = await transaction.get(userDoc)
|
const userSnap = await transaction.get(userDoc)
|
||||||
if (!userSnap.exists) return
|
if (!userSnap.exists) return
|
||||||
|
@ -104,4 +112,3 @@ const payUser = ([userId, payout]: [string, number]) => {
|
||||||
transaction.update(userDoc, { balance: newUserBalance })
|
transaction.update(userDoc, { balance: newUserBalance })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
export type Contract = {
|
export type Contract = {
|
||||||
id: string // Chosen by creator; must be unique
|
id: string // Chosen by creator; must be unique
|
||||||
creatorId: string
|
creatorId: string
|
||||||
|
@ -6,11 +5,11 @@ export type Contract = {
|
||||||
|
|
||||||
question: string
|
question: string
|
||||||
description: string // More info about what the contract is about
|
description: string // More info about what the contract is about
|
||||||
|
|
||||||
outcomeType: 'BINARY' // | 'MULTI' | 'interval' | 'date'
|
outcomeType: 'BINARY' // | 'MULTI' | 'interval' | 'date'
|
||||||
// outcomes: ['YES', 'NO']
|
// outcomes: ['YES', 'NO']
|
||||||
seedAmounts: { YES: number; NO: number }
|
|
||||||
pot: { YES: number; NO: number }
|
startPool: { YES: number; NO: number }
|
||||||
|
pool: { YES: number; NO: number }
|
||||||
dpmWeights: { YES: number; NO: number }
|
dpmWeights: { YES: number; NO: number }
|
||||||
|
|
||||||
createdTime: number // Milliseconds since epoch
|
createdTime: number // Milliseconds since epoch
|
||||||
|
@ -18,6 +17,6 @@ export type Contract = {
|
||||||
closeTime?: number // When no more trading is allowed
|
closeTime?: number // When no more trading is allowed
|
||||||
|
|
||||||
isResolved: boolean
|
isResolved: boolean
|
||||||
resolutionTime?: 10293849 // When the contract creator resolved the market; 0 if unresolved
|
resolutionTime?: number // When the contract creator resolved the market
|
||||||
resolution?: 'YES' | 'NO' | 'CANCEL' // Chosen by creator; must be one of outcomes
|
resolution?: 'YES' | 'NO' | 'CANCEL' // Chosen by creator; must be one of outcomes
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,13 +77,13 @@ export function BetPanel(props: { contract: Contract; className?: string }) {
|
||||||
|
|
||||||
const betDisabled = isSubmitting || !betAmount || error
|
const betDisabled = isSubmitting || !betAmount || error
|
||||||
|
|
||||||
const initialProb = getProbability(contract.pot)
|
const initialProb = getProbability(contract.pool)
|
||||||
const resultProb = getProbabilityAfterBet(
|
const resultProb = getProbabilityAfterBet(
|
||||||
contract.pot,
|
contract.pool,
|
||||||
betChoice,
|
betChoice,
|
||||||
betAmount ?? 0
|
betAmount ?? 0
|
||||||
)
|
)
|
||||||
const dpmWeight = getDpmWeight(contract.pot, betAmount ?? 0, betChoice)
|
const dpmWeight = getDpmWeight(contract.pool, betAmount ?? 0, betChoice)
|
||||||
|
|
||||||
const estimatedWinnings = Math.floor((betAmount ?? 0) + dpmWeight)
|
const estimatedWinnings = Math.floor((betAmount ?? 0) + dpmWeight)
|
||||||
const estimatedReturn = betAmount
|
const estimatedReturn = betAmount
|
||||||
|
|
|
@ -7,19 +7,19 @@ import { Contract } from '../lib/firebase/contracts'
|
||||||
|
|
||||||
export function ContractProbGraph(props: { contract: Contract }) {
|
export function ContractProbGraph(props: { contract: Contract }) {
|
||||||
const { contract } = props
|
const { contract } = props
|
||||||
const { id, seedAmounts, resolutionTime } = contract
|
const { id, startPool, resolutionTime } = contract
|
||||||
|
|
||||||
let bets = useBets(id)
|
let bets = useBets(id)
|
||||||
if (bets === 'loading') bets = []
|
if (bets === 'loading') bets = []
|
||||||
|
|
||||||
const seedProb =
|
const startProb =
|
||||||
seedAmounts.YES ** 2 / (seedAmounts.YES ** 2 + seedAmounts.NO ** 2)
|
startPool.YES ** 2 / (startPool.YES ** 2 + startPool.NO ** 2)
|
||||||
|
|
||||||
const times = [
|
const times = [
|
||||||
contract.createdTime,
|
contract.createdTime,
|
||||||
...bets.map((bet) => bet.createdTime),
|
...bets.map((bet) => bet.createdTime),
|
||||||
].map((time) => new Date(time))
|
].map((time) => new Date(time))
|
||||||
const probs = [seedProb, ...bets.map((bet) => bet.probAfter)]
|
const probs = [startProb, ...bets.map((bet) => bet.probAfter)]
|
||||||
|
|
||||||
const latestTime = dayjs(resolutionTime ? resolutionTime : Date.now())
|
const latestTime = dayjs(resolutionTime ? resolutionTime : Date.now())
|
||||||
|
|
||||||
|
|
|
@ -3,35 +3,35 @@ import { Contract } from '../firebase/contracts'
|
||||||
|
|
||||||
const fees = 0.02
|
const fees = 0.02
|
||||||
|
|
||||||
export function getProbability(pot: { YES: number; NO: number }) {
|
export function getProbability(pool: { YES: number; NO: number }) {
|
||||||
const [yesPot, noPot] = [pot.YES, pot.NO]
|
const [yesPool, noPool] = [pool.YES, pool.NO]
|
||||||
const numerator = Math.pow(yesPot, 2)
|
const numerator = Math.pow(yesPool, 2)
|
||||||
const denominator = Math.pow(yesPot, 2) + Math.pow(noPot, 2)
|
const denominator = Math.pow(yesPool, 2) + Math.pow(noPool, 2)
|
||||||
return numerator / denominator
|
return numerator / denominator
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getProbabilityAfterBet(
|
export function getProbabilityAfterBet(
|
||||||
pot: { YES: number; NO: number },
|
pool: { YES: number; NO: number },
|
||||||
outcome: 'YES' | 'NO',
|
outcome: 'YES' | 'NO',
|
||||||
bet: number
|
bet: number
|
||||||
) {
|
) {
|
||||||
const [YES, NO] = [
|
const [YES, NO] = [
|
||||||
pot.YES + (outcome === 'YES' ? bet : 0),
|
pool.YES + (outcome === 'YES' ? bet : 0),
|
||||||
pot.NO + (outcome === 'NO' ? bet : 0),
|
pool.NO + (outcome === 'NO' ? bet : 0),
|
||||||
]
|
]
|
||||||
return getProbability({ YES, NO })
|
return getProbability({ YES, NO })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDpmWeight(
|
export function getDpmWeight(
|
||||||
pot: { YES: number; NO: number },
|
pool: { YES: number; NO: number },
|
||||||
bet: number,
|
bet: number,
|
||||||
betChoice: 'YES' | 'NO'
|
betChoice: 'YES' | 'NO'
|
||||||
) {
|
) {
|
||||||
const [yesPot, noPot] = [pot.YES, pot.NO]
|
const [yesPool, noPool] = [pool.YES, pool.NO]
|
||||||
|
|
||||||
return betChoice === 'YES'
|
return betChoice === 'YES'
|
||||||
? (bet * Math.pow(noPot, 2)) / (Math.pow(yesPot, 2) + bet * yesPot)
|
? (bet * Math.pow(noPool, 2)) / (Math.pow(yesPool, 2) + bet * yesPool)
|
||||||
: (bet * Math.pow(yesPot, 2)) / (Math.pow(noPot, 2) + bet * noPot)
|
: (bet * Math.pow(yesPool, 2)) / (Math.pow(noPool, 2) + bet * noPool)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function calculatePayout(
|
export function calculatePayout(
|
||||||
|
@ -44,18 +44,18 @@ export function calculatePayout(
|
||||||
if (outcome === 'CANCEL') return amount
|
if (outcome === 'CANCEL') return amount
|
||||||
if (betOutcome !== outcome) return 0
|
if (betOutcome !== outcome) return 0
|
||||||
|
|
||||||
let { dpmWeights, pot, seedAmounts } = contract
|
let { dpmWeights, pool, startPool } = contract
|
||||||
|
|
||||||
// Fake data if not set.
|
// Fake data if not set.
|
||||||
if (!dpmWeights) dpmWeights = { YES: 100, NO: 100 }
|
if (!dpmWeights) dpmWeights = { YES: 100, NO: 100 }
|
||||||
|
|
||||||
// Fake data if not set.
|
// Fake data if not set.
|
||||||
if (!pot) pot = { YES: 100, NO: 100 }
|
if (!pool) pool = { YES: 100, NO: 100 }
|
||||||
|
|
||||||
const otherOutcome = outcome === 'YES' ? 'NO' : 'YES'
|
const otherOutcome = outcome === 'YES' ? 'NO' : 'YES'
|
||||||
const potSize = pot[otherOutcome] - seedAmounts[otherOutcome]
|
const poolSize = pool[otherOutcome] - startPool[otherOutcome]
|
||||||
|
|
||||||
return (1 - fees) * (dpmWeight / dpmWeights[outcome]) * potSize + amount
|
return (1 - fees) * (dpmWeight / dpmWeights[outcome]) * poolSize + amount
|
||||||
}
|
}
|
||||||
export function resolvedPayout(contract: Contract, bet: Bet) {
|
export function resolvedPayout(contract: Contract, bet: Bet) {
|
||||||
if (contract.resolution)
|
if (contract.resolution)
|
||||||
|
@ -64,7 +64,7 @@ export function resolvedPayout(contract: Contract, bet: Bet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function currentValue(contract: Contract, bet: Bet) {
|
export function currentValue(contract: Contract, bet: Bet) {
|
||||||
const prob = getProbability(contract.pot)
|
const prob = getProbability(contract.pool)
|
||||||
const yesPayout = calculatePayout(contract, bet, 'YES')
|
const yesPayout = calculatePayout(contract, bet, 'YES')
|
||||||
const noPayout = calculatePayout(contract, bet, 'NO')
|
const noPayout = calculatePayout(contract, bet, 'NO')
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,9 @@ export type Contract = {
|
||||||
description: string // More info about what the contract is about
|
description: string // More info about what the contract is about
|
||||||
outcomeType: 'BINARY' // | 'MULTI' | 'interval' | 'date'
|
outcomeType: 'BINARY' // | 'MULTI' | 'interval' | 'date'
|
||||||
// outcomes: ['YES', 'NO']
|
// outcomes: ['YES', 'NO']
|
||||||
seedAmounts: { YES: number; NO: number } // seedBets: [number, number]
|
|
||||||
pot: { YES: number; NO: number }
|
startPool: { YES: number; NO: number }
|
||||||
|
pool: { YES: number; NO: number }
|
||||||
dpmWeights: { YES: number; NO: number }
|
dpmWeights: { YES: number; NO: number }
|
||||||
|
|
||||||
createdTime: number // Milliseconds since epoch
|
createdTime: number // Milliseconds since epoch
|
||||||
|
@ -33,7 +34,7 @@ export type Contract = {
|
||||||
closeTime?: number // When no more trading is allowed
|
closeTime?: number // When no more trading is allowed
|
||||||
|
|
||||||
isResolved: boolean
|
isResolved: boolean
|
||||||
resolutionTime?: number // When the contract creator resolved the market; 0 if unresolved
|
resolutionTime?: number // When the contract creator resolved the market
|
||||||
resolution?: 'YES' | 'NO' | 'CANCEL' // Chosen by creator; must be one of outcomes
|
resolution?: 'YES' | 'NO' | 'CANCEL' // Chosen by creator; must be one of outcomes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,9 +46,9 @@ export function path(contract: Contract) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function compute(contract: Contract) {
|
export function compute(contract: Contract) {
|
||||||
const { pot, seedAmounts, createdTime, resolutionTime, isResolved } = contract
|
const { pool, startPool, createdTime, resolutionTime, isResolved } = contract
|
||||||
const volume = pot.YES + pot.NO - seedAmounts.YES - seedAmounts.NO
|
const volume = pool.YES + pool.NO - startPool.YES - startPool.NO
|
||||||
const prob = pot.YES ** 2 / (pot.YES ** 2 + pot.NO ** 2)
|
const prob = pool.YES ** 2 / (pool.YES ** 2 + pool.NO ** 2)
|
||||||
const probPercent = Math.round(prob * 100) + '%'
|
const probPercent = Math.round(prob * 100) + '%'
|
||||||
const createdDate = dayjs(createdTime).format('MMM D')
|
const createdDate = dayjs(createdTime).format('MMM D')
|
||||||
const resolvedDate = isResolved
|
const resolvedDate = isResolved
|
||||||
|
|
|
@ -16,7 +16,7 @@ export async function createContract(
|
||||||
|
|
||||||
const contractId = preexistingContract ? slug + '-' + randomString() : slug
|
const contractId = preexistingContract ? slug + '-' + randomString() : slug
|
||||||
|
|
||||||
const { seedYes, seedNo } = calcSeedBets(initialProb)
|
const { startYes, startNo } = calcStartPool(initialProb)
|
||||||
|
|
||||||
const contract: Contract = {
|
const contract: Contract = {
|
||||||
id: contractId,
|
id: contractId,
|
||||||
|
@ -28,8 +28,8 @@ export async function createContract(
|
||||||
question: question.trim(),
|
question: question.trim(),
|
||||||
description: description.trim(),
|
description: description.trim(),
|
||||||
|
|
||||||
seedAmounts: { YES: seedYes, NO: seedNo },
|
startPool: { YES: startYes, NO: startNo },
|
||||||
pot: { YES: seedYes, NO: seedNo },
|
pool: { YES: startYes, NO: startNo },
|
||||||
dpmWeights: { YES: 0, NO: 0 },
|
dpmWeights: { YES: 0, NO: 0 },
|
||||||
isResolved: false,
|
isResolved: false,
|
||||||
|
|
||||||
|
@ -43,15 +43,15 @@ export async function createContract(
|
||||||
return contract
|
return contract
|
||||||
}
|
}
|
||||||
|
|
||||||
export function calcSeedBets(initialProb: number, initialCapital = 100) {
|
export function calcStartPool(initialProb: number, initialCapital = 100) {
|
||||||
const p = initialProb / 100.0
|
const p = initialProb / 100.0
|
||||||
|
|
||||||
const seedYes =
|
const startYes =
|
||||||
p === 0.5
|
p === 0.5
|
||||||
? p * initialCapital
|
? p * initialCapital
|
||||||
: -(initialCapital * (-p + Math.sqrt((-1 + p) * -p))) / (-1 + 2 * p)
|
: -(initialCapital * (-p + Math.sqrt((-1 + p) * -p))) / (-1 + 2 * p)
|
||||||
|
|
||||||
const seedNo = initialCapital - seedYes
|
const startNo = initialCapital - startYes
|
||||||
|
|
||||||
return { seedYes, seedNo }
|
return { startYes, startNo }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user