Chapter 19 Exercises
Section 19.1-19.2: From Backtest to Live Trading & Bot Architecture
Exercise 1: Identifying Backtest-to-Live Gaps
You have a backtest that shows a strategy earning 3.2 cents per trade on average with a 62% win rate across 1,200 historical trades. The strategy trades prediction markets with an average bid-ask spread of 4 cents and average daily volume of 500 contracts.
(a) Estimate the expected slippage per trade if you use limit orders at the midpoint. (b) Estimate the expected slippage per trade if you use market orders. (c) After accounting for slippage, is the strategy likely profitable in live trading? Justify quantitatively. (d) What position size constraints would you impose given the daily volume?
Exercise 2: Event Bus Implementation
Extend the EventBus class to support:
(a) Event filtering -- subscribers can register for events matching a pattern (e.g., "order_*" matches "order_submitted", "order_filled", etc.)
(b) Priority ordering -- subscribers with higher priority receive events first.
(c) Asynchronous dispatch -- events are published to a queue and processed by a background thread.
Write unit tests for each feature.
Exercise 3: Component Dependency Analysis
Draw a dependency diagram for the trading bot components described in Section 19.2. For each dependency: (a) Classify it as "essential" (the system cannot function without it) or "optional" (degraded but functional without it). (b) Describe the failure mode if that component goes down. (c) Propose a fallback behavior for each component failure.
Exercise 4: Data Feed Resilience
The DataFeedHandler in Section 19.2 uses polling. Modify it to:
(a) Detect stale data (no update for a configurable number of poll cycles).
(b) Publish a StaleDataAlert event when staleness is detected.
(c) Support multiple data sources with automatic failover.
(d) Track data quality metrics (number of successful fetches, failures, average latency).
Exercise 5: Bot Startup Sequence
Write a startup_sequence() function for the trading bot that performs these steps in the correct order:
1. Load persisted state from disk.
2. Connect to the API and verify authentication.
3. Reconcile local positions with exchange positions.
4. Cancel any stale orders from the previous session.
5. Reset daily risk limits.
6. Start the data feed.
7. Enable signal generation.
Handle failures at each step appropriately (some failures should abort startup, others should trigger warnings).
Section 19.3: API Integration and Order Management
Exercise 6: Order State Machine Validation
Implement a method validate_transition(from_state, to_state) -> bool that returns True only if the transition is valid according to the order state machine diagram in Section 19.3.2. Write tests covering all valid and invalid transitions.
Exercise 7: Duplicate Order Prevention
A timeout during order submission means you do not know if the order was placed. Implement a SafeOrderSubmitter class that:
(a) Assigns a unique client order ID before submission.
(b) After a timeout, queries the exchange for orders with that client ID.
(c) Only resubmits if the original order is confirmed not to exist.
(d) Tracks "ambiguous" orders that could not be confirmed either way.
Exercise 8: Order Book Reconstruction
Given a stream of order book updates (price level changes), implement a class that maintains a local copy of the order book with: (a) Best bid and best ask. (b) Total volume at each price level. (c) Mid-price calculation. (d) Spread calculation. (e) Detection of crossed books (best bid >= best ask), which indicates a data error.
Exercise 9: API Response Parser
Different prediction market platforms return order responses in different formats. Write an OrderResponseParser with adapters for three hypothetical platforms:
Platform A returns: {"id": "abc", "state": "open", "filled_size": 10, "price": "0.65"}
Platform B returns: {"order_id": 12345, "status": "ACTIVE", "qty_filled": 10, "limit_price": 0.65}
Platform C returns: {"ref": "xyz-123", "execution_status": "partial", "executed_qty": 10, "px": 65} (price in cents)
Normalize all responses to a common internal format.
Exercise 10: Order Modification
Some platforms support modifying orders (changing price or quantity) rather than cancel-and-replace. Implement an amend_order() method that:
(a) Tries to amend if the platform supports it.
(b) Falls back to cancel-and-replace if amendment is not supported.
(c) Handles the race condition where the original order fills between cancel and replace.
Section 19.4: Rate Limiting and Reliability
Exercise 11: Multi-Tier Rate Limiter
Implement a MultiTierRateLimiter that enforces multiple rate limits simultaneously. For example, an API might have:
- 10 requests per second
- 300 requests per minute
- 5,000 requests per hour
A request is only allowed if it satisfies all tiers. Write a test that demonstrates correct behavior when different tiers are the binding constraint.
Exercise 12: Weighted Rate Limiter
Implement a rate limiter where different API endpoints have different costs: - GET /markets: 1 point - GET /orders: 1 point - POST /orders: 5 points - DELETE /orders: 2 points
Total budget: 100 points per minute. The limiter should track usage by endpoint type and enforce the global budget.
Exercise 13: Circuit Breaker with Metrics
Extend the CircuitBreaker class to track and report:
(a) Total number of successful calls.
(b) Total number of failed calls.
(c) Number of times the circuit opened.
(d) Average time in each state (CLOSED, OPEN, HALF_OPEN).
(e) Current error rate over a sliding window.
Implement a get_health_report() method that returns all metrics.
Exercise 14: Graceful Degradation
Design and implement a GracefulDegrader that manages the bot's behavior as conditions worsen:
- Level 0 (Normal): Full operation.
- Level 1 (Elevated): Reduce polling frequency by 50%, widen spread requirements.
- Level 2 (Degraded): Stop opening new positions, only manage existing ones.
- Level 3 (Critical): Cancel all orders, freeze all activity.
The degradation level should be determined by combining metrics: API error rate, data staleness, and P&L drawdown.
Section 19.5: Pre-Trade Risk Checks
Exercise 15: Correlation-Aware Risk Check
Implement a risk check that limits exposure to correlated markets. Given: - A correlation matrix between markets - A threshold for "correlated" (e.g., correlation > 0.7) - A maximum combined exposure for correlated groups
Write a check_correlation_exposure() method that rejects orders that would cause the combined exposure of any correlated group to exceed the limit.
Exercise 16: Dynamic Risk Limits
Implement a risk manager that adjusts limits based on recent performance: (a) After 3 consecutive losing trades, reduce max order size by 25%. (b) After daily P&L exceeds -50% of the daily loss limit, reduce max order size by 50%. (c) After 5 consecutive winning trades, increase max order size by 10% (but never above the base limit). (d) At the start of each day, reset to base limits.
Exercise 17: Market Regime Risk Checks
Implement a risk check that adjusts behavior based on detected market regime: (a) Normal regime: Standard limits apply. (b) High volatility regime (detected by realized volatility exceeding 2x historical average): Reduce position limits by 50%. (c) Low liquidity regime (detected by volume below 25% of historical average): Reduce order sizes and widen minimum spread requirements. (d) Event regime (approaching known event time): Reduce new position sizes, increase monitoring frequency.
Exercise 18: Risk Limit Configuration
Write a RiskLimitConfig class that:
(a) Loads risk limits from a YAML configuration file.
(b) Validates all limits (e.g., max_order_size must be positive, max_daily_loss must be negative).
(c) Supports per-market overrides (some markets may have tighter limits than the default).
(d) Supports "profiles" (e.g., "conservative", "moderate", "aggressive") that can be switched at runtime.
Section 19.6: Execution Quality
Exercise 19: Execution Quality Benchmarks
Given the following execution data for 100 trades: - Average intended price: 0.55 - Average fill price: 0.557 (for buys), 0.543 (for sells) - Average total latency: 450ms - Fill rate: 72%
(a) Calculate the average slippage in cents and basis points for buys and sells separately. (b) Calculate the implementation shortfall assuming an equal mix of buys and sells. (c) If the average edge per trade is 3 cents, what fraction of the edge is consumed by execution costs? (d) Propose three specific improvements to reduce execution costs.
Exercise 20: Order Splitting Algorithm
Implement a TWAPSplitter (Time-Weighted Average Price) that:
(a) Takes a target quantity and a time window.
(b) Divides the quantity into equal-sized child orders.
(c) Spaces child orders evenly over the time window.
(d) Adjusts remaining child orders if earlier ones do not fill.
(e) Reports the average fill price and total slippage versus a benchmark.
Exercise 21: Adaptive Order Pricing
Implement a pricing strategy that adapts based on recent execution quality: (a) Start with passive pricing (at the best bid for buys, best ask for sells). (b) If the fill rate over the last 10 orders is below 50%, become more aggressive (cross the spread by 1 tick). (c) If the fill rate is above 80%, become more passive (move price 1 tick inside the spread). (d) Track the cost of each pricing level (aggressive vs. passive) over time.
Section 19.7-19.8: Position Tracking, Logging, and Monitoring
Exercise 22: Position Reconciliation
Write a reconciliation algorithm that: (a) Compares local positions with exchange-reported positions. (b) Identifies discrepancies (missing positions, quantity mismatches, price discrepancies). (c) Proposes corrective actions (adjust local records, place corrective trades). (d) Generates a reconciliation report with severity levels (INFO, WARNING, CRITICAL).
Exercise 23: P&L Attribution
Implement a P&L attribution system that breaks down total P&L by: (a) Strategy (which model generated the signal). (b) Market category. (c) Time period (daily, weekly, monthly). (d) Trade type (new position vs. add to existing vs. close position).
Exercise 24: Alert Escalation
Design an alert escalation system with the following rules: (a) Level 1 (email): Any error in the last hour. (b) Level 2 (SMS): More than 5 errors in 15 minutes, or any single loss > $100. (c) Level 3 (phone call): Connection lost for > 5 minutes, or daily loss limit reached. (d) Implement cooldown periods to prevent alert fatigue (same alert type cannot fire more than once every 15 minutes).
Section 19.9-19.11: Psychology, Paper Trading, and Operations
Exercise 25: Decision Journal Analysis
You have kept a decision journal for 60 manual interventions. The outcomes: - 15 interventions were profitable (average gain: +$23) - 45 interventions were unprofitable (average loss: -$31)
(a) Calculate the expected value of a manual intervention. (b) Calculate the total cost of manual interventions over this period. (c) If you had not intervened at all, what would the impact have been? (Assume the bot's decision would have been the opposite of your intervention.) (d) At what win rate would manual interventions break even, given the average gain/loss ratio?
Exercise 26: Paper Trading Validation
You ran a strategy in paper trading for 30 days with these results: - 156 trades, 93 winning (59.6% win rate) - Average win: $18.40, Average loss: $15.20 - Total P&L: +$415 - Fill rate: 95%
Your backtest over the same period showed: - 189 trades, 116 winning (61.4% win rate) - Average win: $19.10, Average loss: $14.80 - Total P&L: +$587 - Fill rate: 100%
(a) What is the fill rate gap and how much P&L does it explain? (b) What is the win rate gap and how much P&L does it explain? (c) Is the paper trading result statistically significantly different from the backtest? (Use a z-test on win rate.) (d) What adjustments would you make before going live?
Exercise 27: Disaster Recovery Drill
Design a disaster recovery drill that simulates each of the following scenarios. For each, describe: (a) How the failure is injected (in a test environment). (b) The expected automated response. (c) The expected manual response. (d) Success criteria (how you know recovery was successful).
Scenarios: (i) API returns 500 errors for 10 minutes, (ii) Internet connection drops for 5 minutes, (iii) Bot process crashes while orders are outstanding, (iv) A market resolves while data feed is stale.
Exercise 28: Security Audit
Perform a security audit of the trading bot code in this chapter. For each finding: (a) Describe the vulnerability. (b) Assess the risk (probability x impact). (c) Propose a remediation. (d) Classify as P0 (fix before deployment), P1 (fix within 1 week), or P2 (fix within 1 month).
Exercise 29: End-to-End Integration Test
Design and implement an end-to-end integration test that: (a) Creates a paper trading environment. (b) Registers a simple mean-reversion signal generator. (c) Configures risk limits. (d) Feeds in 100 simulated market updates. (e) Verifies that: - Signals are generated for the expected market conditions. - Risk checks approve/reject orders correctly. - Positions are tracked accurately. - P&L is calculated correctly. - Logs contain all expected events.
Exercise 30: Full Bot Deployment Plan
Write a complete deployment plan for taking the trading bot from development to production. Include: (a) A testing matrix covering unit tests, integration tests, paper trading, and small live trading. (b) Go/no-go criteria for each stage. (c) A rollback plan for each stage. (d) Monitoring and alerting configuration. (e) A 30-day post-deployment observation plan with specific metrics to track. (f) A schedule for regular reviews and improvements.