log scale
This commit is contained in:
parent
1afe62296e
commit
543b9960d1
|
@ -1,10 +0,0 @@
|
|||
import { PseudoNumericContract } from './contract'
|
||||
|
||||
export function formatNumericProbability(
|
||||
p: number,
|
||||
contract: PseudoNumericContract
|
||||
) {
|
||||
const { min, max } = contract
|
||||
const value = p * (max - min) + min
|
||||
return Math.round(value).toString()
|
||||
}
|
45
common/pseudo-numeric.ts
Normal file
45
common/pseudo-numeric.ts
Normal file
|
@ -0,0 +1,45 @@
|
|||
import { BinaryContract, PseudoNumericContract } from './contract'
|
||||
import { formatLargeNumber, formatPercent } from './util/format'
|
||||
|
||||
export function formatNumericProbability(
|
||||
p: number,
|
||||
contract: PseudoNumericContract
|
||||
) {
|
||||
const value = getMappedValue(contract)(p)
|
||||
return formatLargeNumber(value)
|
||||
}
|
||||
|
||||
export const getMappedValue =
|
||||
(contract: PseudoNumericContract | BinaryContract) => (p: number) => {
|
||||
if (contract.outcomeType === 'BINARY') return p
|
||||
|
||||
const { min, max, isLogScale } = contract
|
||||
|
||||
if (isLogScale) {
|
||||
const logValue = p * Math.log10(max - min)
|
||||
return 10 ** logValue + min
|
||||
}
|
||||
|
||||
return p * (max - min) + min
|
||||
}
|
||||
|
||||
export const getFormattedMappedValue =
|
||||
(contract: PseudoNumericContract | BinaryContract) => (p: number) => {
|
||||
if (contract.outcomeType === 'BINARY') return formatPercent(p)
|
||||
|
||||
const value = getMappedValue(contract)(p)
|
||||
return formatLargeNumber(value)
|
||||
}
|
||||
|
||||
export const getPseudoProbability = (
|
||||
value: number,
|
||||
min: number,
|
||||
max: number,
|
||||
isLogScale = false
|
||||
) => {
|
||||
if (isLogScale) {
|
||||
return Math.log10(value - min) / Math.log10(max - min)
|
||||
}
|
||||
|
||||
return (value - min) / (max - min)
|
||||
}
|
|
@ -28,6 +28,7 @@ import { getNewContract } from '../../common/new-contract'
|
|||
import { NUMERIC_BUCKET_COUNT } from '../../common/numeric-constants'
|
||||
import { User } from '../../common/user'
|
||||
import { Group, MAX_ID_LENGTH } from '../../common/group'
|
||||
import { getPseudoProbability } from '../../common/pseudo-numeric'
|
||||
|
||||
const bodySchema = z.object({
|
||||
question: z.string().min(1).max(MAX_QUESTION_LENGTH),
|
||||
|
@ -67,7 +68,7 @@ export const createmarket = newEndpoint(['POST'], async (req, auth) => {
|
|||
if (max - min <= 0.01 || initialValue < min || initialValue > max)
|
||||
throw new APIError(400, 'Invalid range.')
|
||||
|
||||
initialProb = ((initialValue - min) / (max - min)) * 100
|
||||
initialProb = getPseudoProbability(initialValue, min, max, isLogScale) * 100
|
||||
}
|
||||
if (outcomeType === 'BINARY') {
|
||||
;({ initialProb } = validate(binarySchema, req.body))
|
||||
|
|
|
@ -6,9 +6,13 @@ import { Comment } from '../../common/comment'
|
|||
import { Contract } from '../../common/contract'
|
||||
import { DPM_CREATOR_FEE } from '../../common/fees'
|
||||
import { PrivateUser, User } from '../../common/user'
|
||||
import { formatMoney, formatPercent } from '../../common/util/format'
|
||||
import {
|
||||
formatLargeNumber,
|
||||
formatMoney,
|
||||
formatPercent,
|
||||
} from '../../common/util/format'
|
||||
import { getValueFromBucket } from '../../common/calculate-dpm'
|
||||
import { formatNumericProbability } from '../../common/numeric'
|
||||
import { formatNumericProbability } from '../../common/pseudo-numeric'
|
||||
|
||||
import { sendTemplateEmail } from './send-email'
|
||||
import { getPrivateUser, getUser } from './utils'
|
||||
|
@ -103,13 +107,14 @@ const toDisplayResolution = (
|
|||
}
|
||||
|
||||
if (contract.outcomeType === 'PSEUDO_NUMERIC') {
|
||||
return (
|
||||
contract.resolutionValue?.toString() ??
|
||||
formatNumericProbability(
|
||||
resolutionProbability ?? getProbability(contract),
|
||||
contract
|
||||
)
|
||||
)
|
||||
const { resolutionValue } = contract
|
||||
|
||||
return resolutionValue
|
||||
? formatLargeNumber(resolutionValue)
|
||||
: formatNumericProbability(
|
||||
resolutionProbability ?? getProbability(contract),
|
||||
contract
|
||||
)
|
||||
}
|
||||
|
||||
if (resolution === 'MKT' && resolutions) return 'MULTI'
|
||||
|
|
|
@ -39,6 +39,7 @@ import {
|
|||
getCpmmProbability,
|
||||
getCpmmLiquidityFee,
|
||||
} from 'common/calculate-cpmm'
|
||||
import { getFormattedMappedValue } from 'common/pseudo-numeric'
|
||||
import { SellRow } from './sell-row'
|
||||
import { useSaveShares } from './use-save-shares'
|
||||
import { SignUpPrompt } from './sign-up-prompt'
|
||||
|
@ -314,10 +315,7 @@ function BuyPanel(props: {
|
|||
)} ${betChoice ?? 'YES'} shares`
|
||||
: undefined
|
||||
|
||||
const format = isPseudoNumeric
|
||||
? (p: number) =>
|
||||
Math.round(p * (contract.max - contract.min) + contract.min).toString()
|
||||
: (p: number) => formatPercent(p)
|
||||
const format = getFormattedMappedValue(contract)
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -512,10 +510,7 @@ export function SellPanel(props: {
|
|||
|
||||
const { outcomeType } = contract
|
||||
const isPseudoNumeric = outcomeType === 'PSEUDO_NUMERIC'
|
||||
const format = isPseudoNumeric
|
||||
? (p: number) =>
|
||||
Math.round(p * (contract.max - contract.min) + contract.min).toString()
|
||||
: (p: number) => formatPercent(p)
|
||||
const format = getFormattedMappedValue(contract)
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -29,7 +29,7 @@ import { useContractWithPreload } from 'web/hooks/use-contract'
|
|||
import { useUser } from 'web/hooks/use-user'
|
||||
import { track } from '@amplitude/analytics-browser'
|
||||
import { trackCallback } from 'web/lib/service/analytics'
|
||||
import { formatNumericProbability } from 'common/numeric'
|
||||
import { formatNumericProbability } from 'common/pseudo-numeric'
|
||||
|
||||
export function ContractCard(props: {
|
||||
contract: Contract
|
||||
|
@ -283,7 +283,9 @@ export function NumericResolutionOrExpectation(props: {
|
|||
{resolution === 'CANCEL' ? (
|
||||
<CancelLabel />
|
||||
) : (
|
||||
<div className="text-blue-400">{resolutionValue}</div>
|
||||
<div className="text-blue-400">
|
||||
{formatLargeNumber(resolutionValue)}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
|
@ -316,8 +318,12 @@ export function PseudoNumericResolutionOrExpectation(props: {
|
|||
<CancelLabel />
|
||||
) : (
|
||||
<div className="text-blue-400">
|
||||
{resolutionValue ??
|
||||
formatNumericProbability(resolutionProbability ?? 0, contract)}
|
||||
{resolutionValue
|
||||
? formatLargeNumber(resolutionValue)
|
||||
: formatNumericProbability(
|
||||
resolutionProbability ?? 0,
|
||||
contract
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
|
|
|
@ -7,6 +7,7 @@ import { Bet } from 'common/bet'
|
|||
import { getInitialProbability } from 'common/calculate'
|
||||
import { BinaryContract, PseudoNumericContract } from 'common/contract'
|
||||
import { useWindowSize } from 'web/hooks/use-window-size'
|
||||
import { getMappedValue } from 'common/pseudo-numeric'
|
||||
|
||||
export const ContractProbGraph = memo(function ContractProbGraph(props: {
|
||||
contract: BinaryContract | PseudoNumericContract
|
||||
|
@ -26,10 +27,7 @@ export const ContractProbGraph = memo(function ContractProbGraph(props: {
|
|||
...bets.map((bet) => bet.createdTime),
|
||||
].map((time) => new Date(time))
|
||||
|
||||
const f =
|
||||
contract.outcomeType === 'PSEUDO_NUMERIC'
|
||||
? (p: number) => (p * (contract.max - contract.min) + contract.min) / 100
|
||||
: (p: number) => p
|
||||
const f = getMappedValue(contract)
|
||||
|
||||
const probs = [startProb, ...bets.map((bet) => bet.probAfter)].map(f)
|
||||
|
||||
|
@ -46,9 +44,11 @@ export const ContractProbGraph = memo(function ContractProbGraph(props: {
|
|||
times.push(latestTime.toDate())
|
||||
probs.push(probs[probs.length - 1])
|
||||
|
||||
const quartiles = [0, 25, 50, 75, 100]
|
||||
|
||||
const yTickValues = isBinary
|
||||
? [0, 25, 50, 75, 100]
|
||||
: [0, 0.25, 0.5, 0.75, 1].map(f).map((x) => x * 100)
|
||||
? quartiles
|
||||
: quartiles.map((x) => x / 100).map(f)
|
||||
|
||||
const { width } = useWindowSize()
|
||||
|
||||
|
@ -64,9 +64,12 @@ export const ContractProbGraph = memo(function ContractProbGraph(props: {
|
|||
const totalPoints = width ? (width > 800 ? 300 : 50) : 1
|
||||
|
||||
const timeStep: number = latestTime.diff(startDate, 'ms') / totalPoints
|
||||
|
||||
const points: { x: Date; y: number }[] = []
|
||||
const s = isBinary ? 100 : 1
|
||||
|
||||
for (let i = 0; i < times.length - 1; i++) {
|
||||
points[points.length] = { x: times[i], y: probs[i] * 100 }
|
||||
points[points.length] = { x: times[i], y: s * probs[i] }
|
||||
const numPoints: number = Math.floor(
|
||||
dayjs(times[i + 1]).diff(dayjs(times[i]), 'ms') / timeStep
|
||||
)
|
||||
|
@ -78,7 +81,7 @@ export const ContractProbGraph = memo(function ContractProbGraph(props: {
|
|||
x: dayjs(times[i])
|
||||
.add(thisTimeStep * n, 'ms')
|
||||
.toDate(),
|
||||
y: probs[i] * 100,
|
||||
y: s * probs[i],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +106,11 @@ export const ContractProbGraph = memo(function ContractProbGraph(props: {
|
|||
yScale={
|
||||
isBinary
|
||||
? { min: 0, max: 100, type: 'linear' }
|
||||
: { min: contract.min, max: contract.max, type: 'linear' }
|
||||
: {
|
||||
min: contract.min,
|
||||
max: contract.max,
|
||||
type: contract.isLogScale ? 'log' : 'linear',
|
||||
}
|
||||
}
|
||||
yFormat={formatter}
|
||||
gridYValues={yTickValues}
|
||||
|
|
|
@ -26,7 +26,7 @@ import { useSaveShares } from '../use-save-shares'
|
|||
import { sellShares } from 'web/lib/firebase/api-call'
|
||||
import { calculateCpmmSale, getCpmmProbability } from 'common/calculate-cpmm'
|
||||
import { track } from 'web/lib/service/analytics'
|
||||
import { formatNumericProbability } from 'common/numeric'
|
||||
import { formatNumericProbability } from 'common/pseudo-numeric'
|
||||
|
||||
const BET_SIZE = 10
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import { ResolveConfirmationButton } from './confirmation-button'
|
|||
import { resolveMarket } from 'web/lib/firebase/fn-call'
|
||||
import { NumericContract, PseudoNumericContract } from 'common/contract'
|
||||
import { BucketInput } from './bucket-input'
|
||||
import { getPseudoProbability } from 'common/pseudo-numeric'
|
||||
|
||||
export function NumericResolutionPanel(props: {
|
||||
creator: User
|
||||
|
@ -44,7 +45,15 @@ export function NumericResolutionPanel(props: {
|
|||
setIsSubmitting(true)
|
||||
|
||||
const boundedValue = Math.max(Math.min(max, value ?? 0), min)
|
||||
const probabilityInt = ((boundedValue - min) / (max - min)) * 100
|
||||
|
||||
const probabilityInt =
|
||||
100 *
|
||||
getPseudoProbability(
|
||||
boundedValue,
|
||||
min,
|
||||
max,
|
||||
outcomeType === 'PSEUDO_NUMERIC' && contract.isLogScale
|
||||
)
|
||||
|
||||
const result = await resolveMarket({
|
||||
outcome: finalOutcome,
|
||||
|
|
Loading…
Reference in New Issue
Block a user