Chapter 32: Key Takeaways — Building a Platform from Scratch

Architecture and Design

  • Use a layered architecture separating routers (HTTP), services (business logic), engines (market mechanisms), and models (data). This makes each layer independently testable and replaceable.
  • Start with FastAPI for prediction market backends. Its native Pydantic validation, automatic OpenAPI documentation, and async support accelerate development significantly.
  • Version your API from day one (/api/v1/). Breaking changes happen; versioning lets you evolve without disrupting existing clients.
  • Use SQLite for prototyping, PostgreSQL for production. SQLAlchemy makes the switch a one-line configuration change.

Order Book Engine

  • Price-time priority is the standard matching rule: best price first, then earliest order among ties.
  • Limit orders rest in the book and provide liquidity; market orders consume liquidity and execute immediately.
  • Lazy cancellation (setting remaining quantity to zero) is cheaper than heap removal and works well when cancellations are infrequent relative to new orders.
  • The trade executes at the maker's (resting order's) price, rewarding liquidity providers.

LMSR Automated Market Maker

  • Cost function: $C(\mathbf{q}) = b \cdot \ln\!\left(\sum_{i=1}^{n} e^{q_i / b}\right)$ determines the running total spent by all traders.
  • Price function: $p_i = e^{q_i / b} / \sum_j e^{q_j / b}$ (softmax) produces probabilities that always sum to 1.
  • Trade cost: $C(\mathbf{q'}) - C(\mathbf{q})$ is the cost difference before and after the share vector changes.
  • Maximum loss: $b \cdot \ln(n)$ bounds the market maker's worst-case subsidy. For binary markets: $\approx 0.693 \cdot b$.
  • The liquidity parameter $b$ controls the trade-off between price stability (high $b$) and subsidy cost (also high $b$). For binary markets with 40-100 traders, $b = 100$ is a reasonable starting point.
  • Always use the log-sum-exp trick to prevent numerical overflow in the exponential calculations.

REST API Design

  • Keep routers thin: They should validate input, call the service, and format the response. Business logic belongs in services.
  • Use Pydantic models for all request and response schemas. This provides automatic validation, documentation, and serialization.
  • Design endpoints around resources (markets, orders, positions) with standard HTTP methods (GET, POST, DELETE).
  • Return appropriate HTTP status codes: 201 for creation, 400 for bad requests, 401 for authentication failures, 404 for not found.

Authentication

  • JWT tokens are stateless: no database lookup needed per request, which scales well.
  • Hash passwords with bcrypt (via passlib). Never store plaintext passwords.
  • Use dependency injection (Depends(get_current_user)) to protect endpoints cleanly.
  • Store secrets in environment variables, never in source code.
  • Set token expiration appropriately (1 hour is common for access tokens).

Market Resolution

  • Markets follow a lifecycle: Open (trading active) -> Closed (trading stopped) -> Resolved (payouts distributed).
  • **Winning positions pay $1 per share**; losing positions pay $0.
  • Voiding refunds participants at cost basis when a market cannot be properly resolved.
  • Pre-specify resolution criteria in the market description to avoid disputes.
  • Record closing prices for calibration analysis—this proves the platform's forecasting value.

Order Book vs. LMSR Decision Framework

  • Use LMSR when: few traders, niche topics, need guaranteed liquidity, want simple UX.
  • Use order book when: many traders, high volume, want best price discovery, cost-sensitive.
  • Consider a hybrid that defaults to LMSR and adds an order book overlay when volume justifies it.

Frontend Considerations

  • API-first development: Use FastAPI's /docs to explore endpoints before building the frontend.
  • Use WebSockets for real-time price updates instead of polling.
  • Optimistic updates make the UI feel responsive: update immediately, roll back on error.
  • Token management: Store JWTs in httpOnly cookies for production security.

Common Pitfalls to Avoid

  • Do not use floating-point for money in production. Use Decimal or integer-cent representation.
  • Do not store engine state only in memory. Server restarts will lose all order books and AMM states. Persist to database or Redis.
  • Do not allow allow_origins=["*"] in production CORS configuration.
  • Do not set $b$ too low for LMSR. This creates excessive price volatility that discourages participation.
  • Do not skip input validation. Always validate that prices are in [0, 1], quantities are positive, and markets are open before executing trades.