calculate fixed payouts; bets list calculations

This commit is contained in:
mantikoros 2022-03-03 11:40:10 -05:00
parent 9b10be065e
commit f06ec7a170
5 changed files with 93 additions and 66 deletions

View File

@ -1,7 +1,6 @@
import * as _ from 'lodash' import * as _ from 'lodash'
import { Bet } from './bet' import { Bet } from './bet'
import { Binary, CPMM, FullContract } from './contract' import { Binary, CPMM, FullContract } from './contract'
import { FEES } from './fees'
export function getCpmmProbability(pool: { [outcome: string]: number }) { export function getCpmmProbability(pool: { [outcome: string]: number }) {
// For binary contracts only. // For binary contracts only.
@ -95,48 +94,3 @@ export function getCpmmProbabilityAfterSale(
const { newPool } = calculateCpmmSale(contract, bet) const { newPool } = calculateCpmmSale(contract, bet)
return getCpmmProbability(newPool) return getCpmmProbability(newPool)
} }
export function calculateFixedPayout(
contract: FullContract<CPMM, Binary>,
bet: Bet,
outcome: string
) {
if (outcome === 'CANCEL') return calculateFixedCancelPayout(bet)
if (outcome === 'MKT') return calculateFixedMktPayout(contract, bet)
return calculateStandardFixedPayout(bet, outcome)
}
export function calculateFixedCancelPayout(bet: Bet) {
return bet.amount
}
export function calculateStandardFixedPayout(bet: Bet, outcome: string) {
const { amount, outcome: betOutcome, shares } = bet
if (betOutcome !== outcome) return 0
return deductCpmmFees(amount, shares - amount)
}
function calculateFixedMktPayout(
contract: FullContract<CPMM, Binary>,
bet: Bet
) {
const { resolutionProbability, pool } = contract
const p =
resolutionProbability !== undefined
? resolutionProbability
: getCpmmProbability(pool)
const { outcome, amount, shares } = bet
const betP = outcome === 'YES' ? p : 1 - p
const winnings = betP * shares
return deductCpmmFees(amount, winnings)
}
export const deductCpmmFees = (betAmount: number, winnings: number) => {
return winnings > betAmount
? betAmount + (1 - FEES) * (winnings - betAmount)
: winnings
}

View File

@ -0,0 +1,49 @@
import { Bet } from './bet'
import { getProbability } from './calculate'
import { Binary, FixedPayouts, FullContract } from './contract'
import { FEES } from './fees'
export function calculateFixedPayout(
contract: FullContract<FixedPayouts, Binary>,
bet: Bet,
outcome: string
) {
if (outcome === 'CANCEL') return calculateFixedCancelPayout(bet)
if (outcome === 'MKT') return calculateFixedMktPayout(contract, bet)
return calculateStandardFixedPayout(bet, outcome)
}
export function calculateFixedCancelPayout(bet: Bet) {
return bet.amount
}
export function calculateStandardFixedPayout(bet: Bet, outcome: string) {
const { amount, outcome: betOutcome, shares } = bet
if (betOutcome !== outcome) return 0
return deductFixedFees(amount, shares - amount)
}
function calculateFixedMktPayout(
contract: FullContract<FixedPayouts, Binary>,
bet: Bet
) {
const { resolutionProbability } = contract
const p =
resolutionProbability !== undefined
? resolutionProbability
: getProbability(contract)
const { outcome, amount, shares } = bet
const betP = outcome === 'YES' ? p : 1 - p
const winnings = betP * shares
return deductFixedFees(amount, winnings)
}
export const deductFixedFees = (betAmount: number, winnings: number) => {
return winnings > betAmount
? betAmount + (1 - FEES) * (winnings - betAmount)
: winnings
}

View File

@ -1,20 +1,26 @@
import { Bet } from './bet' import { Bet } from './bet'
import { import {
calculateCpmmShares, calculateCpmmShares,
calculateCpmmShareValue,
getCpmmProbability, getCpmmProbability,
getCpmmProbabilityAfterBet, getCpmmProbabilityAfterBet,
getCpmmProbabilityAfterSale, getCpmmProbabilityAfterSale,
} from './calculate-cpmm' } from './calculate-cpmm'
import { import {
calculateDpmPayout,
calculateDpmPayoutAfterCorrectBet, calculateDpmPayoutAfterCorrectBet,
calculateDpmSaleAmount,
calculateDpmShares, calculateDpmShares,
getDpmOutcomeProbability, getDpmOutcomeProbability,
getDpmProbability, getDpmProbability,
getDpmProbabilityAfterBet, getDpmProbabilityAfterBet,
getDpmProbabilityAfterSale, getDpmProbabilityAfterSale,
} from './calculate-dpm' } from './calculate-dpm'
import {
calculateFixedPayout,
deductFixedFees,
} from './calculate-fixed-payouts'
import { Binary, Contract, CPMM, DPM, FullContract } from './contract' import { Binary, Contract, CPMM, DPM, FullContract } from './contract'
import { FEES } from './fees'
export function getProbability(contract: FullContract<DPM | CPMM, Binary>) { export function getProbability(contract: FullContract<DPM | CPMM, Binary>) {
return contract.mechanism === 'cpmm-1' return contract.mechanism === 'cpmm-1'
@ -60,9 +66,18 @@ export function calculateShares(
: calculateDpmShares(contract.totalShares, bet, betChoice) : calculateDpmShares(contract.totalShares, bet, betChoice)
} }
export function calculateSaleAmount(contract: Contract, bet: Bet) {
return contract.mechanism === 'cpmm-1' && contract.outcomeType === 'BINARY'
? deductFixedFees(
bet.amount,
calculateCpmmShareValue(contract, bet.shares, bet.outcome)
)
: calculateDpmSaleAmount(contract, bet)
}
export function calculatePayoutAfterCorrectBet(contract: Contract, bet: Bet) { export function calculatePayoutAfterCorrectBet(contract: Contract, bet: Bet) {
return contract.mechanism === 'cpmm-1' return contract.mechanism === 'cpmm-1'
? deductFees(bet.amount, bet.shares) ? deductFixedFees(bet.amount, bet.shares)
: calculateDpmPayoutAfterCorrectBet(contract, bet) : calculateDpmPayoutAfterCorrectBet(contract, bet)
} }
@ -79,8 +94,17 @@ export function getProbabilityAfterSale(
: getDpmProbabilityAfterSale(contract.totalShares, outcome, shares) : getDpmProbabilityAfterSale(contract.totalShares, outcome, shares)
} }
export const deductFees = (betAmount: number, winnings: number) => { export function calculatePayout(contract: Contract, bet: Bet, outcome: string) {
return winnings > betAmount return contract.mechanism === 'cpmm-1' && contract.outcomeType === 'BINARY'
? betAmount + (1 - FEES) * (winnings - betAmount) ? calculateFixedPayout(contract, bet, outcome)
: winnings : calculateDpmPayout(contract, bet, outcome)
}
export function resolvedPayout(contract: Contract, bet: Bet) {
const outcome = contract.resolution
if (!outcome) throw new Error('Contract not resolved')
return contract.mechanism === 'cpmm-1' && contract.outcomeType === 'BINARY'
? calculateFixedPayout(contract, bet, outcome)
: calculateDpmPayout(contract, bet, outcome)
} }

View File

@ -52,6 +52,8 @@ export type CPMM = {
liquidity: { [userId: string]: { [outcome: string]: number } } // track liquidity providers liquidity: { [userId: string]: { [outcome: string]: number } } // track liquidity providers
} }
export type FixedPayouts = CPMM
export type Binary = { export type Binary = {
outcomeType: 'BINARY' outcomeType: 'BINARY'
resolutionProbability?: number // Used for BINARY markets resolved to MKT resolutionProbability?: number // Used for BINARY markets resolved to MKT

View File

@ -22,11 +22,6 @@ import {
} from '../lib/firebase/contracts' } from '../lib/firebase/contracts'
import { Row } from './layout/row' import { Row } from './layout/row'
import { UserLink } from './user-page' import { UserLink } from './user-page'
import {
calculateDpmPayout,
calculateDpmSaleAmount,
resolvedDpmPayout,
} from '../../common/calculate-dpm'
import { sellBet } from '../lib/firebase/api-call' import { sellBet } from '../lib/firebase/api-call'
import { ConfirmationButton } from './confirmation-button' import { ConfirmationButton } from './confirmation-button'
import { OutcomeLabel, YesLabel, NoLabel } from './outcome-label' import { OutcomeLabel, YesLabel, NoLabel } from './outcome-label'
@ -34,9 +29,12 @@ import { filterDefined } from '../../common/util/array'
import { LoadingIndicator } from './loading-indicator' import { LoadingIndicator } from './loading-indicator'
import { SiteLink } from './site-link' import { SiteLink } from './site-link'
import { import {
calculatePayout,
calculateSaleAmount,
getOutcomeProbability, getOutcomeProbability,
getProbability, getProbability,
getProbabilityAfterSale, getProbabilityAfterSale,
resolvedPayout,
} from '../../common/calculate' } from '../../common/calculate'
type BetSort = 'newest' | 'profit' | 'settled' | 'value' type BetSort = 'newest' | 'profit' | 'settled' | 'value'
@ -84,7 +82,7 @@ export function BetsList(props: { user: User }) {
if (bet.isSold || bet.sale) return 0 if (bet.isSold || bet.sale) return 0
const contract = contracts.find((c) => c.id === contractId) const contract = contracts.find((c) => c.id === contractId)
const payout = contract ? calculateDpmPayout(contract, bet, 'MKT') : 0 const payout = contract ? calculatePayout(contract, bet, 'MKT') : 0
return payout - (bet.loanAmount ?? 0) return payout - (bet.loanAmount ?? 0)
}) })
} }
@ -290,21 +288,21 @@ export function MyBetsSummary(props: {
const betsTotal = _.sumBy(excludeSales, (bet) => bet.amount) const betsTotal = _.sumBy(excludeSales, (bet) => bet.amount)
const betsPayout = resolution const betsPayout = resolution
? _.sumBy(excludeSales, (bet) => resolvedDpmPayout(contract, bet)) ? _.sumBy(excludeSales, (bet) => resolvedPayout(contract, bet))
: 0 : 0
const yesWinnings = _.sumBy(excludeSales, (bet) => const yesWinnings = _.sumBy(excludeSales, (bet) =>
calculateDpmPayout(contract, bet, 'YES') calculatePayout(contract, bet, 'YES')
) )
const noWinnings = _.sumBy(excludeSales, (bet) => const noWinnings = _.sumBy(excludeSales, (bet) =>
calculateDpmPayout(contract, bet, 'NO') calculatePayout(contract, bet, 'NO')
) )
// const p = getProbability(contract.totalShares) // const p = getProbability(contract.totalShares)
// const expectation = p * yesWinnings + (1 - p) * noWinnings // const expectation = p * yesWinnings + (1 - p) * noWinnings
const marketWinnings = _.sumBy(excludeSales, (bet) => const marketWinnings = _.sumBy(excludeSales, (bet) =>
calculateDpmPayout(contract, bet, 'MKT') calculatePayout(contract, bet, 'MKT')
) )
const currentValue = resolution ? betsPayout : marketWinnings const currentValue = resolution ? betsPayout : marketWinnings
@ -475,15 +473,15 @@ function BetRow(props: { bet: Bet; contract: Contract; saleBet?: Bet }) {
) : ( ) : (
formatMoney( formatMoney(
isResolved isResolved
? resolvedDpmPayout(contract, bet) ? resolvedPayout(contract, bet)
: calculateDpmSaleAmount(contract, bet) : calculateSaleAmount(contract, bet)
) )
) )
const payoutIfChosenDisplay = const payoutIfChosenDisplay =
bet.outcome === '0' && bet.isAnte bet.outcome === '0' && bet.isAnte
? 'N/A' ? 'N/A'
: formatMoney(calculateDpmPayout(contract, bet, bet.outcome)) : formatMoney(calculatePayout(contract, bet, bet.outcome))
return ( return (
<tr> <tr>
@ -528,7 +526,7 @@ function SellButton(props: { contract: Contract; bet: Bet }) {
const outcomeProb = getProbabilityAfterSale(contract, outcome, shares) const outcomeProb = getProbabilityAfterSale(contract, outcome, shares)
const saleAmount = calculateDpmSaleAmount(contract, bet) const saleAmount = calculateSaleAmount(contract, bet)
return ( return (
<ConfirmationButton <ConfirmationButton