diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml deleted file mode 100644 index 797acea..0000000 --- a/.idea/runConfigurations.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Data-Integration.iml b/Data-Integration.iml index 6f3b297..0133fd5 100644 --- a/Data-Integration.iml +++ b/Data-Integration.iml @@ -6,7 +6,7 @@ - + @@ -20,24 +20,24 @@ - - + + - + - - - - - - - - + + + + + + + + diff --git a/src/OrderBook/OrderBook.java b/src/OrderBook/OrderBook.java index 0e15e35..3522d2b 100644 --- a/src/OrderBook/OrderBook.java +++ b/src/OrderBook/OrderBook.java @@ -29,7 +29,7 @@ private void sortedPlace(Order order){ return; } else if (sideOfBook.get(i).price < order.price && !isAsk || - sideOfBook.get(i).price > order.price && isAsk){ + sideOfBook.get(i).price > order.price && isAsk) { if (order.side == Side.ASK) asks.add(i,order); else @@ -84,8 +84,14 @@ public void placeOrder(Order order){ sittingVolume += order.size; adjustBBO(); placedOrders.put(order.orderID, order.orderID); + + if (bestBidPrice > bestAskPrice && bestBidPrice != -1 && bestAskPrice != -1) { + // NEW ASSERTION, check for crossed orderbook condition where best bid over best ask + throw new RuntimeException("Crossed orderbook condition!"); + } } + /** * Registers fill event on the order book * WARNING: Will throw if fill event doesn't fill any sitting order @@ -100,4 +106,4 @@ public void fillEvent(Fill fill){ adjustBBO(); recordedFills.put(fill.orderID, fill.orderID); } -} +} \ No newline at end of file diff --git a/src/test/testOrderBook.java b/src/test/testOrderBook.java index 063dff6..bd5c24d 100644 --- a/src/test/testOrderBook.java +++ b/src/test/testOrderBook.java @@ -1,6 +1,12 @@ import OrderBook.Order; +import OrderBook.Fill; import OrderBook.OrderBook; import OrderBook.Side; + +import static OrderBook.OrderType.MARKET_ORDER; +import static OrderBook.OrderType.LIMIT_ORDER; +import static OrderBook.OrderType.STOP_LIMIT_ORDER; + import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; @@ -168,4 +174,146 @@ void placeTwoAsk() { assertEquals(-1f, testSubject.bestBidPrice); assertEquals(1.8f, testSubject.sittingVolume); } -} + + @Test + void placeOneBidSTOPLIMIT() { + // Init and checking start conditions + OrderBook testSubject = new OrderBook(); + assertEquals(0, testSubject.asks.size()); + assertEquals(0, testSubject.bids.size()); + assertEquals(-1f, testSubject.bestAskPrice); + assertEquals(-1f, testSubject.bestBidPrice); + assertEquals(0f, testSubject.sittingVolume); + // Operation + Order newSTOPLIMIT = new Order("helloUUID!", "helloproductID!", 2.2f, 99.99f, + STOP_LIMIT_ORDER, false, Side.BID, 1677598183L); + testSubject.placeOrder(newSTOPLIMIT); + // Checking Operation + assertEquals(0, testSubject.asks.size()); + assertEquals(1, testSubject.bids.size()); + assertEquals(99.99f, testSubject.bids.getFirst().price); + assertEquals(2.2f, testSubject.bids.getFirst().size); + assertEquals(1677598183L, testSubject.bids.getFirst().createdTs); + assertEquals(-1f, testSubject.bestAskPrice); + assertEquals(99.99f, testSubject.bestBidPrice); + assertEquals(2.2f, testSubject.sittingVolume); + } + + @Test + void placeOneAskLIMITORDER() { + // Init and checking start conditions + OrderBook testSubject = new OrderBook(); + assertEquals(0, testSubject.asks.size()); + assertEquals(0, testSubject.bids.size()); + assertEquals(-1f, testSubject.bestAskPrice); + assertEquals(-1f, testSubject.bestBidPrice); + assertEquals(0f, testSubject.sittingVolume); + // Operation + Order newLIMIT = new Order("helloUUID!", "helloproductID!", 6.9f, 69.69f, + LIMIT_ORDER, false, Side.ASK, 69L); + testSubject.placeOrder(newLIMIT); + // Checking Operation + assertEquals(1, testSubject.asks.size()); + assertEquals(0, testSubject.bids.size()); + assertEquals(69.69f, testSubject.asks.getFirst().price); + assertEquals(6.9f, testSubject.asks.getFirst().size); + assertEquals(69L, testSubject.asks.getFirst().createdTs); + assertEquals(69.69f, testSubject.bestAskPrice); + assertEquals(-1f, testSubject.bestBidPrice); + assertEquals(6.9f, testSubject.sittingVolume); + } + + @Test + void placeTwoAskMARKETORDERandOneBidLIMITORDERthrowCROSSED_ORDERBOOK() { + // Init and checking start conditions + OrderBook testSubject = new OrderBook(); + assertEquals(0, testSubject.asks.size()); + assertEquals(0, testSubject.bids.size()); + assertEquals(-1f, testSubject.bestAskPrice); + assertEquals(-1f, testSubject.bestBidPrice); + assertEquals(0f, testSubject.sittingVolume); + // Operation + Order newMARKETORDER = new Order("helloUUID!", "helloproductID_1!", 106.0f, + 99.99f, MARKET_ORDER, false, Side.ASK, 1677598097L); + testSubject.placeOrder(newMARKETORDER); + // Checking Operation + assertEquals(1, testSubject.asks.size()); + assertEquals(0, testSubject.bids.size()); + assertEquals(99.99f, testSubject.asks.getFirst().price); // No orders have been filled yet + assertEquals(106.0f, testSubject.asks.getFirst().size); // No orders have been filled yet + assertEquals(1677598097L, testSubject.asks.getFirst().createdTs); + assertEquals(99.99f, testSubject.bestAskPrice); + assertEquals(-1f, testSubject.bestBidPrice); + assertEquals(106.0f, testSubject.sittingVolume); + // Operation + newMARKETORDER = new Order("helloUUID!", "helloproductID_2!", 3.7f, + 0.01f, MARKET_ORDER, false, Side.ASK, 1677598150L); + testSubject.placeOrder(newMARKETORDER); + // Checking Operation + assertEquals(2, testSubject.asks.size()); + assertEquals(0, testSubject.bids.size()); + assertEquals(0.01f, testSubject.asks.getFirst().price); + assertEquals(3.7f, testSubject.asks.getFirst().size); + assertEquals(1677598150L, testSubject.asks.getFirst().createdTs); + assertEquals(0.01f, testSubject.bestAskPrice); + assertEquals(-1f, testSubject.bestBidPrice); + assertEquals(109.7f, testSubject.sittingVolume); + /* // Operation + Order newLIMITORDER = new Order("helloUUID!", "helloproductID_3!", 100.0f, + 49.97f, LIMIT_ORDER, false, Side.BID, 1677598167L); + testSubject.placeOrder(newLIMITORDER); + // Checking Operation, note CROSSED ORDERBOOK */ + } + + @Test + void placeOneBidandOneAskLIMITORDERfillEvent() { + // Init and checking start conditions + OrderBook testSubject = new OrderBook(); + assertEquals(0, testSubject.asks.size()); + assertEquals(0, testSubject.bids.size()); + assertEquals(-1f, testSubject.bestAskPrice); + assertEquals(-1f, testSubject.bestBidPrice); + assertEquals(0f, testSubject.sittingVolume); + // Operation + Order newLIMITORDER = new Order("helloUUID!", "helloproductID_1!", 100.0f, + 27.37f, LIMIT_ORDER, false, Side.BID, 100L); + testSubject.placeOrder(newLIMITORDER); + assertEquals(0, testSubject.asks.size()); + assertEquals(1, testSubject.bids.size()); + assertEquals(27.37f, testSubject.bids.getFirst().price); + assertEquals(100.0f, testSubject.bids.getFirst().size); + assertEquals(100L, testSubject.bids.getFirst().createdTs); + assertEquals(-1f, testSubject.bestAskPrice); + assertEquals(27.37f, testSubject.bestBidPrice); + assertEquals(100.0f, testSubject.sittingVolume); + // Operation + newLIMITORDER = new Order("helloUUID!", "helloproductID_2!", 50.0f, + 34.31f, LIMIT_ORDER, false, Side.ASK, 200L); + testSubject.placeOrder(newLIMITORDER); + assertEquals(1, testSubject.asks.size()); + assertEquals(1, testSubject.bids.size()); + assertEquals(34.31f, testSubject.asks.getFirst().price); + assertEquals(50.0f, testSubject.asks.getFirst().size); + assertEquals(27.37f, testSubject.bids.getFirst().price); + assertEquals(100.0f, testSubject.bids.getFirst().size); + assertEquals(200L, testSubject.asks.getFirst().createdTs); + assertEquals(100L, testSubject.bids.getFirst().createdTs); + assertEquals(34.31f, testSubject.bestAskPrice); + assertEquals(27.37f, testSubject.bestBidPrice); + assertEquals(150.0f, testSubject.sittingVolume); + // Operation + Fill newFill = new Fill("helloproductID_2!", "helloclientID!", 35.5f, + 34.31f, 1.5f, LIMIT_ORDER, Side.ASK, 330L); + testSubject.fillEvent(newFill); + assertEquals(1, testSubject.asks.size()); + assertEquals(1, testSubject.bids.size()); + assertEquals(34.31f, testSubject.asks.getFirst().price); + assertEquals(14.5f, testSubject.asks.getFirst().size); + assertEquals(27.37f, testSubject.bids.getFirst().price); + assertEquals(100.0f, testSubject.bids.getFirst().size); + assertEquals(100L, testSubject.bids.getFirst().createdTs); + assertEquals(34.31f, testSubject.bestAskPrice); + assertEquals(27.37f, testSubject.bestBidPrice); + assertEquals(114.5f, testSubject.sittingVolume); + } +} \ No newline at end of file