Fix infinite loop in numeric limit bet

This commit is contained in:
James Grugett 2022-07-22 21:03:07 -05:00
parent 56a579ff91
commit 2116b86aec
3 changed files with 29 additions and 17 deletions

View File

@ -142,6 +142,13 @@ export const computeFills = (
limitProb: number | undefined, limitProb: number | undefined,
unfilledBets: LimitBet[] unfilledBets: LimitBet[]
) => { ) => {
if (isNaN(betAmount)) {
throw new Error('Invalid bet amount: ${betAmount}')
}
if (isNaN(limitProb ?? 0)) {
throw new Error('Invalid limitProb: ${limitProb}')
}
const sortedBets = sortBy( const sortedBets = sortBy(
unfilledBets.filter((bet) => bet.outcome !== outcome), unfilledBets.filter((bet) => bet.outcome !== outcome),
(bet) => (outcome === 'YES' ? bet.limitProb : -bet.limitProb), (bet) => (outcome === 'YES' ? bet.limitProb : -bet.limitProb),

View File

@ -37,6 +37,9 @@ export const getPseudoProbability = (
max: number, max: number,
isLogScale = false isLogScale = false
) => { ) => {
if (value < min) return 0
if (value > max) return 1
if (isLogScale) { if (isLogScale) {
return Math.log10(value - min + 1) / Math.log10(max - min + 1) return Math.log10(value - min + 1) / Math.log10(max - min + 1)
} }

View File

@ -1,6 +1,6 @@
import clsx from 'clsx' import clsx from 'clsx'
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { partition, sum, sumBy } from 'lodash' import { clamp, partition, sum, sumBy } from 'lodash'
import { useUser } from 'web/hooks/use-user' import { useUser } from 'web/hooks/use-user'
import { CPMMBinaryContract, PseudoNumericContract } from 'common/contract' import { CPMMBinaryContract, PseudoNumericContract } from 'common/contract'
@ -385,20 +385,22 @@ function LimitOrderPanel(props: {
(!hasYesLimitBet && !hasNoLimitBet) (!hasYesLimitBet && !hasNoLimitBet)
const yesLimitProb = const yesLimitProb =
lowLimitProb === undefined ? undefined : lowLimitProb / 100 lowLimitProb === undefined ? undefined : clamp(lowLimitProb, 0.001, 0.999)
const noLimitProb = const noLimitProb =
highLimitProb === undefined ? undefined : highLimitProb / 100 highLimitProb === undefined ? undefined : clamp(highLimitProb, 0.001, 0.999)
const amount = betAmount ?? 0
const shares = const shares =
yesLimitProb !== undefined && noLimitProb !== undefined yesLimitProb !== undefined && noLimitProb !== undefined
? Math.min( ? Math.min(amount / yesLimitProb, amount / (1 - noLimitProb))
(betAmount ?? 0) / yesLimitProb, : yesLimitProb !== undefined
(betAmount ?? 0) / (1 - noLimitProb) ? amount / yesLimitProb
) : noLimitProb !== undefined
: (betAmount ?? 0) / (yesLimitProb ?? 1 - (noLimitProb ?? 1)) ? amount / (1 - noLimitProb)
: 0
const yesAmount = shares * (yesLimitProb ?? 1) const yesAmount = shares * (yesLimitProb ?? 1)
const noAmount = shares * (1 - (noLimitProb ?? 1)) const noAmount = shares * (1 - (noLimitProb ?? 0))
const profitIfBothFilled = shares - (yesAmount + noAmount) const profitIfBothFilled = shares - (yesAmount + noAmount)
@ -490,7 +492,7 @@ function LimitOrderPanel(props: {
'YES', 'YES',
yesAmount, yesAmount,
contract, contract,
Math.min(yesLimitProb ?? initialProb, 0.999), yesLimitProb ?? initialProb,
unfilledBets as LimitBet[] unfilledBets as LimitBet[]
) )
const yesReturnPercent = formatPercent(yesReturn) const yesReturnPercent = formatPercent(yesReturn)
@ -504,7 +506,7 @@ function LimitOrderPanel(props: {
'NO', 'NO',
noAmount, noAmount,
contract, contract,
Math.max(noLimitProb ?? initialProb, 0.01), noLimitProb ?? initialProb,
unfilledBets as LimitBet[] unfilledBets as LimitBet[]
) )
const noReturnPercent = formatPercent(noReturn) const noReturnPercent = formatPercent(noReturn)
@ -536,17 +538,17 @@ function LimitOrderPanel(props: {
</Col> </Col>
</Row> </Row>
{rangeError && (
<div className="mb-2 mr-auto self-center whitespace-nowrap text-xs font-medium tracking-wide text-red-500">
{isPseudoNumeric ? 'HIGHER' : 'YES'} limit must be less than{' '}
{isPseudoNumeric ? 'LOWER' : 'NO'} limit
</div>
)}
{outOfRangeError && ( {outOfRangeError && (
<div className="mb-2 mr-auto self-center whitespace-nowrap text-xs font-medium tracking-wide text-red-500"> <div className="mb-2 mr-auto self-center whitespace-nowrap text-xs font-medium tracking-wide text-red-500">
Limit is out of range Limit is out of range
</div> </div>
)} )}
{rangeError && !outOfRangeError && (
<div className="mb-2 mr-auto self-center whitespace-nowrap text-xs font-medium tracking-wide text-red-500">
{isPseudoNumeric ? 'HIGHER' : 'YES'} limit must be less than{' '}
{isPseudoNumeric ? 'LOWER' : 'NO'} limit
</div>
)}
<div className="mt-1 mb-3 text-left text-sm text-gray-500"> <div className="mt-1 mb-3 text-left text-sm text-gray-500">
Max amount<span className="ml-1 text-red-500">*</span> Max amount<span className="ml-1 text-red-500">*</span>