diff --git a/common/antes.ts b/common/antes.ts index 5f269083..f94c9f35 100644 --- a/common/antes.ts +++ b/common/antes.ts @@ -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 } +} diff --git a/common/calculate.ts b/common/calculate.ts index 5468588e..ef81fd72 100644 --- a/common/calculate.ts +++ b/common/calculate.ts @@ -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) { diff --git a/common/new-contract.ts b/common/new-contract.ts index e3da778d..b2fb08b5 100644 --- a/common/new-contract.ts +++ b/common/new-contract.ts @@ -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() {} diff --git a/functions/src/create-contract.ts b/functions/src/create-contract.ts index dbe3806b..779b38d4 100644 --- a/functions/src/create-contract.ts +++ b/functions/src/create-contract.ts @@ -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 } } ) diff --git a/web/components/bet-panel.tsx b/web/components/bet-panel.tsx index 53fd89f7..1309e9b2 100644 --- a/web/components/bet-panel.tsx +++ b/web/components/bet-panel.tsx @@ -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 ( diff --git a/web/lib/firebase/init.ts b/web/lib/firebase/init.ts index 98734946..ba10545a 100644 --- a/web/lib/firebase/init.ts +++ b/web/lib/firebase/init.ts @@ -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 ? {