Skip to content

COG-GTM/Fixed-Income-RFQ-Trading-Platform

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

48 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Fixed-Income RFQ Trading Platform

A SpringBoot monolith simulating a fixed-income Request-for-Quote (RFQ) trading platform.

Technologies used:

Domain Entities

Three domain entities:

  • Counterparty
    • name
    • lei (Legal Entity Identifier)
    • creditLimit (BigDecimal)
    • availableCredit (BigDecimal)
  • Bond
    • isin (unique, e.g. US912828YK15)
    • issuer
    • couponRate (BigDecimal)
    • maturityDate (LocalDate)
    • availableNotional (BigDecimal — par amount available for trading)
  • RFQ (Request for Quote)
    • counterparty (manyToOne)
    • bond (manyToOne)
    • notionalAmount (BigDecimal — par amount requested)
    • side (BUY / SELL)
    • status (PENDING / QUOTED / EXECUTED / REJECTED)
    • executionPrice (BigDecimal — total settlement amount)
    • createdAt (Instant)

Counterparty and Bond must be in place before executing an RFQ. If the bond has insufficient available notional or the counterparty has insufficient available credit, an exception will be thrown. The core logic is in RFQExecutionSaga.java, which attempts to execute an RFQ in a single transaction.

A PATCH method endpoint exists for both Counterparty and Bond controllers to update credit / notional inventory.

A trade confirmation is sent to a counterparty whenever credit is added, handled by TradeConfirmationService.java.

REST Endpoints

Method Path Description
GET /counterparties List all counterparties
POST /counterparties Create a counterparty
GET /counterparties/{id} Get a counterparty by ID
PUT /counterparties/{id} Update a counterparty
PATCH /counterparties/{id} Add or deduct credit (JSON: amount, operation)
DELETE /counterparties/{id} Delete a counterparty
GET /bonds List all bonds
POST /bonds Create a bond
GET /bonds/{id} Get a bond by ID
PUT /bonds/{id} Update a bond
PATCH /bonds/{id} Add or deduct notional (JSON: amount, operation)
DELETE /bonds/{id} Delete a bond
GET /rfqs List all RFQs
POST /rfqs Execute an RFQ
GET /rfqs/{id} Get an RFQ by ID
DELETE /rfqs/{id} Delete an RFQ

Seed Data

On startup the application loads:

  • Counterparty: Acme Asset Management (LEI: 549300EXAMPLE12345678, credit limit: $50,000,000)
  • Bond: US Treasury 2.75% 11/15/2030 (ISIN: US912828YK15, available notional: $100,000,000)
  • RFQ: BUY $5,000,000 notional at $4,987,500 — status EXECUTED

Running the Application

cd monolith
./mvnw spring-boot:run

The application starts on port 8080. Hit /counterparties, /bonds, and /rfqs to verify the REST endpoints.

Testing

cd monolith
./mvnw clean test

See IntegrationTest.java for the full set of use-cases covering RFQ execution, insufficient notional/credit, and missing counterparty/bond scenarios.

About

Everyday is getting more and more popular and, sometimes, worthy and useful -> split a monolith into microservices. In this repo I will show an example of how to split a monolith into microservices using the Strangler Fig and Branch By Abstraction patterns.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • Java 100.0%