import React, { Fragment, useEffect, useMemo, useState } from 'react' import { CategoryScale, Chart, LinearScale, PointElement, LineElement, Title, Tooltip, Legend, } from 'chart.js' import { ChartData } from 'chart.js' import { Line } from 'react-chartjs-2' import { bids as sampleBids } from './sample-bids' import { Entry, makeEntries } from './entries' // Auto import doesn't work for some reason... // So we manually register ChartJS components instead: Chart.register( CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend ) function toTable(entries: Entry[]) { return entries.map((entry, i) => { return ( {i + 1} {toRowStart(entry)} {toRowEnd(entry)} ) }) } function toRowStart(entry: Entry) { if (entry.yesBid && entry.noBid) { return (
SEED
{entry.yesBid} / {entry.noBid}
) } else if (entry.yesBid) { return (
YES
{entry.yesBid}
) } else if (entry.noBid) { return (
NO
{entry.noBid}
) } } function toRowEnd(entry: Entry) { if (!entry.yesBid && !entry.noBid) { return ( N/A N/A N/A N/A ) } else if (entry.yesBid && entry.noBid) { return ( N/A {entry.prob.toFixed(2)} N/A N/A ) } else if (entry.yesBid) { return ( {entry.yesWeight.toFixed(2)} {entry.prob.toFixed(2)} {entry.yesPayout.toFixed(2)} {(entry.yesReturn * 100).toFixed(2)}% ) } else { return ( {entry.noWeight.toFixed(2)} {entry.prob.toFixed(2)} {entry.noPayout.toFixed(2)} {(entry.noReturn * 100).toFixed(2)}% ) } } function newBidTable( steps: number, newBid: number, setNewBid: (newBid: number) => void, submitBid: () => void ) { return ( {/* */}
Order # Type Bid Weight Probability Payout Return
{steps + 1}
YES

NO
setNewBid(parseInt(e.target.value) || 0)} onKeyUp={(e) => { if (e.key === 'Enter') { submitBid() } }} onFocus={(e) => e.target.select()} />
) } // Show a hello world React page export default function Simulator() { const [steps, setSteps] = useState(10) const [bids, setBids] = useState(sampleBids) const entries = useMemo( () => makeEntries(bids.slice(0, steps)), [bids, steps] ) const probs = useMemo(() => entries.map((entry) => entry.prob), [entries]) // Set up chart const [chartData, setChartData] = useState({ datasets: [] } as ChartData) useEffect(() => { setChartData({ labels: Array.from({ length: steps }, (_, i) => i + 1), datasets: [ { label: 'Implied probability', data: probs, borderColor: 'rgb(75, 192, 192)', }, ], }) }, [steps]) // Prepare for new bids const [newBid, setNewBid] = useState(0) const [newBidType, setNewBidType] = useState('YES') function makeBid(type: string, bid: number) { return { yesBid: type == 'YES' ? bid : 0, noBid: type == 'YES' ? 0 : bid, } } function submitBid() { if (newBid <= 0) return const bid = makeBid(newBidType, newBid) bids.splice(steps, 0, bid) setBids(bids) setSteps(steps + 1) setNewBid(0) } return (
{/* Left column */}

Dynamic Parimutuel Market Simulator

{/* Range slider that sets the current step */} setSteps(parseInt(e.target.value))} /> {/* New bid table */} {newBidTable(steps, newBid, setNewBid, submitBid)} {/* History of bids */}
{toTable(entries)}
Order # Type Bid Weight Prob Max Payout Return
{/* Right column */}

Probability of
YES

) }