Support limit orders on numeric markets
This commit is contained in:
parent
a68c100df8
commit
60f5f311f9
|
@ -33,7 +33,10 @@ import {
|
||||||
getCpmmLiquidityFee,
|
getCpmmLiquidityFee,
|
||||||
calculateCpmmAmount,
|
calculateCpmmAmount,
|
||||||
} from 'common/calculate-cpmm'
|
} from 'common/calculate-cpmm'
|
||||||
import { getFormattedMappedValue } from 'common/pseudo-numeric'
|
import {
|
||||||
|
getFormattedMappedValue,
|
||||||
|
getPseudoProbability,
|
||||||
|
} from 'common/pseudo-numeric'
|
||||||
import { SellRow } from './sell-row'
|
import { SellRow } from './sell-row'
|
||||||
import { useSaveShares } from './use-save-shares'
|
import { useSaveShares } from './use-save-shares'
|
||||||
import { SignUpPrompt } from './sign-up-prompt'
|
import { SignUpPrompt } from './sign-up-prompt'
|
||||||
|
@ -43,6 +46,7 @@ import { track } from 'web/lib/service/analytics'
|
||||||
import { removeUndefinedProps } from 'common/util/object'
|
import { removeUndefinedProps } from 'common/util/object'
|
||||||
import { useUnfilledBets } from 'web/hooks/use-bets'
|
import { useUnfilledBets } from 'web/hooks/use-bets'
|
||||||
import { LimitBets } from './limit-bets'
|
import { LimitBets } from './limit-bets'
|
||||||
|
import { BucketInput } from './bucket-input'
|
||||||
|
|
||||||
export function BetPanel(props: {
|
export function BetPanel(props: {
|
||||||
contract: CPMMBinaryContract | PseudoNumericContract
|
contract: CPMMBinaryContract | PseudoNumericContract
|
||||||
|
@ -98,7 +102,11 @@ export function BetPanel(props: {
|
||||||
<SignUpPrompt />
|
<SignUpPrompt />
|
||||||
</Col>
|
</Col>
|
||||||
{yourUnfilledBets.length > 0 && (
|
{yourUnfilledBets.length > 0 && (
|
||||||
<LimitBets className="mt-4" bets={yourUnfilledBets} />
|
<LimitBets
|
||||||
|
className="mt-4"
|
||||||
|
contract={contract}
|
||||||
|
bets={yourUnfilledBets}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</Col>
|
</Col>
|
||||||
)
|
)
|
||||||
|
@ -407,16 +415,37 @@ function BuyPanel(props: {
|
||||||
{isLimitOrder && (
|
{isLimitOrder && (
|
||||||
<>
|
<>
|
||||||
<div className="my-3 text-left text-sm text-gray-500">
|
<div className="my-3 text-left text-sm text-gray-500">
|
||||||
{betChoice === 'NO' ? 'Min' : 'Max'} probability
|
{betChoice === 'NO' ? 'Min' : 'Max'}{' '}
|
||||||
|
{isPseudoNumeric ? 'value' : 'probability'}
|
||||||
</div>
|
</div>
|
||||||
<ProbabilityInput
|
{isPseudoNumeric ? (
|
||||||
inputClassName="w-full max-w-none"
|
<BucketInput
|
||||||
prob={limitProb}
|
contract={contract}
|
||||||
onChange={setLimitProb}
|
onBucketChange={(value) =>
|
||||||
error={error}
|
setLimitProb(
|
||||||
setError={setError}
|
value === undefined
|
||||||
disabled={isSubmitting}
|
? 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">
|
<Col className="mt-3 w-full gap-3">
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
|
|
||||||
import { NumericContract } from 'common/contract'
|
import { NumericContract, PseudoNumericContract } from 'common/contract'
|
||||||
import { getMappedBucket } from 'common/calculate-dpm'
|
import { getMappedBucket } from 'common/calculate-dpm'
|
||||||
|
|
||||||
import { NumberInput } from './number-input'
|
import { NumberInput } from './number-input'
|
||||||
|
|
||||||
export function BucketInput(props: {
|
export function BucketInput(props: {
|
||||||
contract: NumericContract
|
contract: NumericContract | PseudoNumericContract
|
||||||
isSubmitting?: boolean
|
isSubmitting?: boolean
|
||||||
onBucketChange: (value?: number, bucket?: string) => void
|
onBucketChange: (value?: number, bucket?: string) => void
|
||||||
}) {
|
}) {
|
||||||
|
@ -24,7 +24,10 @@ export function BucketInput(props: {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const bucket = getMappedBucket(value, contract)
|
const bucket =
|
||||||
|
contract.outcomeType === 'PSEUDO_NUMERIC'
|
||||||
|
? ''
|
||||||
|
: getMappedBucket(value, contract)
|
||||||
|
|
||||||
onBucketChange(value, bucket)
|
onBucketChange(value, bucket)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { LimitBet } from 'common/bet'
|
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 { formatMoney, formatPercent } from 'common/util/format'
|
||||||
import { sortBy, sumBy } from 'lodash'
|
import { sortBy } from 'lodash'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { cancelBet } from 'web/lib/firebase/api-call'
|
import { cancelBet } from 'web/lib/firebase/api-call'
|
||||||
import { Col } from './layout/col'
|
import { Col } from './layout/col'
|
||||||
import { LoadingIndicator } from './loading-indicator'
|
import { LoadingIndicator } from './loading-indicator'
|
||||||
import { BinaryOutcomeLabel } from './outcome-label'
|
import { BinaryOutcomeLabel, PseudoNumericOutcomeLabel } from './outcome-label'
|
||||||
|
|
||||||
export function LimitBets(props: { bets: LimitBet[]; className?: string }) {
|
export function LimitBets(props: {
|
||||||
const { bets, className } = props
|
contract: CPMMBinaryContract | PseudoNumericContract
|
||||||
|
bets: LimitBet[]
|
||||||
|
className?: string
|
||||||
|
}) {
|
||||||
|
const { contract, bets, className } = props
|
||||||
const recentBets = sortBy(bets, (bet) => bet.createdTime).reverse()
|
const recentBets = sortBy(bets, (bet) => bet.createdTime).reverse()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -18,7 +24,7 @@ export function LimitBets(props: { bets: LimitBet[]; className?: string }) {
|
||||||
<table className="table-compact table w-full rounded text-gray-500">
|
<table className="table-compact table w-full rounded text-gray-500">
|
||||||
<tbody>
|
<tbody>
|
||||||
{recentBets.map((bet) => (
|
{recentBets.map((bet) => (
|
||||||
<LimitBet key={bet.id} bet={bet} />
|
<LimitBet key={bet.id} bet={bet} contract={contract} />
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -26,9 +32,14 @@ export function LimitBets(props: { bets: LimitBet[]; className?: string }) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function LimitBet(props: { bet: LimitBet }) {
|
function LimitBet(props: {
|
||||||
const { bet } = props
|
contract: CPMMBinaryContract | PseudoNumericContract
|
||||||
|
bet: LimitBet
|
||||||
|
}) {
|
||||||
|
const { contract, bet } = props
|
||||||
const { orderAmount, amount, limitProb, outcome } = bet
|
const { orderAmount, amount, limitProb, outcome } = bet
|
||||||
|
const isPseudoNumeric = contract.outcomeType === 'PSEUDO_NUMERIC'
|
||||||
|
|
||||||
const [isCancelling, setIsCancelling] = useState(false)
|
const [isCancelling, setIsCancelling] = useState(false)
|
||||||
|
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
|
@ -40,11 +51,19 @@ function LimitBet(props: { bet: LimitBet }) {
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div className="pl-2">
|
<div className="pl-2">
|
||||||
<BinaryOutcomeLabel outcome={outcome as 'YES' | 'NO'} />
|
{isPseudoNumeric ? (
|
||||||
|
<PseudoNumericOutcomeLabel outcome={outcome as 'YES' | 'NO'} />
|
||||||
|
) : (
|
||||||
|
<BinaryOutcomeLabel outcome={outcome as 'YES' | 'NO'} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>{formatMoney(orderAmount - amount)}</td>
|
<td>{formatMoney(orderAmount - amount)}</td>
|
||||||
<td>{formatPercent(limitProb)}</td>
|
<td>
|
||||||
|
{isPseudoNumeric
|
||||||
|
? getFormattedMappedValue(contract)(limitProb)
|
||||||
|
: formatPercent(limitProb)}
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{isCancelling ? (
|
{isCancelling ? (
|
||||||
<LoadingIndicator />
|
<LoadingIndicator />
|
||||||
|
|
|
@ -96,7 +96,7 @@ export function NumericResolutionPanel(props: {
|
||||||
|
|
||||||
{outcomeMode === 'NUMBER' && (
|
{outcomeMode === 'NUMBER' && (
|
||||||
<BucketInput
|
<BucketInput
|
||||||
contract={contract as any}
|
contract={contract}
|
||||||
isSubmitting={isSubmitting}
|
isSubmitting={isSubmitting}
|
||||||
onBucketChange={(v, o) => (setValue(v), setOutcome(o))}
|
onBucketChange={(v, o) => (setValue(v), setOutcome(o))}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -39,7 +39,7 @@ import { FeedBet } from 'web/components/feed/feed-bets'
|
||||||
import { useIsIframe } from 'web/hooks/use-is-iframe'
|
import { useIsIframe } from 'web/hooks/use-is-iframe'
|
||||||
import ContractEmbedPage from '../embed/[username]/[contractSlug]'
|
import ContractEmbedPage from '../embed/[username]/[contractSlug]'
|
||||||
import { useBets, useUnfilledBets } from 'web/hooks/use-bets'
|
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 { AlertBox } from 'web/components/alert-box'
|
||||||
import { useTracking } from 'web/hooks/use-tracking'
|
import { useTracking } from 'web/hooks/use-tracking'
|
||||||
import { CommentTipMap, useTipTxns } from 'web/hooks/use-tip-txns'
|
import { CommentTipMap, useTipTxns } from 'web/hooks/use-tip-txns'
|
||||||
|
@ -222,7 +222,11 @@ export function ContractPageContent(
|
||||||
<ContractOverview contract={contract} bets={bets} />
|
<ContractOverview contract={contract} bets={bets} />
|
||||||
|
|
||||||
{yourUnfilledBets.length > 0 && (
|
{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 && (
|
{isNumeric && (
|
||||||
|
|
Loading…
Reference in New Issue
Block a user