Kai Niemi
Kai Niemi's Blog

Kai Niemi's Blog

Trading Engine using CockroachDB

Photo by Wance Paleri on Unsplash

Trading Engine using CockroachDB

Creating a Trading Engine sandbox using Spring Boot and CockroachDB

Kai Niemi's photo
Kai Niemi
·Oct 26, 2022·

4 min read

Table of contents

  • Overview
  • Example Code
  • Design
  • Structure
  • Product Server
  • Trading Server
  • Conclusion

Overview

This article describes a simple online trading engine sandbox implemented using Spring Boot and CockroachDB. The purpose is to showcase this technology stack in a slightly more involved use case than ordinary "hello world". It demonstrates a few common mechanisms and microservice architecture patterns such as retryable transactions and event-driven data redundancy via CDC.

Example Code

The code for this service is available in Github.

Design

The system provides the ability to place buy and sell orders on stock products and review order history. It models customer and market accounts. Accounts must not be overdrawn, i.e. have a negative balance at any given time and the total balance must be constant in the system.

The system uses double entry bookkeeping for maintaining a transaction history, even though all orders (transactions) are two-legged. When a buy order is placed, the market (trading) account is debited and the customer (system) account credited. When a sell order is placed, the market account is credited and the customer account debited. Portfolios containing the holdings are created when accounts are created.

Structure

The system is composed by the following artifacts:

  • product-server - Technical authority for stock products, feeds trading engine via CDC
  • trading-api - REST API value objects
  • trading-client - Spring shell application for submitting order requests
  • trading-server - Main trading engine service

The code is organized by feature rather than domain responsibility. Each feature such as products, orders, accounts and portfolios have dedicated packages that include API controllers, business services, persistent domain entities and repositories.

trading (1).jpg

Product Server

This is a very small service and the authority for stock products. It stores products and uses an internal scheduler to simulate creation and updates of products. It uses CDC via the webhook sink to feed the trading service that keeps a materialized view of the product inventory.

Trading Server

This service provides an API for placing buy and sell orders. It receives CDC events from the product service to keep a materialized view of the product inventory updated.

It uses the following entity model:

trading-schema.jpg

tabledescription
accountTrading and system account balance with currency
booking_orderBuy and sell order header
booking_order_itemBuy and sell order item or leg (2-legged per order)
limitsMarket buy and sell limits
portfolioProduct portfolio per market
portfolio_itemProduct item for a portfolio (one item per placed order where the order sum is aggregated)
productStock products with buy and sell prices (shallow copy)

Architectural Mechanisms

An architectural mechanism represents a common solution to a frequently encountered architectural problem that is not specific to a project or business domain. Architectural mechanisms can be divided into three categories: Analysis, design and implementation. For instance, if persistence is needed (analysis) and ACID properties are relevant for protecting invariants, then a RDBMS (design) should be used where CockroachDB (implementation) is a suitable option.

Interface

The service uses a hypermedia driven API for accepting buy and sell orders, review order history and products.

Persistence

The service uses JPA with Hibernate and Spring Data JPA. Both CockroachDB and PostgreSQL is supported. Flyway is used to version the database scheme and load initial data.

Transactions

The application relies on database ACID properties and uses local transactions. Pessimistic locking is used in critical sections to reduce likelihood for retries due to transient serialization rollback errors.

Retries

Server-side transaction retries of transient rollback errors (code 40001) are done through AOP, mainly at order placement.

Eventing

The system does not use any messaging system but instead CockroachDB's integrated CDC feature with the webhook sink to drive keep a materialized view of stock products up-to-date.

Technology Stack

Summary of used technology stack:

  • JDK 1.8+
  • CockroachDB 22.1
  • PostgreSQL 10+
  • JDBC 4
  • JPA 2 with Hibernate 5
  • Flyway
  • SLF4J and Logback
  • Spring Boot with Jetty
  • Spring Data JPA
  • Spring Hateoas
  • Junit5 and Mockito

Conclusion

This article demonstrated a simple online trading system using CockroachDB, full source code available in Github.

 
Share this