Chapter 7 Exercises
Part A: Order Book Fundamentals (Exercises 1-6)
Exercise 1: Reading an Order Book
Given the following order book for a prediction market contract "Will Team A win the championship?":
BIDS (Buy Orders) ASKS (Sell Orders)
Price Quantity Price Quantity
$0.62 300 $0.64 200
$0.61 150 $0.65 450
$0.60 500 $0.66 100
$0.58 200 $0.68 350
$0.55 800 $0.70 600
Answer the following:
a) What is the best bid? The best ask? b) What is the bid-ask spread? c) What is the midpoint price? d) What is the cumulative bid depth at $0.60 or better? e) What is the total depth on each side of the book? f) If you wanted to buy 250 contracts immediately, what would you pay per contract on average?
Exercise 2: Order Book Terminology
Match each term to its correct definition:
| Term | Definition | |
|---|---|---|
| 1. Maker | A. An order to buy or sell at the best available price | |
| 2. Taker | B. The difference between the best ask and best bid | |
| 3. Spread | C. A trader whose order rests in the book, providing liquidity | |
| 4. Market order | D. A trader whose order matches immediately, consuming liquidity | |
| 5. Depth | E. The total quantity available at a given price level | |
| 6. Midpoint | F. The average of the best bid and best ask |
Exercise 3: Price Bounds in Prediction Markets
A prediction market contract pays $1.00 if an event occurs and $0.00 otherwise.
a) Explain why no rational trader would place a bid above $1.00. b) Explain why no rational trader would place an ask below $0.00. c) A contract is trading at $0.03. What does this imply about the market's view of the event? d) What is the maximum possible spread for a prediction market contract? e) Why are prediction market spreads typically expressed in absolute terms rather than percentage terms?
Exercise 4: Comparing Order Books
Below are snapshots from two different prediction market contracts:
Market A: "Will it rain tomorrow in NYC?"
Bids: $0.70 (1000), $0.69 (800), $0.68 (500)
Asks: $0.71 (900), $0.72 (600), $0.73 (400)
Market B: "Will Company X IPO this year?"
Bids: $0.30 (50), $0.25 (30), $0.20 (20)
Asks: $0.40 (40), $0.45 (25), $0.50 (15)
a) Calculate the spread for each market. b) Calculate the relative spread for each market. c) Which market is more liquid? Justify your answer with at least three metrics. d) In which market would you face more slippage on a 100-contract market buy?
Exercise 5: Order Book Construction
Starting from an empty order book, process the following orders sequentially. After each order, write out the state of the bid and ask sides.
- BUY 100 @ $0.50
- SELL 200 @ $0.55
- BUY 150 @ $0.52
- SELL 80 @ $0.54
- BUY 50 @ $0.54
- SELL 300 @ $0.48
- BUY 100 @ $0.56
For orders 5, 6, and 7, specify: - Whether a trade occurs - The trade price and quantity - The final state of the book after the order
Exercise 6: Spread Dynamics
Explain what happens to the bid-ask spread in each of the following scenarios. Use directional language (widens, narrows, stays the same) and explain why.
a) A major news event is about to be announced (but has not yet occurred). b) A new market maker joins the market and starts quoting both sides. c) All bids at the best price are cancelled simultaneously. d) A large market buy order consumes all the liquidity at the best ask. e) The event in question is resolved -- the outcome is now known.
Part B: Continuous Double Auction and Matching (Exercises 7-12)
Exercise 7: Price-Time Priority
The following sell orders are resting in the book:
| Order ID | Price | Quantity | Arrival Time |
|---|---|---|---|
| S1 | $0.60 | 100 | 10:00:01 |
| S2 | $0.58 | 50 | 10:00:05 |
| S3 | $0.58 | 75 | 10:00:03 |
| S4 | $0.59 | 200 | 10:00:02 |
A buy order arrives: BUY 200 @ $0.60 at 10:00:10.
a) In what order are the sell orders matched? List the order IDs in sequence. b) What trades are generated? List each trade's price, quantity, and counterparty IDs. c) What is the state of the order book after matching?
Exercise 8: Partial Fills
You submit a buy order for 500 contracts at $0.65. The ask side of the book is:
$0.60 150 contracts
$0.62 80 contracts
$0.64 200 contracts
$0.66 300 contracts
a) How many contracts are filled at each price level? b) What is your volume-weighted average execution price? c) How many contracts remain unfilled? d) What happens to the unfilled contracts (assuming GTC time-in-force)? e) What is the new best ask after your order is processed?
Exercise 9: Time-in-Force Comparison
You want to buy 100 contracts. The ask side is:
$0.55 30 contracts
$0.57 40 contracts
$0.60 200 contracts
Describe the outcome if you submit a buy order at $0.57 with each time-in-force:
a) GTC (Good 'Til Cancelled) b) IOC (Immediate or Cancel) c) FOK (Fill or Kill)
Exercise 10: Pro-Rata vs Price-Time Priority
Three sell orders are resting at $0.55:
| Order | Quantity | Arrival Time |
|---|---|---|
| A | 200 | 10:00:01 |
| B | 100 | 10:00:02 |
| C | 300 | 10:00:03 |
A buy order arrives for 300 contracts at $0.55.
a) Under price-time priority, how is the buy order allocated? b) Under pro-rata matching, how is the buy order allocated? c) Discuss one advantage and one disadvantage of each method.
Exercise 11: Market Order Slippage
You submit a market sell order for 400 contracts. The bid side is:
$0.72 100 contracts
$0.70 150 contracts
$0.68 50 contracts
$0.65 200 contracts
$0.60 500 contracts
a) Calculate the exact execution of your order (fills at each price level). b) Calculate your VWAP for this order. c) Calculate the slippage relative to the best bid. d) If you had submitted a limit sell at $0.68, what would have happened differently?
Exercise 12: Matching Engine Edge Cases
For each scenario, describe what the matching engine should do:
a) A buy order at $0.55 and a sell order at $0.55 arrive at exactly the same time. b) A buy order at $0.60 arrives when the best ask is $0.55. At what price does the trade execute? c) A trader submits a sell order at $0.40, but the best bid is $0.45. What happens? d) A FOK buy order for 500 contracts at $0.55 arrives when only 300 contracts are available at $0.55 or below. e) An IOC buy order for 500 contracts at $0.55 arrives when 300 contracts are available at $0.55 or below.
Part C: Depth Charts and Visualization (Exercises 13-18)
Exercise 13: Manual Depth Chart
Given the order book:
Bids: $0.60 (200), $0.58 (300), $0.55 (500), $0.50 (1000)
Asks: $0.62 (150), $0.64 (250), $0.67 (400), $0.70 (700)
a) Calculate the cumulative depth at each bid and ask price level. b) Sketch the depth chart on paper (or describe it in detail). c) Identify any visible support or resistance levels. d) Is this a "thick" or "thin" book? Justify your answer.
Exercise 14: Depth Chart Interpretation
A depth chart for a prediction market shows the following features:
- The bid curve rises steeply from the midpoint to about 1,000 contracts at $0.02 below the midpoint.
- The ask curve rises gently, reaching only 200 contracts at $0.05 above the midpoint.
- There is a large step in the bid curve at $0.45 (a sudden increase of 2,000 contracts).
a) What does the asymmetry between bid and ask curves suggest? b) What might the large step at $0.45 represent? c) How might a large market sell order affect the depth chart? d) Would you describe the overall market as liquid or illiquid?
Exercise 15: Python Depth Chart
Write a Python function analyze_depth(bids, asks) that takes lists of (price, quantity) tuples and returns a dictionary containing:
- Cumulative bid depth at each level
- Cumulative ask depth at each level
- The price level with the most bid depth (single level, not cumulative)
- The price level with the most ask depth (single level, not cumulative)
- The "depth ratio" (total bid depth / total ask depth)
Exercise 16: Dynamic Depth Analysis
At time T=0, the order book is:
Bids: $0.55 (200), $0.54 (300), $0.53 (400)
Asks: $0.57 (200), $0.58 (300), $0.59 (400)
At time T=1, the order book is:
Bids: $0.57 (500), $0.56 (300), $0.55 (200)
Asks: $0.58 (50), $0.60 (100), $0.62 (200)
a) What happened between T=0 and T=1? (Describe the likely event.) b) How did the depth change on each side? c) Calculate the order imbalance at each time point. d) Did the spread change? If so, how and why?
Exercise 17: Support and Resistance Testing
Consider a contract trading at a midpoint of $0.60 with the following depth:
Bids: $0.60 (100), $0.59 (100), $0.58 (100), $0.57 (100),
$0.56 (100), $0.55 (5000)
Asks: $0.61 (100), $0.62 (100), $0.63 (100), $0.64 (100),
$0.65 (5000)
a) Identify the support and resistance levels. b) How many contracts would need to be sold to push the price below $0.55? c) How many contracts would need to be bought to push the price above $0.65? d) If the large order at $0.55 is suddenly cancelled, what happens to the support level? e) How would you verify whether the large orders are genuine or potential spoofing?
Exercise 18: Visualization Challenge
Write Python code using matplotlib to create a combined order book and trade chart that shows:
- A depth chart (top panel) showing bid and ask cumulative depth.
- A time series of trades (bottom panel) showing price and volume over time.
- Color-code trades as green (buyer-initiated) or red (seller-initiated).
Use the following synthetic data (or generate your own):
bids = [(0.55, 200), (0.54, 350), (0.53, 500), (0.52, 150)]
asks = [(0.57, 150), (0.58, 100), (0.59, 300), (0.60, 200)]
trades = [
{'time': 1, 'price': 0.57, 'qty': 50, 'side': 'BUY'},
{'time': 2, 'price': 0.55, 'qty': 30, 'side': 'SELL'},
{'time': 3, 'price': 0.57, 'qty': 80, 'side': 'BUY'},
{'time': 4, 'price': 0.58, 'qty': 20, 'side': 'BUY'},
{'time': 5, 'price': 0.55, 'qty': 100, 'side': 'SELL'},
]
Part D: Market Quality and Metrics (Exercises 19-24)
Exercise 19: Spread Calculations
A prediction market has the following order book snapshots at three different times:
| Time | Best Bid | Best Ask |
|---|---|---|
| T=1 | $0.50 | $0.55 | |
| T=2 | $0.52 | $0.54 | |
| T=3 | $0.48 | $0.60 |
a) Calculate the absolute spread at each time. b) Calculate the relative spread at each time. c) Calculate the time-weighted average spread (assuming equal time intervals). d) At which time is the market most liquid? Least liquid?
Exercise 20: VWAP Calculation
The following trades occurred in a prediction market session:
| Trade # | Price | Quantity |
|---|---|---|
| 1 | $0.55 | 100 |
| 2 | $0.56 | 200 |
| 3 | $0.54 | 50 |
| 4 | $0.57 | 300 |
| 5 | $0.55 | 150 |
| 6 | $0.58 | 100 |
a) Calculate the session VWAP. b) You bought 200 contracts at an average price of $0.555. Did you beat VWAP? c) Calculate the VWAP for only trades 4-6 (the second half of the session). d) Why might VWAP differ between the first and second half of a session?
Exercise 21: Order Imbalance Analysis
At five consecutive time points, the best bid and ask quantities are:
| Time | Bid Qty at Best | Ask Qty at Best |
|---|---|---|
| T=1 | 200 | 200 |
| T=2 | 300 | 150 |
| T=3 | 100 | 400 |
| T=4 | 500 | 100 |
| T=5 | 250 | 250 |
a) Calculate the order book imbalance (OBI) at each time. b) Plot or describe the OBI time series. c) At which time points would you expect upward price pressure? Downward? d) If the midpoint price increased from T=2 to T=3, would this be consistent with the OBI data? Why or why not?
Exercise 22: Price Impact Estimation
An order book has the following ask side:
$0.60 200 contracts
$0.61 100 contracts
$0.62 150 contracts
$0.63 300 contracts
$0.65 500 contracts
The midpoint is $0.595.
a) Calculate the price impact (average execution price minus midpoint) for market buy orders of sizes: 50, 200, 350, 500, and 1000 contracts. b) Plot or describe the price impact curve (price impact vs order size). c) At what order size does price impact accelerate? d) Fit a linear approximation: price_impact = k * order_size. What is k?
Exercise 23: Market Quality Comparison
You are evaluating two prediction markets for the same event. Market A uses an order book (CLOB) and Market B uses an AMM.
Over a 1-hour period, you observe:
Market A (CLOB): - Average spread: $0.03 - Trades: 150 - Total volume: 5,000 contracts - Average depth at best: 100 contracts
Market B (AMM): - Average spread: $0.05 - Trades: 80 - Total volume: 3,000 contracts - Average depth at best: Unlimited (AMM provides continuous liquidity)
a) Which market has lower transaction costs for a 50-contract trade? b) Which market has lower transaction costs for a 500-contract trade? c) Which market provides better price discovery? Why? d) If you were a market maker, which market would you prefer? Why?
Exercise 24: Effective Spread
The following trades occurred with the corresponding midpoint prices at the time of each trade:
| Trade | Price | Quantity | Midpoint |
|---|---|---|---|
| 1 | $0.57 | 100 | $0.555 | ||
| 2 | $0.54 | 80 | $0.555 | ||
| 3 | $0.56 | 200 | $0.560 | ||
| 4 | $0.55 | 150 | $0.555 | ||
| 5 | $0.58 | 50 | $0.565 |
a) Classify each trade as buyer-initiated or seller-initiated. b) Calculate the effective spread for each trade: $2 \times |P_{trade} - P_{mid}|$. c) Calculate the volume-weighted average effective spread. d) Compare the average effective spread to the quoted spread. What does the difference tell you?
Part E: Building and Extending Order Book Systems (Exercises 25-30)
Exercise 25: Order Book Data Class
Implement a Python Order dataclass that includes:
- order_id (string)
- side (BUY or SELL enum)
- price (float)
- quantity (int)
- remaining_quantity (int, defaults to quantity)
- timestamp (float, from time.time())
- time_in_force (GTC, IOC, or FOK enum)
- status (NEW, PARTIALLY_FILLED, FILLED, CANCELLED enum)
Include properties for is_filled and filled_quantity. Write unit tests that verify the dataclass works correctly.
Exercise 26: Price Level Implementation
Implement a PriceLevel class that:
- Stores orders at a single price in FIFO order
- Supports add_order(order), remove_order(order_id), peek() (returns first order without removing)
- Has properties total_quantity and order_count
- Can iterate over orders in time priority
Write tests covering: adding orders, removing orders, peeking at an empty level, and verifying FIFO ordering.
Exercise 27: Simple Matching Engine
Implement a simplified matching engine function:
def match(incoming_order, resting_orders):
"""
Match an incoming order against a list of resting orders
sorted by price-time priority.
Returns:
trades: list of (price, quantity) tuples
remaining: remaining quantity of the incoming order
"""
Test it with the following scenarios: a) Incoming buy at $0.55 against asks at $0.53, $0.54, $0.55 (100 each). Incoming quantity: 250. b) Incoming sell at $0.50 against bids at $0.52, $0.51, $0.50 (50 each). Incoming quantity: 200. c) Incoming buy at $0.45 against asks at $0.50, $0.55 (100 each). No match expected.
Exercise 28: Order Book with Cancel Support
Extend the OrderBook class from Section 7.5 to support:
a) cancel_order(order_id) -- Remove an order and return it (or None if not found).
b) modify_order(order_id, new_price=None, new_quantity=None) -- Modify an order. If price changes, the order loses time priority. If only quantity decreases, time priority is preserved.
c) get_order(order_id) -- Return the order object without modifying it.
Write tests covering: - Cancelling an order that exists - Cancelling an order that does not exist - Modifying price (verify loss of time priority) - Modifying quantity downward (verify preservation of time priority)
Exercise 29: Market Quality Dashboard
Build a Python class MarketDashboard that takes an OrderBook instance and produces a formatted text report including:
- Current best bid and ask with quantities
- Spread (absolute and relative)
- Top 5 price levels on each side with quantities
- Order imbalance at top 1, 3, and 5 levels
- Recent trade summary (last 10 trades): VWAP, total volume, min price, max price
- A simple ASCII depth chart
Test your dashboard by creating an order book, submitting 20+ orders, and printing the report.
Exercise 30: Event Simulation
Build a simulation that:
- Creates a prediction market order book for "Will Event X occur?"
- Initializes with market makers providing liquidity (bids and asks around $0.50).
- Simulates 100 "retail" traders arriving with random buy/sell limit orders normally distributed around the current midpoint.
- At step 50, simulates a "news shock" -- shift the fundamental probability from 50% to 70% by having new orders arrive centered around $0.70.
- Tracks and plots the midpoint price over time.
- Tracks and plots the spread over time.
- Calculates final market quality metrics.
This exercise ties together all concepts from the chapter: order book construction, matching, depth analysis, and market quality measurement.
Hint: Use the OrderBook class from Section 7.5 and the MarketQualityMetrics class from Section 7.7. Generate random orders using Python's random module.