problemhardood

Object-Oriented Design for an Online Stock Brokerage System

Problem

Design an Online Stock Brokerage System that enables users to buy/sell stocks, maintain watchlists and stock lots, place multiple order types (market, limit, stop loss, stop limit), and manage deposits/withdrawals and reports. The system should provide low-latency execution, durable order logging, and notifications when orders are executed.

Online Stock Brokerage System

Solution

1. Requirements Analysis

Functional Requirements:

  • Users must be able to register and manage accounts.
  • Users can create multiple watchlists and query stock inventory by symbol.
  • Users can place and cancel orders of types: market, limit, stop-loss, stop-limit.
  • Support partial fills via OrderPart and track multiple StockLots per user.
  • Allow deposit and withdrawal via check, wire, or electronic transfer.
  • Generate periodic statements and tax reports.
  • Send notifications when orders execute or update.

Non-Functional Requirements:

  • Latency: quick order handling (low ms to <200ms for internal steps where possible).
  • Durability: append-only MoveLog-like OrderLog for replay and auditing.
  • Scalability: support many users and market data feeds; shard by account/region.
  • Consistency: strong consistency for account balances and order matching where required.

Assumptions & Constraints:

  • The system integrates with one or more external StockExchange gateways.
  • Order matching and exchange interactions may be asynchronous and produce callbacks.

2. Use Case Diagram

Actors: Admin, Member, System

Primary Use Cases: Register Account, Create/Modify Watchlist, Place Order, Cancel Order, Deposit/Withdraw, Get Statements

graph TD
    subgraph BrokerageSystem
        UC1(Register Account)
        UC2(Create/Modify Watchlist)
        UC3(Place Order)
        UC4(Cancel Order)
        UC5(Deposit/Withdraw)
        UC6(Get Statements)
    end
    Admin --> UC1
    Member --> UC2
    Member --> UC3
    Member --> UC4
    Member --> UC5
    Member --> UC6
    System --> UC3
    System --> UC5

Online Stock Brokerage System Use Case Diagram

3. Class Diagram

Core classes and responsibilities (from existing notes):

  • Account / Member: identity, contact, balances, stock positions.
  • StockExchange: singleton gateway to external market(s) and order submission.
  • Stock / StockInventory: hold current prices and metadata.
  • Order / LimitOrder / MarketOrder / StopOrder: encapsulate order types and parts.
  • OrderPart: partial fills and execution details.
  • StockLot / StockPosition: track lots and holdings per account.
  • Statement: generate reports for taxes and quarterlies.
  • Notification: send execution updates to users.
classDiagram
    class Account { +UUID id +String name +Money balance }
    class Member { +Map~StockPosition~ positions +place_order() }
    class StockExchange { +place_order() }
    class Order { +UUID id +OrderStatus status +List~OrderPart~ parts }
    class OrderPart { +int quantity +float price }
    class Stock { +String symbol +float currentPrice }

    Account <|-- Member
    Member "1" o-- "*" StockPosition : holds
    Member "1" o-- "*" Order : places
    Order "1" o-- "*" OrderPart : fulfilled_by
    StockExchange --> Order : submits

Online Stock Brokerage System Class Diagram Online Stock Brokerage System UML

4. Activity Diagrams

Activity: Place a Buy Order (high-level)

graph TD
    A[User places buy order] --> B[Validate funds & orderform]
    B --> C[Persist order as OPEN]
    C --> D[Submit to StockExchange]
    D --> E[Exchange ack / partial fill / full fill]
    E --> F[Callback to system → update OrderParts and balances]
    F --> G[Notify Member]

Online Stock Brokerage System Buy Order

Activity: Cancel Order

graph TD
    A[Member requests cancel] --> B[Check cancellable state]
    B -- cancellable --> C[Send cancel to exchange]
    C --> D[Update order status & refund holds]
    D --> E[Notify member]
    B -- not cancellable --> F[Return error]

Online Stock Brokerage System Sell Order

5. High-Level Code Implementation

Presenting concise skeletons (Python and Java) extracted and reorganized from the original note.

Python (skeleton)

from enum import Enum
from typing import Dict, List, Optional


class OrderStatus(Enum):
    OPEN = 1
    FILLED = 2
    PARTIALLY_FILLED = 3
    CANCELLED = 4


class TimeEnforcementType(Enum):
    GOOD_TILL_CANCELLED = 1
    FILL_OR_KILL = 2
    IMMEDIATE_OR_CANCEL = 3


class Order:
    def __init__(self, id: str, is_buy: bool, symbol: str, qty: int, price: Optional[float] = None):
        self.id = id
        self.is_buy = is_buy
        self.symbol = symbol
        self.qty = qty
        self.price = price
        self.status = OrderStatus.OPEN
        self.parts: List[OrderPart] = []

    def save(self):
        pass


class OrderPart:
    def __init__(self, qty: int, price: float):
        self.qty = qty
        self.price = price


class StockExchangeGateway:
    def place_order(self, order: Order) -> bool:
        """Submit order to external exchange (async)."""
        pass


class Member:
    def __init__(self, member_id: str):
        self.member_id = member_id
        self.positions: Dict[str, StockPosition] = {}

    def place_limit_order(self, symbol: str, qty: int, price: float) -> bool:
        pass


class StockPosition:
    def __init__(self, symbol: str):
        self.symbol = symbol
        self.lots = []

Java (skeleton)

public enum OrderStatus { OPEN, FILLED, PARTIALLY_FILLED, CANCELLED }

public abstract class Order {
    protected String id;
    protected boolean isBuy;
    protected String symbol;
    protected int qty;
    protected double price;
    protected OrderStatus status;
}

public class StockExchangeGateway {
    public boolean placeOrder(Order order) { return false; }
}

public class Member {
    private String id;
    public boolean placeLimitOrder(String symbol, int qty, double price) { return false; }
}

Appendix — Original code & examples

The remainder of the original note contained expanded Python examples (enums, StockExchange, Order, Member implementations) which have been preserved below for reference and as a starting point for tests or a small demo.

from enum import Enum


class ReturnStatus(Enum):
    SUCCESS, FAIL, INSUFFICIENT_FUNDS, INSUFFICIENT_QUANTITY, NO_STOCK_POSITION = 1, 2, 3, 4, 5, 6


class OrderStatus(Enum):
    OPEN, FILLED, PARTIALLY_FILLED, CANCELLED = 1, 2, 3, 4


class TimeEnforcementType(Enum):
    GOOD_TILL_CANCELLED, FILL_OR_KILL, IMMEDIATE_OR_CANCEL, ON_THE_OPEN, ON_THE_CLOSE = 1, 2, 3, 4, 5


class AccountStatus(Enum):
    ACTIVE, CLOSED, CANCELED, BLACKLISTED, NONE = 1, 2, 3, 5


class Location:
    def __init__(self, street, city, state, zip_code, country):
        self.__street_address = street
        self.__city = city
        self.__state = state
        self.__zip_code = zip_code
        self.__country = country


class Constants:
    def __init__(self):
        self.__MONEY_TRANSFER_LIMIT = 100000


from .order import Order


class StockExchange:
    # singleton, used for restricting to create only one instance
    instance = None

    class __OnlyOne:
        def __init__(self):
            None

    def __init__(self):
        if not StockExchange.instance:
            StockExchange.instance = StockExchange.__OnlyOne()

    def place_order(self, order):
        return_status = self.get_instance().submit_order(Order)
        return return_status


from abc import ABC
from datetime import datetime
from .constants import OrderStatus, TimeEnforcementType


class Order(ABC):
    def __init__(self, id):
        self.__order_id = id
        self.__is_buy_order = False
        self.__status = OrderStatus.OPEN
        self.__time_enforcement = TimeEnforcementType.ON_THE_OPEN
        self.__creation_time = datetime.now()

        self.__parts = {}

    def set_status(self, status):
        self.status = status

    def save_in_DB(self):
        None

    # save in the database

    def add_order_parts(self, parts):
        for part in parts:
            self.parts[part.get_id()] = part


class LimitOrder(Order):
    def __init__(self):
        self.__price_limit = 0.0


from datetime import datetime
from abc import ABC
from .constants import OrderStatus, AccountStatus, ReturnStatus
from .order import LimitOrder
from .stock_exchange import StockExchange


class Account(ABC):
    def __init__(self, id, password, name, address, email, phone, status=AccountStatus.NONE):
        self.__id = id
        self.__password = password
        self.__name = name
        self.__address = address
        self.__email = email
        self.__phone = phone
        self.__status = AccountStatus.NONE

    def reset_password(self):
        None


class Member(Account):
    def __init__(self):
        self.__available_funds_for_trading = 0.0
        self.__date_of_membership = datetime.date.today()
        self.__stock_positions = {}
        self.__active_orders = {}

    def place_sell_limit_order(self, stock_id, quantity, limit_price, enforcement_type):
        # check if member has this stock position
        if stock_id not in self.__stock_positions:
            return ReturnStatus.NO_STOCK_POSITION

        stock_position = self.__stock_positions[stock_id]
        # check if the member has enough quantity available to sell
        if stock_position.get_quantity() < quantity:
            return ReturnStatus.INSUFFICIENT_QUANTITY

        order = LimitOrder(stock_id, quantity, limit_price, enforcement_type)
        order.is_buy_order = False
        order.save_in_DB()
        success = StockExchange.place_order(order)
        if success:
            order.set_status(OrderStatus.FAILED)
            order.save_in_DB()
        else:
            self.active_orders.add(order.get_order_id(), order)
        return success

    def place_buy_limit_order(self, stock_id, quantity, limit_price, enforcement_type):
        # check if the member has enough funds to buy this stock
        if self.__available_funds_for_trading < quantity * limit_price:
            return ReturnStatus.INSUFFICIENT_FUNDS

        order = LimitOrder(stock_id, quantity, limit_price, enforcement_type)
        order.is_buy_order = True
        order.save_in_DB()
        success = StockExchange.place_order(order)
        if not success:
            order.set_status(OrderStatus.FAILED)
            order.save_in_DB()
        else:
            self.active_orders.add(order.get_order_id(), order)
        return success

    # this function will be invoked whenever there is an update from
    # stock exchange against an order
    def callback_stock_exchange(self, order_id, order_parts, status):
        order = self.active_orders[order_id]
        order.add_order_parts(order_parts)
        order.set_status(status)
        order.update_in_DB()

        if status == OrderStatus.FILLED or status == OrderStatus.CANCELLEd:
            self.active_orders.remove(order_id)

Comments