RITC Volatility Trading Platform
Turning options theory into a tested trading system under competition pressure. Built the full solo volatility-case platform for the Rotman International Trading Competition: Black-Scholes pricing, mispricing detection, constrained portfolio optimization, execution, delta hedging, logging, and operational tooling.
Context
RITC is a three-day global university trading competition built around simulated markets. It was my first trading competition. I represented uOttawa and placed 9th of 38 teams in the solo Volatility Trading case; the team placed 15th of 36 universities overall.
I placed second in the uOttawa team tryout, earned a team spot, and then took full ownership of the volatility case.
The volatility case was the part I owned end-to-end. It was not a market-making strategy. The goal was to understand the case mechanics, identify where options were mispriced relative to theoretical value, and convert that into a repeatable, delta-neutral trading system that could operate under time pressure and strict position limits.

University of Ottawa’s live volatility-case workstation at RITC, with the Python strategy running beside the competition interface.
The harder part was not writing a single pricing script. It was figuring out which options-theory strategy actually produced P&L in the case, then turning that strategy into a system with execution rules, risk controls, logs, and tests.
Problem
The case presented a simple-looking but constraint-heavy trading problem:
- 20 options contracts: 10 calls and 10 puts with strikes from 45 to 54.
- Analyst/news events revealed volatility information over the session.
- Market prices could diverge from Black-Scholes theoretical values.
- Position limits, order-size limits, fees, spreads, delta risk, and time-to-expiry all affected whether a theoretical edge was actually tradeable.
A naive approach would buy anything that looked cheap and sell anything that looked expensive. That was not enough. The system needed to answer a more practical question:
Given the current market, volatility input, option prices, limits, fees, and existing positions, which trades are worth taking now?
My Role & Ownership
What I owned:
- Strategy research for the volatility case
- Black-Scholes pricing and mispricing logic
- Market/news parsing workflow
- Constrained portfolio optimizer
- Execution engine and order sizing
- Delta/risk controls
- SQLite/CSV logging and post-session analysis
- Terminal UI used operationally
Team context: RITC was a broader team competition. The volatility-case platform was my solo build.
System Architecture
RIT REST API + News Feed
↓
Market State Layer
↓
Option Chain + Volatility Parser
↓
Black-Scholes Pricing + Greeks
↓
Mispricing / Edge Calculation
↓
Constrained Portfolio Optimizer
↓
Execution Engine
↓
Delta Hedger + Risk Checks
↓
SQLite / CSV Logs + Post-Session Analysis
↓
Terminal UI for live operation
Core Modules
| Module | Responsibility |
|---|---|
api.py |
RIT REST API wrapper for case state, securities, orders, news, trader state |
news_poller.py |
Parsed analyst/news events for volatility forecasts, delta limits, penalty rates |
market.py |
Maintained current market state, positions, Greeks, pricing volatility |
options_pricer.py |
Generated option contracts, priced with Black-Scholes, computed Greeks |
optimizer.py |
Selected trades using scipy.optimize.linprog under constraints |
execution.py |
Traded the diff between current and target positions, close-first |
hedger.py |
Managed RTM delta exposure under penalty and cost constraints |
orchestrator.py |
Composed the live loop: refresh, price, optimize, execute, hedge, log |
Core Trading Logic
The core signal was theoretical-value mispricing:
- Parse volatility/news events for fair-volatility input.
- Price each option with Black-Scholes.
- Compare theoretical value against market bid/mid/ask.
- Buy underpriced options and sell overpriced options, but only when the edge survived fees, spread, position limits, and risk constraints.
- Use linear programming to allocate limited risk and capacity to the highest-value trades.
- Maintain a delta-neutral strategy by hedging the resulting exposure with the underlying when needed.
- Log each session for review and strategy improvement.
Key Engineering Decisions
1. Target-Portfolio Architecture
Instead of sending ad hoc trades, the system computed a desired target portfolio, compared it to current positions, and traded the difference. This made the execution layer easier to reason about and helped avoid churn.
2. Close-First Execution
The execution engine closed positions before opening new ones. That freed gross/net capacity before adding new exposure, reducing failures caused by competition limits.
3. Risk Limits Before Speed
The system included gross, net, delta, per-option, and order-size constraints. In a competition, a fast bad order is worse than a slower valid one.
4. Logging as a Strategy Tool
Every tick/session produced data for later review: market state, option-chain snapshots, trades, volatility events, gamma exposure, P&L attribution, and execution behavior. The logs turned “it felt like the strategy worked” into something inspectable and improvable.
5. Operational Interface Matched the Real Need
A React/TypeScript/Tailwind dashboard was built during development, but the live competition workflow ultimately did not need a heavy web dashboard. The operational interface moved to a faster terminal UI. A useful lesson: the best interface is the one that fits the task, not the one that looks best in a demo.
Result

Published RITC results with the University of Ottawa row highlighted: 9th in Volatility Trading and 15th overall.
View my original LinkedIn competition recap.
Accuracy Notes
- This was not market making.
- I did not win RITC; the team placed 15th.
- The volatility case was built solo; broader RITC was a team event.