A small, educational stock market simulation and library implemented in Java. The project models product order books, orders and quotes, matching/trading logic, a current-market publisher/subscriber system, and a simple GUI for observing market updates. It is intended for learning, experimentation, and lightweight simulation.
- Order book matching (price/time priority) implemented in
bookpackage PriceandPriceFactoryuse integer cents to avoid floating-point issuesProductManagerandUserManagerprovide high-level APIsTradingSimruns an automated market simulation and hooks into the GUI- A simple Swing-based GUI (in
gui) shows current market/top-of-book updates
The project contains several common programming patterns used throughout the codebase:
- Singleton: ProductManager, UserManager, CurrentMarketPublisher, CurrentMarketTracker — see src/book/ProductManager.java, src/user/UserManager.java, src/market/CurrentMarketPublisher.java, src/market/CurrentMarketTracker.java.
- Factory + Flyweight:
PriceFactory.makePrice(...)creates and caches immutablePriceinstances — see src/price/PriceFactory.java and src/price/Price.java. - Value Object / Immutable:
PriceandCurrentMarketSideare immutable value objects used across the model — see src/price/Price.java and src/market/CurrentMarketSide.java. - Observer / Publisher–Subscriber:
CurrentMarketPublisher+CurrentMarketObserverwith subscribers likeUserandGui— see src/market/CurrentMarketPublisher.java, src/market/CurrentMarketObserver.java, src/user/User.java, src/gui/Gui.java. - DTO (Data Transfer Object):
TradableDTOcarries order/quote state between components (Order,QuoteSide,ProductBook,User) — see src/tradable/TradableDTO.java. - Facade / Manager :
ProductManagerandUserManagerprovide high-level APIs and maintain in-memory registries (HashMaps) acting as facades/repositories — see src/book/ProductManager.java and src/user/UserManager.java. - Exceptions (checked exceptions): package-specific custom exceptions for validation and domain errors (e.g.,
DataValidationException,InvalidInput) are used throughout — see src/exceptions/DataValidationException.java and src/tradable/InvalidInput.java. - Event-driven / MVC separation: GUI components (
Gui,UserDisplayManager,MarketDisplay) receive model updates via the publisher/observer, separating UI from model logic — see src/gui/Gui.java and src/gui/UserDisplayManager.java. - Guard clauses (Defensive Validation): Domain objects validate inputs in constructors and setters (
Order,Quote,ProductBook) to enforce invariants — see src/tradable/Order.java, src/tradable/Quote.java, src/book/ProductBook.java.
- JDK 8 or newer
- Basic shell tools (for compilation scripts) on macOS / Linux; equivalent commands work on Windows with minor tweaks
From the repository root:
- Create an output directory and compile all source files:
mkdir -p out
find src -name "*.java" > sources.txt
javac -d out @sources.txt- Run one of the example mains:
java -cp out Main # runs the TradingSim simulation (includes GUI)
java -cp out Main2 # runs price/ProductBook demo (console)
java -cp out Main3 # runs ProductManager + user demo (console)
java -cp out Main4 # demo showing CurrentMarketPublisher + subscriptionsIf you prefer an IDE: import this as a Java project (mark src as source root) and run any of the Main classes.
Main— Callssim.TradingSim.runSim(), which sets up users/products, starts aGui, subscribes to current-market events, and executes a loop that randomly adds/cancels orders to exercise matching logic.Main2— DemonstratesPriceparsing andProductBookbehavior through console examples.Main3— ShowsProductManagerfeatures (adding products, quotes, trades) and inspectsUserstate.Main4— DemonstratesCurrentMarketPublishersubscriptions and how the GUI and users receive market updates.
-
src/book— Core order-book logic:ProductBook.java— top-level book for a single product; manages buy/sell sides and matching.ProductBookSide.java— manages orders/quotes at specific prices and executes fills.ProductManager.java— singleton that tracks all product books and provides product-level APIs.
-
src/tradable— Domain objects:Order.java— buy/sell orders with validation and DTO conversion.Quote.java,QuoteSide.java— two-sided quotes composed of quote sides.Tradable.java/TradableDTO.java— interfaces and lightweight DTOs used for user/state updates.
-
src/price— Price handling:Price.java— immutable price object storing cents asintand comparison helpers.PriceFactory.java— parses strings/integers toPriceand caches instances.
-
src/market— Current-market publication:CurrentMarketPublisher.java,CurrentMarketTracker.java,CurrentMarketObserver.java— publish/subscribe for top-of-book updates.
-
src/user— User tracking:User.javaandUserManager.java— per-user state, subscribed markets, and tradable ownership.
-
src/gui— Simple GUI for market display:Gui.java— implementsCurrentMarketObserverand updatesUserDisplayManager.UserDisplayManager.java,MarketDisplay.java,MarketTableCellRenderer.java— Swing UI components.
-
src/sim— Simulation runner:TradingSim.java— automated simulation that creates random orders/quotes and demonstrates matching.
-
src/exceptionsand package-specific exception classes —DataValidationException,InvalidInput, andInvalidPriceOperationused for validating inputs and operations. -
trash/— legacy/duplicate files. Not used by the build.
- Orders are placed into a
ProductBook, which maintains separate buy and sellProductBookSidecontainers. - Each side stores entries grouped by
Price(aHashMap<Price, ArrayList<Tradable>>). ProductBook.tryTrade()repeatedly checks top-of-book buy and sell prices; if top buy >= top sell, it trades the minimum available quantity and records fills/cancellations.- After changes,
CurrentMarketTrackeris updated and publishes to subscribers viaCurrentMarketPublisher.
Priceis stored as an integer number of cents. UsePriceFactoryto constructPriceobjects correctly and consistently.ProductManagerandUserManagerare singletons — usegetInstance()to access them.OrderandQuoteconstructors validate inputs (user IDs must be 3 letters, product symbols 1–5 letters, volumes within limits, and price non-null).
- To add products or users programmatically, call
ProductManager.getInstance().addProduct(...)orUserManager.getInstance().init(...). - The simulation parameters (loop count, sleep duration) are in
sim/TradingSim.java— adjust theforloop or sleep interval to change runtime behavior. - GUI updates are executed by the
GuiandUserDisplayManager;Gui.shutdown()is called by the sim after completion.
- Simulation entry: src/sim/TradingSim.java
- Core book: src/book/ProductBook.java
- Book side behavior: src/book/ProductBookSide.java
- Order model: src/tradable/Order.java
- Price handling: src/price/Price.java and src/price/PriceFactory.java
- GUI observer: src/gui/Gui.java