A SpringBoot monolith simulating a fixed-income Request-for-Quote (RFQ) trading platform.
Technologies used:
-
Java 11, Spring Boot, Spring Data JPA
-
H2 in-memory database
-
Maven
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.
| 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 |
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
cd monolith
./mvnw spring-boot:runThe application starts on port 8080. Hit /counterparties, /bonds, and /rfqs to verify the REST endpoints.
cd monolith
./mvnw clean testSee IntegrationTest.java for the full set of use-cases covering RFQ execution, insufficient notional/credit, and missing counterparty/bond scenarios.