Multi-Stock Trading Simulation: Diversify Your Portfolio!

by Admin 58 views
Multi-Stock Trading Simulation: Diversify Your Portfolio!

Hey guys! Let's dive into an exciting new feature for our trading simulation: multiple stock trading support! This upgrade lets you trade several stocks at the same time, opening up a whole new world of strategies like portfolio diversification, pairs trading, and figuring out which stocks are a steal versus overpriced.

Overview

Currently, our simulation is pretty solid. We've got single-stock trading down with dividends, short-selling, and a detailed order book. Plus, we've got the risk-free rate covered with interest on cash. However, you can't trade multiple different stocks just yet, which is where this awesome upgrade comes in!

Motivation

So, why are we even bothering with multiple stocks? Well, imagine the possibilities! With multiple stock support, we can really dig into some cool research areas:

  1. Pairs Trading: This lets you play with mean-reversion strategies using stocks that tend to move together.
  2. Relative Value: You can spot which stocks are undervalued or overvalued compared to their peers.
  3. Portfolio Diversification: Building portfolios across different stocks can help spread risk.
  4. Sector Dynamics: Simulate how different sectors like tech and consumer goods interact.
  5. Contagion: See how a hiccup in one stock can ripple through others.
  6. Market Making: Provide liquidity across multiple stocks and earn the spread.
  7. Information Spillovers: Explore how news about one stock affects others in the same industry.

Required Changes

Alright, let's get into the nitty-gritty of what needs to change to make this happen:

1. Core Data Structures

First up, we need to tweak some of our core data structures:

  • [ ] Add stock_id field to Order class (src/market/orders/order.py)
  • [ ] Add stock_id field to Trade class (src/market/trade.py)
  • [ ] Update AgentRepository to track Dict[stock_id, shares] positions
    • Current: Single shares field
    • New: positions = {"AAPL": 1000, "MSFT": 500}
  • [ ] Add portfolio-level position tracking (total value, allocations)

2. Market Infrastructure

Next, we need to beef up our market infrastructure:

  • [ ] Create StockContext class (per-stock version of SimulationContext)
    • Each stock has its own: price, fundamental value, dividend params
  • [ ] Create MultiStockContext to manage multiple StockContext instances
  • [ ] Build OrderBookRegistry - one order book per stock
  • [ ] Update MatchingEngine to route orders by stock_id
    • Match AAPL orders separately from MSFT orders
  • [ ] Create per-stock DividendService instances
  • [ ] Add stock correlation modeling (optional)

3. Scenario Configuration

We'll need to update src/scenarios.py to handle the new multi-stock configurations. Check out this example:

"multi_stock_scenario": {
 "STOCKS": {
 "TECH_A": {
 "INITIAL_PRICE": 100,
 "FUNDAMENTAL_PRICE": 95,
 "REDEMPTION_VALUE": 95,
 "DIVIDEND_PARAMS": {
 "base_dividend": 2.0,
 "probability": 0.5,
 "variation": 0.5
 }
 },
 "TECH_B": {
 "INITIAL_PRICE": 50,
 "FUNDAMENTAL_PRICE": 55,
 "REDEMPTION_VALUE": 55,
 "DIVIDEND_PARAMS": {
 "base_dividend": 1.0,
 "probability": 0.6,
 "variation": 0.3
 }
 }
 },
 "CORRELATIONS": {
 ("TECH_A", "TECH_B"): 0.7 # Positively correlated tech stocks
 },
 "AGENT_PARAMS": {
 "INITIAL_CASH": 1000000,
 "INITIAL_POSITIONS": {
 "TECH_A": 5000,
 "TECH_B": 10000
 }
 }
}

4. Agent System

Our agents need an upgrade too! That means we need to:

  • [ ] Update BaseAgent.decide() to return List[Order] with stock_id
    • Agents can now trade multiple stocks per round
  • [ ] Rewrite LLM prompt templates for portfolio of stocks:
Your Stock Portfolio:
1. TECH_A
 - Price: $100.00, Fundamental: $95.00 (5% overvalued)
 - Your Position: 5,000 shares ($500,000 value)
 - P/F Ratio: 1.05

2. TECH_B
 - Price: $50.00, Fundamental: $55.00 (10% undervalued)
 - Your Position: 10,000 shares ($500,000 value)
 - P/F Ratio: 0.91

Cash: $200,000
Total Portfolio Value: $1,200,000

Consider:
- Which stock offers better value?
- Should you rebalance between stocks?
- Are there arbitrage opportunities?
  • [ ] Implement new deterministic strategies:
    • [ ] Pairs Trader: Buy undervalued stock, sell overvalued stock
    • [ ] Relative Value Trader: Focus on P/F ratio differences
    • [ ] Sector Rotator: Rotate between stocks based on momentum
    • [ ] Multi-Stock Market Maker: Provide liquidity in multiple stocks

5. Information Providers

Information is key, so we'll also need to update our information providers:

  • [ ] Update MarketPriceProvider to provide prices for all stocks
  • [ ] Update DividendProvider to distinguish which stock pays dividends
  • [ ] Add CorrelationProvider for stock-to-stock relationships (optional)
  • [ ] Update agent information formatting to show all stocks

6. Position & Trade Services

We'll need services to keep the positions in check. These include

  • [ ] Update PositionCalculator for stock-specific position changes
  • [ ] Update PositionServices to handle multi-stock portfolio updates
  • [ ] Update commitment tracking per stock:
    • Cash committed across all stocks
    • Shares committed per stock
  • [ ] Add portfolio-level valuation (mark-to-market across all stocks)

7. Data Recording & Analysis

Keeping track of everything is essential for analysis, so we'll update the DataRecorder for:

  • [ ] Per-stock trade data with stock_id column
  • [ ] Per-stock price/volume/fundamental data
  • [ ] Portfolio-level metrics:
    • Total portfolio value over time
    • Stock allocation percentages
    • Correlation realized vs expected
    • Cross-stock trading flows
  • [ ] New visualizations:
    • [ ] Portfolio composition (stacked area chart)
    • [ ] Relative performance (Stock A vs Stock B)
    • [ ] Cross-stock correlation heatmaps
    • [ ] Pairs spread plots (price_A/price_B over time)

8. Base Simulation Loop

Finally, the heart of the simulation needs an update. Here's how src/base_sim.py will change:

def run_round(self):
 # Collect decisions (agents return orders for multiple stocks)
 orders = self.collect_agent_decisions()
 
 # Match each stock's orders independently
 results = {}
 for stock_id in self.stocks:
 stock_orders = [o for o in orders if o.stock_id == stock_id]
 results[stock_id] = self.engines[stock_id].match(stock_orders)
 
 # Update each stock's price independently
 for stock_id, result in results.items():
 self.contexts[stock_id].current_price = result.clearing_price
 
 # (Optional) Apply cross-stock effects (correlation shocks)
 self.update_correlation_dynamics()
 
 # Pay dividends for each stock
 for stock_id, dividend_service in self.dividend_services.items():
 dividend_service.pay_dividends(round_number)

Implementation Strategy

To make this manageable, we'll break it down into phases:

Phase 1: Foundation (2 Stocks)

  • Start with just 2 stocks to prove the concept.
  • Reuse existing single-stock infrastructure.
  • Focus on data structure changes.

Phase 2: Agent Intelligence

  • Update LLM prompts for multi-stock portfolio context.
  • Implement pairs trading and relative value strategies.
  • Add portfolio metrics to decision inputs.

Phase 3: Market Dynamics (Optional)

  • Add cross-stock correlations.
  • Information spillovers between stocks.
  • Sector effects.

Phase 4: Scenarios & Analysis

  • Create multi-stock scenario configurations.
  • Portfolio analysis tools.
  • Pairs trading experiments.

Example Scenarios

Let's think about some cool scenarios we can test out:

Scenario 1: Pairs Trading

  • 2 tech stocks with 0.8 correlation.
  • One starts overvalued, one undervalued.
  • Test if agents exploit mean-reversion.

Scenario 2: Value vs Growth

  • "Value" stock: High dividend, low P/F.
  • "Growth" stock: Low dividend, high P/F.
  • Test agent preferences and allocation.

Scenario 3: Contagion

  • Shock one stock's fundamental value.
  • Observe spillover effects on other stock.

Design Principles

We want to make sure we're doing this right, so we're sticking to these principles:

  1. ✅ Backwards Compatibility: Keep single-stock scenarios working
  2. ✅ Stock-First Design: Focus on equities, not bonds/commodities
  3. ✅ Incremental Testing: Test with 2 stocks, then scale to N stocks
  4. ✅ Research Focus: Enable pairs trading, relative value research

Success Criteria

How will we know if we've nailed it? We'll be looking for these things:

  • [ ] Can run a scenario with 2+ stocks
  • [ ] Agents can submit orders for multiple stocks per round
  • [ ] Portfolio value correctly calculated (mark-to-market)
  • [ ] Can observe pairs trading behavior
  • [ ] At least 2 multi-stock scenarios (pairs trading, value vs growth)

Simplifications vs Multi-Asset

Since all assets are stocks (same class):

  • ✅ Same order mechanics (limit/market, short-selling)
  • ✅ Same dividend mechanics (just different params per stock)
  • ✅ No need for bond-specific features (duration, yield curve)
  • ✅ Simpler agent prompts (comparing apples to apples)

Key Files

Keep an eye on these files as we roll this out:

  • src/market/orders/order.py - Add stock_id field
  • src/scenarios.py - Multi-stock configuration
  • src/agents/LLMs/llm_agent.py - Portfolio decision logic
  • src/agents/agent_manager/agent_repository.py - Multi-stock positions
  • src/base_sim.py - Main simulation loop
  • src/market/state/sim_context.py - Per-stock context

Alright guys, that's the plan! Get ready to level up your trading simulation game!