2021-12-05 08:39:42 +00:00
|
|
|
type Bid = { yesBid: number; noBid: number }
|
|
|
|
|
|
|
|
// An entry has a yes/no for bid, weight, payout, return. Also a current probability
|
|
|
|
export type Entry = {
|
|
|
|
yesBid: number
|
|
|
|
noBid: number
|
|
|
|
yesWeight: number
|
|
|
|
noWeight: number
|
|
|
|
yesPayout: number
|
|
|
|
noPayout: number
|
|
|
|
yesReturn: number
|
|
|
|
noReturn: number
|
|
|
|
prob: number
|
|
|
|
}
|
|
|
|
|
2021-12-08 16:30:29 +00:00
|
|
|
function makeWeights(bids: Bid[]) {
|
|
|
|
const weights = []
|
2021-12-05 08:39:42 +00:00
|
|
|
let yesPot = 0
|
|
|
|
let noPot = 0
|
2021-12-12 23:06:37 +00:00
|
|
|
|
2021-12-05 08:39:42 +00:00
|
|
|
// First pass: calculate all the weights
|
|
|
|
for (const { yesBid, noBid } of bids) {
|
2021-12-14 07:30:09 +00:00
|
|
|
const yesWeight =
|
|
|
|
(yesBid * Math.pow(noPot, 2)) / (Math.pow(yesPot, 2) + yesBid * yesPot) ||
|
|
|
|
0
|
|
|
|
const noWeight =
|
|
|
|
(noBid * Math.pow(yesPot, 2)) / (Math.pow(noPot, 2) + noBid * noPot) || 0
|
2021-12-05 08:39:42 +00:00
|
|
|
|
|
|
|
// Note: Need to calculate weights BEFORE updating pot
|
|
|
|
yesPot += yesBid
|
|
|
|
noPot += noBid
|
2021-12-14 07:30:09 +00:00
|
|
|
const prob =
|
|
|
|
Math.pow(yesPot, 2) / (Math.pow(yesPot, 2) + Math.pow(noPot, 2))
|
2021-12-05 08:39:42 +00:00
|
|
|
|
2021-12-08 16:30:29 +00:00
|
|
|
weights.push({
|
2021-12-05 08:39:42 +00:00
|
|
|
yesBid,
|
|
|
|
noBid,
|
|
|
|
yesWeight,
|
|
|
|
noWeight,
|
|
|
|
prob,
|
|
|
|
})
|
|
|
|
}
|
2021-12-08 16:30:29 +00:00
|
|
|
return weights
|
|
|
|
}
|
2021-12-05 08:39:42 +00:00
|
|
|
|
2021-12-08 16:30:29 +00:00
|
|
|
export function makeEntries(bids: Bid[]): Entry[] {
|
2021-12-05 08:39:42 +00:00
|
|
|
const YES_SEED = bids[0].yesBid
|
|
|
|
const NO_SEED = bids[0].noBid
|
2021-12-12 23:06:37 +00:00
|
|
|
|
2021-12-08 16:30:29 +00:00
|
|
|
const weights = makeWeights(bids)
|
|
|
|
const yesPot = weights.reduce((sum, { yesBid }) => sum + yesBid, 0)
|
|
|
|
const noPot = weights.reduce((sum, { noBid }) => sum + noBid, 0)
|
|
|
|
const yesWeightsSum = weights.reduce((sum, entry) => sum + entry.yesWeight, 0)
|
|
|
|
const noWeightsSum = weights.reduce((sum, entry) => sum + entry.noWeight, 0)
|
2021-12-12 23:06:37 +00:00
|
|
|
|
2021-12-05 08:39:42 +00:00
|
|
|
// Second pass: calculate all the payouts
|
2021-12-08 16:30:29 +00:00
|
|
|
const entries: Entry[] = []
|
2021-12-12 23:06:37 +00:00
|
|
|
|
2021-12-08 16:30:29 +00:00
|
|
|
for (const weight of weights) {
|
|
|
|
const { yesBid, noBid, yesWeight, noWeight } = weight
|
2021-12-05 08:39:42 +00:00
|
|
|
// Payout: You get your initial bid back, as well as your share of the
|
|
|
|
// (noPot - seed) according to your yesWeight
|
2021-12-08 16:30:29 +00:00
|
|
|
const yesPayout = yesBid + (yesWeight / yesWeightsSum) * (noPot - NO_SEED)
|
|
|
|
const noPayout = noBid + (noWeight / noWeightsSum) * (yesPot - YES_SEED)
|
|
|
|
const yesReturn = (yesPayout - yesBid) / yesBid
|
|
|
|
const noReturn = (noPayout - noBid) / noBid
|
|
|
|
entries.push({ ...weight, yesPayout, noPayout, yesReturn, noReturn })
|
2021-12-05 08:39:42 +00:00
|
|
|
}
|
|
|
|
return entries
|
|
|
|
}
|