~/experience/columbia

Columbia - Eric J. Schoenberg

Software Engineer · Toronto, Canada · 2023

Market Experiment

Image: Market Experiment Landing

A fintech client came to me with an idea: a prediction market platform — think Robinhood meets a trading floor, but for event-based markets. Tight deadline, limited resources, and a greenfield project with no brand guidelines. It was the kind of engagement where you either ship or you don't.

Starting From Zero

A blank canvas is exciting until you realize you also have to build the brushes.

There were no existing systems to integrate with, no component library to pull from, and no design system to reference. The first thing I had to do was make decisions — about the data model, the market resolution logic, and the overall architecture — before writing a single line of product code.

The core challenge was that prediction markets are harder than they look. Resolving a market isn't just "did X happen" — it requires modelling aggregate demand, supply levels, and price movement in a way that feels fair and believable to users.

The Market Simulation Engine

The hardest part of building a financial system isn't the math — it's making the math feel right.

The centerpiece of the platform was a market resolution engine written in Go. It served as the oracle — the authoritative system that determined how markets moved and eventually settled. I designed an algorithm that calculated demand levels, aggregated supply and demand curves, and resolved markets based on real event outcomes. Tuning this took time. The first versions felt either too volatile or too sluggish — neither inspired confidence. Getting it to a place where price movement was responsive but not erratic was an iterative process of adjusting weights, testing scenarios, and watching the curves.


Market Simulation Engine

The Price Ingestion Pipeline

A financial platform is only as trustworthy as its data.

Underneath the market engine was a real-time price ingestion feed — a polling loop that pulled thousands of financial data points per hour, processed them through a worker pipeline with retries and a dead-letter queue, and recorded every financial event via the Outbox pattern to guarantee no data was lost, even under failure.


Outbox Pattern

This was the first time I implemented the Outbox pattern at this scale, and it fundamentally changed how I think about data reliability. Writing to an events table in the same transaction as your domain data is one of those ideas that feels obvious in retrospect.

The User Portal

The best trading interfaces get out of the way and let you focus on the decision.

The user-facing portal was built with Next.js and styled with Tailwind — a "Robinhood-style" interface for browsing markets, placing positions, and tracking performance. With no brand guidelines to start from, I had to establish a visual language from scratch: color system, typography, component hierarchy.

The admin portal ran parallel to it — a separate surface for managing markets, reviewing outcomes, and overriding edge cases in resolution.

Application Architecture

What I Carried Forward

This project compressed a lot of learning into a short window. Financial systems demand a level of correctness that most applications don't — there's no "good enough" when money is on the line. The Outbox pattern, idempotency, and careful transaction design became parts of my standard toolkit after this engagement. So did the ability to make confident architectural decisions quickly when there's no one else in the room.

  • Go
  • Next.js
  • React
  • PostgreSQL
  • Redis
  • Tailwind CSS
  • Docker
  • AWS