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.

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
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
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]
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]
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)