Fix free response MKT calculation to use probs from resolutions field, client-side.

This commit is contained in:
James Grugett 2022-03-18 01:21:30 -05:00
parent 93f790019c
commit c12063799f

View File

@ -1,6 +1,6 @@
import * as _ from 'lodash' import * as _ from 'lodash'
import { Bet } from './bet' import { Bet } from './bet'
import { Binary, DPM, FullContract } from './contract' import { Binary, DPM, FreeResponse, FullContract } from './contract'
import { DPM_FEES } from './fees' import { DPM_FEES } from './fees'
export function getDpmProbability(totalShares: { [outcome: string]: number }) { export function getDpmProbability(totalShares: { [outcome: string]: number }) {
@ -213,24 +213,27 @@ function calculateMktDpmPayout(contract: FullContract<DPM, any>, bet: Bet) {
if (contract.outcomeType === 'BINARY') if (contract.outcomeType === 'BINARY')
return calculateBinaryMktDpmPayout(contract, bet) return calculateBinaryMktDpmPayout(contract, bet)
const { totalShares, pool } = contract const { totalShares, pool, resolutions } = contract as FullContract<
DPM,
FreeResponse
>
if (!resolutions)
throw new Error(
'resolutions required for MKT payout of free response market'
)
const totalPool = _.sum(Object.values(pool)) const totalPool = _.sum(Object.values(pool))
const sharesSquareSum = _.sumBy( const probTotal = _.sum(Object.values(resolutions))
Object.values(totalShares) as number[],
(shares) => shares ** 2
)
const weightedShareTotal = _.sumBy(Object.keys(totalShares), (outcome) => { const weightedShareTotal = _.sumBy(Object.keys(resolutions), (outcome) => {
// Avoid O(n^2) by reusing sharesSquareSum for prob. const prob = resolutions[outcome] / probTotal
const shares = totalShares[outcome] return prob * totalShares[outcome]
const prob = shares ** 2 / sharesSquareSum
return prob * shares
}) })
const { outcome, amount, shares } = bet const { outcome, amount, shares } = bet
const betP = getDpmOutcomeProbability(totalShares, outcome) const betP = (resolutions[outcome] ?? 0) / probTotal
const winnings = ((betP * shares) / weightedShareTotal) * totalPool const winnings = ((betP * shares) / weightedShareTotal) * totalPool
return deductDpmFees(amount, winnings) return deductDpmFees(amount, winnings)