import clsx from 'clsx' import { sortBy } from 'lodash' import { filterDefined } from 'common/util/array' import { ContractMetrics } from 'common/calculate-metrics' import { CPMMBinaryContract, CPMMContract } from 'common/contract' import { formatPercent } from 'common/util/format' import { Col } from '../layout/col' import { LoadingIndicator } from '../loading-indicator' import { ContractCardProbChange } from './contract-card' import { formatNumericProbability } from 'common/pseudo-numeric' export function ProfitChangeTable(props: { contracts: CPMMBinaryContract[] metrics: ContractMetrics[] maxRows?: number }) { const { contracts, metrics, maxRows } = props const contractProfit = metrics.map( (m) => [m.contractId, m.from?.day.profit ?? 0] as const ) const positiveProfit = sortBy( contractProfit.filter(([, profit]) => profit > 0), ([, profit]) => profit ).reverse() const positive = filterDefined( positiveProfit.map(([contractId]) => contracts.find((c) => c.id === contractId) ) ).slice(0, maxRows) const negativeProfit = sortBy( contractProfit.filter(([, profit]) => profit < 0), ([, profit]) => profit ) const negative = filterDefined( negativeProfit.map(([contractId]) => contracts.find((c) => c.id === contractId) ) ).slice(0, maxRows) if (positive.length === 0 && negative.length === 0) return
None
return ( {positive.map((contract) => ( ))} {negative.map((contract) => ( ))} ) } export function ProbChangeTable(props: { changes: CPMMContract[] | undefined full?: boolean }) { const { changes, full } = props if (!changes) return const descendingChanges = sortBy(changes, (c) => c.probChanges.day).reverse() const ascendingChanges = sortBy(changes, (c) => c.probChanges.day) const threshold = 0.01 const positiveAboveThreshold = descendingChanges.filter( (c) => c.probChanges.day > threshold ) const negativeAboveThreshold = ascendingChanges.filter( (c) => c.probChanges.day < threshold ) const maxRows = Math.min( positiveAboveThreshold.length, negativeAboveThreshold.length ) const rows = full ? maxRows : Math.min(3, maxRows) const filteredPositiveChanges = positiveAboveThreshold.slice(0, rows) const filteredNegativeChanges = negativeAboveThreshold.slice(0, rows) if (rows === 0) return
None
return ( {filteredPositiveChanges.map((contract) => ( ))} {filteredNegativeChanges.map((contract) => ( ))} ) } export function ProbOrNumericChange(props: { contract: CPMMContract className?: string }) { const { contract, className } = props const { prob, probChanges: { day: change }, } = contract const number = contract.outcomeType === 'PSEUDO_NUMERIC' ? formatNumericProbability(prob, contract) : null const color = change >= 0 ? 'text-teal-500' : 'text-red-400' return (
{number ? number : formatPercent(Math.round(100 * prob) / 100)}
{(change > 0 ? '+' : '') + (change * 100).toFixed(0) + '%'}
) }