Support limit orders on numeric markets

This commit is contained in:
James Grugett 2022-07-06 23:09:38 -05:00
parent a68c100df8
commit 60f5f311f9
5 changed files with 81 additions and 26 deletions

View File

@ -33,7 +33,10 @@ import {
getCpmmLiquidityFee,
calculateCpmmAmount,
} from 'common/calculate-cpmm'
import { getFormattedMappedValue } from 'common/pseudo-numeric'
import {
getFormattedMappedValue,
getPseudoProbability,
} from 'common/pseudo-numeric'
import { SellRow } from './sell-row'
import { useSaveShares } from './use-save-shares'
import { SignUpPrompt } from './sign-up-prompt'
@ -43,6 +46,7 @@ import { track } from 'web/lib/service/analytics'
import { removeUndefinedProps } from 'common/util/object'
import { useUnfilledBets } from 'web/hooks/use-bets'
import { LimitBets } from './limit-bets'
import { BucketInput } from './bucket-input'
export function BetPanel(props: {
contract: CPMMBinaryContract | PseudoNumericContract
@ -98,7 +102,11 @@ export function BetPanel(props: {
<SignUpPrompt />
</Col>
{yourUnfilledBets.length > 0 && (
<LimitBets className="mt-4" bets={yourUnfilledBets} />
<LimitBets
className="mt-4"
contract={contract}
bets={yourUnfilledBets}
/>
)}
</Col>
)
@ -407,16 +415,37 @@ function BuyPanel(props: {
{isLimitOrder && (
<>
<div className="my-3 text-left text-sm text-gray-500">
{betChoice === 'NO' ? 'Min' : 'Max'} probability
{betChoice === 'NO' ? 'Min' : 'Max'}{' '}
{isPseudoNumeric ? 'value' : 'probability'}
</div>
<ProbabilityInput
inputClassName="w-full max-w-none"
prob={limitProb}
onChange={setLimitProb}
error={error}
setError={setError}
disabled={isSubmitting}
/>
{isPseudoNumeric ? (
<BucketInput
contract={contract}
onBucketChange={(value) =>
setLimitProb(
value === undefined
? undefined
: 100 *
getPseudoProbability(
value,
contract.min,
contract.max,
contract.isLogScale
)
)
}
isSubmitting={isSubmitting}
/>
) : (
<ProbabilityInput
inputClassName="w-full max-w-none"
prob={limitProb}
onChange={setLimitProb}
error={error}
setError={setError}
disabled={isSubmitting}
/>
)}
</>
)}
<Col className="mt-3 w-full gap-3">

View File

@ -1,12 +1,12 @@
import { useState } from 'react'
import { NumericContract } from 'common/contract'
import { NumericContract, PseudoNumericContract } from 'common/contract'
import { getMappedBucket } from 'common/calculate-dpm'
import { NumberInput } from './number-input'
export function BucketInput(props: {
contract: NumericContract
contract: NumericContract | PseudoNumericContract
isSubmitting?: boolean
onBucketChange: (value?: number, bucket?: string) => void
}) {
@ -24,7 +24,10 @@ export function BucketInput(props: {
return
}
const bucket = getMappedBucket(value, contract)
const bucket =
contract.outcomeType === 'PSEUDO_NUMERIC'
? ''
: getMappedBucket(value, contract)
onBucketChange(value, bucket)
}

View File

@ -1,15 +1,21 @@
import clsx from 'clsx'
import { LimitBet } from 'common/bet'
import { CPMMBinaryContract, PseudoNumericContract } from 'common/contract'
import { getFormattedMappedValue } from 'common/pseudo-numeric'
import { formatMoney, formatPercent } from 'common/util/format'
import { sortBy, sumBy } from 'lodash'
import { sortBy } from 'lodash'
import { useState } from 'react'
import { cancelBet } from 'web/lib/firebase/api-call'
import { Col } from './layout/col'
import { LoadingIndicator } from './loading-indicator'
import { BinaryOutcomeLabel } from './outcome-label'
import { BinaryOutcomeLabel, PseudoNumericOutcomeLabel } from './outcome-label'
export function LimitBets(props: { bets: LimitBet[]; className?: string }) {
const { bets, className } = props
export function LimitBets(props: {
contract: CPMMBinaryContract | PseudoNumericContract
bets: LimitBet[]
className?: string
}) {
const { contract, bets, className } = props
const recentBets = sortBy(bets, (bet) => bet.createdTime).reverse()
return (
@ -18,7 +24,7 @@ export function LimitBets(props: { bets: LimitBet[]; className?: string }) {
<table className="table-compact table w-full rounded text-gray-500">
<tbody>
{recentBets.map((bet) => (
<LimitBet key={bet.id} bet={bet} />
<LimitBet key={bet.id} bet={bet} contract={contract} />
))}
</tbody>
</table>
@ -26,9 +32,14 @@ export function LimitBets(props: { bets: LimitBet[]; className?: string }) {
)
}
function LimitBet(props: { bet: LimitBet }) {
const { bet } = props
function LimitBet(props: {
contract: CPMMBinaryContract | PseudoNumericContract
bet: LimitBet
}) {
const { contract, bet } = props
const { orderAmount, amount, limitProb, outcome } = bet
const isPseudoNumeric = contract.outcomeType === 'PSEUDO_NUMERIC'
const [isCancelling, setIsCancelling] = useState(false)
const onCancel = () => {
@ -40,11 +51,19 @@ function LimitBet(props: { bet: LimitBet }) {
<tr>
<td>
<div className="pl-2">
<BinaryOutcomeLabel outcome={outcome as 'YES' | 'NO'} />
{isPseudoNumeric ? (
<PseudoNumericOutcomeLabel outcome={outcome as 'YES' | 'NO'} />
) : (
<BinaryOutcomeLabel outcome={outcome as 'YES' | 'NO'} />
)}
</div>
</td>
<td>{formatMoney(orderAmount - amount)}</td>
<td>{formatPercent(limitProb)}</td>
<td>
{isPseudoNumeric
? getFormattedMappedValue(contract)(limitProb)
: formatPercent(limitProb)}
</td>
<td>
{isCancelling ? (
<LoadingIndicator />

View File

@ -96,7 +96,7 @@ export function NumericResolutionPanel(props: {
{outcomeMode === 'NUMBER' && (
<BucketInput
contract={contract as any}
contract={contract}
isSubmitting={isSubmitting}
onBucketChange={(v, o) => (setValue(v), setOutcome(o))}
/>

View File

@ -39,7 +39,7 @@ import { FeedBet } from 'web/components/feed/feed-bets'
import { useIsIframe } from 'web/hooks/use-is-iframe'
import ContractEmbedPage from '../embed/[username]/[contractSlug]'
import { useBets, useUnfilledBets } from 'web/hooks/use-bets'
import { CPMMBinaryContract } from 'common/contract'
import { CPMMBinaryContract, PseudoNumericContract } from 'common/contract'
import { AlertBox } from 'web/components/alert-box'
import { useTracking } from 'web/hooks/use-tracking'
import { CommentTipMap, useTipTxns } from 'web/hooks/use-tip-txns'
@ -222,7 +222,11 @@ export function ContractPageContent(
<ContractOverview contract={contract} bets={bets} />
{yourUnfilledBets.length > 0 && (
<LimitBets className="mb-4 xl:hidden" bets={yourUnfilledBets} />
<LimitBets
className="mb-4 xl:hidden"
contract={contract as CPMMBinaryContract | PseudoNumericContract}
bets={yourUnfilledBets}
/>
)}
{isNumeric && (