Skip to content

Commit 6bfdb5d

Browse files
authored
Merge pull request #18 from Laffini/core
Creating 'core'
2 parents c83d637 + 4965851 commit 6bfdb5d

30 files changed

+156
-163
lines changed

README.md

Lines changed: 24 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,53 +8,34 @@ A matching engine written in Java.
88
A matching engine matches buy and sell orders in a market.
99

1010
## Matching Algorithm
11-
The matching engine uses a price-time-priority algorithm. The matching priority is firstly price, then time. Market participants are rewarded for offering the best price and coming early.
11+
The matching engine uses a price-time-priority algorithm.
12+
The matching priority is firstly price, then time.
13+
Market participants are rewarded for offering the best price and coming early.
1214

1315
## Usage
14-
To use this API, you will need to run a local service which will be responsible for managing your matching engine. Your application will interact with this service locally via HTTP API calls. By default the service runs on the port 3000.
16+
The Java-Matching-Engine is broken up into multiple projects.
17+
This is the 'core' project.
18+
This project only contains the engine (no REST API, persistence, etc).
1519

16-
It is recommended that every user of this service audits and verifies all underlying code for its validity and suitability. Mistakes and bugs happen.
17-
18-
## Usage Examples
19-
### Buying and Selling Example
20-
#### Creating a maker order
21-
User A creates a buy order of 2 items (e.g. 2 shares, 2 bitcoin, etc) with a price of 5 (e.g. £5, $5, etc)
22-
##### Request
23-
```
24-
POST /order/
25-
?side=BUY
26-
&amount=2
27-
&price=5
28-
```
29-
##### Response
30-
```
31-
{
32-
"trades": [],
33-
"id": "02923822-070b-448d-9240-f3623f90927a"
34-
}
35-
```
36-
A unique ID is generated for the order (so that it can be modified/viewed). A list of trades is also returned. In this example the list of trades returned is empty as no trades have been made (due to the order book being empty).
37-
#### Creating a taker order
38-
User B creates a sell order of 2 items with a price of 5.
39-
##### Request
40-
```
41-
POST /order/
42-
?side=SELL
43-
&amount=2
44-
&price=5
45-
```
46-
##### Response
20+
To use this project, you will need to include the 'core' package as part of your Spring configuration scanning (as seen below).
4721
```
48-
{
49-
"trades": [
50-
{
51-
"takerOrderId": "12964731-2cd4-401b-ac8d-3853f58f75c0",
52-
"makerOrderId": "02923822-070b-448d-9240-f3623f90927a",
53-
"amount": 2,
54-
"price": 5
22+
@SpringBootApplication(scanBasePackages = "net.laffyco.javamatchingengine.core")
23+
public class ExampleApp {
24+
25+
@Autowired
26+
private OrderInterface orderInterface
27+
28+
public static void main(final String[] args) {
29+
SpringApplication.run(DbApp.class, args);
30+
System.out.println(this.getOrders());
5531
}
56-
],
57-
"id": "12964731-2cd4-401b-ac8d-3853f58f75c0"
32+
5833
}
34+
5935
```
60-
As the sell order matches the buy order created earlier we can see that a trade has taken place.
36+
37+
In the example above, we are interacting with the order book through the OrderInterface.
38+
The example starts and prints the orders to the console (it will be empty as no orders have been added).
39+
In most cases you will want to use some of the other Java-Matching-Engine projects as these add additional functionality (such as a REST API) that may suit your needs.
40+
41+
It is recommended that every user of this service audits and verifies all underlying code for its validity and suitability. Mistakes and bugs happen.

pom.xml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
<groupId>org.springframework.boot</groupId>
88
<artifactId>spring-boot-starter-parent</artifactId>
99
<version>2.5.0</version>
10-
<relativePath /> <!-- lookup parent from repository -->
10+
<relativePath />
1111
</parent>
12-
<groupId>net.laffyco</groupId>
13-
<artifactId>java-matching-engine</artifactId>
14-
<version>0.1.0</version>
15-
<name>java-matching-engine</name>
12+
<groupId>net.laffyco.java-matching-engine</groupId>
13+
<artifactId>core</artifactId>
14+
<version>0.0.1</version>
15+
<name>java-matching-engine-core</name>
1616
<description>A matching engine made in Java</description>
1717
<properties>
1818
<java.version>1.8</java.version>
@@ -88,7 +88,7 @@
8888
<repository>
8989
<id>github</id>
9090
<name>GitHub Laffini Apache Maven Packages</name>
91-
<url>https://maven.pkg.github.com/Laffini/Java-Matching-Engine</url>
91+
<url>https://maven.pkg.github.com/Laffini/Java-Matching-Engine-Core</url>
9292
</repository>
9393
</distributionManagement>
9494

src/main/java/net/laffyco/javamatchingengine/JavaMatchingEngineApplication.java

Lines changed: 0 additions & 39 deletions
This file was deleted.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package net.laffyco.javamatchingengine.core;
2+
3+
import org.springframework.boot.autoconfigure.SpringBootApplication;
4+
5+
/**
6+
* Service bootstrap.
7+
*
8+
* @author Laffini
9+
*
10+
*/
11+
@SpringBootApplication
12+
public class CoreApplication {
13+
14+
/**
15+
* Start the service.
16+
*
17+
* @param args
18+
*/
19+
public static void main(final String[] args) {
20+
/*
21+
* Intentionally left blank.
22+
*/
23+
}
24+
25+
}

src/main/java/net/laffyco/javamatchingengine/OrderController.java renamed to src/main/java/net/laffyco/javamatchingengine/core/api/OrderInterface.java

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package net.laffyco.javamatchingengine;
1+
package net.laffyco.javamatchingengine.core.api;
22

33
import java.util.HashMap;
44
import java.util.List;
@@ -7,31 +7,25 @@
77

88
import org.springframework.beans.factory.annotation.Autowired;
99
import org.springframework.context.ApplicationEventPublisher;
10-
import org.springframework.web.bind.annotation.DeleteMapping;
11-
import org.springframework.web.bind.annotation.GetMapping;
10+
import org.springframework.stereotype.Service;
1211
import org.springframework.web.bind.annotation.PathVariable;
13-
import org.springframework.web.bind.annotation.PostMapping;
14-
import org.springframework.web.bind.annotation.PutMapping;
15-
import org.springframework.web.bind.annotation.RequestMapping;
1612
import org.springframework.web.bind.annotation.RequestParam;
17-
import org.springframework.web.bind.annotation.RestController;
1813

19-
import net.laffyco.javamatchingengine.engine.Order;
20-
import net.laffyco.javamatchingengine.engine.OrderBook;
21-
import net.laffyco.javamatchingengine.engine.Side;
22-
import net.laffyco.javamatchingengine.engine.Trade;
23-
import net.laffyco.javamatchingengine.events.OrderAddedEvent;
24-
import net.laffyco.javamatchingengine.events.OrderMatchedEvent;
14+
import net.laffyco.javamatchingengine.core.engine.Order;
15+
import net.laffyco.javamatchingengine.core.engine.OrderBook;
16+
import net.laffyco.javamatchingengine.core.engine.Side;
17+
import net.laffyco.javamatchingengine.core.engine.Trade;
18+
import net.laffyco.javamatchingengine.core.events.OrderAddedEvent;
19+
import net.laffyco.javamatchingengine.core.events.OrderMatchedEvent;
2520

2621
/**
2722
* Controller for orders.
2823
*
2924
* @author Laffini
3025
*
3126
*/
32-
@RestController
33-
@RequestMapping("/order")
34-
public class OrderController {
27+
@Service
28+
public class OrderInterface {
3529

3630
/**
3731
* Order book.
@@ -50,7 +44,6 @@ public class OrderController {
5044
*
5145
* @return orders
5246
*/
53-
@GetMapping("/")
5447
public Map<String, List<Order>> getOrders() {
5548
final Map<String, List<Order>> response = new HashMap<>();
5649
response.put("buy", this.orderBook.getBuyOrders());
@@ -65,7 +58,6 @@ public Map<String, List<Order>> getOrders() {
6558
* @param side
6659
* @return order (or null if not found)
6760
*/
68-
@GetMapping("/{id}")
6961
public Map<String, Order> getOrder(@PathVariable final String id,
7062
@RequestParam("side") final Side side) {
7163
final Map<String, Order> response = new HashMap<>();
@@ -83,7 +75,6 @@ public Map<String, Order> getOrder(@PathVariable final String id,
8375
* @param price
8476
* @return order id
8577
*/
86-
@PostMapping("/")
8778
public Map<String, Object> addOrder(@RequestParam("side") final Side side,
8879
@RequestParam("amount") final double amount,
8980
@RequestParam("price") final double price) {
@@ -113,7 +104,6 @@ public Map<String, Object> addOrder(@RequestParam("side") final Side side,
113104
* @param side
114105
* @return whether an order was deleted or not
115106
*/
116-
@DeleteMapping("/{id}")
117107
public Map<String, Object> deleteOrder(@PathVariable final String id,
118108
@RequestParam("side") final Side side) {
119109
final Map<String, Object> response = new HashMap<>();
@@ -135,7 +125,6 @@ public Map<String, Object> deleteOrder(@PathVariable final String id,
135125
* @param newSide
136126
* @return whether an order has been updated or not
137127
*/
138-
@PutMapping("/{id}")
139128
public Map<String, Object> updateOrder(@PathVariable final String id,
140129
@RequestParam("side") final Side side,
141130
@RequestParam("newAmount") final Optional<Double> newAmount,

src/main/java/net/laffyco/javamatchingengine/SpreadController.java renamed to src/main/java/net/laffyco/javamatchingengine/core/api/SpreadInterface.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
1-
package net.laffyco.javamatchingengine;
1+
package net.laffyco.javamatchingengine.core.api;
22

33
import java.util.HashMap;
44
import java.util.Map;
55

66
import org.springframework.beans.factory.annotation.Autowired;
7-
import org.springframework.web.bind.annotation.GetMapping;
8-
import org.springframework.web.bind.annotation.RequestMapping;
9-
import org.springframework.web.bind.annotation.RestController;
7+
import org.springframework.stereotype.Service;
108

11-
import net.laffyco.javamatchingengine.engine.OrderBook;
9+
import net.laffyco.javamatchingengine.core.engine.OrderBook;
1210

1311
/**
1412
* Spread controller.
1513
*
1614
* @author Laffini
1715
*
1816
*/
19-
@RestController
20-
@RequestMapping("/spread")
21-
public class SpreadController {
17+
@Service
18+
public class SpreadInterface {
2219

2320
/**
2421
* Order book.
@@ -31,7 +28,6 @@ public class SpreadController {
3128
*
3229
* @return spread
3330
*/
34-
@GetMapping("/")
3531
public Map<String, Double> getSpread() {
3632
final Map<String, Double> response = new HashMap<>();
3733
final double spread = this.orderBook.getSpread();
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/**
2+
* @author Laffini
3+
*
4+
*/
5+
package net.laffyco.javamatchingengine.core.api;

src/main/java/net/laffyco/javamatchingengine/engine/Order.java renamed to src/main/java/net/laffyco/javamatchingengine/core/engine/Order.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package net.laffyco.javamatchingengine.engine;
1+
package net.laffyco.javamatchingengine.core.engine;
22

33
import java.util.Date;
44
import java.util.UUID;

src/main/java/net/laffyco/javamatchingengine/engine/OrderBook.java renamed to src/main/java/net/laffyco/javamatchingengine/core/engine/OrderBook.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package net.laffyco.javamatchingengine.engine;
1+
package net.laffyco.javamatchingengine.core.engine;
22

33
import java.util.ArrayList;
44
import java.util.Collections;

src/main/java/net/laffyco/javamatchingengine/engine/Side.java renamed to src/main/java/net/laffyco/javamatchingengine/core/engine/Side.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package net.laffyco.javamatchingengine.engine;
1+
package net.laffyco.javamatchingengine.core.engine;
22

33
/**
44
* Order sides.

0 commit comments

Comments
 (0)