Stock Exchange

Architecture

System architecture and design overview

System Overview

The Stock Exchange is built as a modular, event-driven system with three main components working together to provide a complete trading platform.

┌─────────────────────────────────────────────────┐
│                   Client                        │
│              (HTTP Requests)                    │
└────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────┐
│              Echo Server                        │
│          (REST API Layer)                       │
└─────┬─────────────────────────────┬─────────────┘
      │                             │
      ▼                             ▼
┌──────────────────┐      ┌──────────────────────┐
│  Matching Engine │◄────►│    Market Maker      │
│   (Order Logic)  │      │  (Liquidity Bot)     │
└─────────┬────────┘      └──────────────────────┘


┌──────────────────────────────────────────────────┐
│              Orderbook                           │
│        (State Management)                        │
└──────────────────────────────────────────────────┘

Core Components

1. Server (HTTP Layer)

Built with the Echo web framework, the server provides RESTful endpoints for:

  • Placing orders
  • Querying orderbook state
  • Retrieving trade history
  • Getting user orders

Key Files:

  • server/server.go - HTTP handlers and routing
  • main.go - Application entry point

2. Matching Engine

The heart of the exchange that processes orders and executes trades.

Responsibilities:

  • Order validation
  • Price-time priority matching
  • Trade execution
  • Partial fill handling

Key Features:

  • O(1) best bid/ask retrieval
  • FIFO ordering within price levels
  • Support for limit and market orders

3. Orderbook

Maintains the state of all active orders for each market.

Data Structures:

  • Sorted bid/ask arrays
  • Hash map for order lookup
  • Trade history log

Operations:

  • Add order
  • Cancel order
  • Match order
  • Get market depth

4. Market Maker

An automated agent that provides liquidity by continuously quoting both sides of the market.

Behavior:

  • Places orders at multiple price levels
  • Adjusts quotes based on market conditions
  • Manages inventory position
  • Refreshes orders periodically

Technology Stack

Language & Framework

  • Go 1.19+
  • Echo v4 (Web framework)

Key Libraries

  • Standard library for core logic
  • Echo middleware for HTTP

Container & Orchestration

  • Docker
  • Docker Compose

Blockchain

  • Ganache (Ethereum local node)

Testing

  • Go testing package
  • Table-driven tests

Build Tools

  • Go modules
  • Makefile

Data Flow

Order Placement Flow

Client Request

Client sends HTTP POST to /order with order details.

Server Validation

Echo handler validates the request payload.

Matching Engine

Order is passed to the matching engine for processing.

Orderbook Update

  • If matched: Generate trades, update both orders
  • If unmatched: Add to orderbook

Response

Server returns order ID or trade details to client.

Concurrency Model

The system handles concurrent requests safely:

// Orderbook uses mutex for thread safety
type Orderbook struct {
    mu     sync.RWMutex
    asks   []*Limit
    bids   []*Limit
    Orders map[int64]*Order
}

Synchronization:

  • Read operations use RLock()
  • Write operations use Lock()
  • Atomic operations for counters

Design Patterns

Repository Pattern

Orderbook acts as a repository for orders:

type Orderbook interface {
    PlaceOrder(price float64, order *Order) []Trade
    CancelOrder(orderID int64) error
    GetBestBid() *Order
    GetBestAsk() *Order
}

Factory Pattern

Orders are created through factory methods:

func NewLimitOrder(bid bool, size int, price float64) *Order
func NewMarketOrder(bid bool, size int) *Order

Observer Pattern

Market maker observes orderbook changes and adjusts quotes accordingly.

Performance Considerations

Time Complexity

OperationComplexityNotes
Place OrderO(1)Amortized
Get Best Bid/AskO(1)Direct access
Match OrderO(k)k = number of matches
Cancel OrderO(1)Hash map lookup

Memory Usage

  • Each order: ~100 bytes
  • 10,000 active orders: ~1 MB
  • Trade history: Grows linearly

Scalability

Current Limitations:

  • Single-threaded matching per market
  • In-memory storage (no persistence)
  • No horizontal scaling

Future Improvements:

  • Per-market order processing threads
  • Database persistence
  • Redis for distributed state
  • Message queue for event streaming

Security Considerations

This is a demonstration project. Production systems require additional security measures.

Current State:

  • No authentication
  • No authorization
  • No rate limiting
  • No input sanitization

Production Requirements:

  • JWT or OAuth authentication
  • Role-based access control
  • Rate limiting per user
  • Input validation and sanitization
  • Audit logging
  • DDoS protection

Monitoring & Observability

Metrics to Track:

  • Orders per second
  • Latency percentiles (p50, p95, p99)
  • Order fill rate
  • Active orders count
  • Trade volume
  • Error rates

Logging:

  • Structured logging with levels
  • Request/response logging
  • Error tracking
  • Performance profiling

Deployment

Local Development

# Start dependencies
docker-compose up -d

# Run tests
go test ./...

# Start server
go run main.go

Production Deployment

Recommended setup:

  • Load balancer (nginx/HAProxy)
  • Multiple application instances
  • Monitoring (Prometheus + Grafana)
  • Centralized logging (ELK stack)
  • Database cluster (PostgreSQL)

Next Steps

On this page