From c12063799f5f25ac2a253a3ec4781d92b043f8d7 Mon Sep 17 00:00:00 2001 From: James Grugett Date: Fri, 18 Mar 2022 01:21:30 -0500 Subject: [PATCH] Fix free response MKT calculation to use probs from resolutions field, client-side. --- common/calculate-dpm.ts | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/common/calculate-dpm.ts b/common/calculate-dpm.ts index 76b464e5..a4730d14 100644 --- a/common/calculate-dpm.ts +++ b/common/calculate-dpm.ts @@ -1,6 +1,6 @@ import * as _ from 'lodash' import { Bet } from './bet' -import { Binary, DPM, FullContract } from './contract' +import { Binary, DPM, FreeResponse, FullContract } from './contract' import { DPM_FEES } from './fees' export function getDpmProbability(totalShares: { [outcome: string]: number }) { @@ -213,24 +213,27 @@ function calculateMktDpmPayout(contract: FullContract, bet: Bet) { if (contract.outcomeType === 'BINARY') 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 sharesSquareSum = _.sumBy( - Object.values(totalShares) as number[], - (shares) => shares ** 2 - ) + const probTotal = _.sum(Object.values(resolutions)) - const weightedShareTotal = _.sumBy(Object.keys(totalShares), (outcome) => { - // Avoid O(n^2) by reusing sharesSquareSum for prob. - const shares = totalShares[outcome] - const prob = shares ** 2 / sharesSquareSum - return prob * shares + const weightedShareTotal = _.sumBy(Object.keys(resolutions), (outcome) => { + const prob = resolutions[outcome] / probTotal + return prob * totalShares[outcome] }) const { outcome, amount, shares } = bet - const betP = getDpmOutcomeProbability(totalShares, outcome) + const betP = (resolutions[outcome] ?? 0) / probTotal const winnings = ((betP * shares) / weightedShareTotal) * totalPool return deductDpmFees(amount, winnings)