simpler payout mechanism; lower phantom ante to $1
This commit is contained in:
parent
bcc011c1fd
commit
e31e97219d
|
@ -3,7 +3,7 @@ import { getProbability } from './calculate'
|
||||||
import { Contract } from './contract'
|
import { Contract } from './contract'
|
||||||
import { User } from './user'
|
import { User } from './user'
|
||||||
|
|
||||||
export const PHANTOM_ANTE = 100
|
export const PHANTOM_ANTE = 1
|
||||||
export const MINIMUM_ANTE = 10
|
export const MINIMUM_ANTE = 10
|
||||||
|
|
||||||
export const calcStartPool = (initialProbInt: number, ante = 0) => {
|
export const calcStartPool = (initialProbInt: number, ante = 0) => {
|
||||||
|
|
|
@ -133,19 +133,14 @@ export function calculateStandardPayout(
|
||||||
const { amount, outcome: betOutcome, shares } = bet
|
const { amount, outcome: betOutcome, shares } = bet
|
||||||
if (betOutcome !== outcome) return 0
|
if (betOutcome !== outcome) return 0
|
||||||
|
|
||||||
const { totalShares, totalBets, phantomShares } = contract
|
const { totalShares, phantomShares } = contract
|
||||||
if (totalShares[outcome] === 0) return 0
|
if (totalShares[outcome] === 0) return 0
|
||||||
|
|
||||||
const truePool = contract.pool.YES + contract.pool.NO
|
const pool = contract.pool.YES + contract.pool.NO
|
||||||
|
const total = totalShares[outcome] - phantomShares[outcome]
|
||||||
|
|
||||||
if (totalBets[outcome] >= truePool)
|
const winnings = (shares / total) * pool
|
||||||
return (amount / totalBets[outcome]) * truePool
|
return deductFees(amount, winnings)
|
||||||
|
|
||||||
const total =
|
|
||||||
totalShares[outcome] - phantomShares[outcome] - totalBets[outcome]
|
|
||||||
const winningsPool = truePool - totalBets[outcome]
|
|
||||||
|
|
||||||
return amount + (1 - FEES) * ((shares - amount) / total) * winningsPool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function calculatePayoutAfterCorrectBet(contract: Contract, bet: Bet) {
|
export function calculatePayoutAfterCorrectBet(contract: Contract, bet: Bet) {
|
||||||
|
@ -179,35 +174,18 @@ function calculateMktPayout(contract: Contract, bet: Bet) {
|
||||||
? contract.resolutionProbability
|
? contract.resolutionProbability
|
||||||
: getProbability(contract.totalShares)
|
: getProbability(contract.totalShares)
|
||||||
|
|
||||||
const weightedTotal =
|
const pool = contract.pool.YES + contract.pool.NO
|
||||||
p * contract.totalBets.YES + (1 - p) * contract.totalBets.NO
|
|
||||||
|
|
||||||
const truePool = contract.pool.YES + contract.pool.NO
|
|
||||||
|
|
||||||
const betP = bet.outcome === 'YES' ? p : 1 - p
|
|
||||||
|
|
||||||
if (weightedTotal >= truePool) {
|
|
||||||
return ((betP * bet.amount) / weightedTotal) * truePool
|
|
||||||
}
|
|
||||||
|
|
||||||
const winningsPool = truePool - weightedTotal
|
|
||||||
|
|
||||||
const weightedShareTotal =
|
const weightedShareTotal =
|
||||||
p *
|
p * (contract.totalShares.YES - contract.phantomShares.YES) +
|
||||||
(contract.totalShares.YES -
|
(1 - p) * (contract.totalShares.NO - contract.phantomShares.NO)
|
||||||
contract.phantomShares.YES -
|
|
||||||
contract.totalBets.YES) +
|
|
||||||
(1 - p) *
|
|
||||||
(contract.totalShares.NO -
|
|
||||||
contract.phantomShares.NO -
|
|
||||||
contract.totalBets.NO)
|
|
||||||
|
|
||||||
return (
|
const { outcome, amount, shares } = bet
|
||||||
betP * bet.amount +
|
|
||||||
(1 - FEES) *
|
const betP = outcome === 'YES' ? p : 1 - p
|
||||||
((betP * (bet.shares - bet.amount)) / weightedShareTotal) *
|
const winnings = ((betP * shares) / weightedShareTotal) * pool
|
||||||
winningsPool
|
|
||||||
)
|
return deductFees(amount, winnings)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolvedPayout(contract: Contract, bet: Bet) {
|
export function resolvedPayout(contract: Contract, bet: Bet) {
|
||||||
|
@ -224,3 +202,9 @@ export function currentValue(contract: Contract, bet: Bet) {
|
||||||
|
|
||||||
return prob * yesPayout + (1 - prob) * noPayout
|
return prob * yesPayout + (1 - prob) * noPayout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const deductFees = (betAmount: number, winnings: number) => {
|
||||||
|
return winnings > betAmount
|
||||||
|
? betAmount + (1 - FEES) * (winnings - betAmount)
|
||||||
|
: betAmount
|
||||||
|
}
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
|
import * as _ from 'lodash'
|
||||||
|
|
||||||
import { Bet } from './bet'
|
import { Bet } from './bet'
|
||||||
import { getProbability } from './calculate'
|
import { deductFees, getProbability } from './calculate'
|
||||||
import { Contract, outcome } from './contract'
|
import { Contract, outcome } from './contract'
|
||||||
import { CREATOR_FEE, FEES } from './fees'
|
import { CREATOR_FEE } from './fees'
|
||||||
|
|
||||||
export const getCancelPayouts = (contract: Contract, bets: Bet[]) => {
|
export const getCancelPayouts = (contract: Contract, bets: Bet[]) => {
|
||||||
const { pool } = contract
|
const { pool } = contract
|
||||||
const poolTotal = pool.YES + pool.NO
|
const poolTotal = pool.YES + pool.NO
|
||||||
console.log('resolved N/A, pool M$', poolTotal)
|
console.log('resolved N/A, pool M$', poolTotal)
|
||||||
|
|
||||||
const betSum = sumBy(bets, (b) => b.amount)
|
const betSum = _.sumBy(bets, (b) => b.amount)
|
||||||
|
|
||||||
return bets.map((bet) => ({
|
return bets.map((bet) => ({
|
||||||
userId: bet.userId,
|
userId: bet.userId,
|
||||||
|
@ -21,35 +23,24 @@ export const getStandardPayouts = (
|
||||||
contract: Contract,
|
contract: Contract,
|
||||||
bets: Bet[]
|
bets: Bet[]
|
||||||
) => {
|
) => {
|
||||||
const [yesBets, noBets] = partition(bets, (bet) => bet.outcome === 'YES')
|
const [yesBets, noBets] = _.partition(bets, (bet) => bet.outcome === 'YES')
|
||||||
const winningBets = outcome === 'YES' ? yesBets : noBets
|
const winningBets = outcome === 'YES' ? yesBets : noBets
|
||||||
|
|
||||||
const betSum = sumBy(winningBets, (b) => b.amount)
|
const pool = contract.pool.YES + contract.pool.NO
|
||||||
|
const totalShares = _.sumBy(winningBets, (b) => b.shares)
|
||||||
const poolTotal = contract.pool.YES + contract.pool.NO
|
|
||||||
|
|
||||||
if (betSum >= poolTotal) return getCancelPayouts(contract, winningBets)
|
|
||||||
|
|
||||||
const shareDifferenceSum = sumBy(winningBets, (b) => b.shares - b.amount)
|
|
||||||
|
|
||||||
const winningsPool = poolTotal - betSum
|
|
||||||
|
|
||||||
const winnerPayouts = winningBets.map((bet) => ({
|
const winnerPayouts = winningBets.map((bet) => ({
|
||||||
userId: bet.userId,
|
userId: bet.userId,
|
||||||
payout:
|
payout: deductFees(bet.amount, (bet.shares / totalShares) * pool),
|
||||||
bet.amount +
|
|
||||||
(1 - FEES) *
|
|
||||||
((bet.shares - bet.amount) / shareDifferenceSum) *
|
|
||||||
winningsPool,
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const creatorPayout = CREATOR_FEE * winningsPool
|
const creatorPayout = CREATOR_FEE * pool
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
'resolved',
|
'resolved',
|
||||||
outcome,
|
outcome,
|
||||||
'pool: M$',
|
'pool: M$',
|
||||||
poolTotal,
|
pool,
|
||||||
'creator fee: M$',
|
'creator fee: M$',
|
||||||
creatorPayout
|
creatorPayout
|
||||||
)
|
)
|
||||||
|
@ -69,50 +60,32 @@ export const getMktPayouts = (
|
||||||
? getProbability(contract.totalShares)
|
? getProbability(contract.totalShares)
|
||||||
: resolutionProbability
|
: resolutionProbability
|
||||||
|
|
||||||
const poolTotal = contract.pool.YES + contract.pool.NO
|
const pool = contract.pool.YES + contract.pool.NO
|
||||||
console.log('Resolved MKT at p=', p, 'pool: $M', poolTotal)
|
console.log('Resolved MKT at p=', p, 'pool: $M', pool)
|
||||||
|
|
||||||
const [yesBets, noBets] = partition(bets, (bet) => bet.outcome === 'YES')
|
const [yesBets, noBets] = _.partition(bets, (bet) => bet.outcome === 'YES')
|
||||||
|
|
||||||
const weightedBetTotal =
|
|
||||||
p * sumBy(yesBets, (b) => b.amount) +
|
|
||||||
(1 - p) * sumBy(noBets, (b) => b.amount)
|
|
||||||
|
|
||||||
if (weightedBetTotal >= poolTotal) {
|
|
||||||
return bets.map((bet) => ({
|
|
||||||
userId: bet.userId,
|
|
||||||
payout:
|
|
||||||
(((bet.outcome === 'YES' ? p : 1 - p) * bet.amount) /
|
|
||||||
weightedBetTotal) *
|
|
||||||
poolTotal,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
const winningsPool = poolTotal - weightedBetTotal
|
|
||||||
|
|
||||||
const weightedShareTotal =
|
const weightedShareTotal =
|
||||||
p * sumBy(yesBets, (b) => b.shares - b.amount) +
|
p * _.sumBy(yesBets, (b) => b.shares) +
|
||||||
(1 - p) * sumBy(noBets, (b) => b.shares - b.amount)
|
(1 - p) * _.sumBy(noBets, (b) => b.shares)
|
||||||
|
|
||||||
const yesPayouts = yesBets.map((bet) => ({
|
const yesPayouts = yesBets.map((bet) => ({
|
||||||
userId: bet.userId,
|
userId: bet.userId,
|
||||||
payout:
|
payout: deductFees(
|
||||||
p * bet.amount +
|
bet.amount,
|
||||||
(1 - FEES) *
|
((p * bet.shares) / weightedShareTotal) * pool
|
||||||
((p * (bet.shares - bet.amount)) / weightedShareTotal) *
|
),
|
||||||
winningsPool,
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const noPayouts = noBets.map((bet) => ({
|
const noPayouts = noBets.map((bet) => ({
|
||||||
userId: bet.userId,
|
userId: bet.userId,
|
||||||
payout:
|
payout: deductFees(
|
||||||
(1 - p) * bet.amount +
|
bet.amount,
|
||||||
(1 - FEES) *
|
(((1 - p) * bet.shares) / weightedShareTotal) * pool
|
||||||
(((1 - p) * (bet.shares - bet.amount)) / weightedShareTotal) *
|
),
|
||||||
winningsPool,
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const creatorPayout = CREATOR_FEE * winningsPool
|
const creatorPayout = CREATOR_FEE * pool
|
||||||
|
|
||||||
return [
|
return [
|
||||||
...yesPayouts,
|
...yesPayouts,
|
||||||
|
@ -137,20 +110,3 @@ export const getPayouts = (
|
||||||
return getCancelPayouts(contract, bets)
|
return getCancelPayouts(contract, bets)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const partition = <T>(array: T[], f: (t: T) => boolean) => {
|
|
||||||
const yes = []
|
|
||||||
const no = []
|
|
||||||
|
|
||||||
for (let t of array) {
|
|
||||||
if (f(t)) yes.push(t)
|
|
||||||
else no.push(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
return [yes, no] as [T[], T[]]
|
|
||||||
}
|
|
||||||
|
|
||||||
const sumBy = <T>(array: T[], f: (t: T) => number) => {
|
|
||||||
const values = array.map(f)
|
|
||||||
return values.reduce((prev, cur) => prev + cur, 0)
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user