resolve to PROB
This commit is contained in:
parent
a3011d1da7
commit
97c8b86259
|
@ -174,7 +174,10 @@ export function calculatePayoutAfterCorrectBet(contract: Contract, bet: Bet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculateMktPayout(contract: Contract, bet: Bet) {
|
function calculateMktPayout(contract: Contract, bet: Bet) {
|
||||||
const p = getProbability(contract.totalShares)
|
const p =
|
||||||
|
contract.resolutionProbability !== undefined
|
||||||
|
? contract.resolutionProbability
|
||||||
|
: getProbability(contract.totalShares)
|
||||||
|
|
||||||
const weightedTotal =
|
const weightedTotal =
|
||||||
p * contract.totalBets.YES + (1 - p) * contract.totalBets.NO
|
p * contract.totalBets.YES + (1 - p) * contract.totalBets.NO
|
||||||
|
|
|
@ -27,6 +27,7 @@ export type Contract = {
|
||||||
isResolved: boolean
|
isResolved: boolean
|
||||||
resolutionTime?: number // When the contract creator resolved the market
|
resolutionTime?: number // When the contract creator resolved the market
|
||||||
resolution?: outcome // Chosen by creator; must be one of outcomes
|
resolution?: outcome // Chosen by creator; must be one of outcomes
|
||||||
|
resolutionProbability?: number
|
||||||
|
|
||||||
volume24Hours: number
|
volume24Hours: number
|
||||||
volume7Days: number
|
volume7Days: number
|
||||||
|
|
|
@ -59,8 +59,16 @@ export const getStandardPayouts = (
|
||||||
]) // add creator fee
|
]) // add creator fee
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getMktPayouts = (contract: Contract, bets: Bet[]) => {
|
export const getMktPayouts = (
|
||||||
const p = getProbability(contract.totalShares)
|
contract: Contract,
|
||||||
|
bets: Bet[],
|
||||||
|
resolutionProbability?: number
|
||||||
|
) => {
|
||||||
|
const p =
|
||||||
|
resolutionProbability === undefined
|
||||||
|
? getProbability(contract.totalShares)
|
||||||
|
: resolutionProbability
|
||||||
|
|
||||||
const poolTotal = contract.pool.YES + contract.pool.NO
|
const poolTotal = contract.pool.YES + contract.pool.NO
|
||||||
console.log('Resolved MKT at p=', p, 'pool: $M', poolTotal)
|
console.log('Resolved MKT at p=', p, 'pool: $M', poolTotal)
|
||||||
|
|
||||||
|
@ -116,14 +124,15 @@ export const getMktPayouts = (contract: Contract, bets: Bet[]) => {
|
||||||
export const getPayouts = (
|
export const getPayouts = (
|
||||||
outcome: outcome,
|
outcome: outcome,
|
||||||
contract: Contract,
|
contract: Contract,
|
||||||
bets: Bet[]
|
bets: Bet[],
|
||||||
|
resolutionProbability?: number
|
||||||
) => {
|
) => {
|
||||||
switch (outcome) {
|
switch (outcome) {
|
||||||
case 'YES':
|
case 'YES':
|
||||||
case 'NO':
|
case 'NO':
|
||||||
return getStandardPayouts(outcome, contract, bets)
|
return getStandardPayouts(outcome, contract, bets)
|
||||||
case 'MKT':
|
case 'MKT':
|
||||||
return getMktPayouts(contract, bets)
|
return getMktPayouts(contract, bets, resolutionProbability)
|
||||||
case 'CANCEL':
|
case 'CANCEL':
|
||||||
return getCancelPayouts(contract, bets)
|
return getCancelPayouts(contract, bets)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,8 @@ export const sendMarketResolutionEmail = async (
|
||||||
payout: number,
|
payout: number,
|
||||||
creator: User,
|
creator: User,
|
||||||
contract: Contract,
|
contract: Contract,
|
||||||
resolution: 'YES' | 'NO' | 'CANCEL' | 'MKT'
|
resolution: 'YES' | 'NO' | 'CANCEL' | 'MKT',
|
||||||
|
resolutionProbability?: number
|
||||||
) => {
|
) => {
|
||||||
const privateUser = await getPrivateUser(userId)
|
const privateUser = await getPrivateUser(userId)
|
||||||
if (
|
if (
|
||||||
|
@ -33,8 +34,15 @@ export const sendMarketResolutionEmail = async (
|
||||||
const user = await getUser(userId)
|
const user = await getUser(userId)
|
||||||
if (!user) return
|
if (!user) return
|
||||||
|
|
||||||
const prob = formatPercent(getProbability(contract.totalShares))
|
const prob = resolutionProbability ?? getProbability(contract.totalShares)
|
||||||
const outcome = toDisplayResolution[resolution].replace('PROB', prob)
|
|
||||||
|
const toDisplayResolution = {
|
||||||
|
YES: 'YES',
|
||||||
|
NO: 'NO',
|
||||||
|
CANCEL: 'N/A',
|
||||||
|
MKT: formatPercent(prob),
|
||||||
|
}
|
||||||
|
const outcome = toDisplayResolution[resolution]
|
||||||
|
|
||||||
const subject = `Resolved ${outcome}: ${contract.question}`
|
const subject = `Resolved ${outcome}: ${contract.question}`
|
||||||
|
|
||||||
|
@ -59,5 +67,3 @@ export const sendMarketResolutionEmail = async (
|
||||||
templateData
|
templateData
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const toDisplayResolution = { YES: 'YES', NO: 'NO', CANCEL: 'N/A', MKT: 'PROB' }
|
|
||||||
|
|
|
@ -16,17 +16,24 @@ export const resolveMarket = functions
|
||||||
data: {
|
data: {
|
||||||
outcome: 'YES' | 'NO' | 'CANCEL' | 'MKT'
|
outcome: 'YES' | 'NO' | 'CANCEL' | 'MKT'
|
||||||
contractId: string
|
contractId: string
|
||||||
|
probabilityInt?: number
|
||||||
},
|
},
|
||||||
context
|
context
|
||||||
) => {
|
) => {
|
||||||
const userId = context?.auth?.uid
|
const userId = context?.auth?.uid
|
||||||
if (!userId) return { status: 'error', message: 'Not authorized' }
|
if (!userId) return { status: 'error', message: 'Not authorized' }
|
||||||
|
|
||||||
const { outcome, contractId } = data
|
const { outcome, contractId, probabilityInt } = data
|
||||||
|
|
||||||
if (!['YES', 'NO', 'MKT', 'CANCEL'].includes(outcome))
|
if (!['YES', 'NO', 'MKT', 'CANCEL'].includes(outcome))
|
||||||
return { status: 'error', message: 'Invalid outcome' }
|
return { status: 'error', message: 'Invalid outcome' }
|
||||||
|
|
||||||
|
if (
|
||||||
|
probabilityInt !== undefined &&
|
||||||
|
(probabilityInt < 1 || probabilityInt > 99 || !isFinite(probabilityInt))
|
||||||
|
)
|
||||||
|
return { status: 'error', message: 'Invalid probability' }
|
||||||
|
|
||||||
const contractDoc = firestore.doc(`contracts/${contractId}`)
|
const contractDoc = firestore.doc(`contracts/${contractId}`)
|
||||||
const contractSnap = await contractDoc.get()
|
const contractSnap = await contractDoc.get()
|
||||||
if (!contractSnap.exists)
|
if (!contractSnap.exists)
|
||||||
|
@ -42,10 +49,16 @@ export const resolveMarket = functions
|
||||||
const creator = await getUser(contract.creatorId)
|
const creator = await getUser(contract.creatorId)
|
||||||
if (!creator) return { status: 'error', message: 'Creator not found' }
|
if (!creator) return { status: 'error', message: 'Creator not found' }
|
||||||
|
|
||||||
|
const resolutionProbability =
|
||||||
|
probabilityInt !== undefined ? probabilityInt / 100 : undefined
|
||||||
|
|
||||||
await contractDoc.update({
|
await contractDoc.update({
|
||||||
isResolved: true,
|
isResolved: true,
|
||||||
resolution: outcome,
|
resolution: outcome,
|
||||||
resolutionTime: Date.now(),
|
resolutionTime: Date.now(),
|
||||||
|
...(resolutionProbability === undefined
|
||||||
|
? {}
|
||||||
|
: { resolutionProbability }),
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('contract ', contractId, 'resolved to:', outcome)
|
console.log('contract ', contractId, 'resolved to:', outcome)
|
||||||
|
@ -57,7 +70,12 @@ export const resolveMarket = functions
|
||||||
const bets = betsSnap.docs.map((doc) => doc.data() as Bet)
|
const bets = betsSnap.docs.map((doc) => doc.data() as Bet)
|
||||||
const openBets = bets.filter((b) => !b.isSold && !b.sale)
|
const openBets = bets.filter((b) => !b.isSold && !b.sale)
|
||||||
|
|
||||||
const payouts = getPayouts(outcome, contract, openBets)
|
const payouts = getPayouts(
|
||||||
|
outcome,
|
||||||
|
contract,
|
||||||
|
openBets,
|
||||||
|
resolutionProbability
|
||||||
|
)
|
||||||
|
|
||||||
console.log('payouts:', payouts)
|
console.log('payouts:', payouts)
|
||||||
|
|
||||||
|
@ -79,7 +97,8 @@ export const resolveMarket = functions
|
||||||
userPayouts,
|
userPayouts,
|
||||||
creator,
|
creator,
|
||||||
contract,
|
contract,
|
||||||
outcome
|
outcome,
|
||||||
|
resolutionProbability
|
||||||
)
|
)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
@ -91,7 +110,8 @@ const sendResolutionEmails = async (
|
||||||
userPayouts: { [userId: string]: number },
|
userPayouts: { [userId: string]: number },
|
||||||
creator: User,
|
creator: User,
|
||||||
contract: Contract,
|
contract: Contract,
|
||||||
outcome: 'YES' | 'NO' | 'CANCEL' | 'MKT'
|
outcome: 'YES' | 'NO' | 'CANCEL' | 'MKT',
|
||||||
|
resolutionProbability?: number
|
||||||
) => {
|
) => {
|
||||||
const nonWinners = _.difference(
|
const nonWinners = _.difference(
|
||||||
_.uniq(openBets.map(({ userId }) => userId)),
|
_.uniq(openBets.map(({ userId }) => userId)),
|
||||||
|
@ -103,7 +123,14 @@ const sendResolutionEmails = async (
|
||||||
]
|
]
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
emailPayouts.map(([userId, payout]) =>
|
emailPayouts.map(([userId, payout]) =>
|
||||||
sendMarketResolutionEmail(userId, payout, creator, contract, outcome)
|
sendMarketResolutionEmail(
|
||||||
|
userId,
|
||||||
|
payout,
|
||||||
|
creator,
|
||||||
|
contract,
|
||||||
|
outcome,
|
||||||
|
resolutionProbability
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ import { YesNoCancelSelector } from './yes-no-selector'
|
||||||
import { Spacer } from './layout/spacer'
|
import { Spacer } from './layout/spacer'
|
||||||
import { ConfirmationButton as ConfirmationButton } from './confirmation-button'
|
import { ConfirmationButton as ConfirmationButton } from './confirmation-button'
|
||||||
import { resolveMarket } from '../lib/firebase/api-call'
|
import { resolveMarket } from '../lib/firebase/api-call'
|
||||||
|
import { ProbabilitySelector } from './probability-selector'
|
||||||
|
import { getProbability } from '../../common/calculate'
|
||||||
|
|
||||||
export function ResolutionPanel(props: {
|
export function ResolutionPanel(props: {
|
||||||
creator: User
|
creator: User
|
||||||
|
@ -26,6 +28,8 @@ export function ResolutionPanel(props: {
|
||||||
'YES' | 'NO' | 'MKT' | 'CANCEL' | undefined
|
'YES' | 'NO' | 'MKT' | 'CANCEL' | undefined
|
||||||
>()
|
>()
|
||||||
|
|
||||||
|
const [prob, setProb] = useState(getProbability(contract.totalShares) * 100)
|
||||||
|
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||||
const [error, setError] = useState<string | undefined>(undefined)
|
const [error, setError] = useState<string | undefined>(undefined)
|
||||||
|
|
||||||
|
@ -35,6 +39,7 @@ export function ResolutionPanel(props: {
|
||||||
const result = await resolveMarket({
|
const result = await resolveMarket({
|
||||||
outcome,
|
outcome,
|
||||||
contractId: contract.id,
|
contractId: contract.id,
|
||||||
|
probabilityInt: prob,
|
||||||
}).then((r) => r.data as any)
|
}).then((r) => r.data as any)
|
||||||
|
|
||||||
console.log('resolved', outcome, 'result:', result)
|
console.log('resolved', outcome, 'result:', result)
|
||||||
|
@ -113,7 +118,20 @@ export function ResolutionPanel(props: {
|
||||||
}}
|
}}
|
||||||
onSubmit={resolve}
|
onSubmit={resolve}
|
||||||
>
|
>
|
||||||
<p>Are you sure you want to resolve this market?</p>
|
{outcome === 'MKT' ? (
|
||||||
|
<>
|
||||||
|
<p className="mb-4">
|
||||||
|
What probability would you like to resolve the market to?
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ProbabilitySelector
|
||||||
|
probabilityInt={Math.round(prob)}
|
||||||
|
setProbabilityInt={setProb}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<p>Are you sure you want to resolve this market?</p>
|
||||||
|
)}
|
||||||
</ConfirmationButton>
|
</ConfirmationButton>
|
||||||
</Col>
|
</Col>
|
||||||
)
|
)
|
||||||
|
|
|
@ -35,10 +35,11 @@ export function contractMetrics(contract: Contract) {
|
||||||
createdTime,
|
createdTime,
|
||||||
resolutionTime,
|
resolutionTime,
|
||||||
isResolved,
|
isResolved,
|
||||||
|
resolutionProbability,
|
||||||
} = contract
|
} = contract
|
||||||
|
|
||||||
const truePool = pool.YES + pool.NO
|
const truePool = pool.YES + pool.NO
|
||||||
const prob = getProbability(totalShares)
|
const prob = resolutionProbability ?? getProbability(totalShares)
|
||||||
const probPercent = Math.round(prob * 100) + '%'
|
const probPercent = Math.round(prob * 100) + '%'
|
||||||
|
|
||||||
const startProb = getProbability(phantomShares)
|
const startProb = getProbability(phantomShares)
|
||||||
|
|
|
@ -27,13 +27,18 @@ export function scoreTraders(contracts: Contract[], bets: Bet[][]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function scoreUsersByContract(contract: Contract, bets: Bet[]) {
|
function scoreUsersByContract(contract: Contract, bets: Bet[]) {
|
||||||
const { resolution } = contract
|
const { resolution, resolutionProbability } = contract
|
||||||
|
|
||||||
const [closedBets, openBets] = _.partition(
|
const [closedBets, openBets] = _.partition(
|
||||||
bets,
|
bets,
|
||||||
(bet) => bet.isSold || bet.sale
|
(bet) => bet.isSold || bet.sale
|
||||||
)
|
)
|
||||||
const resolvePayouts = getPayouts(resolution ?? 'MKT', contract, openBets)
|
const resolvePayouts = getPayouts(
|
||||||
|
resolution ?? 'MKT',
|
||||||
|
contract,
|
||||||
|
openBets,
|
||||||
|
resolutionProbability
|
||||||
|
)
|
||||||
|
|
||||||
const salePayouts = closedBets.map((bet) => {
|
const salePayouts = closedBets.map((bet) => {
|
||||||
const { userId, sale } = bet
|
const { userId, sale } = bet
|
||||||
|
|
Loading…
Reference in New Issue
Block a user