Quant Trading Systems: Architecture & Infrastructure › Putting It All Together

Michael BrenndoerferJanuary 21, 20264 min read
Quantitative FinanceAll chapters
Part 15 of 15Trading Systems and Production Deployment
Chapter 77Quant Trading Systems: Architecture & Infrastructure › Putting It All Together
Reading section 11 of 14 · Putting It All Together · 4 minSection 11 of 14 · 4 min

Book contents

Section 11 of 14 · 4 min read

Quant Trading Systems: Architecture & Infrastructure › Putting It All TogetherOne section · Sections in this chapter11 / 14 ↓
Reading tools Definitions & inline links

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

A complete trading system integrates all these components into a cohesive whole. The challenge is building each component correctly and ensuring they work together under the dynamic conditions of real markets.

The following example shows a simplified trading system that connects the components we've discussed. In production, this integration would be more sophisticated, with proper threading, error handling, and monitoring. But the basic structure illustrates how data flows through the system from market updates to trading decisions.

In[50]:
Code
from datetime import datetime


class TradingSystem:
    """
    Simplified trading system integrating all components.
    Production systems would be significantly more complex.
    """

    def __init__(self, initial_capital: float):
        # Initialize components
        self.market_data = MarketDataHandler(buffer_size=1000)
        self.strategy = MomentumStrategy(
            ["AAPL", "GOOGL"], lookback=5, threshold=0.01
        )
        self.risk_checker = PreTradeRiskChecker(RiskLimits())
        self.oms = OrderManagementSystem()
        self.portfolio = PortfolioManager(initial_capital)
        self.circuit_breaker = CircuitBreaker()

        # System state
        self.is_running = False
        self.trade_log: list[dict] = []

    def start(self):
        """Start the trading system."""
        self.is_running = True
        print("Trading system started")

    def stop(self):
        """Stop the trading system gracefully."""
        self.is_running = False
        # Cancel all open orders
        for order in self.oms.get_open_orders():
            print(f"Cancelling open order: {order.order_id}")
        print("Trading system stopped")

    def on_market_data(self, symbol: str, price: float, bid: float, ask: float):
        """Process incoming market data."""
        if not self.is_running:
            return

        # Create tick and validate
        tick = MarketDataTick(
            symbol=symbol,
            timestamp=datetime.now(),
            bid_price=bid,
            ask_price=ask,
            bid_size=100,
            ask_size=100,
            last_price=price,
        )

        if not self.market_data.on_tick(tick):
            print(f"Invalid tick rejected for {symbol}")
            return

        # Update portfolio prices
        self.portfolio.update_prices({symbol: price})

        # Generate signals
        data = {symbol: price}
        signals = self.strategy.on_data(data)

        # Generate orders from signals
        self._process_signals(signals)

    def _process_signals(self, signals: dict[str, Signal]):
        """Convert signals to orders with risk checks."""
        if not self.circuit_breaker.can_trade():
            return

        target_positions = self.strategy.calculate_target_positions()
        portfolio_summary = self.portfolio.get_portfolio_summary()

        for symbol, target_weight in target_positions.items():
            if symbol not in self.market_data.current_quotes:
                continue

            current_price = self.market_data.current_quotes[symbol].mid_price
            current_position = self.portfolio.positions.get(
                symbol, Position(symbol, 0, 0)
            ).quantity

            # Calculate target shares
            target_notional = target_weight * portfolio_summary["nav"]
            target_shares = target_notional / current_price
            shares_to_trade = target_shares - current_position

            if abs(shares_to_trade) < 1:
                continue

            # Determine order side
            side = "BUY" if shares_to_trade > 0 else "SELL"
            quantity = abs(shares_to_trade)

            # Create and check order
            order = Order(symbol, side, quantity, "MARKET")

            approved, reason = self.risk_checker.check_order(
                order=order,
                current_position=current_position,
                portfolio_value=portfolio_summary["nav"],
                current_price=current_price,
                total_exposure=portfolio_summary["market_value"],
                daily_pnl=portfolio_summary["total_pnl"],
            )

            if approved:
                order_id = self.oms.create_order(
                    symbol, side, quantity, "MARKET"
                )
                self.oms.submit_order(order_id)

                # Simulate immediate fill for demonstration
                self.oms.on_fill(order_id, quantity, current_price)
                self.portfolio.update_position(
                    symbol,
                    quantity if side == "BUY" else -quantity,
                    current_price,
                )

                self.trade_log.append(
                    {
                        "time": datetime.now(),
                        "order_id": order_id,
                        "symbol": symbol,
                        "side": side,
                        "quantity": quantity,
                        "price": current_price,
                    }
                )
                print(
                    f"Order submitted and filled: {side} {quantity:.0f} {symbol} @ {current_price:.2f}"
                )
            else:
                print(f"Order rejected: {reason}")
In[51]:
Code
# Demonstrate integrated system
system = TradingSystem(initial_capital=500000)
system.start()

# Simulate market data updates
np.random.seed(42)
prices = {"AAPL": 185.0, "GOOGL": 141.0}

system_log = []
for minute in range(10):
    # Simulate price movements
    for symbol in prices:
        change = np.random.normal(0, 0.005)  # 0.5% volatility
        prices[symbol] *= 1 + change

        # Generate realistic bid/ask
        spread = prices[symbol] * 0.0005  # 5 bps spread
        bid = prices[symbol] - spread / 2
        ask = prices[symbol] + spread / 2

        system.on_market_data(symbol, prices[symbol], bid, ask)

    if minute % 3 == 0:  # Print status every 3 minutes
        summary = system.portfolio.get_portfolio_summary()
        system_log.append(
            f"\nMinute {minute}: NAV = ${summary['nav']:,.2f}, "
            f"P&L = ${summary['total_pnl']:,.2f}"
        )

system.stop()

final_summary = system.portfolio.get_portfolio_summary()
Out[52]:
Console

Simulating trading day...
============================================================

Minute 0: NAV = $500,000.00, P&L = $0.00

Minute 3: NAV = $500,000.00, P&L = $0.00

Minute 6: NAV = $500,000.00, P&L = $0.00

Minute 9: NAV = $500,000.00, P&L = $0.00

============================================================
Executed Trades:
  No trades executed.

============================================================
Final Portfolio Summary:
  cash: 500000
  market_value: 0
  nav: 500000
  unrealized_pnl: 0
  realized_pnl: 0
  total_pnl: 0
  num_positions: 0

The integrated simulation shows the system in action. Market data drives the strategy, which generates signals that pass through risk checks before becoming orders. The portfolio manager tracks the resulting execution and P&L, and gives a complete view of the trading operation. This demonstration illustrates the flow of information through the system, though production systems would include many additional features for reliability and compliance.