Inspiration

We're mathematicians who got addicted to hackathons. Not the most obvious combination, but it means every time we show up to one we're looking for a problem where the math is the moat.

Prediction markets were it. Polymarket has real volume, real price discovery, real money and zero derivatives infrastructure. You can buy YES or NO and that's it. No options, no hedging, no way to say "I think this probability stays flat" or "volatility spikes before the ruling." Every serious financial market has solved this. Prediction markets haven't, and the reason is the math is genuinely hard.

You can't use Black-Scholes on a probability. The underlying is bounded in [0,1], log-normal dynamics are invalid, and the Greeks break in non-obvious ways. That's exactly the kind of problem we wanted to bring to a hackathon.


What it does

Pythia is a full-stack derivatives platform for prediction markets. It lets traders price, analyze, and paper-trade vanilla options contracts on any Polymarket event.

Pick any market ("Will X win the election?", "Will GDP exceed 3%?") and Pythia gives you:

  • A live options chain with calls and puts across multiple strikes and expiries (3D, 1W, 2W, 1M)
  • Real-time Greeks (Delta, Gamma, Theta, nu) computed via our custom pricing engine
  • Interactive P&L charts showing your exact profit/loss profile at expiry across all possible outcomes
  • Paper trading with a $10,000 simulated portfolio, full order history, and position tracking
  • Portfolio analytics including P&L attribution (directional vs. time decay vs. residual), scenario analysis with probability sliders, and an EV calculator that binary-searches for your breakeven probability
  • Multi-outcome event support: for markets like "Who will win the Republican nomination?", view and trade across all candidates simultaneously with correlated probability charts

Every number on screen is computed from first principles. No hardcoded values, no approximations swept under the rug.


How we built it

The Mathematical Foundation

The core challenge: Black-Scholes doesn't work here. Traditional option pricing assumes the underlying can range from 0 to infinity.

Prediction market probabilities are bounded p in [0,1]. A normal distribution on bounded space violates basic axioms, you'd get negative probabilities or probabilities exceeding 100%.

We developed a logit-normal option pricing model. The key insight:

$$L = \text{logit}(p) = \ln!\left(\frac{p}{1-p}\right) \in (-\infty, +\infty)$$

The logit transform maps bounded probabilities to unbounded log-odds, where standard Brownian motion is valid:

$$dL = \sigma \, dW$$

No drift. In Black-Scholes, the stock price drifts at the risk-free rate under the risk-neutral measure because the hedge can be financed by borrowing at that rate. A probability has no such cost of carry, there is nothing to finance, so the drift is zero. The expected value of a probability is itself. Well, almost.

Jensen's Inequality: The Trap We Almost Fell Into

The naive assumption is $\mathbb{E}[p_T] = p_0$. But:

$$\mathbb{E}[p_T] = \mathbb{E}[\text{sigmoid}(L_T)] \neq \text{sigmoid}(\mathbb{E}[L_T]) = p_0$$

Because sigmoid is concave for $L > 0$ and convex for $L < 0$, Jensen's inequality creates a systematic bias.

For markets near resolution ($p = 0.95+$), the difference between $\mathbb{E}[p_T]$ and $p_0$ can be 3-5%. Getting put-call parity wrong by 5% would create free arbitrage, the one thing a pricing engine must never allow.

We compute $\mathbb{E}^Q[p_T]$ numerically via 400-point midpoint quadrature:

$$\mathbb{E}[p_T] = \int_{-\infty}^{\infty} \text{sigmoid}(l) \cdot \phi!\left(\frac{l - L_0}{\sigma\sqrt{\tau}}\right) \frac{dl}{\sigma\sqrt{\tau}}$$

This expectation feeds directly into our corrected put-call parity: $C - P = \mathbb{E}^Q[p_T] - K$, not $p_0 - K$.

Vanilla Pricing via Numerical Integration

For a call paying $\max(p_T - K,\, 0)$ at expiry:

$$C = \int_{L_K}^{\infty} \bigl[\text{sigmoid}(l) - K\bigr] \cdot \phi!\left(\frac{l - L_0}{\sigma\sqrt{\tau}}\right) \frac{dl}{\sigma\sqrt{\tau}}$$

We only integrate above the kink $L_K = \text{logit}(K)$. Below the kink, payoff is exactly zero, including it wastes quadrature points on a flat region and introduces discontinuity error at the strike.

The Gamma Problem

This was our hardest technical challenge. The standard second finite difference for gamma:

$$\Gamma_{\text{raw}} = \frac{V(p + \delta p) - 2V(p) + V(p - \delta p)}{(\delta p)^2}$$

With $\delta p = 0.005$, the denominator is $2.5 \times 10^{-5}$. Our 400-point integration has numerical error $\sim 10^{-5}$. Dividing noise by $2.5 \times 10^{-5}$ amplifies it $40{,}000\times$. Deep ITM calls (which should have $\Gamma \approx 0$) showed $\Gamma = 0.58$.

Our solution: differentiate the delta function, not the price function:

$$\Gamma = \frac{\Delta(p + \delta p_{\text{outer}}) - \Delta(p - \delta p_{\text{outer}})}{2 \cdot \delta p_{\text{outer}}} \times 0.01$$

$\Delta$ itself uses a central difference with $\epsilon = 0.001$, which smooths integration noise before the outer difference is taken. Noise amplification drops from $40{,}000\times$ to $\sim 25\times$. Deep ITM gamma correctly returns $\approx 0$.

The $\times 0.01$ normalizes to "delta change per 1 percentage point," the unit traders actually think in.

Strike Generation in Logit Space

Fixed percentage grids (5%, 10%, 15%...) are useless for short-dated prediction market options. A 1-week option with $\sigma = 0.8$ has $\sigma\sqrt{\tau} \approx 0.11$ in logit space. A strike at $p = 0.80$ when $p_0 = 0.50$ is $\sim 12\sigma$ away, every Greek rounds to zero.

We generate strikes in logit space with step size $= \max(\sigma\sqrt{\tau} \times 1.2,\; 0.15)$, placing 3 strikes per side of ATM. Every strike is within $\sim 2\sigma$ of the current probability, guaranteeing meaningful premiums and Greeks. Strikes where all Greeks are negligible are filtered out entirely.

Historical Volatility from CLOB Data

We compute $\sigma$ directly from Polymarket's order book history: fetch 30 days of price ticks from the CLOB API, transform to logit space ($L_t = \text{logit}(p_t)$), take first differences ($\Delta L_t = L_{t+1} - L_t$), winsorize at $[1\%, 99\%]$ for robustness against flash crashes, then annualize:

$$\sigma_{\text{annual}} = \sigma_{\text{daily}} \times \sqrt{365}$$

Calendar days (365), not trading days (252). Polymarket resolves any day, including weekends.


The Tech Stack

Frontend: Next.js 16, React 18, TypeScript, Tailwind. Charts: Recharts. Pricing Engine: TypeScript (frontend) + Python/FastAPI (backend). Auth and DB: Supabase (Postgres + RLS + JWT auth). Market Data: Polymarket Gamma API + CLOB WebSocket. Deployment: Vercel (frontend) + Render (backend).

Each contract is \$100 notional. Commission is \$0.02/contract. Paper trading tracks everything through Supabase with row-level security.


Challenges we ran into

Jensen's inequality silently breaks put-call parity. We had puts mispriced by 3-5% for weeks before we realized $\mathbb{E}[\text{sigmoid}(L_T)] \neq p_0$. This would have allowed risk-free arbitrage on our own platform. The fix required numerical integration of the expected terminal probability, something Black-Scholes never needs because stock prices are unbounded.

Gamma noise amplification: dividing integration noise by $(\delta p)^2$ amplified errors $40{,}000\times$. We spent days debugging why deep ITM options showed massive gamma before realizing the issue was fundamental to finite differences on numerically integrated prices. The solution (differentiating delta instead of price) required rethinking the computational graph.

Calendar days vs. trading days. Polymarket resolves on weekends. Using 252 (equity convention) instead of 365 systematically overpriced short-dated options by $\sim 40\%$. A one-line constant change with massive downstream impact.

Polymarket's anonymized labels. For sensitive markets (elections), Polymarket replaces candidate names with "Person AN", "Person CX" in the API. We built regex detection (/^(Person|Team|Player|Contestant)\s+[A-Z]{1,4}$/) and fall back to parsing real names from the question field, which itself is sometimes anonymized, requiring a second layer of detection.

Bounded underlying breaks trader intuition. In equity options, buying a call always gives you positive gamma. In probability space, the sigmoid's concavity can make raw $d^2V/dp^2$ negative for deep ITM options. Mathematically correct, but no trader would trust a platform showing negative gamma on a long call. Our normalization resolves this.


Accomplishments we're proud of

We genuinely did new math. The logit-normal option pricing model, the gamma noise solution via delta-differencing, the Jensen-corrected put-call parity — these aren't in any textbook. We derived them from first principles, validated them empirically, and built them into production code.

Every number is traceable to a formula. Premium? 400-point quadrature over the logit-normal density. Delta? Central difference with $\epsilon = 0.001$. Breakeven? Analytical: $K + \text{premium}/N + \text{commission}/N$. Nothing is faked.

Full portfolio analytics. P&L attribution decomposes returns into directional ($\Delta \times$ probability move), time decay ($\Theta \times$ days held), and residual, the same framework institutional desks use. Scenario analysis lets you drag probability sliders and watch your portfolio reprice in real time.

It works on live markets. Connect to Polymarket, pick any active market, and get a sensible options chain with proper Greeks in under 2 seconds.


What we learned

Bounded underlyings require fundamentally different mathematics. You can't plug probabilities into Black-Scholes. The logit transform, the Jensen correction, the gamma normalization, each is a consequence of working in $[0,1]$ instead of $[0, \infty)$. "Just adapt Black-Scholes" is a trap.

Numerical stability matters more than theoretical elegance. Our closed-form gamma formula was correct but computationally useless. The delta-differencing approach sacrifices mathematical purity for numerical stability, and that's the right tradeoff for a production system.

Financial software is unforgiving. A sign error in put-call parity isn't a UI bug, it's an arbitrage opportunity. An off-by-one in calendar days isn't a rounding error, it's a 40% mispricing. Every constant, every formula, every edge case matters.


What's next for Pythia

Prediction market derivatives are a billion-dollar inevitability.

Polymarket regularly sees \$50M+ daily volume. Kalshi is CFTC-regulated and growing. Yet there is zero derivatives infrastructure. No options, no spreads, no hedging instruments. Hedge funds can't participate at scale because they can't manage risk, they need Greeks, they need hedging, they need portfolio analytics.

Our roadmap: a real matching engine with visible order book depth; a strategy builder where you upload a Python strategy, backtest against historical probability data, and deploy with risk limits; multi-leg structures including spreads, straddles, and strangles on probability space; and an institutional API with FIX protocol integration, bulk pricing endpoints, and real-time Greeks streaming for quant desks.

We're taking this to YC, to hedge funds, to Polymarket itself. The infrastructure for prediction market derivatives doesn't exist yet. We're building it.

IF YOU WANT TO TEST THE PRODUCT WITH AN ACCOUNT, YOU CAN EITHER CREATE AN ACCOUNT or reach out to us at deekshith1210@gmail.com, we will happily provide you with credentials

Built With

  • auth
  • clob
  • db:
  • frontend:-next.js-16
  • gammaapi
  • jwt
  • postgresql
  • python/fastapi
  • react-18
  • render
  • rls
  • tailwind.
  • typescript
  • vercel
  • websocket.
Share this project:

Updates