Add factors to weight new contracts higher, contracts with unseen comments, and contracts with prob closer to 50%

This commit is contained in:
James Grugett 2022-04-20 16:36:41 -05:00
parent 0390ec0f47
commit 01e43abd17
3 changed files with 54 additions and 25 deletions

View File

@ -18,7 +18,14 @@ import {
getDpmProbabilityAfterSale, getDpmProbabilityAfterSale,
} from './calculate-dpm' } from './calculate-dpm'
import { calculateFixedPayout } from './calculate-fixed-payouts' import { calculateFixedPayout } from './calculate-fixed-payouts'
import { Binary, Contract, CPMM, DPM, FullContract } from './contract' import {
Binary,
Contract,
CPMM,
DPM,
FreeResponseContract,
FullContract,
} from './contract'
export function getProbability(contract: FullContract<DPM | CPMM, Binary>) { export function getProbability(contract: FullContract<DPM | CPMM, Binary>) {
return contract.mechanism === 'cpmm-1' return contract.mechanism === 'cpmm-1'
@ -170,3 +177,15 @@ export function getContractBetNullMetrics() {
profitPercent: 0, profitPercent: 0,
} }
} }
export function getTopAnswer(contract: FreeResponseContract) {
const { answers } = contract
const top = _.maxBy(
answers.map((answer) => ({
answer,
prob: getOutcomeProbability(contract, answer.id),
})),
({ prob }) => prob
)
return top?.answer
}

View File

@ -23,7 +23,7 @@ import {
BinaryContractOutcomeLabel, BinaryContractOutcomeLabel,
FreeResponseOutcomeLabel, FreeResponseOutcomeLabel,
} from '../outcome-label' } from '../outcome-label'
import { getOutcomeProbability } from '../../../common/calculate' import { getOutcomeProbability, getTopAnswer } from '../../../common/calculate'
import { AbbrContractDetails } from './contract-details' import { AbbrContractDetails } from './contract-details'
export function ContractCard(props: { export function ContractCard(props: {
@ -122,18 +122,6 @@ export function BinaryResolutionOrChance(props: {
) )
} }
function getTopAnswer(contract: FreeResponseContract) {
const { answers } = contract
const top = _.maxBy(
answers.map((answer) => ({
answer,
prob: getOutcomeProbability(contract, answer.id),
})),
({ prob }) => prob
)
return top?.answer
}
export function FreeResponseResolutionOrChance(props: { export function FreeResponseResolutionOrChance(props: {
contract: FreeResponseContract contract: FreeResponseContract
truncate: 'short' | 'long' | 'none' truncate: 'short' | 'long' | 'none'

View File

@ -8,6 +8,12 @@ import { logInterpolation } from '../../common/util/math'
import { getRecommendedContracts } from '../../common/recommended-contracts' import { getRecommendedContracts } from '../../common/recommended-contracts'
import { useSeenContracts } from './use-seen-contracts' import { useSeenContracts } from './use-seen-contracts'
import { useGetUserBetContractIds, useUserBetContracts } from './use-user-bets' import { useGetUserBetContractIds, useUserBetContracts } from './use-user-bets'
import { DAY_MS } from '../../common/util/time'
import {
getProbability,
getOutcomeProbability,
getTopAnswer,
} from '../../common/calculate'
const MAX_FEED_CONTRACTS = 75 const MAX_FEED_CONTRACTS = 75
@ -120,11 +126,13 @@ function getContractsActivityScores(
) )
const scoredContracts = contracts.map((contract) => { const scoredContracts = contracts.map((contract) => {
const { outcomeType } = contract
const seenTime = seenContracts[contract.id] const seenTime = seenContracts[contract.id]
const lastCommentTime = contractMostRecentComment[contract.id]?.createdTime const lastCommentTime = contractMostRecentComment[contract.id]?.createdTime
const hasNewComments = const hasNewComments =
!seenTime || (lastCommentTime && lastCommentTime > seenTime) !seenTime || (lastCommentTime && lastCommentTime > seenTime)
const newCommentScore = hasNewComments ? 1 : 0.75 const newCommentScore = hasNewComments ? 1 : 0.5
const commentCount = contractComments[contract.id]?.length ?? 0 const commentCount = contractComments[contract.id]?.length ?? 0
const betCount = contractBets[contract.id]?.length ?? 0 const betCount = contractBets[contract.id]?.length ?? 0
@ -132,25 +140,39 @@ function getContractsActivityScores(
const activityCountScore = const activityCountScore =
0.5 + 0.5 * logInterpolation(0, 200, activtyCount) 0.5 + 0.5 * logInterpolation(0, 200, activtyCount)
const lastBetTime = contractMostRecentBet[contract.id]?.createdTime const lastBetTime =
const timeSinceLastBet = !lastBetTime contractMostRecentBet[contract.id]?.createdTime ?? contract.createdTime
? contract.createdTime const timeSinceLastBet = Date.now() - lastBetTime
: Date.now() - lastBetTime const daysAgo = timeSinceLastBet / DAY_MS
const daysAgo = timeSinceLastBet / oneDayMs
const timeAgoScore = 1 - logInterpolation(0, 3, daysAgo) const timeAgoScore = 1 - logInterpolation(0, 3, daysAgo)
const score = newCommentScore * activityCountScore * timeAgoScore let prob = 0.5
if (outcomeType === 'BINARY') {
prob = getProbability(contract)
} else if (outcomeType === 'FREE_RESPONSE') {
const topAnswer = getTopAnswer(contract)
if (topAnswer)
prob = Math.max(0.5, getOutcomeProbability(contract, topAnswer.id))
}
const frac = 1 - Math.abs(prob - 0.5) ** 2 / 0.25
const probScore = 0.5 + frac * 0.5
const score =
newCommentScore * activityCountScore * timeAgoScore * probScore
// Map score to [0.5, 1] since no recent activty is not a deal breaker. // Map score to [0.5, 1] since no recent activty is not a deal breaker.
const mappedScore = 0.5 + score / 2 const mappedScore = 0.5 + score / 2
return [contract.id, mappedScore] as [string, number] const newMappedScore = 0.75 + score / 4
const isNew = Date.now() < contract.createdTime + DAY_MS
const activityScore = isNew ? newMappedScore : mappedScore
return [contract.id, activityScore] as [string, number]
}) })
return _.fromPairs(scoredContracts) return _.fromPairs(scoredContracts)
} }
const oneDayMs = 24 * 60 * 60 * 1000
function getSeenContractsScore( function getSeenContractsScore(
contract: Contract, contract: Contract,
seenContracts: { [contractId: string]: number } seenContracts: { [contractId: string]: number }
@ -160,7 +182,7 @@ function getSeenContractsScore(
return 1 return 1
} }
const daysAgo = (Date.now() - lastSeen) / oneDayMs const daysAgo = (Date.now() - lastSeen) / DAY_MS
if (daysAgo < 0.5) { if (daysAgo < 0.5) {
const frac = logInterpolation(0, 0.5, daysAgo) const frac = logInterpolation(0, 0.5, daysAgo)