Update range order UI

This commit is contained in:
James Grugett 2022-07-21 12:28:35 -05:00
parent 90f3204dbf
commit 1ae6756f8f
3 changed files with 148 additions and 61 deletions

View File

@ -262,7 +262,7 @@ export const getBinaryBetStats = (
const totalFees = sum(Object.values(newBet.fees)) const totalFees = sum(Object.values(newBet.fees))
return { currentPayout, currentReturn, totalFees } return { currentPayout, currentReturn, totalFees, newBet }
} }
export const getBinaryRangeBetInfo = ( export const getBinaryRangeBetInfo = (

View File

@ -428,35 +428,58 @@ function RangeOrderPanel(props: {
highLimitProb !== undefined && highLimitProb !== undefined &&
lowLimitProb >= highLimitProb lowLimitProb >= highLimitProb
const betDisabled = isSubmitting || !betAmount || rangeError || error
const hasYesLimitBet = lowLimitProb !== undefined && !!betAmount
const hasNoLimitBet = highLimitProb !== undefined && !!betAmount
const hasTwoBets = hasYesLimitBet && hasNoLimitBet
const yesLimitProb = (lowLimitProb ?? initialProb * 100) / 100
const noLimitProb = (highLimitProb ?? initialProb * 100) / 100
const shares = Math.min(
(betAmount ?? 0) / yesLimitProb,
(betAmount ?? 0) / (1 - noLimitProb)
)
const yesAmount = shares * yesLimitProb
const noAmount = shares * (1 - noLimitProb)
const profitIfBothFilled = shares - (yesAmount + noAmount)
function onBetChange(newAmount: number | undefined) { function onBetChange(newAmount: number | undefined) {
setWasSubmitted(false) setWasSubmitted(false)
setBetAmount(newAmount) setBetAmount(newAmount)
} }
async function submitBet() { async function submitBet() {
if (!user || !betAmount || rangeError) return if (!user || betDisabled) return
const limitProbScaled =
lowLimitProb !== undefined ? lowLimitProb / 100 : undefined
setError(undefined) setError(undefined)
setIsSubmitting(true) setIsSubmitting(true)
placeBet( const betsPromise = hasTwoBets
removeUndefinedProps({ ? Promise.all([
amount: betAmount, placeBet({
outcome: betChoice, betChoice: 'YES',
amount: yesAmount,
limitProb: yesLimitProb,
contractId: contract.id, contractId: contract.id,
limitProb: limitProbScaled, }),
}) placeBet({
) betChoice: 'NO',
.then((r) => { amount: noAmount,
console.log('placed bet. Result:', r) limitProb: noLimitProb,
setIsSubmitting(false) contractId: contract.id,
setWasSubmitted(true) }),
setBetAmount(undefined) ])
if (onBuySuccess) onBuySuccess() : placeBet({
betChoice: hasYesLimitBet ? 'YES' : 'NO',
amount: betAmount,
contractId: contract.id,
limitProb: hasYesLimitBet ? yesLimitProb : noLimitProb,
}) })
betsPromise
.catch((e) => { .catch((e) => {
if (e instanceof APIError) { if (e instanceof APIError) {
setError(e.toString()) setError(e.toString())
@ -466,54 +489,75 @@ function RangeOrderPanel(props: {
} }
setIsSubmitting(false) setIsSubmitting(false)
}) })
.then((r) => {
console.log('placed bet. Result:', r)
setIsSubmitting(false)
setWasSubmitted(true)
setBetAmount(undefined)
if (onBuySuccess) onBuySuccess()
})
if (hasYesLimitBet) {
track('bet', { track('bet', {
location: 'bet panel', location: 'bet panel',
outcomeType: contract.outcomeType, outcomeType: contract.outcomeType,
slug: contract.slug, slug: contract.slug,
contractId: contract.id, contractId: contract.id,
amount: betAmount, amount: yesAmount,
outcome: betChoice, outcome: 'YES',
limitProb: yesLimitProb,
isLimitOrder: true, isLimitOrder: true,
limitProb: limitProbScaled, isRangeOrder: hasTwoBets,
}) })
} }
if (hasNoLimitBet) {
track('bet', {
location: 'bet panel',
outcomeType: contract.outcomeType,
slug: contract.slug,
contractId: contract.id,
amount: noAmount,
outcome: 'NO',
limitProb: noLimitProb,
isLimitOrder: true,
isRangeOrder: hasTwoBets,
})
}
}
const betDisabled = isSubmitting || !betAmount || rangeError || error
const lowProbFrac = (lowLimitProb ?? initialProb * 100) / 100
const { const {
currentPayout: lowPayout, currentPayout: yesPayout,
currentReturn: lowReturn, currentReturn: yesReturn,
totalFees: lowFees, totalFees: yesFees,
newBet: yesBet,
} = getBinaryBetStats( } = getBinaryBetStats(
'YES', 'YES',
betAmount ?? 0, yesAmount,
contract, contract,
lowProbFrac, yesLimitProb,
unfilledBets as LimitBet[] unfilledBets as LimitBet[]
) )
const lowReturnPercent = formatPercent(lowReturn) const yesReturnPercent = formatPercent(yesReturn)
const highProbFrac = (highLimitProb ?? initialProb * 100) / 100
const { const {
currentPayout: highPayout, currentPayout: noPayout,
currentReturn: highReturn, currentReturn: noReturn,
totalFees: highFees, totalFees: noFees,
newBet: noBet,
} = getBinaryBetStats( } = getBinaryBetStats(
'NO', 'NO',
betAmount ?? 0, noAmount,
contract, contract,
highProbFrac, noLimitProb,
unfilledBets as LimitBet[] unfilledBets as LimitBet[]
) )
const highReturnPercent = formatPercent(highReturn) const noReturnPercent = formatPercent(noReturn)
return ( return (
<> <>
<div className="my-3 text-sm text-gray-500"> <div className="my-3 text-sm text-gray-500">
Bet only when the {isPseudoNumeric ? 'value' : 'probability'} reaches Bet only when the {isPseudoNumeric ? 'value' : 'probability'} reaches
low or high limit. Low or High limit.
</div> </div>
<Row className="items-center gap-4"> <Row className="items-center gap-4">
@ -541,7 +585,7 @@ function RangeOrderPanel(props: {
{rangeError && ( {rangeError && (
<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">
Low limit must be less than high limit Low limit must be less than High limit
</div> </div>
)} )}
@ -558,7 +602,50 @@ function RangeOrderPanel(props: {
/> />
<Col className="mt-3 w-full gap-3"> <Col className="mt-3 w-full gap-3">
{lowLimitProb !== undefined && ( {hasYesLimitBet && (
<Row className="items-center justify-between gap-2 text-sm">
<div className="whitespace-nowrap text-gray-500">
{isPseudoNumeric ? (
'Bought now'
) : (
<>
<BinaryOutcomeLabel outcome={'YES'} /> bought now
</>
)}
</div>
<div className="mr-2 whitespace-nowrap">
{formatMoney(yesBet.amount)}/
{formatMoney(yesBet.orderAmount ?? 0)}
</div>
</Row>
)}
{hasNoLimitBet && (
<Row className="items-center justify-between gap-2 text-sm">
<div className="whitespace-nowrap text-gray-500">
{isPseudoNumeric ? (
'Bought now'
) : (
<>
<BinaryOutcomeLabel outcome={'NO'} /> bought now
</>
)}
</div>
<div className="mr-2 whitespace-nowrap">
{formatMoney(noBet.amount)}/{formatMoney(noBet.orderAmount ?? 0)}
</div>
</Row>
)}
{hasTwoBets && (
<Row className="items-center justify-between gap-2 text-sm">
<div className="whitespace-nowrap text-gray-500">
Profit if both orders filled
</div>
<div className="mr-2 whitespace-nowrap">
{formatMoney(profitIfBothFilled)}
</div>
</Row>
)}
{hasYesLimitBet && !hasTwoBets && (
<Row className="items-center justify-between gap-2 text-sm"> <Row className="items-center justify-between gap-2 text-sm">
<Row className="flex-nowrap items-center gap-2 whitespace-nowrap text-gray-500"> <Row className="flex-nowrap items-center gap-2 whitespace-nowrap text-gray-500">
<div> <div>
@ -571,18 +658,18 @@ function RangeOrderPanel(props: {
)} )}
</div> </div>
<InfoTooltip <InfoTooltip
text={`Includes ${formatMoneyWithDecimals(lowFees)} in fees`} text={`Includes ${formatMoneyWithDecimals(yesFees)} in fees`}
/> />
</Row> </Row>
<div> <div>
<span className="mr-2 whitespace-nowrap"> <span className="mr-2 whitespace-nowrap">
{formatMoney(lowPayout)} {formatMoney(yesPayout)}
</span> </span>
(+{lowReturnPercent}) (+{yesReturnPercent})
</div> </div>
</Row> </Row>
)} )}
{highLimitProb !== undefined && ( {hasNoLimitBet && !hasTwoBets && (
<Row className="items-center justify-between gap-2 text-sm"> <Row className="items-center justify-between gap-2 text-sm">
<Row className="flex-nowrap items-center gap-2 whitespace-nowrap text-gray-500"> <Row className="flex-nowrap items-center gap-2 whitespace-nowrap text-gray-500">
<div> <div>
@ -595,22 +682,20 @@ function RangeOrderPanel(props: {
)} )}
</div> </div>
<InfoTooltip <InfoTooltip
text={`Includes ${formatMoneyWithDecimals(highFees)} in fees`} text={`Includes ${formatMoneyWithDecimals(noFees)} in fees`}
/> />
</Row> </Row>
<div> <div>
<span className="mr-2 whitespace-nowrap"> <span className="mr-2 whitespace-nowrap">
{formatMoney(highPayout)} {formatMoney(noPayout)}
</span> </span>
(+{highReturnPercent}) (+{noReturnPercent})
</div> </div>
</Row> </Row>
)} )}
</Col> </Col>
{(lowLimitProb !== undefined || highLimitProb !== undefined) && ( {(hasYesLimitBet || hasNoLimitBet) && <Spacer h={8} />}
<Spacer h={8} />
)}
{user && ( {user && (
<button <button
@ -625,7 +710,9 @@ function RangeOrderPanel(props: {
)} )}
onClick={betDisabled ? undefined : submitBet} onClick={betDisabled ? undefined : submitBet}
> >
{isSubmitting ? 'Submitting...' : 'Submit order'} {isSubmitting
? 'Submitting...'
: `Submit order${hasTwoBets ? 's' : ''}`}
</button> </button>
)} )}

View File

@ -39,7 +39,7 @@ export function BucketInput(props: {
error={undefined} error={undefined}
disabled={isSubmitting} disabled={isSubmitting}
numberString={numberString} numberString={numberString}
label="Value" label=""
/> />
) )
} }