Skip to content

Instantly share code, notes, and snippets.

@mcapodici
Created February 22, 2022 05:57
Show Gist options
  • Save mcapodici/ffdba0cb36f8aacbe44730cf2ea44093 to your computer and use it in GitHub Desktop.
Save mcapodici/ffdba0cb36f8aacbe44730cf2ea44093 to your computer and use it in GitHub Desktop.
Simple implementation of a dynamic parimutuel market.
interface Bet {
who: string;
outcome: number; // 1 for A, 2 for B
shares: number; // Number of shares allocated
money: number; // Money placed for given shares
}
interface Pool {
initialMoney: number; // Initial pool
initialProb: number; // Initial probability
bets: Bet[];
}
function initPool(money: number, prob: number): Pool {
return {
initialMoney: money,
initialProb: prob,
bets: [],
};
}
function sum(nums: number[]) {
return nums.reduce((p, c) => p + c, 0);
}
function poolInfo(pool: Pool): any {
const result: any = {
poolSize: pool.initialMoney + sum(pool.bets.map((b) => b.money)),
moneyOnA:
pool.initialMoney * pool.initialProb +
sum(pool.bets.filter((b) => b.outcome === 1).map((b) => b.money)),
moneyOnB:
pool.initialMoney * (1 - pool.initialProb) +
sum(pool.bets.filter((b) => b.outcome === 2).map((b) => b.money)),
sharesOfA:
1 + sum(pool.bets.filter((b) => b.outcome === 1).map((b) => b.shares)),
sharesOfB:
1 + sum(pool.bets.filter((b) => b.outcome === 2).map((b) => b.shares)),
};
result.totalMoney = result.moneyOnA + result.moneyOnB;
result.impliedProb = result.moneyOnA / result.totalMoney;
result.bets = pool.bets.map((b) => {
let profitOnWin =
b.shares *
(b.outcome === 1
? result.moneyOnB / result.sharesOfA
: result.moneyOnA / result.sharesOfB);
return {
...b,
profitOnWin,
returnOnWin: b.money + profitOnWin,
betIPForChosenOutcome: b.money / (b.money + profitOnWin),
};
});
return result;
}
function bet(pool: Pool, who: string, outcome: number, money: number) {
const pi = poolInfo(pool);
const moneyOnOutcome = outcome === 1 ? pi.moneyOnA : pi.moneyOnB;
const sharesOfOther = outcome === 1 ? pi.sharesOfB : pi.sharesOfA;
const shares = Math.log(money / moneyOnOutcome + 1) * sharesOfOther;
pool.bets.push({
who,
money,
shares,
outcome,
});
}
const pool = initPool(100, 0.6);
for (let i = 0; i < 10; i++) {
bet(pool, "player" +i, Math.ceil(Math.random() * 2), Math.ceil(Math.random() * 20));
}
console.log(poolInfo(pool));
@mcapodici
Copy link
Author

MIT licence

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment