2022-10-10 20:32:29 +00:00
|
|
|
import { groupBy, sumBy, mapValues, keyBy, sortBy } from 'lodash'
|
2022-03-15 22:27:51 +00:00
|
|
|
|
2022-02-02 03:23:13 +00:00
|
|
|
import { Bet } from './bet'
|
2022-10-10 20:32:29 +00:00
|
|
|
import { getContractBetMetrics, resolvedPayout } from './calculate'
|
2022-06-01 02:42:35 +00:00
|
|
|
import { Contract } from './contract'
|
2022-10-10 20:32:29 +00:00
|
|
|
import { ContractComment } from './comment'
|
2022-01-22 23:59:50 +00:00
|
|
|
|
2022-05-26 00:12:36 +00:00
|
|
|
export function scoreCreators(contracts: Contract[]) {
|
2022-05-22 08:36:05 +00:00
|
|
|
const creatorScore = mapValues(
|
|
|
|
groupBy(contracts, ({ creatorId }) => creatorId),
|
2022-06-22 16:35:50 +00:00
|
|
|
(contracts) =>
|
|
|
|
sumBy(
|
|
|
|
contracts.map((contract) => {
|
|
|
|
return contract.volume
|
|
|
|
})
|
|
|
|
)
|
2022-01-22 23:59:50 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
return creatorScore
|
|
|
|
}
|
|
|
|
|
|
|
|
export function scoreTraders(contracts: Contract[], bets: Bet[][]) {
|
|
|
|
const userScoresByContract = contracts.map((contract, index) =>
|
|
|
|
scoreUsersByContract(contract, bets[index])
|
|
|
|
)
|
|
|
|
const userScores: { [userId: string]: number } = {}
|
|
|
|
for (const scores of userScoresByContract) {
|
2022-02-02 03:23:13 +00:00
|
|
|
addUserScores(scores, userScores)
|
2022-01-22 23:59:50 +00:00
|
|
|
}
|
|
|
|
return userScores
|
|
|
|
}
|
|
|
|
|
2022-06-01 02:42:35 +00:00
|
|
|
export function scoreUsersByContract(contract: Contract, bets: Bet[]) {
|
2022-10-10 20:32:29 +00:00
|
|
|
const betsByUser = groupBy(bets, (bet) => bet.userId)
|
|
|
|
return mapValues(
|
|
|
|
betsByUser,
|
|
|
|
(bets) => getContractBetMetrics(contract, bets).profit
|
|
|
|
)
|
2022-01-22 23:59:50 +00:00
|
|
|
}
|
2022-02-02 03:23:13 +00:00
|
|
|
|
|
|
|
export function addUserScores(
|
|
|
|
src: { [userId: string]: number },
|
|
|
|
dest: { [userId: string]: number }
|
|
|
|
) {
|
|
|
|
for (const [userId, score] of Object.entries(src)) {
|
|
|
|
if (dest[userId] === undefined) dest[userId] = 0
|
|
|
|
dest[userId] += score
|
|
|
|
}
|
|
|
|
}
|
2022-10-10 20:32:29 +00:00
|
|
|
|
|
|
|
export function scoreCommentorsAndBettors(
|
|
|
|
contract: Contract,
|
|
|
|
bets: Bet[],
|
|
|
|
comments: ContractComment[]
|
|
|
|
) {
|
|
|
|
const commentsById = keyBy(comments, 'id')
|
|
|
|
const betsById = keyBy(bets, 'id')
|
|
|
|
|
|
|
|
// If 'id2' is the sale of 'id1', both are logged with (id2 - id1) of profit
|
|
|
|
// Otherwise, we record the profit at resolution time
|
|
|
|
const profitById: Record<string, number> = {}
|
|
|
|
for (const bet of bets) {
|
|
|
|
if (bet.sale) {
|
|
|
|
const originalBet = betsById[bet.sale.betId]
|
|
|
|
const profit = bet.sale.amount - originalBet.amount
|
|
|
|
profitById[bet.id] = profit
|
|
|
|
profitById[originalBet.id] = profit
|
|
|
|
} else {
|
|
|
|
profitById[bet.id] = resolvedPayout(contract, bet) - bet.amount
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now find the betId with the highest profit
|
|
|
|
const topBetId = sortBy(bets, (b) => -profitById[b.id])[0]?.id
|
|
|
|
const topBettor = betsById[topBetId]?.userName
|
|
|
|
|
|
|
|
// And also the commentId of the comment with the highest profit
|
|
|
|
const topCommentId = sortBy(
|
|
|
|
comments,
|
|
|
|
(c) => c.betId && -profitById[c.betId]
|
|
|
|
)[0]?.id
|
|
|
|
const topCommentBetId = commentsById[topCommentId]?.betId
|
|
|
|
|
|
|
|
return {
|
|
|
|
topCommentId,
|
|
|
|
topBetId,
|
|
|
|
topBettor,
|
|
|
|
profitById,
|
|
|
|
commentsById,
|
|
|
|
betsById,
|
|
|
|
topCommentBetId,
|
|
|
|
}
|
|
|
|
}
|