Calculate global leaderboard from contract bets

This commit is contained in:
James Grugett 2022-02-01 21:23:13 -06:00
parent 375ce69b7d
commit ca29a43da9
3 changed files with 42 additions and 22 deletions

View File

@ -1,7 +1,7 @@
import _ from 'lodash' import * as _ from 'lodash'
import { Bet } from './bet'
import { Contract } from './contract' import { Contract } from './contract'
import { getPayouts } from './payouts' import { getPayouts } from './payouts'
import { Bet } from '../web/lib/firebase/bets'
export function scoreCreators(contracts: Contract[], bets: Bet[][]) { export function scoreCreators(contracts: Contract[], bets: Bet[][]) {
const creatorScore = _.mapValues( const creatorScore = _.mapValues(
@ -18,15 +18,12 @@ export function scoreTraders(contracts: Contract[], bets: Bet[][]) {
) )
const userScores: { [userId: string]: number } = {} const userScores: { [userId: string]: number } = {}
for (const scores of userScoresByContract) { for (const scores of userScoresByContract) {
for (const [userId, score] of Object.entries(scores)) { addUserScores(scores, userScores)
if (userScores[userId] === undefined) userScores[userId] = 0
userScores[userId] += score
}
} }
return userScores return userScores
} }
function scoreUsersByContract(contract: Contract, bets: Bet[]) { export function scoreUsersByContract(contract: Contract, bets: Bet[]) {
const { resolution, resolutionProbability } = contract const { resolution, resolutionProbability } = contract
const [closedBets, openBets] = _.partition( const [closedBets, openBets] = _.partition(
@ -61,3 +58,13 @@ function scoreUsersByContract(contract: Contract, bets: Bet[]) {
return userScore return userScore
} }
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
}
}

View File

@ -5,6 +5,7 @@ import * as _ from 'lodash'
import { getValues } from './utils' import { getValues } from './utils'
import { Contract } from '../../common/contract' import { Contract } from '../../common/contract'
import { Bet } from '../../common/bet' import { Bet } from '../../common/bet'
import { addUserScores, scoreUsersByContract } from '../../common/scoring'
const firestore = admin.firestore() const firestore = admin.firestore()
@ -16,8 +17,16 @@ export const updateContractMetrics = functions.pubsub
const contracts = await getValues<Contract>( const contracts = await getValues<Contract>(
firestore.collection('contracts') firestore.collection('contracts')
) )
const userScores: { [userId: string]: number } = {}
await Promise.all( await Promise.all(
contracts.map(async (contract) => { contracts.map(async (contract) => {
const bets = await getValues<Bet>(
firestore.collection(`contracts/${contract.id}/bets`)
)
const contractUserScores = scoreUsersByContract(contract, bets)
addUserScores(contractUserScores, userScores)
const volume24Hours = await computeVolumeFrom(contract, oneDay) const volume24Hours = await computeVolumeFrom(contract, oneDay)
const volume7Days = await computeVolumeFrom(contract, oneDay * 7) const volume7Days = await computeVolumeFrom(contract, oneDay * 7)
@ -28,6 +37,12 @@ export const updateContractMetrics = functions.pubsub
}) })
}) })
) )
for (const [userId, score] of Object.entries(userScores)) {
await firestore.collection('users').doc(userId).update({
totalPnLCached: score,
})
}
}) })
const computeVolumeFrom = async (contract: Contract, timeAgoMs: number) => { const computeVolumeFrom = async (contract: Contract, timeAgoMs: number) => {

View File

@ -7,7 +7,6 @@ import { Contract } from '../../common/contract'
import { Bet } from '../../common/bet' import { Bet } from '../../common/bet'
import { User } from '../../common/user' import { User } from '../../common/user'
import { calculatePayout } from '../../common/calculate' import { calculatePayout } from '../../common/calculate'
import { StripeTransaction } from '.'
const firestore = admin.firestore() const firestore = admin.firestore()
@ -25,25 +24,24 @@ export const updateUserMetrics = functions.pubsub
await Promise.all( await Promise.all(
users.map(async (user) => { users.map(async (user) => {
const investmentValue = await computeInvestmentValue( // const investmentValue = await computeInvestmentValue(
user, // user,
contractsDict // contractsDict
) // )
const deposits = await getValues<StripeTransaction>( // const deposits = await getValues<StripeTransaction>(
firestore // firestore
.collection('stripe-transactions') // .collection('stripe-transactions')
.where('userId', '==', user.id) // .where('userId', '==', user.id)
) // )
const totalDeposits = // const totalDeposits =
1000 + _.sumBy(deposits, (deposit) => deposit.manticDollarQuantity) // 1000 + _.sumBy(deposits, (deposit) => deposit.manticDollarQuantity)
const totalValue = user.balance + investmentValue // const totalValue = user.balance + investmentValue
const totalPnL = totalValue - totalDeposits // const totalPnL = totalValue - totalDeposits
const creatorVolume = await computeTotalVolume(user, contractsDict) const creatorVolume = await computeTotalVolume(user, contractsDict)
return firestore.collection('users').doc(user.id).update({ return firestore.collection('users').doc(user.id).update({
totalPnLCached: totalPnL,
creatorVolumeCached: creatorVolume, creatorVolumeCached: creatorVolume,
}) })
}) })