Include antes as bets; more calculations

This commit is contained in:
mantikoros 2022-01-11 16:48:27 -06:00
parent 2fccba1e0f
commit f4cabf17cb
6 changed files with 120 additions and 10 deletions

View File

@ -1,3 +1,8 @@
import { Bet } from './bet'
import { getProbability } from './calculate'
import { Contract } from './contract'
import { User } from './user'
export const PHANTOM_ANTE = 200
export const calcStartPool = (initialProbInt: number, ante = 0) => {
@ -15,3 +20,39 @@ export const calcStartPool = (initialProbInt: number, ante = 0) => {
return { sharesYes, sharesNo, poolYes, poolNo, startYes, startNo }
}
export function getAnteBets(
creator: User,
contract: Contract,
yesAnteId: string,
noAnteId: string
) {
const p = getProbability(contract.totalShares)
const ante = contract.totalBets.YES + contract.totalBets.NO
const yesBet: Bet = {
id: yesAnteId,
userId: creator.id,
contractId: contract.id,
amount: p * ante,
shares: Math.sqrt(p) * ante,
outcome: 'YES',
probBefore: p,
probAfter: p,
createdTime: Date.now(),
}
const noBet: Bet = {
id: noAnteId,
userId: creator.id,
contractId: contract.id,
amount: (1 - p) * ante,
shares: Math.sqrt(1 - p) * ante,
outcome: 'NO',
probBefore: p,
probAfter: p,
createdTime: Date.now(),
}
return { yesBet, noBet }
}

View File

@ -36,6 +36,22 @@ export function calculateShares(
: Math.sqrt(bet ** 2 + noShares ** 2 + c) - noShares
}
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 (shares * estPool) / total
}
export function calculateRawShareValue(
totalShares: { YES: number; NO: number },
shares: number,
@ -112,15 +128,35 @@ export function calculateStandardPayout(
if (totalBets[outcome] >= truePool)
return (amount / totalBets[outcome]) * truePool
const startShares = startPool.YES + startPool.NO
const total = totalShares[outcome] - startShares - totalBets[outcome]
const total = totalShares[outcome] - startPool[outcome] - totalBets[outcome]
const winningsPool = truePool - totalBets[outcome]
return (1 - FEES) * (amount + ((shares - amount) / total) * winningsPool)
}
export function calculatePayoutAfterCorrectBet(contract: Contract, bet: Bet) {
return calculateStandardPayout(contract, bet, bet.outcome)
const { totalShares, pool, totalBets } = contract
const ind = bet.outcome === 'YES' ? 1 : 0
const { shares, amount } = bet
const newContract = {
...contract,
totalShares: {
YES: totalShares.YES + ind * shares,
NO: totalShares.NO + (1 - ind) * shares,
},
pool: {
YES: pool.YES + ind * amount,
NO: pool.NO + (1 - ind) * amount,
},
totalBets: {
YES: totalBets.YES + ind * amount,
NO: totalBets.NO + (1 - ind) * amount,
},
}
return calculateStandardPayout(newContract, bet, bet.outcome)
}
function calculateMktPayout(contract: Contract, bet: Bet) {

View File

@ -1,4 +1,5 @@
import { calcStartPool } from './antes'
import { Contract } from './contract'
import { User } from './user'
@ -45,5 +46,3 @@ export function getNewContract(
return contract
}
function getAnteBets() {}

View File

@ -6,6 +6,7 @@ import { Contract } from '../../common/contract'
import { slugify } from '../../common/util/slugify'
import { randomString } from '../../common/util/random-string'
import { getNewContract } from '../../common/new-contract'
import { getAnteBets } from '../../common/antes'
export const createContract = functions
.runWith({ minInstances: 1 })
@ -64,6 +65,26 @@ export const createContract = functions
if (ante) await chargeUser(creator.id, ante)
await contractRef.create(contract)
if (ante) {
const yesBetDoc = firestore
.collection(`contracts/${contract.id}/bets`)
.doc()
const noBetDoc = firestore
.collection(`contracts/${contract.id}/bets`)
.doc()
const { yesBet, noBet } = getAnteBets(
creator,
contract,
yesBetDoc.id,
noBetDoc.id
)
await yesBetDoc.set(yesBet)
await noBetDoc.set(noBet)
}
return { status: 'success', contract }
}
)

View File

@ -18,6 +18,7 @@ import {
calculateShares,
getProbabilityAfterBet,
calculatePayoutAfterCorrectBet,
calculateEstimatedWinnings,
} from '../../common/calculate'
import { firebaseLogin } from '../lib/firebase/users'
import { OutcomeLabel } from './outcome-label'
@ -84,18 +85,30 @@ export function BetPanel(props: { contract: Contract; className?: string }) {
const betDisabled = isSubmitting || !betAmount || error
const initialProb = getProbability(contract.pool)
const initialProb = getProbability(contract.totalShares)
const resultProb = getProbabilityAfterBet(
contract.totalShares,
betChoice,
betAmount ?? 0
)
const shares = calculateShares(contract.pool, betAmount ?? 0, betChoice)
const estimatedWinnings = Math.floor(shares)
const shares = calculateShares(
contract.totalShares,
betAmount ?? 0,
betChoice
)
const estimatedWinnings = calculateEstimatedWinnings(
contract.totalShares,
shares,
betChoice
)
const estimatedReturn = betAmount
? (estimatedWinnings - betAmount) / betAmount
: 0
const estimatedReturnPercent = (estimatedReturn * 100).toFixed() + '%'
return (

View File

@ -2,8 +2,8 @@ import { getFirestore } from '@firebase/firestore'
import { initializeApp } from 'firebase/app'
// TODO: Reenable this when we have a way to set the Firebase db in dev
// export const isProd = process.env.NODE_ENV === 'production'
export const isProd = true
export const isProd = process.env.NODE_ENV === 'production'
// export const isProd = true
const firebaseConfig = isProd
? {