From d20c0b663d1e3848ad700aa41ce3073ef009ae33 Mon Sep 17 00:00:00 2001 From: Arjun Vachhani Date: Mon, 8 Jun 2020 12:24:33 +0530 Subject: [PATCH] order matcher now calculates fee for maker and taker (#13) --- .../CancelledOrderSerializerTests.cs | 31 +- .../OrderMatcher.Tests/FillSerializerTests.cs | 46 +- .../OrderMatcher.Tests/MatchingEngineTests.cs | 470 +++++++++--------- .../OrderSerializerTests.cs | 31 +- OrderMatcher/OrderMatcher/CancelledOrder.cs | 1 + OrderMatcher/OrderMatcher/Fee.cs | 8 + OrderMatcher/OrderMatcher/Fill.cs | 2 + OrderMatcher/OrderMatcher/IFeeProvider.cs | 7 + .../OrderMatcher/Listeners/ITradeListener.cs | 4 +- OrderMatcher/OrderMatcher/MatchingEngine.cs | 59 ++- OrderMatcher/OrderMatcher/MessageType.cs | 1 + OrderMatcher/OrderMatcher/Order.cs | 3 +- OrderMatcher/OrderMatcher/OrderMatcher.csproj | 7 +- .../Serializers/CancelledOrderSerializer.cs | 13 +- .../Serializers/FillSerializer.cs | 44 +- .../Serializers/OrderSerializer.cs | 8 +- .../OrderMatcher/Serializers/Serializer.cs | 2 + 17 files changed, 420 insertions(+), 317 deletions(-) create mode 100644 OrderMatcher/OrderMatcher/Fee.cs create mode 100644 OrderMatcher/OrderMatcher/IFeeProvider.cs diff --git a/OrderMatcher/OrderMatcher.Tests/CancelledOrderSerializerTests.cs b/OrderMatcher/OrderMatcher.Tests/CancelledOrderSerializerTests.cs index 244e5b5..5ecfe08 100644 --- a/OrderMatcher/OrderMatcher.Tests/CancelledOrderSerializerTests.cs +++ b/OrderMatcher/OrderMatcher.Tests/CancelledOrderSerializerTests.cs @@ -8,13 +8,13 @@ public class CancelledOrderSerializerTests [Fact] public void Serialize_Doesnotthrowexception_Min() { - var bytes = CancelledOrderSerializer.Serialize(new CancelledOrder { OrderId = OrderId.MinValue, Timestamp = int.MinValue, RemainingQuantity = int.MinValue, CancelReason = CancelReason.UserRequested, Cost = Quantity.MinValue }); + var bytes = CancelledOrderSerializer.Serialize(new CancelledOrder { OrderId = OrderId.MinValue, Timestamp = int.MinValue, RemainingQuantity = int.MinValue, CancelReason = CancelReason.UserRequested, Cost = Quantity.MinValue, Fee = Quantity.MinValue }); } [Fact] public void Serialize_Doesnotthrowexception_Max() { - var bytes = CancelledOrderSerializer.Serialize(new CancelledOrder { OrderId = OrderId.MaxValue, Timestamp = int.MaxValue, RemainingQuantity = int.MaxValue, CancelReason = CancelReason.ValidityExpired, Cost = Quantity.MaxValue }); + var bytes = CancelledOrderSerializer.Serialize(new CancelledOrder { OrderId = OrderId.MaxValue, Timestamp = int.MaxValue, RemainingQuantity = int.MaxValue, CancelReason = CancelReason.ValidityExpired, Cost = Quantity.MaxValue, Fee = Quantity.MaxValue }); } [Fact] @@ -34,23 +34,23 @@ public void Deserialize_ThrowsExecption_IfNullPassed() [Fact] public void Deserialize_ThrowsExecption_IfMessageIsLessThan35Bytes() { - var bytes = new byte[51]; + var bytes = new byte[67]; Exception ex = Assert.Throws(() => CancelledOrderSerializer.Deserialize(bytes)); - Assert.Equal("Canceled Order Message must be of Size : 52", ex.Message); + Assert.Equal("Canceled Order Message must be of Size : 68", ex.Message); } [Fact] public void Deserialize_ThrowsExecption_IfMessageIsGreaterThan35Bytes() { - var bytes = new byte[53]; + var bytes = new byte[69]; Exception ex = Assert.Throws(() => CancelledOrderSerializer.Deserialize(bytes)); - Assert.Equal("Canceled Order Message must be of Size : 52", ex.Message); + Assert.Equal("Canceled Order Message must be of Size : 68", ex.Message); } [Fact] public void Deserialize_ThrowsExecption_IfMessageIsNothaveValidType() { - var bytes = new byte[52]; + var bytes = new byte[68]; Exception ex = Assert.Throws(() => CancelledOrderSerializer.Deserialize(bytes)); Assert.Equal("Invalid Message", ex.Message); } @@ -58,7 +58,7 @@ public void Deserialize_ThrowsExecption_IfMessageIsNothaveValidType() [Fact] public void Deserialize_ThrowsExecption_IfVersionIsNotSet() { - var bytes = new byte[52]; + var bytes = new byte[68]; bytes[4] = (byte)MessageType.Cancel; Exception ex = Assert.Throws(() => CancelledOrderSerializer.Deserialize(bytes)); Assert.Equal("version mismatch", ex.Message); @@ -67,44 +67,47 @@ public void Deserialize_ThrowsExecption_IfVersionIsNotSet() [Fact] public void Deserialize_Doesnotthrowexception_Min() { - var bytes = CancelledOrderSerializer.Serialize(new CancelledOrder { OrderId = OrderId.MinValue, Timestamp = int.MinValue, RemainingQuantity = int.MinValue, CancelReason = CancelReason.UserRequested, Cost = Quantity.MinValue }); + var bytes = CancelledOrderSerializer.Serialize(new CancelledOrder { OrderId = OrderId.MinValue, Timestamp = int.MinValue, RemainingQuantity = int.MinValue, CancelReason = CancelReason.UserRequested, Cost = Quantity.MinValue, Fee = Quantity.MinValue }); var messageLength = BitConverter.ToInt32(bytes, 0); - Assert.Equal(52, messageLength); + Assert.Equal(68, messageLength); var cancelledOrder = CancelledOrderSerializer.Deserialize(bytes); Assert.Equal(OrderId.MinValue, cancelledOrder.OrderId); Assert.Equal(int.MinValue, cancelledOrder.RemainingQuantity); Assert.Equal(int.MinValue, cancelledOrder.Timestamp); Assert.Equal(CancelReason.UserRequested, cancelledOrder.CancelReason); Assert.Equal(Quantity.MinValue, cancelledOrder.Cost); + Assert.Equal(Quantity.MinValue, cancelledOrder.Fee); } [Fact] public void Deserialize_Doesnotthrowexception_Max() { - var bytes = CancelledOrderSerializer.Serialize(new CancelledOrder { OrderId = OrderId.MaxValue, Timestamp = int.MaxValue, RemainingQuantity = int.MaxValue, CancelReason = CancelReason.ValidityExpired, Cost = Quantity.MaxValue }); + var bytes = CancelledOrderSerializer.Serialize(new CancelledOrder { OrderId = OrderId.MaxValue, Timestamp = int.MaxValue, RemainingQuantity = int.MaxValue, CancelReason = CancelReason.ValidityExpired, Cost = Quantity.MaxValue, Fee = Quantity.MaxValue }); var messageLength = BitConverter.ToInt32(bytes, 0); - Assert.Equal(52, messageLength); + Assert.Equal(68, messageLength); var cancelledOrder = CancelledOrderSerializer.Deserialize(bytes); Assert.Equal(OrderId.MaxValue, cancelledOrder.OrderId); Assert.Equal(int.MaxValue, cancelledOrder.RemainingQuantity); Assert.Equal(int.MaxValue, cancelledOrder.Timestamp); Assert.Equal(CancelReason.ValidityExpired, cancelledOrder.CancelReason); Assert.Equal(Quantity.MaxValue, cancelledOrder.Cost); + Assert.Equal(Quantity.MaxValue, cancelledOrder.Fee); } [Fact] public void Deserialize_Doesnotthrowexception() { - var bytes = CancelledOrderSerializer.Serialize(new CancelledOrder { OrderId = 12345678, RemainingQuantity = 56789, Timestamp = 404, CancelReason = CancelReason.ValidityExpired, Cost = 12.13m }); + var bytes = CancelledOrderSerializer.Serialize(new CancelledOrder { OrderId = 12345678, RemainingQuantity = 56789, Timestamp = 404, CancelReason = CancelReason.ValidityExpired, Cost = 12.13m, Fee = 92.005m }); var messageLength = BitConverter.ToInt32(bytes, 0); - Assert.Equal(52, messageLength); + Assert.Equal(68, messageLength); var cancelledOrder = CancelledOrderSerializer.Deserialize(bytes); Assert.Equal((OrderId)12345678, cancelledOrder.OrderId); Assert.Equal(56789, cancelledOrder.RemainingQuantity); Assert.Equal(404, cancelledOrder.Timestamp); Assert.Equal(CancelReason.ValidityExpired, cancelledOrder.CancelReason); Assert.Equal((Quantity)12.13m, cancelledOrder.Cost); + Assert.Equal((Quantity)92.005m, cancelledOrder.Fee); } } } diff --git a/OrderMatcher/OrderMatcher.Tests/FillSerializerTests.cs b/OrderMatcher/OrderMatcher.Tests/FillSerializerTests.cs index 1cd714a..5aef6be 100644 --- a/OrderMatcher/OrderMatcher.Tests/FillSerializerTests.cs +++ b/OrderMatcher/OrderMatcher.Tests/FillSerializerTests.cs @@ -8,13 +8,13 @@ public class FillSerializerTests [Fact] public void Serialize_Doesnotthrowexception_Min() { - var bytes = FillSerializer.Serialize(new Fill { MakerOrderId = OrderId.MinValue, TakerOrderId = OrderId.MinValue, Timestamp = int.MinValue, MatchQuantity = int.MinValue, MatchRate = int.MinValue, BidCost = Quantity.MinValue, AskRemainingQuantity = Quantity.MinValue }); + var bytes = FillSerializer.Serialize(new Fill { MakerOrderId = OrderId.MinValue, TakerOrderId = OrderId.MinValue, Timestamp = int.MinValue, MatchQuantity = int.MinValue, MatchRate = int.MinValue, BidCost = Quantity.MinValue, BidFee = Quantity.MinValue, AskRemainingQuantity = Quantity.MinValue, AskFee = Quantity.MinValue }); } [Fact] public void Serialize_Doesnotthrowexception_Max() { - var bytes = FillSerializer.Serialize(new Fill { MakerOrderId = OrderId.MaxValue, TakerOrderId = OrderId.MaxValue, Timestamp = int.MaxValue, MatchQuantity = int.MaxValue, MatchRate = int.MaxValue, BidCost = Quantity.MaxValue, AskRemainingQuantity = Quantity.MaxValue }); + var bytes = FillSerializer.Serialize(new Fill { MakerOrderId = OrderId.MaxValue, TakerOrderId = OrderId.MaxValue, Timestamp = int.MaxValue, MatchQuantity = int.MaxValue, MatchRate = int.MaxValue, BidCost = Quantity.MaxValue, BidFee = Quantity.MaxValue, AskRemainingQuantity = Quantity.MaxValue, AskFee = Quantity.MaxValue }); } [Fact] @@ -34,23 +34,23 @@ public void Deserialize_ThrowsExecption_IfNullPassed() [Fact] public void Deserialize_ThrowsExecption_IfMessageIsLessThan35Bytes() { - var bytes = new byte[92]; + var bytes = new byte[126]; Exception ex = Assert.Throws(() => FillSerializer.Deserialize(bytes)); - Assert.Equal("Fill Message must be of Size : 93", ex.Message); + Assert.Equal("Fill Message must be of Size : 127", ex.Message); } [Fact] public void Deserialize_ThrowsExecption_IfMessageIsGreaterThan35Bytes() { - var bytes = new byte[94]; + var bytes = new byte[128]; Exception ex = Assert.Throws(() => FillSerializer.Deserialize(bytes)); - Assert.Equal("Fill Message must be of Size : 93", ex.Message); + Assert.Equal("Fill Message must be of Size : 127", ex.Message); } [Fact] public void Deserialize_ThrowsExecption_IfMessageIsNothaveValidType() { - var bytes = new byte[93]; + var bytes = new byte[127]; Exception ex = Assert.Throws(() => FillSerializer.Deserialize(bytes)); Assert.Equal("Invalid Message", ex.Message); } @@ -58,7 +58,7 @@ public void Deserialize_ThrowsExecption_IfMessageIsNothaveValidType() [Fact] public void Deserialize_ThrowsExecption_IfVersionIsNotSet() { - var bytes = new byte[93]; + var bytes = new byte[127]; bytes[4] = (byte)MessageType.Fill; Exception ex = Assert.Throws(() => FillSerializer.Deserialize(bytes)); Assert.Equal("version mismatch", ex.Message); @@ -67,9 +67,9 @@ public void Deserialize_ThrowsExecption_IfVersionIsNotSet() [Fact] public void Deserialize_Doesnotthrowexception_Min() { - var bytes = FillSerializer.Serialize(new Fill { MakerOrderId = OrderId.MinValue, TakerOrderId = OrderId.MinValue, Timestamp = int.MinValue, MatchQuantity = int.MinValue, MatchRate = int.MinValue, BidCost = Quantity.MinValue, AskRemainingQuantity = Quantity.MinValue }); + var bytes = FillSerializer.Serialize(new Fill { MakerOrderId = OrderId.MinValue, TakerOrderId = OrderId.MinValue, Timestamp = int.MinValue, MatchQuantity = int.MinValue, MatchRate = int.MinValue, BidCost = Quantity.MinValue, BidFee = Quantity.MinValue, AskRemainingQuantity = Quantity.MinValue, AskFee = Quantity.MinValue }); var messageLength = BitConverter.ToInt32(bytes, 0); - Assert.Equal(93, messageLength); + Assert.Equal(127, messageLength); var fill = FillSerializer.Deserialize(bytes); Assert.Equal(OrderId.MinValue, fill.MakerOrderId); Assert.Equal(OrderId.MinValue, fill.TakerOrderId); @@ -77,15 +77,17 @@ public void Deserialize_Doesnotthrowexception_Min() Assert.Equal(int.MinValue, fill.MatchQuantity); Assert.Equal(int.MinValue, fill.Timestamp); Assert.Equal(Quantity.MinValue, fill.BidCost); + Assert.Equal(Quantity.MinValue, fill.BidFee); Assert.Equal(Quantity.MinValue, fill.AskRemainingQuantity); + Assert.Equal(Quantity.MinValue, fill.AskFee); } [Fact] public void Deserialize_Doesnotthrowexception_Max() { - var bytes = FillSerializer.Serialize(new Fill { MakerOrderId = OrderId.MaxValue, TakerOrderId = OrderId.MaxValue, Timestamp = int.MaxValue, MatchQuantity = int.MaxValue, MatchRate = int.MaxValue, BidCost = Quantity.MaxValue, AskRemainingQuantity = Quantity.MaxValue }); + var bytes = FillSerializer.Serialize(new Fill { MakerOrderId = OrderId.MaxValue, TakerOrderId = OrderId.MaxValue, Timestamp = int.MaxValue, MatchQuantity = int.MaxValue, MatchRate = int.MaxValue, BidCost = Quantity.MaxValue, BidFee = Quantity.MaxValue, AskRemainingQuantity = Quantity.MaxValue, AskFee = Quantity.MaxValue }); var messageLength = BitConverter.ToInt32(bytes, 0); - Assert.Equal(93, messageLength); + Assert.Equal(127, messageLength); var fill = FillSerializer.Deserialize(bytes); Assert.Equal(OrderId.MaxValue, fill.MakerOrderId); Assert.Equal(OrderId.MaxValue, fill.TakerOrderId); @@ -94,14 +96,16 @@ public void Deserialize_Doesnotthrowexception_Max() Assert.Equal(int.MaxValue, fill.Timestamp); Assert.Equal(Quantity.MaxValue, fill.AskRemainingQuantity); Assert.Equal(Quantity.MaxValue, fill.BidCost); + Assert.Equal(Quantity.MaxValue, fill.AskFee); + Assert.Equal(Quantity.MaxValue, fill.BidFee); } [Fact] public void Deserialize_Doesnotthrowexception() { - var bytes = FillSerializer.Serialize(new Fill { MakerOrderId = 12345678, TakerOrderId = 56789, Timestamp = 404, MatchQuantity = 2356, MatchRate = 9534, BidCost = 4347, AskRemainingQuantity = 87135 }); + var bytes = FillSerializer.Serialize(new Fill { MakerOrderId = 12345678, TakerOrderId = 56789, Timestamp = 404, MatchQuantity = 2356, MatchRate = 9534, BidCost = 4347, BidFee = 76157, AskRemainingQuantity = 87135, AskFee = 12103 }); var messageLength = BitConverter.ToInt32(bytes, 0); - Assert.Equal(93, messageLength); + Assert.Equal(127, messageLength); var fill = FillSerializer.Deserialize(bytes); Assert.Equal((OrderId)12345678, fill.MakerOrderId); Assert.Equal((OrderId)56789, fill.TakerOrderId); @@ -109,15 +113,17 @@ public void Deserialize_Doesnotthrowexception() Assert.Equal(2356, fill.MatchQuantity); Assert.Equal(404, fill.Timestamp); Assert.Equal(4347, fill.BidCost); + Assert.Equal(76157, fill.BidFee); Assert.Equal(87135, fill.AskRemainingQuantity); + Assert.Equal(12103, fill.AskFee); } [Fact] public void Deserialize_Doesnotthrowexception_BidCostNull() { - var bytes = FillSerializer.Serialize(new Fill { MakerOrderId = 12345678, TakerOrderId = 56789, Timestamp = 404, MatchQuantity = 2356, MatchRate = 9534, BidCost = null, AskRemainingQuantity = 87135 }); + var bytes = FillSerializer.Serialize(new Fill { MakerOrderId = 12345678, TakerOrderId = 56789, Timestamp = 404, MatchQuantity = 2356, MatchRate = 9534, BidCost = null, BidFee = null, AskRemainingQuantity = 87135, AskFee = 5434 }); var messageLength = BitConverter.ToInt32(bytes, 0); - Assert.Equal(93, messageLength); + Assert.Equal(127, messageLength); var fill = FillSerializer.Deserialize(bytes); Assert.Equal((OrderId)12345678, fill.MakerOrderId); Assert.Equal((OrderId)56789, fill.TakerOrderId); @@ -125,15 +131,17 @@ public void Deserialize_Doesnotthrowexception_BidCostNull() Assert.Equal(2356, fill.MatchQuantity); Assert.Equal(404, fill.Timestamp); Assert.Null(fill.BidCost); + Assert.Null(fill.BidFee); Assert.Equal(87135, fill.AskRemainingQuantity); + Assert.Equal(5434, fill.AskFee); } [Fact] public void Deserialize_Doesnotthrowexception_AskRemainingQuantityNull() { - var bytes = FillSerializer.Serialize(new Fill { MakerOrderId = 12345678, TakerOrderId = 56789, Timestamp = 404, MatchQuantity = 2356, MatchRate = 9534, BidCost = 4347, AskRemainingQuantity = null }); + var bytes = FillSerializer.Serialize(new Fill { MakerOrderId = 12345678, TakerOrderId = 56789, Timestamp = 404, MatchQuantity = 2356, MatchRate = 9534, BidCost = 4347, BidFee = 891434, AskRemainingQuantity = null, AskFee = null }); var messageLength = BitConverter.ToInt32(bytes, 0); - Assert.Equal(93, messageLength); + Assert.Equal(127, messageLength); var fill = FillSerializer.Deserialize(bytes); Assert.Equal((OrderId)12345678, fill.MakerOrderId); Assert.Equal((OrderId)56789, fill.TakerOrderId); @@ -141,7 +149,9 @@ public void Deserialize_Doesnotthrowexception_AskRemainingQuantityNull() Assert.Equal(2356, fill.MatchQuantity); Assert.Equal(404, fill.Timestamp); Assert.Equal(4347, fill.BidCost); + Assert.Equal(891434, fill.BidFee); Assert.Null(fill.AskRemainingQuantity); + Assert.Null(fill.AskFee); } } } diff --git a/OrderMatcher/OrderMatcher.Tests/MatchingEngineTests.cs b/OrderMatcher/OrderMatcher.Tests/MatchingEngineTests.cs index 367c5c7..7e927cf 100644 --- a/OrderMatcher/OrderMatcher.Tests/MatchingEngineTests.cs +++ b/OrderMatcher/OrderMatcher.Tests/MatchingEngineTests.cs @@ -8,13 +8,16 @@ public class MatchingEngineTests { private readonly Mock mockTradeListener; private readonly Mock mockTimeProvider; + private readonly Mock mockFeeProcider; private MatchingEngine matchingEngine; public MatchingEngineTests() { mockTradeListener = new Mock(); mockTimeProvider = new Mock(); - matchingEngine = new MatchingEngine(0, 1, mockTradeListener.Object, mockTimeProvider.Object); + mockFeeProcider = new Mock(); + mockFeeProcider.Setup(x => x.GetFee(It.IsAny())).Returns(new Fee { MakerFee = 0.2m, TakerFee = 0.5m }); + matchingEngine = new MatchingEngine(mockTradeListener.Object, mockTimeProvider.Object, mockFeeProcider.Object, 1, 2); } [Fact] @@ -29,7 +32,7 @@ public void CancelOrder_Removes_Orders_If_Exists() OrderMatchingResult result = matchingEngine.CancelOrder(order1.OrderId); Assert.Equal(OrderMatchingResult.CancelAcepted, result); - mockTradeListener.Verify(x => x.OnCancel(1, 1000, 0, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(1, 1000, 0, 0, CancelReason.UserRequested)); mockTradeListener.VerifyNoOtherCalls(); Assert.DoesNotContain(order1, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order1.OrderId, matchingEngine.AcceptedOrders); @@ -38,7 +41,7 @@ public void CancelOrder_Removes_Orders_If_Exists() [Fact] public void CancelOrder_Removes_Orders_No_Cancel_Listener() { - MatchingEngine matchingEngine = new MatchingEngine(0, 1, mockTradeListener.Object, mockTimeProvider.Object); + MatchingEngine matchingEngine = new MatchingEngine(mockTradeListener.Object, mockTimeProvider.Object, mockFeeProcider.Object, 1, 0); Order order1 = new Order { IsBuy = true, OrderId = 1, OpenQuantity = 1000, Price = 10 }; var orderWrapper1 = new OrderWrapper { Order = order1 }; matchingEngine.AddOrder(orderWrapper1); @@ -48,7 +51,7 @@ public void CancelOrder_Removes_Orders_No_Cancel_Listener() OrderMatchingResult result = matchingEngine.CancelOrder(order1.OrderId); Assert.Equal(OrderMatchingResult.CancelAcepted, result); - mockTradeListener.Verify(x => x.OnCancel(1, 1000, 0, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(1, 1000, 0, 0, CancelReason.UserRequested)); mockTradeListener.VerifyNoOtherCalls(); Assert.DoesNotContain(order1, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order1.OrderId, matchingEngine.AcceptedOrders); @@ -66,7 +69,7 @@ public void CancelOrder_If_Orders_Does_Not_Already_Cancelled_Call_OnCancel() OrderMatchingResult cancelled = matchingEngine.CancelOrder(order1.OrderId); Assert.Equal(OrderMatchingResult.CancelAcepted, cancelled); - mockTradeListener.Verify(x => x.OnCancel(1, 1000, 0, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(1, 1000, 0, 0, CancelReason.UserRequested)); Assert.DoesNotContain(order1, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order1.OrderId, matchingEngine.AcceptedOrders); @@ -102,7 +105,7 @@ public void CancelOrder_Normal_Market_After_Match_Enters_Pending_With_Limit_Shou OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 1000, null, 10000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 1000, null, null, 10000, 20)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.Contains(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -119,7 +122,7 @@ public void CancelOrder_Normal_Market_After_Match_Enters_Pending_With_Limit_Shou OrderMatchingResult result3 = matchingEngine.CancelOrder(2); - mockTradeListener.Verify(x => x.OnCancel(2, 500, 10000, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(2, 500, 10000, 50, CancelReason.UserRequested)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.CancelAcepted, result3); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -159,7 +162,7 @@ public void CancelOrder_Normal_Market_After_Match_Enters_Pending_With_Limit_Shou OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 1000, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 1000, 0, 20, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.Contains(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -176,7 +179,7 @@ public void CancelOrder_Normal_Market_After_Match_Enters_Pending_With_Limit_Shou OrderMatchingResult result3 = matchingEngine.CancelOrder(2); - mockTradeListener.Verify(x => x.OnCancel(2, 500, 10000, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(2, 500, 10000, 50, CancelReason.UserRequested)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.CancelAcepted, result3); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -216,7 +219,7 @@ public void CancelOrder_Stop_Limit_Order_Entered_In_Stop_Book_With_Market_Rate_F OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -247,7 +250,7 @@ public void CancelOrder_Stop_Limit_Order_Entered_In_Stop_Book_With_Market_Rate_F Assert.Equal((ulong)2, order3.Sequnce); OrderMatchingResult result4 = matchingEngine.CancelOrder(order3.OrderId); - mockTradeListener.Verify(x => x.OnCancel(3, 500, 0, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(3, 500, 0, 0, CancelReason.UserRequested)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.CancelAcepted, result4); Assert.DoesNotContain(order3, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -286,7 +289,7 @@ public void CancelOrder_Stop_Market_Order_Entered_In_Stop_Book_With_Market_Rate_ OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -317,7 +320,7 @@ public void CancelOrder_Stop_Market_Order_Entered_In_Stop_Book_With_Market_Rate_ Assert.Equal((ulong)2, order3.Sequnce); OrderMatchingResult result4 = matchingEngine.CancelOrder(order3.OrderId); - mockTradeListener.Verify(x => x.OnCancel(3, 500, 0, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(3, 500, 0, 0, CancelReason.UserRequested)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.CancelAcepted, result4); Assert.DoesNotContain(order3, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -356,7 +359,7 @@ public void CancelOrder_Stop_Limit_Order_Entered_In_Stop_Book_With_Market_Rate_F OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -387,7 +390,7 @@ public void CancelOrder_Stop_Limit_Order_Entered_In_Stop_Book_With_Market_Rate_F Assert.Equal((ulong)2, order3.Sequnce); OrderMatchingResult result4 = matchingEngine.CancelOrder(order3.OrderId); - mockTradeListener.Verify(x => x.OnCancel(3, 500, 0, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(3, 500, 0, 0, CancelReason.UserRequested)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.CancelAcepted, result4); Assert.DoesNotContain(order3, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -426,7 +429,7 @@ public void CancelOrder_Stop_Market_Order_Entered_In_Stop_Book_With_Market_Rate_ OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -457,7 +460,7 @@ public void CancelOrder_Stop_Market_Order_Entered_In_Stop_Book_With_Market_Rate_ Assert.Equal((ulong)2, order3.Sequnce); OrderMatchingResult result4 = matchingEngine.CancelOrder(order3.OrderId); - mockTradeListener.Verify(x => x.OnCancel(3, 500, 0, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(3, 500, 0, 0, CancelReason.UserRequested)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.CancelAcepted, result4); Assert.DoesNotContain(order3, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -496,7 +499,7 @@ public void CancelOrder_Cancels_Triggered_Stop_Limit_Order_Buy() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -582,7 +585,7 @@ public void CancelOrder_Cancels_Triggered_Stop_Limit_Order_Buy() OrderMatchingResult result7 = matchingEngine.AddOrder(orderWrapper7); mockTradeListener.Verify(x => x.OnAccept(order7.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(7, 6, 12, 500, 0, 6000)); + mockTradeListener.Verify(x => x.OnTrade(7, 6, 12, 500, 0, 12, 6000, 30)); mockTradeListener.Verify(x => x.OnOrderTriggered(3)); mockTradeListener.Verify(x => x.OnOrderTriggered(4)); mockTradeListener.VerifyNoOtherCalls(); @@ -603,7 +606,7 @@ public void CancelOrder_Cancels_Triggered_Stop_Limit_Order_Buy() OrderMatchingResult result8 = matchingEngine.CancelOrder(order4.OrderId); - mockTradeListener.Verify(x => x.OnCancel(4, 500, 0, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(4, 500, 0, 0, CancelReason.UserRequested)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result7); Assert.DoesNotContain(order7, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -624,7 +627,7 @@ public void CancelOrder_Cancels_Triggered_Stop_Limit_Order_Buy() [Fact] public void TriggerWorks_IfNoTriggerListerPassed() { - var matchingEngine = new MatchingEngine(0, 1, mockTradeListener.Object, mockTimeProvider.Object); + var matchingEngine = new MatchingEngine(mockTradeListener.Object, mockTimeProvider.Object, mockFeeProcider.Object, 1, 0); Order order1 = new Order { IsBuy = false, OpenQuantity = 500, Price = 10, OrderId = 1 }; var orderWrapper1 = new OrderWrapper { Order = order1 }; OrderMatchingResult acceptanceResult = matchingEngine.AddOrder(orderWrapper1); @@ -647,7 +650,7 @@ public void TriggerWorks_IfNoTriggerListerPassed() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -733,7 +736,7 @@ public void TriggerWorks_IfNoTriggerListerPassed() OrderMatchingResult result7 = matchingEngine.AddOrder(orderWrapper7); mockTradeListener.Verify(x => x.OnAccept(order7.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(7, 6, 8, 500, 0, 4000)); + mockTradeListener.Verify(x => x.OnTrade(7, 6, 8, 500, 0, 8, 4000, 20)); mockTradeListener.Verify(x => x.OnOrderTriggered(3)); mockTradeListener.Verify(x => x.OnOrderTriggered(4)); mockTradeListener.VerifyNoOtherCalls(); @@ -757,7 +760,7 @@ public void TriggerWorks_IfNoTriggerListerPassed() OrderMatchingResult result8 = matchingEngine.CancelOrder(order4.OrderId); - mockTradeListener.Verify(x => x.OnCancel(4, 500, 0, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(4, 500, 0, 0, CancelReason.UserRequested)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.CancelAcepted, result8); Assert.DoesNotContain(order4, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -799,7 +802,7 @@ public void CancelOrder_Cancels_Triggered_Stop_Market_Order_Buy() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -817,7 +820,7 @@ public void CancelOrder_Cancels_Triggered_Stop_Market_Order_Buy() OrderMatchingResult result3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 100, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 100, 0, 12, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result3); Assert.Contains(order3, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -832,7 +835,7 @@ public void CancelOrder_Cancels_Triggered_Stop_Market_Order_Buy() Assert.Equal((ulong)2, order3.Sequnce); OrderMatchingResult result4 = matchingEngine.CancelOrder(3); - mockTradeListener.Verify(x => x.OnCancel(3, 500, 1000, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(3, 500, 1000, 5, CancelReason.UserRequested)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.CancelAcepted, result4); Assert.DoesNotContain(order3, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -872,7 +875,7 @@ public void CancelOrder_Cancels_Triggered_Stop_Market_Order_Sell() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.Contains(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -890,7 +893,7 @@ public void CancelOrder_Cancels_Triggered_Stop_Market_Order_Sell() OrderMatchingResult result3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 2, 11, 100, null, 6100)); + mockTradeListener.Verify(x => x.OnTrade(3, 2, 11, 100, null, null, 6100, 27.2m)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result3); Assert.Contains(order3, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -906,7 +909,7 @@ public void CancelOrder_Cancels_Triggered_Stop_Market_Order_Sell() OrderMatchingResult result4 = matchingEngine.CancelOrder(3); - mockTradeListener.Verify(x => x.OnCancel(3, 500, 1100, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(3, 500, 1100, 5.5m, CancelReason.UserRequested)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result3); Assert.DoesNotContain(order3, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -1075,7 +1078,7 @@ public void AddOrder_Rejects_InvalidTotalQuantityIceberg_Order() [Fact] public void AddOrder_Rejects_TotalQuantityNotMultipleOfStepSize_Order() { - matchingEngine = new MatchingEngine(0, 0.5m, mockTradeListener.Object, mockTimeProvider.Object); + matchingEngine = new MatchingEngine(mockTradeListener.Object, mockTimeProvider.Object, mockFeeProcider.Object, 0.5m, 0); Order order1 = new Order { IsBuy = true, OrderId = 1, OpenQuantity = 1000.1m, Price = 10 }; var orderWrapper1 = new OrderWrapper { Order = order1 }; OrderMatchingResult accepted = matchingEngine.AddOrder(orderWrapper1); @@ -1086,7 +1089,7 @@ public void AddOrder_Rejects_TotalQuantityNotMultipleOfStepSize_Order() [Fact] public void AddOrder_Rejects_QuantityNotMultipleOfStepSize_Order() { - matchingEngine = new MatchingEngine(0, 0.5m, mockTradeListener.Object, mockTimeProvider.Object); + matchingEngine = new MatchingEngine(mockTradeListener.Object, mockTimeProvider.Object, mockFeeProcider.Object, 0.5m, 0); Order order1 = new Order { IsBuy = true, OrderId = 1, OpenQuantity = 1000, Price = 10 }; var orderWrapper1 = new OrderWrapper { Order = order1, TotalQuantity = 10000.1m, TipQuantity = 1000 }; OrderMatchingResult accepted = matchingEngine.AddOrder(orderWrapper1); @@ -1097,7 +1100,7 @@ public void AddOrder_Rejects_QuantityNotMultipleOfStepSize_Order() [Fact] public void AddOrder_Rejects_TotalQuantityNotMultipleOfStepSize2_Order() { - matchingEngine = new MatchingEngine(0, 3, mockTradeListener.Object, mockTimeProvider.Object); + matchingEngine = new MatchingEngine(mockTradeListener.Object, mockTimeProvider.Object, mockFeeProcider.Object, 3, 0); Order order1 = new Order { IsBuy = true, OrderId = 1, OpenQuantity = 1000, Price = 10 }; var orderWrapper1 = new OrderWrapper { Order = order1 }; OrderMatchingResult accepted = matchingEngine.AddOrder(orderWrapper1); @@ -1108,7 +1111,7 @@ public void AddOrder_Rejects_TotalQuantityNotMultipleOfStepSize2_Order() [Fact] public void AddOrder_Rejects_QuantityNotMultipleOfStepSize2_Order() { - matchingEngine = new MatchingEngine(0, 3, mockTradeListener.Object, mockTimeProvider.Object); + matchingEngine = new MatchingEngine(mockTradeListener.Object, mockTimeProvider.Object, mockFeeProcider.Object, 3, 0); Order order1 = new Order { IsBuy = true, OrderId = 1, OpenQuantity = 1000, Price = 10 }; var orderWrapper1 = new OrderWrapper { Order = order1, TotalQuantity = 10000, TipQuantity = 1000 }; OrderMatchingResult accepted = matchingEngine.AddOrder(orderWrapper1); @@ -1153,7 +1156,7 @@ public void AddOrder_Normal_Limit_Matches_With_Pending_Order() Assert.Equal(OrderMatchingResult.OrderAccepted, accepted); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 1000, 0, 10000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 1000, 0, 50, 10000, 20)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(0, order1.OpenQuantity); @@ -1167,7 +1170,7 @@ public void AddOrder_Normal_Limit_Matches_With_Pending_Order() [Fact] public void AddOrder_Normal_Limit_Matches_With_Pending_Order_Works_If_No_TradeListener_Passed() { - matchingEngine = new MatchingEngine(0, 1, null, mockTimeProvider.Object); + matchingEngine = new MatchingEngine(null, mockTimeProvider.Object, mockFeeProcider.Object, 1, 0); Order order1 = new Order { IsBuy = true, OrderId = 1, OpenQuantity = 1000, Price = 10 }; var orderWrapper1 = new OrderWrapper { Order = order1 }; @@ -1275,7 +1278,7 @@ public void AddOrder_Normal_Limit_Complex_Matching_Scenario() mockTradeListener.Verify(x => x.OnAccept(order4.OrderId)); Assert.Equal(OrderMatchingResult.OrderAccepted, result4); - mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 500, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 500, 0, 25, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.DoesNotContain(order4, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order4.OrderId, matchingEngine.AcceptedOrders); @@ -1309,7 +1312,7 @@ public void AddOrder_Normal_Limit_Complex_Matching_Scenario() OrderMatchingResult result6 = matchingEngine.AddOrder(orderWrapper6); mockTradeListener.Verify(x => x.OnAccept(order6.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(6, 2, 11, 500, null, 5500)); + mockTradeListener.Verify(x => x.OnTrade(6, 2, 11, 500, null, null, 5500, 27.5m)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result6); Assert.DoesNotContain(order6, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -1479,7 +1482,7 @@ public void AddOrder_Normal_Limit_Complex_Matching_Scenario() OrderMatchingResult result16 = matchingEngine.CancelOrder(2); Assert.Equal(OrderMatchingResult.CancelAcepted, result16); - mockTradeListener.Verify(x => x.OnCancel(2, 500, 5500, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(2, 500, 5500, 11, CancelReason.UserRequested)); mockTradeListener.VerifyNoOtherCalls(); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order2.OrderId, matchingEngine.AcceptedOrders); @@ -1496,11 +1499,11 @@ public void AddOrder_Normal_Limit_Complex_Matching_Scenario() OrderMatchingResult result17 = matchingEngine.AddOrder(orderWrapper17); mockTradeListener.Verify(x => x.OnAccept(order17.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(17, 7, 12, 500, 0, null)); - mockTradeListener.Verify(x => x.OnTrade(17, 8, 13, 1000, 0, null)); - mockTradeListener.Verify(x => x.OnTrade(17, 9, 14, 1000, 0, null)); - mockTradeListener.Verify(x => x.OnTrade(17, 10, 14, 1000, 0, null)); - mockTradeListener.Verify(x => x.OnTrade(17, 11, 15, 1000, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(17, 7, 12, 500, 0, 12, null, null)); + mockTradeListener.Verify(x => x.OnTrade(17, 8, 13, 1000, 0, 26, null, null)); + mockTradeListener.Verify(x => x.OnTrade(17, 9, 14, 1000, 0, 28, null, null)); + mockTradeListener.Verify(x => x.OnTrade(17, 10, 14, 1000, 0, 28, null, null)); + mockTradeListener.Verify(x => x.OnTrade(17, 11, 15, 1000, 0, 30, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result17); Assert.Contains(order17, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -1518,11 +1521,11 @@ public void AddOrder_Normal_Limit_Complex_Matching_Scenario() OrderMatchingResult result18 = matchingEngine.AddOrder(orderWrapper18); mockTradeListener.Verify(x => x.OnAccept(order18.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(18, 17, 16, 500, null, 70000)); - mockTradeListener.Verify(x => x.OnTrade(18, 1, 10, 500, null, 10000)); - mockTradeListener.Verify(x => x.OnTrade(18, 5, 10, 1000, null, 10000)); - mockTradeListener.Verify(x => x.OnTrade(18, 3, 9, 1000, null, 9000)); - mockTradeListener.Verify(x => x.OnTrade(18, 12, 9, 1000, 0, 9000)); + mockTradeListener.Verify(x => x.OnTrade(18, 17, 16, 500, null, null, 70000, 326)); + mockTradeListener.Verify(x => x.OnTrade(18, 1, 10, 500, null, null, 10000, 20)); + mockTradeListener.Verify(x => x.OnTrade(18, 5, 10, 1000, null, null, 10000, 20)); + mockTradeListener.Verify(x => x.OnTrade(18, 3, 9, 1000, null, null, 9000, 18)); + mockTradeListener.Verify(x => x.OnTrade(18, 12, 9, 1000, 0, 205, 9000, 18)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result18); Assert.DoesNotContain(order18, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -1540,9 +1543,9 @@ public void AddOrder_Normal_Limit_Complex_Matching_Scenario() OrderMatchingResult result19 = matchingEngine.AddOrder(orderWrapper19); mockTradeListener.Verify(x => x.OnAccept(order19.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(19, 13, 8, 1000, null, 8000)); - mockTradeListener.Verify(x => x.OnTrade(19, 14, 7, 1000, null, 7000)); - mockTradeListener.Verify(x => x.OnTrade(19, 15, 7, 1000, 0, 7000)); + mockTradeListener.Verify(x => x.OnTrade(19, 13, 8, 1000, null, null, 8000, 16)); + mockTradeListener.Verify(x => x.OnTrade(19, 14, 7, 1000, null, null, 7000, 14)); + mockTradeListener.Verify(x => x.OnTrade(19, 15, 7, 1000, 0, 110, 7000, 14)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result19); Assert.DoesNotContain(order19, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -1581,7 +1584,7 @@ public void AddOrder_Normal_Market_Matches_Order_With_Open_Orders_For_Sell() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 25, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -1620,7 +1623,7 @@ public void AddOrder_Normal_Market_Matches_Order_With_Open_Orders_For_Buy() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -1659,7 +1662,7 @@ public void AddOrder_Normal_Market_Multiple_Matches_Order_With_Open_Orders_For_S OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 25, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -1677,7 +1680,7 @@ public void AddOrder_Normal_Market_Multiple_Matches_Order_With_Open_Orders_For_S OrderMatchingResult result3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, 0, 10000)); + mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, 0, 25, 10000, 20)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result3); Assert.DoesNotContain(order3, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -1716,7 +1719,7 @@ public void AddOrder_Normal_Market_Multiple_Matches_Order_With_Open_Orders_For_B OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -1734,7 +1737,7 @@ public void AddOrder_Normal_Market_Multiple_Matches_Order_With_Open_Orders_For_B OrderMatchingResult result3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, 0, 20, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order3, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -1790,8 +1793,8 @@ public void AddOrder_Normal_Market_Matches_Multiple_Order_With_Open_Orders_For_S OrderMatchingResult result3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, 5000)); - mockTradeListener.Verify(x => x.OnTrade(3, 2, 9, 500, 0, 4500)); + mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, null, 5000, 10)); + mockTradeListener.Verify(x => x.OnTrade(3, 2, 9, 500, 0, 47.5m, 4500, 9)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result3); Assert.DoesNotContain(order3, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -1847,8 +1850,8 @@ public void AddOrder_Normal_Market_Matches_Multiple_Order_With_Open_Orders_For_B OrderMatchingResult result3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, 0, null)); - mockTradeListener.Verify(x => x.OnTrade(3, 2, 11, 500, 0, 10500)); + mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, 0, 10, null, null)); + mockTradeListener.Verify(x => x.OnTrade(3, 2, 11, 500, 0, 11, 10500, 52.5m)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result3); Assert.DoesNotContain(order3, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -1870,7 +1873,7 @@ public void AddOrder_Normal_Market_Cancel_Order_If_Pending_Buy_And_No_Sell_And_N OrderMatchingResult result1 = matchingEngine.AddOrder(orderWrapper1); mockTradeListener.Verify(x => x.OnAccept(order1.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(1, 500, 0, CancelReason.MarketOrderNoLiquidity)); + mockTradeListener.Verify(x => x.OnCancel(1, 500, 0, 0, CancelReason.MarketOrderNoLiquidity)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result1); Assert.DoesNotContain(order1, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -1892,7 +1895,7 @@ public void AddOrder_Normal_Market_Cancel_Order_If_Pending_Sell_And_No_Buy_And_N OrderMatchingResult result1 = matchingEngine.AddOrder(orderWrapper1); mockTradeListener.Verify(x => x.OnAccept(order1.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(1, 500, 0, CancelReason.MarketOrderNoLiquidity)); + mockTradeListener.Verify(x => x.OnCancel(1, 500, 0, 0, CancelReason.MarketOrderNoLiquidity)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result1); Assert.DoesNotContain(order1, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -1931,7 +1934,7 @@ public void AddOrder_Normal_Market_After_Match_Enters_Pending_With_Limit_Price_S OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 1000, null, 10000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 1000, null, null, 10000, 20)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.Contains(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -1972,7 +1975,7 @@ public void AddOrder_Normal_Market_After_Match_Enters_Pending_With_Limit_Price_B OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 1000, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 1000, 0, 20, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.Contains(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -2048,7 +2051,7 @@ public void AddOrder_Normal_Market_Complex_Matching_Scenario() mockTradeListener.Verify(x => x.OnAccept(order4.OrderId)); Assert.Equal(OrderMatchingResult.OrderAccepted, result4); - mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 500, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 500, 0, 25, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.DoesNotContain(order4, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order4.OrderId, matchingEngine.AcceptedOrders); @@ -2066,7 +2069,7 @@ public void AddOrder_Normal_Market_Complex_Matching_Scenario() mockTradeListener.Verify(x => x.OnAccept(order5.OrderId)); Assert.Equal(OrderMatchingResult.OrderAccepted, result5); - mockTradeListener.Verify(x => x.OnTrade(5, 1, 10, 500, 0, 10000)); + mockTradeListener.Verify(x => x.OnTrade(5, 1, 10, 500, 0, 25, 10000, 20)); mockTradeListener.VerifyNoOtherCalls(); Assert.DoesNotContain(order5, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order5.OrderId, matchingEngine.AcceptedOrders); @@ -2083,7 +2086,7 @@ public void AddOrder_Normal_Market_Complex_Matching_Scenario() mockTradeListener.Verify(x => x.OnAccept(order6.OrderId)); Assert.Equal(OrderMatchingResult.OrderAccepted, result6); - mockTradeListener.Verify(x => x.OnTrade(6, 3, 9, 1000, null, 9000)); + mockTradeListener.Verify(x => x.OnTrade(6, 3, 9, 1000, null, null, 9000, 18)); mockTradeListener.VerifyNoOtherCalls(); Assert.Contains(order6, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order6.OrderId, matchingEngine.AcceptedOrders); @@ -2101,8 +2104,8 @@ public void AddOrder_Normal_Market_Complex_Matching_Scenario() OrderMatchingResult result7 = matchingEngine.AddOrder(orderWrapper7); mockTradeListener.Verify(x => x.OnAccept(order7.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(7, 6, 9, 500, 0, null)); - mockTradeListener.Verify(x => x.OnTrade(7, 2, 11, 1000, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(7, 6, 9, 500, 0, 54, null, null)); + mockTradeListener.Verify(x => x.OnTrade(7, 2, 11, 1000, 0, 22, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result7); Assert.Contains(order7, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -2155,9 +2158,9 @@ public void AddOrder_Normal_Market_Complex_Matching_Scenario() mockTradeListener.Verify(x => x.OnAccept(order10.OrderId)); Assert.Equal(OrderMatchingResult.OrderAccepted, result10); - mockTradeListener.Verify(x => x.OnTrade(10, 9, 13, 1000, null, 13000)); - mockTradeListener.Verify(x => x.OnTrade(10, 7, 12, 500, null, 21500)); - mockTradeListener.Verify(x => x.OnTrade(10, 8, 12, 1500, 0, 18000)); + mockTradeListener.Verify(x => x.OnTrade(10, 9, 13, 1000, null, null, 13000, 26)); + mockTradeListener.Verify(x => x.OnTrade(10, 7, 12, 500, null, null, 21500, 89.5m)); + mockTradeListener.Verify(x => x.OnTrade(10, 8, 12, 1500, 0, 185, 18000, 36)); mockTradeListener.VerifyNoOtherCalls(); Assert.DoesNotContain(order10, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order10.OrderId, matchingEngine.AcceptedOrders); @@ -2175,7 +2178,7 @@ public void AddOrder_Normal_Market_Complex_Matching_Scenario() mockTradeListener.Verify(x => x.OnAccept(order11.OrderId)); Assert.Equal(OrderMatchingResult.OrderAccepted, result11); - mockTradeListener.Verify(x => x.OnCancel(11, 3000, 0, CancelReason.MarketOrderNoLiquidity)); + mockTradeListener.Verify(x => x.OnCancel(11, 3000, 0, 0, CancelReason.MarketOrderNoLiquidity)); mockTradeListener.VerifyNoOtherCalls(); Assert.DoesNotContain(order11, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order11.OrderId, matchingEngine.AcceptedOrders); @@ -2193,7 +2196,7 @@ public void AddOrder_Normal_Market_Complex_Matching_Scenario() mockTradeListener.Verify(x => x.OnAccept(order12.OrderId)); Assert.Equal(OrderMatchingResult.OrderAccepted, result12); - mockTradeListener.Verify(x => x.OnCancel(12, 3000, 0, CancelReason.MarketOrderNoLiquidity)); + mockTradeListener.Verify(x => x.OnCancel(12, 3000, 0, 0, CancelReason.MarketOrderNoLiquidity)); mockTradeListener.VerifyNoOtherCalls(); Assert.DoesNotContain(order12, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order12.OrderId, matchingEngine.AcceptedOrders); @@ -2262,7 +2265,7 @@ public void AddOrder_Normal_Market_Complex_Matching_Scenario() mockTradeListener.Verify(x => x.OnAccept(order16.OrderId)); Assert.Equal(OrderMatchingResult.OrderAccepted, result16); - mockTradeListener.Verify(x => x.OnTrade(16, 13, 10, 500, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(16, 13, 10, 500, 0, 25, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.DoesNotContain(order16, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order16.OrderId, matchingEngine.AcceptedOrders); @@ -2384,7 +2387,7 @@ public void AddOrder_Stop_Limit_Order_Entered_In_Stop_Book_With_Market_Rate_For_ OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -2440,7 +2443,7 @@ public void AddOrder_Stop_Market_Order_Entered_In_Stop_Book_With_Market_Rate_For OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -2496,7 +2499,7 @@ public void AddOrder_Stop_Limit_Order_Entered_In_Stop_Book_With_Market_Rate_For_ OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -2552,7 +2555,7 @@ public void AddOrder_Stop_Market_Order_Entered_In_Stop_Book_With_Market_Rate_For OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -2608,7 +2611,7 @@ public void AddOrder_Triggers_Stop_Limit_Order_Buy() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -2694,7 +2697,7 @@ public void AddOrder_Triggers_Stop_Limit_Order_Buy() OrderMatchingResult result7 = matchingEngine.AddOrder(orderWrapper7); mockTradeListener.Verify(x => x.OnAccept(order7.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(7, 6, 12, 500, 0, 6000)); + mockTradeListener.Verify(x => x.OnTrade(7, 6, 12, 500, 0, 12, 6000, 30)); mockTradeListener.Verify(x => x.OnOrderTriggered(3)); mockTradeListener.Verify(x => x.OnOrderTriggered(4)); mockTradeListener.VerifyNoOtherCalls(); @@ -2739,7 +2742,7 @@ public void AddOrder_Triggers_Stop_Limit_Order_Ask() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -2825,7 +2828,7 @@ public void AddOrder_Triggers_Stop_Limit_Order_Ask() OrderMatchingResult result7 = matchingEngine.AddOrder(orderWrapper7); mockTradeListener.Verify(x => x.OnAccept(order7.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(7, 6, 8, 500, 0, 4000)); + mockTradeListener.Verify(x => x.OnTrade(7, 6, 8, 500, 0, 8, 4000, 20)); mockTradeListener.Verify(x => x.OnOrderTriggered(3)); mockTradeListener.Verify(x => x.OnOrderTriggered(4)); mockTradeListener.VerifyNoOtherCalls(); @@ -2873,7 +2876,7 @@ public void AddOrder_Stop_Limit_Order_Added_To_Book_If_Stop_Price_Is_Less_Than_M OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -2929,7 +2932,7 @@ public void AddOrder_Stop_Limit_Order_Added_To_Book_If_Stop_Price_Is_More_Than_M OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -2985,7 +2988,7 @@ public void AddOrder_Stop_Market_Order_Added_To_Book_If_Stop_Price_Is_Less_Than_ OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -3003,7 +3006,7 @@ public void AddOrder_Stop_Market_Order_Added_To_Book_If_Stop_Price_Is_Less_Than_ OrderMatchingResult result3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 100, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 100, 0, 12, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result3); Assert.Contains(order3, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -3043,7 +3046,7 @@ public void AddOrder_Stop_Market_Order_Added_To_Book_If_Stop_Price_Is_More_Than_ OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.Contains(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -3061,7 +3064,7 @@ public void AddOrder_Stop_Market_Order_Added_To_Book_If_Stop_Price_Is_More_Than_ OrderMatchingResult result3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 2, 11, 100, null, 6100)); + mockTradeListener.Verify(x => x.OnTrade(3, 2, 11, 100, null, null, 6100, 27.2m)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result3); Assert.Contains(order3, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -3101,7 +3104,7 @@ public void AddOrder_Stop_Limit_Trigger_And_Matches_As_Taker_Buy() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -3153,8 +3156,8 @@ public void AddOrder_Stop_Limit_Trigger_And_Matches_As_Taker_Buy() OrderMatchingResult result5 = matchingEngine.AddOrder(orderWrapper5); mockTradeListener.Verify(x => x.OnAccept(order5.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(5, 4, 11, 500, null, 5500)); - mockTradeListener.Verify(x => x.OnTrade(3, 4, 11, 500, 0, 5500)); + mockTradeListener.Verify(x => x.OnTrade(5, 4, 11, 500, null, null, 5500, 27.5m)); + mockTradeListener.Verify(x => x.OnTrade(3, 4, 11, 500, 0, 22, 5500, 27.5m)); mockTradeListener.Verify(x => x.OnOrderTriggered(3)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result5); @@ -3195,7 +3198,7 @@ public void AddOrder_Stop_Market_Trigger_And_Matches_As_Taker_Buy() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -3247,8 +3250,8 @@ public void AddOrder_Stop_Market_Trigger_And_Matches_As_Taker_Buy() OrderMatchingResult result5 = matchingEngine.AddOrder(orderWrapper5); mockTradeListener.Verify(x => x.OnAccept(order5.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(5, 4, 11, 500, null, 5500)); - mockTradeListener.Verify(x => x.OnTrade(3, 4, 11, 500, 0, 5500)); + mockTradeListener.Verify(x => x.OnTrade(5, 4, 11, 500, null, null, 5500, 27.5m)); + mockTradeListener.Verify(x => x.OnTrade(3, 4, 11, 500, 0, 22, 5500, 27.5m)); mockTradeListener.Verify(x => x.OnOrderTriggered(3)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result5); @@ -3289,7 +3292,7 @@ public void AddOrder_Stop_Limit_Trigger_And_Matches_As_Taker_Sell() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -3341,8 +3344,8 @@ public void AddOrder_Stop_Limit_Trigger_And_Matches_As_Taker_Sell() OrderMatchingResult result5 = matchingEngine.AddOrder(orderWrapper5); mockTradeListener.Verify(x => x.OnAccept(order5.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(5, 4, 8, 500, 0, null)); - mockTradeListener.Verify(x => x.OnTrade(3, 5, 8, 500, 0, 8000)); + mockTradeListener.Verify(x => x.OnTrade(5, 4, 8, 500, 0, 8, null, null)); + mockTradeListener.Verify(x => x.OnTrade(3, 5, 8, 500, 0, 20, 8000, 28)); mockTradeListener.Verify(x => x.OnOrderTriggered(3)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result5); @@ -3382,7 +3385,7 @@ public void AddOrder_Stop_Market_Trigger_And_Matches_As_Taker_Sell() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -3434,8 +3437,8 @@ public void AddOrder_Stop_Market_Trigger_And_Matches_As_Taker_Sell() OrderMatchingResult result5 = matchingEngine.AddOrder(orderWrapper5); mockTradeListener.Verify(x => x.OnAccept(order5.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(5, 4, 8, 500, 0, null)); - mockTradeListener.Verify(x => x.OnTrade(3, 5, 8, 500, 0, 8000)); + mockTradeListener.Verify(x => x.OnTrade(5, 4, 8, 500, 0, 8, null, null)); + mockTradeListener.Verify(x => x.OnTrade(3, 5, 8, 500, 0, 20, 8000, 28)); mockTradeListener.Verify(x => x.OnOrderTriggered(3)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result5); @@ -3549,7 +3552,7 @@ public void AddOrder_Cancels_BookOrCancel_If_Matching_Sell_Available() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(2, 500, 0, CancelReason.BookOrCancel)); + mockTradeListener.Verify(x => x.OnCancel(2, 500, 0, 0, CancelReason.BookOrCancel)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -3647,7 +3650,7 @@ public void AddOrder_Cancels_BookOrCancel_If_Matching_Buy_Available() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(2, 500, 0, CancelReason.BookOrCancel)); + mockTradeListener.Verify(x => x.OnCancel(2, 500, 0, 0, CancelReason.BookOrCancel)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -3782,8 +3785,8 @@ public void AddOrder_Cancels_ImmediateOrCancel_If_Pending_Limit_Buy() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, null)); - mockTradeListener.Verify(x => x.OnCancel(2, 1000, 5000, CancelReason.ImmediateOrCancel)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, null, null)); + mockTradeListener.Verify(x => x.OnCancel(2, 1000, 5000, 25, CancelReason.ImmediateOrCancel)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -3822,8 +3825,8 @@ public void AddOrder_Cancels_ImmediateOrCancel_If_Pending_Limit_Sell() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, 5000)); - mockTradeListener.Verify(x => x.OnCancel(2, 1000, 5000, CancelReason.ImmediateOrCancel)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, 5000, 10)); + mockTradeListener.Verify(x => x.OnCancel(2, 1000, 5000, 25, CancelReason.ImmediateOrCancel)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -3862,7 +3865,7 @@ public void AddOrder_Cancels_ImmediateOrCancel_If_No_Match_Limit_Buy() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(2, 1500, 0, CancelReason.ImmediateOrCancel)); + mockTradeListener.Verify(x => x.OnCancel(2, 1500, 0, 0, CancelReason.ImmediateOrCancel)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -3901,7 +3904,7 @@ public void AddOrder_Cancels_ImmediateOrCancel_If_No_Match_Limit_Sell() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(2, 1500, 0, CancelReason.ImmediateOrCancel)); + mockTradeListener.Verify(x => x.OnCancel(2, 1500, 0, 0, CancelReason.ImmediateOrCancel)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -3940,7 +3943,7 @@ public void AddOrder_Does_Not_Cancels_ImmediateOrCancel_If_Full_Match_Limit_Buy( OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 100, null, 1000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 100, null, null, 1000, 5)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -3979,7 +3982,7 @@ public void AddOrder_Does_Not_Cancels_ImmediateOrCancel_If_Full_Match_Limit_Sell OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 100, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 100, 0, 5, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4018,8 +4021,8 @@ public void AddOrder_Cancels_ImmediateOrCancel_Pending_MarketOrder_Buy() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, null)); - mockTradeListener.Verify(x => x.OnCancel(2, 1000, 5000, CancelReason.ImmediateOrCancel)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, null, null)); + mockTradeListener.Verify(x => x.OnCancel(2, 1000, 5000, 25, CancelReason.ImmediateOrCancel)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4058,8 +4061,8 @@ public void AddOrder_Cancels_ImmediateOrCancel_If_Pending_MarketOrder_Sell() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, 5000)); - mockTradeListener.Verify(x => x.OnCancel(2, 1000, 5000, CancelReason.ImmediateOrCancel)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, 5000, 10)); + mockTradeListener.Verify(x => x.OnCancel(2, 1000, 5000, 25, CancelReason.ImmediateOrCancel)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4081,7 +4084,7 @@ public void AddOrder_Cancels_ImmediateOrCancel_Full_MarketOrder_Buy() OrderMatchingResult result1 = matchingEngine.AddOrder(orderWrapper1); mockTradeListener.Verify(x => x.OnAccept(order1.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(1, 1500, 0, CancelReason.ImmediateOrCancel)); + mockTradeListener.Verify(x => x.OnCancel(1, 1500, 0, 0, CancelReason.ImmediateOrCancel)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result1); Assert.DoesNotContain(order1, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4103,7 +4106,7 @@ public void AddOrder_Cancels_ImmediateOrCancel_If_Full_MarketOrder_Sell() OrderMatchingResult result1 = matchingEngine.AddOrder(orderWrapper1); mockTradeListener.Verify(x => x.OnAccept(order1.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(1, 1500, 0, CancelReason.ImmediateOrCancel)); + mockTradeListener.Verify(x => x.OnCancel(1, 1500, 0, 0, CancelReason.ImmediateOrCancel)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result1); Assert.DoesNotContain(order1, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4142,7 +4145,7 @@ public void AddOrder_Does_Not_Cancels_ImmediateOrCancel_Full_MarketOrder_Matches OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 100, null, 1000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 100, null, null, 1000, 5)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4181,7 +4184,7 @@ public void AddOrder_Does_Not_Cancels_ImmediateOrCancel_If_Full_MarketOrder_Matc OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 100, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 100, 0, 5, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4231,7 +4234,7 @@ public void AddOrder_CancelsFullQuantityLimitFOKOrder_IfNotEnoughSellAvailable() OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4283,7 +4286,7 @@ public void AddOrder_CancelsFullQuantityLimitFOKOrder_IfNotEnoughSellAvailable() OrderMatchingResult acceptanceResult5 = matchingEngine.AddOrder(orderWrapper5); mockTradeListener.Verify(x => x.OnAccept(order5.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(5, 600, 0, CancelReason.FillOrKill)); + mockTradeListener.Verify(x => x.OnCancel(5, 600, 0, 0, CancelReason.FillOrKill)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult5); Assert.DoesNotContain(order5, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4322,7 +4325,7 @@ public void AddOrder_CancelsFullQuantityFOKMarketOrder_IfNotEnoughSellAvailable( OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4374,7 +4377,7 @@ public void AddOrder_CancelsFullQuantityFOKMarketOrder_IfNotEnoughSellAvailable( OrderMatchingResult acceptanceResult5 = matchingEngine.AddOrder(orderWrapper5); mockTradeListener.Verify(x => x.OnAccept(order5.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(5, 600, 0, CancelReason.FillOrKill)); + mockTradeListener.Verify(x => x.OnCancel(5, 600, 0, 0, CancelReason.FillOrKill)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult5); Assert.DoesNotContain(order5, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4413,7 +4416,7 @@ public void AddOrder_FillsFullQuantityFOKLimitOrder_IfNotEnoughSellAvailable() OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4465,7 +4468,7 @@ public void AddOrder_FillsFullQuantityFOKLimitOrder_IfNotEnoughSellAvailable() OrderMatchingResult acceptanceResult5 = matchingEngine.AddOrder(orderWrapper5); mockTradeListener.Verify(x => x.OnAccept(order5.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(5, 4, 10, 400, null, 4000)); + mockTradeListener.Verify(x => x.OnTrade(5, 4, 10, 400, null, null, 4000, 20)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult5); Assert.DoesNotContain(order5, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4504,7 +4507,7 @@ public void AddOrder_FillsFullQuantityFOKMarketOrder_IfNotEnoughSellAvailable() OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4556,7 +4559,7 @@ public void AddOrder_FillsFullQuantityFOKMarketOrder_IfNotEnoughSellAvailable() OrderMatchingResult acceptanceResult5 = matchingEngine.AddOrder(orderWrapper5); mockTradeListener.Verify(x => x.OnAccept(order5.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(5, 4, 10, 400, null, 4000)); + mockTradeListener.Verify(x => x.OnTrade(5, 4, 10, 400, null, null, 4000, 20)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult5); Assert.DoesNotContain(order5, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4595,7 +4598,7 @@ public void AddOrder_CancelsFullQuantityLimitFOKOrder_IfNotEnoughBuyAvailable() OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4647,7 +4650,7 @@ public void AddOrder_CancelsFullQuantityLimitFOKOrder_IfNotEnoughBuyAvailable() OrderMatchingResult acceptanceResult5 = matchingEngine.AddOrder(orderWrapper5); mockTradeListener.Verify(x => x.OnAccept(order5.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(5, 600, 0, CancelReason.FillOrKill)); + mockTradeListener.Verify(x => x.OnCancel(5, 600, 0, 0, CancelReason.FillOrKill)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult5); Assert.DoesNotContain(order5, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4686,7 +4689,7 @@ public void AddOrder_CancelsFullQuantityFOKMarketOrder_IfNotEnoughBuyAvailable() OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4738,7 +4741,7 @@ public void AddOrder_CancelsFullQuantityFOKMarketOrder_IfNotEnoughBuyAvailable() OrderMatchingResult acceptanceResult5 = matchingEngine.AddOrder(orderWrapper5); mockTradeListener.Verify(x => x.OnAccept(order5.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(5, 600, 0, CancelReason.FillOrKill)); + mockTradeListener.Verify(x => x.OnCancel(5, 600, 0, 0, CancelReason.FillOrKill)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult5); Assert.DoesNotContain(order5, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4777,7 +4780,7 @@ public void AddOrder_FillsFullQuantityFOKLimitOrder_IfNotEnoughBuyAvailable() OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4829,7 +4832,7 @@ public void AddOrder_FillsFullQuantityFOKLimitOrder_IfNotEnoughBuyAvailable() OrderMatchingResult acceptanceResult5 = matchingEngine.AddOrder(orderWrapper5); mockTradeListener.Verify(x => x.OnAccept(order5.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(5, 4, 10, 400, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(5, 4, 10, 400, 0, 20, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult5); Assert.DoesNotContain(order5, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4868,7 +4871,7 @@ public void AddOrder_FillsFullQuantityFOKMarketOrder_IfNotEnoughBuyAvailable() OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4920,7 +4923,7 @@ public void AddOrder_FillsFullQuantityFOKMarketOrder_IfNotEnoughBuyAvailable() OrderMatchingResult acceptanceResult5 = matchingEngine.AddOrder(orderWrapper5); mockTradeListener.Verify(x => x.OnAccept(order5.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(5, 4, 10, 400, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(5, 4, 10, 400, 0, 20, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult5); Assert.DoesNotContain(order5, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -4956,7 +4959,7 @@ public void CancelOrder_CancelsFullOrder_IfNoFillIcebergOrderBuySide() Assert.Equal((ulong)0, order1.Sequnce); OrderMatchingResult acceptanceResult2 = matchingEngine.CancelOrder(order1.OrderId); - mockTradeListener.Verify(x => x.OnCancel(1, 5000, 0, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(1, 5000, 0, 0, CancelReason.UserRequested)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.CancelAcepted, acceptanceResult2); Assert.DoesNotContain(order1.OrderId, matchingEngine.CurrentIcebergOrders.Select(x => x.Key)); @@ -4994,7 +4997,7 @@ public void CancelOrder_CancelCorrectAmount_IfIcebergOrderPartiallyFilledBuy() OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.Contains(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -5016,7 +5019,7 @@ public void CancelOrder_CancelCorrectAmount_IfIcebergOrderPartiallyFilledBuy() OrderMatchingResult acceptanceResult3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 200, null, 2000)); + mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 200, null, null, 2000, 10)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult3); Assert.Contains(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -5034,7 +5037,7 @@ public void CancelOrder_CancelCorrectAmount_IfIcebergOrderPartiallyFilledBuy() Assert.Equal((ulong)0, order3.Sequnce); OrderMatchingResult acceptanceResult4 = matchingEngine.CancelOrder(order1.OrderId); - mockTradeListener.Verify(x => x.OnCancel(1, 4300, 7000, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(1, 4300, 7000, 14, CancelReason.UserRequested)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.CancelAcepted, acceptanceResult4); Assert.DoesNotContain(order1.OrderId, matchingEngine.CurrentIcebergOrders.Select(x => x.Key)); @@ -5072,7 +5075,7 @@ public void CancelOrder_CancelsCorrectAmount_IfLastTipIsPartiallyRemainingBuy() OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.Contains(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -5094,7 +5097,7 @@ public void CancelOrder_CancelsCorrectAmount_IfLastTipIsPartiallyRemainingBuy() OrderMatchingResult acceptanceResult3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult3); Assert.Contains(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -5115,7 +5118,7 @@ public void CancelOrder_CancelsCorrectAmount_IfLastTipIsPartiallyRemainingBuy() OrderMatchingResult acceptanceResult4 = matchingEngine.AddOrder(orderWrapper4); mockTradeListener.Verify(x => x.OnAccept(order4.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 100, null, 1000)); + mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 100, null, null, 1000, 5)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult4); Assert.Contains(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -5132,7 +5135,7 @@ public void CancelOrder_CancelsCorrectAmount_IfLastTipIsPartiallyRemainingBuy() Assert.Equal((ulong)0, order4.Sequnce); OrderMatchingResult acceptanceResult5 = matchingEngine.CancelOrder(order1.OrderId); - mockTradeListener.Verify(x => x.OnCancel(1, 100, 11000, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(1, 100, 11000, 22, CancelReason.UserRequested)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.CancelAcepted, acceptanceResult5); Assert.DoesNotContain(order1.OrderId, matchingEngine.CurrentIcebergOrders.Select(x => x.Key)); @@ -5169,7 +5172,7 @@ public void CancelOrder_RejectsRequest_IfIcebergOrderMatchedFully() OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.Contains(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -5191,7 +5194,7 @@ public void CancelOrder_RejectsRequest_IfIcebergOrderMatchedFully() OrderMatchingResult acceptanceResult3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult3); Assert.Contains(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -5212,7 +5215,7 @@ public void CancelOrder_RejectsRequest_IfIcebergOrderMatchedFully() OrderMatchingResult acceptanceResult4 = matchingEngine.AddOrder(orderWrapper4); mockTradeListener.Verify(x => x.OnAccept(order4.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 500, 0, 30, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult4); Assert.DoesNotContain(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -5280,7 +5283,7 @@ public void AddOrder_AddsTip_IfTipIsMatchedFullyBuySide() OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.Contains(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -5324,7 +5327,7 @@ public void AddOrder_AddedTipWithRemainQuantiy_IfLastTipIsRemaining() OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.Contains(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -5346,7 +5349,7 @@ public void AddOrder_AddedTipWithRemainQuantiy_IfLastTipIsRemaining() OrderMatchingResult acceptanceResult3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult3); Assert.Contains(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -5367,7 +5370,7 @@ public void AddOrder_AddedTipWithRemainQuantiy_IfLastTipIsRemaining() OrderMatchingResult acceptanceResult4 = matchingEngine.AddOrder(orderWrapper4); mockTradeListener.Verify(x => x.OnAccept(order4.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 100, null, 1000)); + mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 100, null, null, 1000, 5)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult4); Assert.Contains(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -5410,7 +5413,7 @@ public void AddOrder_AddedTipWithRemainQuantiy2_IfLastTipIsRemaining() OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.Contains(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -5432,7 +5435,7 @@ public void AddOrder_AddedTipWithRemainQuantiy2_IfLastTipIsRemaining() OrderMatchingResult acceptanceResult3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult3); Assert.Contains(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -5453,7 +5456,7 @@ public void AddOrder_AddedTipWithRemainQuantiy2_IfLastTipIsRemaining() OrderMatchingResult acceptanceResult4 = matchingEngine.AddOrder(orderWrapper4); mockTradeListener.Verify(x => x.OnAccept(order4.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 100, null, 1000)); + mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 100, null, null, 1000, 5)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult4); Assert.Contains(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -5496,7 +5499,7 @@ public void AddOrder_AddedTipNoTip_IfLastTipIsMatcheFully() OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.Contains(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -5518,7 +5521,7 @@ public void AddOrder_AddedTipNoTip_IfLastTipIsMatcheFully() OrderMatchingResult acceptanceResult3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult3); Assert.Contains(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -5539,7 +5542,7 @@ public void AddOrder_AddedTipNoTip_IfLastTipIsMatcheFully() OrderMatchingResult acceptanceResult4 = matchingEngine.AddOrder(orderWrapper4); mockTradeListener.Verify(x => x.OnAccept(order4.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 500, 0, 30, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult4); Assert.DoesNotContain(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -5581,16 +5584,16 @@ public void AddOrder_AddedAllTip_IfMatchedWithHugeOrder() OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 50000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 100, 50000, 250)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.Empty(matchingEngine.CurrentIcebergOrders); @@ -5758,7 +5761,7 @@ public void AddOrder_RejectsBookOrCancel_IfOrderIsPresentBuySideForSell() OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(2, 5000, 0, CancelReason.BookOrCancel)); + mockTradeListener.Verify(x => x.OnCancel(2, 5000, 0, 0, CancelReason.BookOrCancel)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.DoesNotContain(order2.OrderId, matchingEngine.CurrentIcebergOrders.Select(x => x.Key)); @@ -5794,7 +5797,7 @@ public void AddOrder_AddsTip_IfIcebergeOrderTipIsMatchedSell() OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, 5000, 10)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.Contains(order2.OrderId, matchingEngine.CurrentIcebergOrders.Select(x => x.Key)); @@ -5849,8 +5852,8 @@ public void AddOrder_AddsMoreTip_IfIcebergeOrderTipIsMatchedSell() OrderMatchingResult acceptanceResult3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, 5000)); - mockTradeListener.Verify(x => x.OnTrade(3, 2, 10, 400, null, 4000)); + mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, null, 5000, 10)); + mockTradeListener.Verify(x => x.OnTrade(3, 2, 10, 400, null, null, 4000, 8)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult3); Assert.Contains(order3.OrderId, matchingEngine.CurrentIcebergOrders.Select(x => x.Key)); @@ -5921,11 +5924,11 @@ public void AddOrder_AddsAllTip_IfIcebergeOrderTipIsMatchedSell() OrderMatchingResult acceptanceResult4 = matchingEngine.AddOrder(orderWrapper4); mockTradeListener.Verify(x => x.OnAccept(order4.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(4, 2, 11, 400, null, 4400)); - mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 100, null, null)); - mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 400, null, 5000)); - mockTradeListener.Verify(x => x.OnTrade(4, 3, 10, 100, null, null)); - mockTradeListener.Verify(x => x.OnTrade(4, 3, 10, 500, 0, 6000)); + mockTradeListener.Verify(x => x.OnTrade(4, 2, 11, 400, null, null, 4400, 8.8m)); + mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 100, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 400, null, null, 5000, 10)); + mockTradeListener.Verify(x => x.OnTrade(4, 3, 10, 100, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(4, 3, 10, 500, 0, 77, 6000, 12)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult4); Assert.DoesNotContain(order4.OrderId, matchingEngine.CurrentIcebergOrders.Select(x => x.Key)); @@ -5961,16 +5964,16 @@ public void AddOrder_AddsAllTip_IfIcebergeOrderTipIsMatchedWithSingleHugeOrderSe OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 50000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, null, null)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 250, 50000, 100)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.Empty(matchingEngine.CurrentIcebergOrders); @@ -6023,8 +6026,8 @@ public void CancelOrder_CancelsProperAmount_IfIcebergeFewOrderTipIsMatchedAddOrd OrderMatchingResult acceptanceResult3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, 5000)); - mockTradeListener.Verify(x => x.OnTrade(3, 2, 10, 400, null, 4000)); + mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, null, 5000, 10)); + mockTradeListener.Verify(x => x.OnTrade(3, 2, 10, 400, null, null, 4000, 8)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult3); Assert.Contains(order3.OrderId, matchingEngine.CurrentIcebergOrders.Select(x => x.Key)); @@ -6040,7 +6043,7 @@ public void CancelOrder_CancelsProperAmount_IfIcebergeFewOrderTipIsMatchedAddOrd OrderMatchingResult acceptanceResult4 = matchingEngine.CancelOrder(order3.OrderId); - mockTradeListener.Verify(x => x.OnCancel(order3.OrderId, 600, 9000, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(order3.OrderId, 600, 9000, 45, CancelReason.UserRequested)); mockTradeListener.VerifyNoOtherCalls(); Assert.Empty(matchingEngine.CurrentIcebergOrders); Assert.Empty(matchingEngine.Book.BidSide); @@ -6073,7 +6076,7 @@ public void AddOrder_CancelsIceberg_IfIcebergeOrderTipIsMatchedWithSingleHugeOrd OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(2, 5000, 0, CancelReason.BookOrCancel)); + mockTradeListener.Verify(x => x.OnCancel(2, 5000, 0, 0, CancelReason.BookOrCancel)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.Empty(matchingEngine.CurrentIcebergOrders); @@ -6126,8 +6129,8 @@ public void AddOrder_AddsTip_IfIcebergeOrderTipIsMatchedWithMultipleOrderSell() OrderMatchingResult acceptanceResult3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, 5000)); - mockTradeListener.Verify(x => x.OnTrade(3, 2, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, null, 5000, 10)); + mockTradeListener.Verify(x => x.OnTrade(3, 2, 10, 500, null, null, 5000, 10)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult3); Assert.Contains(order3.OrderId, matchingEngine.CurrentIcebergOrders.Select(x => x.Key)); @@ -6181,8 +6184,8 @@ public void AddOrder_AddsTip_IfIcebergeOrderTipIsMatchedWithFullyOrderSell() OrderMatchingResult acceptanceResult3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, 5000)); - mockTradeListener.Verify(x => x.OnTrade(3, 2, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, null, null, 5000, 10)); + mockTradeListener.Verify(x => x.OnTrade(3, 2, 10, 500, 0, 50, 5000, 10)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult3); Assert.Empty(matchingEngine.CurrentIcebergOrders); @@ -6252,10 +6255,10 @@ public void AddOrder_IcebergHasHigherPriotityThanStopOrder() OrderMatchingResult acceptanceResult4 = matchingEngine.AddOrder(orderWrapper4); mockTradeListener.Verify(x => x.OnAccept(order4.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(4, 2, 10, 500, null, 5000)); - mockTradeListener.Verify(x => x.OnTrade(4, 3, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(4, 2, 10, 500, null, null, 5000, 10)); + mockTradeListener.Verify(x => x.OnTrade(4, 3, 10, 500, null, null, 5000, 10)); mockTradeListener.Verify(x => x.OnOrderTriggered(1)); - mockTradeListener.Verify(x => x.OnTrade(1, 4, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(1, 4, 10, 500, 0, 60, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult4); Assert.Empty(matchingEngine.CurrentIcebergOrders); @@ -6278,7 +6281,7 @@ public void AddOrder_Cancels_AlreadyPassedCancelledOn() mockTradeListener.Verify(x => x.OnAccept(order1.OrderId)); mockTimeProvider.Verify(x => x.GetSecondsFromEpoch()); - mockTradeListener.Verify(x => x.OnCancel(1, 500, 0, CancelReason.ValidityExpired)); + mockTradeListener.Verify(x => x.OnCancel(1, 500, 0, 0, CancelReason.ValidityExpired)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult); Assert.Contains(order1.OrderId, matchingEngine.AcceptedOrders); @@ -6321,7 +6324,7 @@ public void AddOrder_Cancels_AlreadyEqualCancelledOn() mockTradeListener.Verify(x => x.OnAccept(order1.OrderId)); mockTimeProvider.Verify(x => x.GetSecondsFromEpoch()); - mockTradeListener.Verify(x => x.OnCancel(1, 500, 0, CancelReason.ValidityExpired)); + mockTradeListener.Verify(x => x.OnCancel(1, 500, 0, 0, CancelReason.ValidityExpired)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult); Assert.Contains(order1.OrderId, matchingEngine.AcceptedOrders); @@ -6359,7 +6362,7 @@ public void AddOrder_CancelsPendingOrderBeforeMatch() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(1, 500, 0, CancelReason.ValidityExpired)); + mockTradeListener.Verify(x => x.OnCancel(1, 500, 0, 0, CancelReason.ValidityExpired)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.Contains(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -6399,7 +6402,7 @@ public void AddOrder_CancelsPendingStopOrderBeforeMatch() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(1, 500, 0, CancelReason.ValidityExpired)); + mockTradeListener.Verify(x => x.OnCancel(1, 500, 0, 0, CancelReason.ValidityExpired)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.Contains(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -6440,7 +6443,7 @@ public void AddOrder_Cancels_PendingIcebergOrder() OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.Contains(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -6462,7 +6465,7 @@ public void AddOrder_Cancels_PendingIcebergOrder() OrderMatchingResult acceptanceResult3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(1, 4500, 5000, CancelReason.ValidityExpired)); + mockTradeListener.Verify(x => x.OnCancel(1, 4500, 5000, 10, CancelReason.ValidityExpired)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult3); Assert.DoesNotContain(order1.OrderId, matchingEngine.Book.AskSide.SelectMany(x => x.Value).Select(x => x.OrderId).ToList()); @@ -6506,7 +6509,7 @@ public void AddOrder_Cancels_MarketOrderAmountIfNoSellAvailable() OrderMatchingResult acceptanceResult = matchingEngine.AddOrder(orderWrapper1); mockTradeListener.Verify(x => x.OnAccept(order1.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(1, 0, 0, CancelReason.MarketOrderNoLiquidity)); + mockTradeListener.Verify(x => x.OnCancel(1, 0, 0, 0, CancelReason.MarketOrderNoLiquidity)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult); Assert.Contains(order1.OrderId, matchingEngine.AcceptedOrders); @@ -6543,7 +6546,7 @@ public void AddOrder_Normal_Market_Order_Amount_Matches_Order_With_Open_Orders_F OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -6582,7 +6585,7 @@ public void AddOrder_Normal_Market_Order_Amount_Multiple_Matches_Order_With_Open OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, null, null, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -6600,7 +6603,7 @@ public void AddOrder_Normal_Market_Order_Amount_Multiple_Matches_Order_With_Open OrderMatchingResult result3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, 0, 20, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order3, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -6622,7 +6625,7 @@ public void AddOrder_Normal_Market_Order_Amount_Matches_MarketOrderNoLiquidity() OrderMatchingResult result3 = matchingEngine.AddOrder(orderWrapper1); mockTradeListener.Verify(x => x.OnAccept(order1.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(3, 0, 0, CancelReason.MarketOrderNoLiquidity)); + mockTradeListener.Verify(x => x.OnCancel(3, 0, 0, 0, CancelReason.MarketOrderNoLiquidity)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result3); Assert.DoesNotContain(order1, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -6678,8 +6681,8 @@ public void AddOrder_Normal_Market_Order_Amount_Matches_Multiple_Order_With_Open OrderMatchingResult result3 = matchingEngine.AddOrder(orderWrapper3); mockTradeListener.Verify(x => x.OnAccept(order3.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, 0, null)); - mockTradeListener.Verify(x => x.OnTrade(3, 2, 11, 454, null, 9994)); + mockTradeListener.Verify(x => x.OnTrade(3, 1, 10, 500, 0, 10, null, null)); + mockTradeListener.Verify(x => x.OnTrade(3, 2, 11, 454, null, null, 9994, 49.97m)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result3); Assert.DoesNotContain(order3, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -6753,7 +6756,7 @@ public void AddOrder_Normal_Market_Order_Amount_Complex_Matching_Scenario() mockTradeListener.Verify(x => x.OnAccept(order4.OrderId)); Assert.Equal(OrderMatchingResult.OrderAccepted, result4); - mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 500, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(4, 1, 10, 500, 0, 25, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.DoesNotContain(order4, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order4.OrderId, matchingEngine.AcceptedOrders); @@ -6771,7 +6774,7 @@ public void AddOrder_Normal_Market_Order_Amount_Complex_Matching_Scenario() mockTradeListener.Verify(x => x.OnAccept(order5.OrderId)); Assert.Equal(OrderMatchingResult.OrderAccepted, result5); - mockTradeListener.Verify(x => x.OnTrade(5, 1, 10, 500, 0, 10000)); + mockTradeListener.Verify(x => x.OnTrade(5, 1, 10, 500, 0, 25, 10000, 20)); mockTradeListener.VerifyNoOtherCalls(); Assert.DoesNotContain(order5, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order5.OrderId, matchingEngine.AcceptedOrders); @@ -6788,7 +6791,7 @@ public void AddOrder_Normal_Market_Order_Amount_Complex_Matching_Scenario() mockTradeListener.Verify(x => x.OnAccept(order6.OrderId)); Assert.Equal(OrderMatchingResult.OrderAccepted, result6); - mockTradeListener.Verify(x => x.OnTrade(6, 3, 9, 1000, null, 9000)); + mockTradeListener.Verify(x => x.OnTrade(6, 3, 9, 1000, null, null, 9000, 18)); mockTradeListener.VerifyNoOtherCalls(); Assert.Contains(order6, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order6.OrderId, matchingEngine.AcceptedOrders); @@ -6806,8 +6809,8 @@ public void AddOrder_Normal_Market_Order_Amount_Complex_Matching_Scenario() OrderMatchingResult result7 = matchingEngine.AddOrder(orderWrapper7); mockTradeListener.Verify(x => x.OnAccept(order7.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(7, 6, 9, 500, 0, null)); - mockTradeListener.Verify(x => x.OnTrade(7, 2, 11, 1000, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(7, 6, 9, 500, 0, 54, null, null)); + mockTradeListener.Verify(x => x.OnTrade(7, 2, 11, 1000, 0, 22, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result7); Assert.Contains(order7, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -6860,9 +6863,9 @@ public void AddOrder_Normal_Market_Order_Amount_Complex_Matching_Scenario() mockTradeListener.Verify(x => x.OnAccept(order10.OrderId)); Assert.Equal(OrderMatchingResult.OrderAccepted, result10); - mockTradeListener.Verify(x => x.OnTrade(10, 9, 13, 1000, null, 13000)); - mockTradeListener.Verify(x => x.OnTrade(10, 7, 12, 500, null, 21500)); - mockTradeListener.Verify(x => x.OnTrade(10, 8, 12, 1500, 0, 18000)); + mockTradeListener.Verify(x => x.OnTrade(10, 9, 13, 1000, null, null, 13000, 26)); + mockTradeListener.Verify(x => x.OnTrade(10, 7, 12, 500, null, null, 21500, 89.5m)); + mockTradeListener.Verify(x => x.OnTrade(10, 8, 12, 1500, 0, 185, 18000, 36)); mockTradeListener.VerifyNoOtherCalls(); Assert.DoesNotContain(order10, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order10.OrderId, matchingEngine.AcceptedOrders); @@ -6880,7 +6883,7 @@ public void AddOrder_Normal_Market_Order_Amount_Complex_Matching_Scenario() mockTradeListener.Verify(x => x.OnAccept(order11.OrderId)); Assert.Equal(OrderMatchingResult.OrderAccepted, result11); - mockTradeListener.Verify(x => x.OnCancel(11, 3000, 0, CancelReason.MarketOrderNoLiquidity)); + mockTradeListener.Verify(x => x.OnCancel(11, 3000, 0, 0, CancelReason.MarketOrderNoLiquidity)); mockTradeListener.VerifyNoOtherCalls(); Assert.DoesNotContain(order11, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order11.OrderId, matchingEngine.AcceptedOrders); @@ -6898,7 +6901,7 @@ public void AddOrder_Normal_Market_Order_Amount_Complex_Matching_Scenario() mockTradeListener.Verify(x => x.OnAccept(order12.OrderId)); Assert.Equal(OrderMatchingResult.OrderAccepted, result12); - mockTradeListener.Verify(x => x.OnCancel(12, 0, 0, CancelReason.MarketOrderNoLiquidity)); + mockTradeListener.Verify(x => x.OnCancel(12, 0, 0, 0, CancelReason.MarketOrderNoLiquidity)); mockTradeListener.VerifyNoOtherCalls(); Assert.DoesNotContain(order12, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order12.OrderId, matchingEngine.AcceptedOrders); @@ -6968,7 +6971,7 @@ public void AddOrder_Normal_Market_Order_Amount_Complex_Matching_Scenario() mockTradeListener.Verify(x => x.OnAccept(order16.OrderId)); Assert.Equal(OrderMatchingResult.OrderAccepted, result16); - mockTradeListener.Verify(x => x.OnTrade(16, 13, 10, 500, 0, null)); + mockTradeListener.Verify(x => x.OnTrade(16, 13, 10, 500, 0, 25, null, null)); mockTradeListener.VerifyNoOtherCalls(); Assert.DoesNotContain(order16, matchingEngine.CurrentOrders.Select(x => x.Value)); Assert.Contains(order16.OrderId, matchingEngine.AcceptedOrders); @@ -7006,7 +7009,7 @@ public void CancelOrder_Stop_Market_Order_Amount_Order_Entered_In_Stop_Book_With OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -7037,7 +7040,7 @@ public void CancelOrder_Stop_Market_Order_Amount_Order_Entered_In_Stop_Book_With Assert.Equal((ulong)2, order3.Sequnce); OrderMatchingResult result4 = matchingEngine.CancelOrder(order3.OrderId); - mockTradeListener.Verify(x => x.OnCancel(3, 0, 0, CancelReason.UserRequested)); + mockTradeListener.Verify(x => x.OnCancel(3, 0, 0, 0, CancelReason.UserRequested)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.CancelAcepted, result4); Assert.DoesNotContain(order3, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -7096,7 +7099,7 @@ public void AddOrder_Stop_Market_Order_Amount_Order_Entered_In_Stop_Book_With_Ma OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -7152,7 +7155,7 @@ public void AddOrder_Stop_Market_Order_Amount_Trigger_And_Matches_As_Taker_Buy() OrderMatchingResult result2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -7203,8 +7206,8 @@ public void AddOrder_Stop_Market_Order_Amount_Trigger_And_Matches_As_Taker_Buy() OrderMatchingResult result5 = matchingEngine.AddOrder(orderWrapper5); mockTradeListener.Verify(x => x.OnAccept(order5.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(5, 4, 11, 500, null, 5500)); - mockTradeListener.Verify(x => x.OnTrade(3, 4, 11, 500, 0, 5500)); + mockTradeListener.Verify(x => x.OnTrade(5, 4, 11, 500, null, null, 5500, 27.5m)); + mockTradeListener.Verify(x => x.OnTrade(3, 4, 11, 500, 0, 22, 5500, 27.5m)); mockTradeListener.Verify(x => x.OnOrderTriggered(3)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, result5); @@ -7245,7 +7248,7 @@ public void AddOrder_CancelsFullQuantityFOKMarketOrderAmount_IfNotEnoughSellAvai OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -7297,7 +7300,7 @@ public void AddOrder_CancelsFullQuantityFOKMarketOrderAmount_IfNotEnoughSellAvai OrderMatchingResult acceptanceResult5 = matchingEngine.AddOrder(orderWrapper5); mockTradeListener.Verify(x => x.OnAccept(order5.OrderId)); - mockTradeListener.Verify(x => x.OnCancel(5, 0, 0, CancelReason.FillOrKill)); + mockTradeListener.Verify(x => x.OnCancel(5, 0, 0, 0, CancelReason.FillOrKill)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult5); Assert.DoesNotContain(order5, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -7335,7 +7338,7 @@ public void AddOrder_FillsFullQuantityFOKMarketOrderAmount_IfNotEnoughSellAvaila OrderMatchingResult acceptanceResult2 = matchingEngine.AddOrder(orderWrapper2); mockTradeListener.Verify(x => x.OnAccept(order2.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 5000)); + mockTradeListener.Verify(x => x.OnTrade(2, 1, 10, 500, 0, 10, 5000, 25)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult2); Assert.DoesNotContain(order2, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -7387,7 +7390,7 @@ public void AddOrder_FillsFullQuantityFOKMarketOrderAmount_IfNotEnoughSellAvaila OrderMatchingResult acceptanceResult5 = matchingEngine.AddOrder(orderWrapper5); mockTradeListener.Verify(x => x.OnAccept(order5.OrderId)); - mockTradeListener.Verify(x => x.OnTrade(5, 4, 10, 400, null, 4000)); + mockTradeListener.Verify(x => x.OnTrade(5, 4, 10, 400, null, null, 4000, 20)); mockTradeListener.VerifyNoOtherCalls(); Assert.Equal(OrderMatchingResult.OrderAccepted, acceptanceResult5); Assert.DoesNotContain(order5, matchingEngine.CurrentOrders.Select(x => x.Value)); @@ -7407,4 +7410,5 @@ public void AddOrder_FillsFullQuantityFOKMarketOrderAmount_IfNotEnoughSellAvaila //TODO complex scenario for good till date to test cacheing logic //TODO test for remaing amout for market order //TODO fill or kill and good till date pre calculation -//TODO test book stop loss \ No newline at end of file +//TODO test book stop loss +//TODO Stop market triggers another Stop orders \ No newline at end of file diff --git a/OrderMatcher/OrderMatcher.Tests/OrderSerializerTests.cs b/OrderMatcher/OrderMatcher.Tests/OrderSerializerTests.cs index 7c9393e..bea429a 100644 --- a/OrderMatcher/OrderMatcher.Tests/OrderSerializerTests.cs +++ b/OrderMatcher/OrderMatcher.Tests/OrderSerializerTests.cs @@ -8,7 +8,7 @@ public class OrderSerializerTests [Fact] public void Serialize_Doesnotthrowexception_Min() { - var order1 = new Order { CancelOn = int.MinValue, IsBuy = false, OrderId = OrderId.MinValue, Price = int.MinValue }; + var order1 = new Order { CancelOn = int.MinValue, IsBuy = false, OrderId = OrderId.MinValue, Price = int.MinValue, FeeId = short.MinValue }; var orderWrapper = new OrderWrapper() { StopPrice = int.MinValue, TotalQuantity = int.MinValue, TipQuantity = int.MinValue, OrderCondition = OrderCondition.None, OrderAmount = Quantity.MinValue, Order = order1 }; var bytes = OrderSerializer.Serialize(orderWrapper); } @@ -16,7 +16,7 @@ public void Serialize_Doesnotthrowexception_Min() [Fact] public void Serialize_Doesnotthrowexception_Max() { - var order1 = new Order { CancelOn = int.MaxValue, IsBuy = true, OrderId = OrderId.MaxValue, Price = int.MaxValue }; + var order1 = new Order { CancelOn = int.MaxValue, IsBuy = true, OrderId = OrderId.MaxValue, Price = int.MaxValue, FeeId = short.MaxValue }; var orderWrapper = new OrderWrapper() { StopPrice = int.MaxValue, TotalQuantity = int.MaxValue, TipQuantity = int.MaxValue, OrderCondition = OrderCondition.FillOrKill, OrderAmount = Quantity.MaxValue, Order = order1 }; var bytes = OrderSerializer.Serialize(orderWrapper); } @@ -38,23 +38,23 @@ public void Deserialize_ThrowsExecption_IfNullPassed() [Fact] public void Deserialize_ThrowsExecption_IfMessageIsLessThan37Bytes() { - var bytes = new byte[96]; + var bytes = new byte[98]; Exception ex = Assert.Throws(() => OrderSerializer.Deserialize(bytes)); - Assert.Equal("Order Message must be of Size : 97", ex.Message); + Assert.Equal("Order Message must be of Size : 99", ex.Message); } [Fact] public void Deserialize_ThrowsExecption_IfMessageIsGreaterThan37Bytes() { - var bytes = new byte[98]; + var bytes = new byte[100]; Exception ex = Assert.Throws(() => OrderSerializer.Deserialize(bytes)); - Assert.Equal("Order Message must be of Size : 97", ex.Message); + Assert.Equal("Order Message must be of Size : 99", ex.Message); } [Fact] public void Deserialize_ThrowsExecption_IfMessageIsNothaveValidType() { - var bytes = new byte[97]; + var bytes = new byte[99]; Exception ex = Assert.Throws(() => OrderSerializer.Deserialize(bytes)); Assert.Equal("Invalid Message", ex.Message); } @@ -62,7 +62,7 @@ public void Deserialize_ThrowsExecption_IfMessageIsNothaveValidType() [Fact] public void Deserialize_ThrowsExecption_IfVersionIsNotSet() { - var bytes = new byte[97]; + var bytes = new byte[99]; bytes[4] = (byte)MessageType.NewOrderRequest; Exception ex = Assert.Throws(() => OrderSerializer.Deserialize(bytes)); Assert.Equal("version mismatch", ex.Message); @@ -71,11 +71,11 @@ public void Deserialize_ThrowsExecption_IfVersionIsNotSet() [Fact] public void Deserialize_Doesnotthrowexception_Min() { - var order1 = new Order { CancelOn = int.MinValue, IsBuy = false, OrderId = OrderId.MinValue, Price = int.MinValue }; + var order1 = new Order { CancelOn = int.MinValue, IsBuy = false, OrderId = OrderId.MinValue, Price = int.MinValue, FeeId = short.MinValue }; var orderWrapper = new OrderWrapper() { StopPrice = int.MinValue, TotalQuantity = int.MinValue, TipQuantity = int.MinValue, OrderCondition = OrderCondition.None, OrderAmount = Quantity.MinValue, Order = order1 }; var bytes = OrderSerializer.Serialize(orderWrapper); var messageLength = BitConverter.ToInt32(bytes, 0); - Assert.Equal(97, messageLength); + Assert.Equal(99, messageLength); var order = OrderSerializer.Deserialize(bytes); Assert.Equal(int.MinValue, order.Order.CancelOn); Assert.False(order.Order.IsBuy); @@ -87,16 +87,17 @@ public void Deserialize_Doesnotthrowexception_Min() Assert.Equal(int.MinValue, order.StopPrice); Assert.Equal(int.MinValue, order.TotalQuantity); Assert.Equal(Quantity.MinValue, order.OrderAmount); + Assert.Equal(short.MinValue, order.Order.FeeId); } [Fact] public void Deserialize_Doesnotthrowexception_Max() { - var order1 = new Order { CancelOn = int.MaxValue, IsBuy = true, OrderId = OrderId.MaxValue, Price = int.MaxValue }; + var order1 = new Order { CancelOn = int.MaxValue, IsBuy = true, OrderId = OrderId.MaxValue, Price = int.MaxValue, FeeId = short.MaxValue }; var orderWrapper = new OrderWrapper() { StopPrice = int.MaxValue, TotalQuantity = int.MaxValue, TipQuantity = int.MaxValue, OrderCondition = OrderCondition.FillOrKill, OrderAmount = Quantity.MaxValue, Order = order1 }; var bytes = OrderSerializer.Serialize(orderWrapper); var messageLength = BitConverter.ToInt32(bytes, 0); - Assert.Equal(97, messageLength); + Assert.Equal(99, messageLength); var order = OrderSerializer.Deserialize(bytes); Assert.Equal(int.MaxValue, order.Order.CancelOn); Assert.True(order.Order.IsBuy); @@ -108,16 +109,17 @@ public void Deserialize_Doesnotthrowexception_Max() Assert.Equal(int.MaxValue, order.StopPrice); Assert.Equal(int.MaxValue, order.TotalQuantity); Assert.Equal(Quantity.MaxValue, order.OrderAmount); + Assert.Equal(short.MaxValue, order.Order.FeeId); } [Fact] public void Deserialize_Doesnotthrowexception() { - var order1 = new Order { CancelOn = 12345678, IsBuy = true, OrderId = 56789, Price = 404 }; + var order1 = new Order { CancelOn = 12345678, IsBuy = true, OrderId = 56789, Price = 404, FeeId = 69 }; var orderWrapper = new OrderWrapper() { StopPrice = 9534, TotalQuantity = 7878234, TipQuantity = 2356, OrderCondition = OrderCondition.ImmediateOrCancel, OrderAmount = 12345.6789m, Order = order1 }; var bytes = OrderSerializer.Serialize(orderWrapper); var messageLength = BitConverter.ToInt32(bytes, 0); - Assert.Equal(97, messageLength); + Assert.Equal(99, messageLength); var order = OrderSerializer.Deserialize(bytes); Assert.Equal(12345678, order.Order.CancelOn); Assert.True(order.Order.IsBuy); @@ -129,6 +131,7 @@ public void Deserialize_Doesnotthrowexception() Assert.Equal(9534, order.StopPrice); Assert.Equal(7878234, order.TotalQuantity); Assert.Equal((Quantity)12345.6789m, order.OrderAmount); + Assert.Equal(69, order.Order.FeeId); } } } diff --git a/OrderMatcher/OrderMatcher/CancelledOrder.cs b/OrderMatcher/OrderMatcher/CancelledOrder.cs index 1a372e3..dda197c 100644 --- a/OrderMatcher/OrderMatcher/CancelledOrder.cs +++ b/OrderMatcher/OrderMatcher/CancelledOrder.cs @@ -5,6 +5,7 @@ public class CancelledOrder public OrderId OrderId { get; set; } public Quantity RemainingQuantity { get; set; } public Quantity Cost { get; set; } + public Quantity Fee { get; set; } public CancelReason CancelReason { get; set; } public int Timestamp { get; set; } } diff --git a/OrderMatcher/OrderMatcher/Fee.cs b/OrderMatcher/OrderMatcher/Fee.cs new file mode 100644 index 0000000..8732d95 --- /dev/null +++ b/OrderMatcher/OrderMatcher/Fee.cs @@ -0,0 +1,8 @@ +namespace OrderMatcher +{ + public class Fee + { + public decimal MakerFee { get; set; } + public decimal TakerFee { get; set; } + } +} diff --git a/OrderMatcher/OrderMatcher/Fill.cs b/OrderMatcher/OrderMatcher/Fill.cs index 3a06a65..2627fd0 100644 --- a/OrderMatcher/OrderMatcher/Fill.cs +++ b/OrderMatcher/OrderMatcher/Fill.cs @@ -7,7 +7,9 @@ public class Fill public Price MatchRate { get; set; } public Quantity MatchQuantity { get; set; } public Quantity? AskRemainingQuantity { get; set; } + public Quantity? AskFee { get; set; } public Quantity? BidCost { get; set; } + public Quantity? BidFee { get; set; } public int Timestamp { get; set; } } } diff --git a/OrderMatcher/OrderMatcher/IFeeProvider.cs b/OrderMatcher/OrderMatcher/IFeeProvider.cs new file mode 100644 index 0000000..53467dc --- /dev/null +++ b/OrderMatcher/OrderMatcher/IFeeProvider.cs @@ -0,0 +1,7 @@ +namespace OrderMatcher +{ + public interface IFeeProvider + { + Fee GetFee(short feeId); + } +} diff --git a/OrderMatcher/OrderMatcher/Listeners/ITradeListener.cs b/OrderMatcher/OrderMatcher/Listeners/ITradeListener.cs index dde6d40..36a7522 100644 --- a/OrderMatcher/OrderMatcher/Listeners/ITradeListener.cs +++ b/OrderMatcher/OrderMatcher/Listeners/ITradeListener.cs @@ -3,8 +3,8 @@ public interface ITradeListener { void OnAccept(OrderId orderId); - void OnTrade(OrderId incomingOrderId, OrderId restingOrderId, Price matchPrice, Quantity matchQuantiy, Quantity? askRemainingQuantity, Quantity? bidCost); - void OnCancel(OrderId orderId, Quantity remainingQuantity, Quantity cost, CancelReason cancelReason); + void OnTrade(OrderId incomingOrderId, OrderId restingOrderId, Price matchPrice, Quantity matchQuantiy, Quantity? askRemainingQuantity, Quantity? askFee, Quantity? bidCost, Quantity? bidFee); + void OnCancel(OrderId orderId, Quantity remainingQuantity, Quantity cost, Quantity fee, CancelReason cancelReason); void OnOrderTriggered(OrderId orderId); } } diff --git a/OrderMatcher/OrderMatcher/MatchingEngine.cs b/OrderMatcher/OrderMatcher/MatchingEngine.cs index 4b1c94b..84c8a76 100644 --- a/OrderMatcher/OrderMatcher/MatchingEngine.cs +++ b/OrderMatcher/OrderMatcher/MatchingEngine.cs @@ -15,6 +15,7 @@ public class MatchingEngine private readonly SortedDictionary> _goodTillDateOrders; private readonly Quantity _stepSize; private readonly ITimeProvider _timeProvider; + private readonly IFeeProvider _feeProvider; private readonly int _quoteCurrencyDecimalPlaces; private readonly decimal _power; private Price _marketPrice; @@ -27,7 +28,7 @@ public class MatchingEngine public Price MarketPrice => _marketPrice; public Book Book => _book; - public MatchingEngine(int quoteCurrencyDecimalPlaces, Quantity stepSize, ITradeListener tradeListener, ITimeProvider timeProvider) + public MatchingEngine(ITradeListener tradeListener, ITimeProvider timeProvider, IFeeProvider feeProvider, Quantity stepSize, int quoteCurrencyDecimalPlaces = 0) { if (quoteCurrencyDecimalPlaces < 0) throw new NotSupportedException($"Invalid value of {nameof(quoteCurrencyDecimalPlaces)}"); @@ -43,6 +44,7 @@ public MatchingEngine(int quoteCurrencyDecimalPlaces, Quantity stepSize, ITradeL _acceptedOrders = new HashSet(); _tradeListener = tradeListener; _timeProvider = timeProvider; + _feeProvider = feeProvider; _quoteCurrencyDecimalPlaces = quoteCurrencyDecimalPlaces; _power = (decimal)Math.Pow(10, _quoteCurrencyDecimalPlaces); _stepSize = stepSize; @@ -146,24 +148,24 @@ public OrderMatchingResult AddOrder(OrderWrapper orderWrapper, bool isOrderTrigg if (orderWrapper.OrderCondition == OrderCondition.BookOrCancel && ((incomingOrder.IsBuy && _book.BestAskPrice <= incomingOrder.Price) || (!incomingOrder.IsBuy && incomingOrder.Price <= _book.BestBidPrice))) { if (orderWrapper.TotalQuantity == 0) - _tradeListener?.OnCancel(incomingOrder.OrderId, incomingOrder.OpenQuantity, incomingOrder.Cost, CancelReason.BookOrCancel); + _tradeListener?.OnCancel(incomingOrder.OrderId, incomingOrder.OpenQuantity, incomingOrder.Cost, incomingOrder.Fee, CancelReason.BookOrCancel); else - _tradeListener?.OnCancel(incomingOrder.OrderId, orderWrapper.TotalQuantity, incomingOrder.Cost, CancelReason.BookOrCancel); + _tradeListener?.OnCancel(incomingOrder.OrderId, orderWrapper.TotalQuantity, incomingOrder.Cost, incomingOrder.Fee, CancelReason.BookOrCancel); } else if (orderWrapper.OrderCondition == OrderCondition.FillOrKill && orderWrapper.OrderAmount == 0 && !_book.CheckCanFillOrder(incomingOrder.IsBuy, incomingOrder.OpenQuantity, incomingOrder.Price)) { - _tradeListener?.OnCancel(incomingOrder.OrderId, incomingOrder.OpenQuantity, incomingOrder.Cost, CancelReason.FillOrKill); + _tradeListener?.OnCancel(incomingOrder.OrderId, incomingOrder.OpenQuantity, incomingOrder.Cost, incomingOrder.Fee, CancelReason.FillOrKill); } else if (orderWrapper.OrderCondition == OrderCondition.FillOrKill && orderWrapper.OrderAmount != 0 && canBeFilled == false) { - _tradeListener?.OnCancel(incomingOrder.OrderId, 0, 0, CancelReason.FillOrKill); + _tradeListener?.OnCancel(incomingOrder.OrderId, 0, 0, 0, CancelReason.FillOrKill); } else if (incomingOrder.CancelOn > 0 && incomingOrder.CancelOn <= timeNow) { if (orderWrapper.TotalQuantity == 0) - _tradeListener?.OnCancel(incomingOrder.OrderId, incomingOrder.OpenQuantity, incomingOrder.Cost, CancelReason.ValidityExpired); + _tradeListener?.OnCancel(incomingOrder.OrderId, incomingOrder.OpenQuantity, incomingOrder.Cost, incomingOrder.Fee, CancelReason.ValidityExpired); else - _tradeListener?.OnCancel(incomingOrder.OrderId, orderWrapper.TotalQuantity, incomingOrder.Cost, CancelReason.ValidityExpired); + _tradeListener?.OnCancel(incomingOrder.OrderId, orderWrapper.TotalQuantity, incomingOrder.Cost, incomingOrder.Fee, CancelReason.ValidityExpired); } else { @@ -171,7 +173,7 @@ public OrderMatchingResult AddOrder(OrderWrapper orderWrapper, bool isOrderTrigg { var iceberg = new Iceberg() { TipQuantity = orderWrapper.TipQuantity, TotalQuantity = orderWrapper.TotalQuantity }; _currentIcebergOrders.Add(incomingOrder.OrderId, iceberg); - incomingOrder = GetTip(incomingOrder, iceberg); + incomingOrder = GetTip(incomingOrder, iceberg, 0, 0); } if (incomingOrder.CancelOn > 0) { @@ -195,7 +197,7 @@ public OrderMatchingResult AddOrder(OrderWrapper orderWrapper, bool isOrderTrigg else { _currentOrders.Remove(orderWrapper.Order.OrderId); - _tradeListener?.OnCancel(orderWrapper.Order.OrderId, 0, 0, CancelReason.MarketOrderNoLiquidity); + _tradeListener?.OnCancel(orderWrapper.Order.OrderId, 0, 0, incomingOrder.Fee, CancelReason.MarketOrderNoLiquidity); } } else @@ -224,7 +226,6 @@ private OrderMatchingResult CancelOrder(OrderId orderId, CancelReason cancelReas if (_currentOrders.TryGetValue(orderId, out Order order)) { var quantityCancel = order.OpenQuantity; - var orderCost = order.Cost; _book.RemoveOrder(order); _currentOrders.Remove(orderId); if (order.IsTip) @@ -241,7 +242,12 @@ private OrderMatchingResult CancelOrder(OrderId orderId, CancelReason cancelReas RemoveGoodTillDateOrder(order.CancelOn, order.OrderId); } - _tradeListener?.OnCancel(orderId, quantityCancel, orderCost, cancelReason); + if (order.IsStop && order.IsBuy && order.OpenQuantity == 0) + { + _orderAmount.Remove(order.OrderId); + } + + _tradeListener?.OnCancel(orderId, quantityCancel, order.Cost, order.Fee, cancelReason); return OrderMatchingResult.CancelAcepted; } return OrderMatchingResult.OrderDoesNotExists; @@ -253,7 +259,7 @@ private void MatchAndAddOrder(Order incomingOrder, OrderCondition? orderConditio var matchResult = MatchWithOpenOrders(incomingOrder); if (orderCondition == OrderCondition.ImmediateOrCancel && !incomingOrder.IsFilled) { - _tradeListener?.OnCancel(incomingOrder.OrderId, incomingOrder.OpenQuantity, incomingOrder.Cost, CancelReason.ImmediateOrCancel); + _tradeListener?.OnCancel(incomingOrder.OrderId, incomingOrder.OpenQuantity, incomingOrder.Cost, incomingOrder.Fee, CancelReason.ImmediateOrCancel); _currentOrders.Remove(incomingOrder.OrderId); } else if (!incomingOrder.IsFilled) @@ -267,7 +273,7 @@ private void MatchAndAddOrder(Order incomingOrder, OrderCondition? orderConditio } else { - _tradeListener?.OnCancel(incomingOrder.OrderId, incomingOrder.OpenQuantity, incomingOrder.Cost, CancelReason.MarketOrderNoLiquidity); + _tradeListener?.OnCancel(incomingOrder.OrderId, incomingOrder.OpenQuantity, incomingOrder.Cost, incomingOrder.Fee, CancelReason.MarketOrderNoLiquidity); _currentOrders.Remove(incomingOrder.OrderId); if (incomingOrder.CancelOn > 0) { @@ -285,7 +291,7 @@ private void MatchAndAddOrder(Order incomingOrder, OrderCondition? orderConditio _currentOrders.Remove(incomingOrder.OrderId); if (incomingOrder.IsTip) { - AddTip(incomingOrder, incomingOrder.Cost); + AddTip(incomingOrder, incomingOrder.Cost, incomingOrder.Fee); } if (incomingOrder.CancelOn > 0) @@ -326,7 +332,7 @@ private void AddStopToOrderBook(List priceLevels) else { _currentOrders.Remove(order.OrderId); - _tradeListener?.OnCancel(order.OrderId, 0, 0, CancelReason.MarketOrderNoLiquidity); + _tradeListener?.OnCancel(order.OrderId, 0, 0, 0, CancelReason.MarketOrderNoLiquidity); } } else @@ -365,6 +371,10 @@ private bool MatchWithOpenOrders(Order incomingOrder) var cost = Math.Round(maxQuantity * matchPrice, _quoteCurrencyDecimalPlaces); restingOrder.Cost += cost; incomingOrder.Cost += cost; + var incomingFee = _feeProvider.GetFee(incomingOrder.FeeId); + var restingFee = _feeProvider.GetFee(restingOrder.FeeId); + restingOrder.Fee += Math.Round((cost * restingFee.MakerFee) / 100, _quoteCurrencyDecimalPlaces); + incomingOrder.Fee += Math.Round((cost * incomingFee.TakerFee) / 100, _quoteCurrencyDecimalPlaces); bool orderFilled = _book.FillOrder(restingOrder, maxQuantity); bool isRestingTipAdded = false; if (orderFilled) @@ -377,7 +387,7 @@ private bool MatchWithOpenOrders(Order incomingOrder) if (restingOrder.IsTip) { - isRestingTipAdded = AddTip(restingOrder, restingOrder.Cost); + isRestingTipAdded = AddTip(restingOrder, restingOrder.Cost, restingOrder.Fee); } } @@ -390,16 +400,20 @@ private bool MatchWithOpenOrders(Order incomingOrder) bool isRestingOrderFilled = restingOrder.IsFilled && !isRestingTipAdded; Quantity? askRemainingQuanity = null; + Quantity? askFee = null; Quantity? bidCost = null; + Quantity? bidFee = null; if (incomingOrder.IsBuy) { if (isIncomingOrderFilled) { bidCost = incomingOrder.Cost; + bidFee = incomingOrder.Fee; } if (isRestingOrderFilled) { askRemainingQuanity = restingOrder.OpenQuantity; + askFee = restingOrder.Fee; } } else @@ -407,14 +421,16 @@ private bool MatchWithOpenOrders(Order incomingOrder) if (isRestingOrderFilled) { bidCost = restingOrder.Cost; + bidFee = restingOrder.Fee; } if (isIncomingOrderFilled) { askRemainingQuanity = incomingOrder.OpenQuantity; + askFee = incomingOrder.Fee; } } - _tradeListener?.OnTrade(incomingOrder.OrderId, restingOrder.OrderId, matchPrice, maxQuantity, askRemainingQuanity, bidCost); + _tradeListener?.OnTrade(incomingOrder.OrderId, restingOrder.OrderId, matchPrice, maxQuantity, askRemainingQuanity, askFee, bidCost, bidFee); _marketPrice = matchPrice; anyMatchHappend = true; } @@ -431,12 +447,11 @@ private bool MatchWithOpenOrders(Order incomingOrder) return anyMatchHappend; } - private bool AddTip(Order order, Quantity cost) + private bool AddTip(Order order, Quantity cost, Quantity fee) { if (_currentIcebergOrders.TryGetValue(order.OrderId, out Iceberg iceberg)) { - iceberg.Cost = cost; - var tip = GetTip(order, iceberg); + var tip = GetTip(order, iceberg, cost, fee); _currentOrders.Add(tip.OrderId, tip); if (order.CancelOn > 0) @@ -518,7 +533,7 @@ private void RemoveGoodTillDateOrder(int time, OrderId orderId) } } - private Order GetTip(Order order, Iceberg iceberg) + private Order GetTip(Order order, Iceberg iceberg, Quantity cost, Quantity fee) { var quantity = iceberg.TipQuantity < iceberg.TotalQuantity ? iceberg.TipQuantity : iceberg.TotalQuantity; iceberg.TotalQuantity -= quantity; @@ -527,7 +542,7 @@ private Order GetTip(Order order, Iceberg iceberg) _currentIcebergOrders.Remove(order.OrderId); } - return new Order { IsBuy = order.IsBuy, Price = order.Price, OrderId = order.OrderId, IsTip = true, OpenQuantity = quantity, CancelOn = order.CancelOn, Cost = iceberg.Cost }; + return new Order { IsBuy = order.IsBuy, Price = order.Price, OrderId = order.OrderId, IsTip = true, OpenQuantity = quantity, CancelOn = order.CancelOn, Cost = cost, Fee = fee }; } private (Quantity? Quantity, bool CanFill) GetQuantity(Quantity orderAmount) diff --git a/OrderMatcher/OrderMatcher/MessageType.cs b/OrderMatcher/OrderMatcher/MessageType.cs index 049db70..e997cdb 100644 --- a/OrderMatcher/OrderMatcher/MessageType.cs +++ b/OrderMatcher/OrderMatcher/MessageType.cs @@ -6,6 +6,7 @@ public enum MessageType : byte NewOrderRequest = 1, CancelRequest = 2, BookRequest = 3, + CancelOpenGTD = 4, //Output from order matcher OrderMatchingResult = 101, diff --git a/OrderMatcher/OrderMatcher/Order.cs b/OrderMatcher/OrderMatcher/Order.cs index ff85c95..264b160 100644 --- a/OrderMatcher/OrderMatcher/Order.cs +++ b/OrderMatcher/OrderMatcher/Order.cs @@ -11,6 +11,8 @@ public class Order public bool IsStop { get; set; } public int CancelOn { get; set; } public Quantity Cost { get; set; } + public Quantity Fee { get; set; }//TODO serialize fee + public short FeeId { get; set; } public bool IsFilled { get @@ -34,6 +36,5 @@ public class Iceberg { public Quantity TipQuantity { get; set; } public Quantity TotalQuantity { get; set; } - public Quantity Cost { get; set; } } } diff --git a/OrderMatcher/OrderMatcher/OrderMatcher.csproj b/OrderMatcher/OrderMatcher/OrderMatcher.csproj index b291729..73f2012 100644 --- a/OrderMatcher/OrderMatcher/OrderMatcher.csproj +++ b/OrderMatcher/OrderMatcher/OrderMatcher.csproj @@ -1,11 +1,14 @@ - netstandard2.0 + netstandard2.1 - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/OrderMatcher/OrderMatcher/Serializers/CancelledOrderSerializer.cs b/OrderMatcher/OrderMatcher/Serializers/CancelledOrderSerializer.cs index 0f9c4f9..a56b6ac 100644 --- a/OrderMatcher/OrderMatcher/Serializers/CancelledOrderSerializer.cs +++ b/OrderMatcher/OrderMatcher/Serializers/CancelledOrderSerializer.cs @@ -11,6 +11,7 @@ public class CancelledOrderSerializer : Serializer private static readonly int orderIdOffset; private static readonly int remainingQuantityOffset; private static readonly int costOffset; + private static readonly int feeOffset; private static readonly int cancelReasonOffset; private static readonly int timestampOffset; @@ -21,6 +22,7 @@ public class CancelledOrderSerializer : Serializer private static readonly int sizeOfOrderId; private static readonly int sizeOfRemainingQuantity; private static readonly int sizeOfCost; + private static readonly int sizeOfFee; private static readonly int sizeOfCancelReason; private static readonly int sizeOfTimestamp; @@ -34,6 +36,7 @@ static CancelledOrderSerializer() sizeOfOrderId = sizeof(ulong); sizeOfRemainingQuantity = Quantity.SizeOfQuantity; sizeOfCost = Quantity.SizeOfQuantity; + sizeOfFee = Quantity.SizeOfQuantity; sizeOfCancelReason = sizeof(CancelReason); sizeOfTimestamp = sizeof(int); version = 1; @@ -44,7 +47,8 @@ static CancelledOrderSerializer() orderIdOffset = versionOffset + sizeOfVersion; remainingQuantityOffset = orderIdOffset + sizeOfOrderId; costOffset = remainingQuantityOffset + sizeOfRemainingQuantity; - cancelReasonOffset = costOffset + sizeOfCost; + feeOffset = costOffset + sizeOfCost; + cancelReasonOffset = feeOffset + sizeOfFee; timestampOffset = cancelReasonOffset + sizeOfCancelReason; sizeOfMessage = timestampOffset + sizeOfTimestamp; } @@ -55,10 +59,10 @@ public static byte[] Serialize(CancelledOrder cancelledOrder) { throw new ArgumentNullException(nameof(cancelledOrder)); } - return Serialize(cancelledOrder.OrderId, cancelledOrder.RemainingQuantity, cancelledOrder.Cost, cancelledOrder.CancelReason, cancelledOrder.Timestamp); + return Serialize(cancelledOrder.OrderId, cancelledOrder.RemainingQuantity, cancelledOrder.Cost, cancelledOrder.Fee, cancelledOrder.CancelReason, cancelledOrder.Timestamp); } - public static byte[] Serialize(OrderId orderId, Quantity remainingQuantity, Quantity cost, CancelReason cancelReason, int timeStamp) + public static byte[] Serialize(OrderId orderId, Quantity remainingQuantity, Quantity cost, Quantity fee, CancelReason cancelReason, int timeStamp) { byte[] msg = new byte[sizeOfMessage]; Write(msg, messageLengthOffset, sizeOfMessage); @@ -69,6 +73,7 @@ public static byte[] Serialize(OrderId orderId, Quantity remainingQuantity, Quan msg[cancelReasonOffset] = (byte)cancelReason; Write(msg, timestampOffset, timeStamp); Write(msg, costOffset, cost); + Write(msg, feeOffset, fee); return msg; } @@ -103,7 +108,7 @@ public static CancelledOrder Deserialize(byte[] bytes) cancelledOrder.CancelReason = (CancelReason)bytes[cancelReasonOffset]; cancelledOrder.Timestamp = BitConverter.ToInt32(bytes, timestampOffset); cancelledOrder.Cost = ReadQuantity(bytes, costOffset); - + cancelledOrder.Fee = ReadQuantity(bytes, feeOffset); return cancelledOrder; } } diff --git a/OrderMatcher/OrderMatcher/Serializers/FillSerializer.cs b/OrderMatcher/OrderMatcher/Serializers/FillSerializer.cs index cb0f0ca..8479c43 100644 --- a/OrderMatcher/OrderMatcher/Serializers/FillSerializer.cs +++ b/OrderMatcher/OrderMatcher/Serializers/FillSerializer.cs @@ -17,6 +17,10 @@ public class FillSerializer : Serializer private static readonly int askRemainingQuantityOffset; private static readonly int isBidCostNullOffset; private static readonly int bidCostOffset; + private static readonly int isBidFeeNullOffset; + private static readonly int bidFeeOffset; + private static readonly int isAskFeeNullOffset; + private static readonly int askFeeOffset; private static readonly int sizeOfMessageLength; private static readonly int sizeOfMessage; @@ -28,9 +32,13 @@ public class FillSerializer : Serializer private static readonly int sizeOfMatchQuantity; private static readonly int sizeOfTimestamp; private static readonly int sizeOfAskRemainingQuantity; + private static readonly int sizeOfAskFee; private static readonly int sizeOfBidCost; + private static readonly int sizeOfBidFee; private static readonly int sizeOfIsAskRemainingNull; + private static readonly int sizeOfIsAskFeeNull; private static readonly int sizeOfIsBidCostNull; + private static readonly int sizeOfIsBidFeeNull; public static int MessageSize => sizeOfMessage; @@ -47,6 +55,10 @@ static FillSerializer() sizeOfBidCost = Quantity.SizeOfQuantity; sizeOfTimestamp = sizeof(int); sizeOfIsAskRemainingNull = sizeof(bool); + sizeOfIsAskFeeNull = sizeof(bool); + sizeOfAskFee = Quantity.SizeOfQuantity; + sizeOfIsBidFeeNull = sizeof(bool); + sizeOfBidFee = Quantity.SizeOfQuantity; sizeOfIsBidCostNull = sizeof(bool); version = 1; @@ -59,9 +71,13 @@ static FillSerializer() matchQuantityOffset = matchRateOffset + sizeOfMatchRate; isAskRemainingNullOffset = matchQuantityOffset + sizeOfMatchQuantity; askRemainingQuantityOffset = isAskRemainingNullOffset + sizeOfIsAskRemainingNull; - isBidCostNullOffset = askRemainingQuantityOffset + sizeOfAskRemainingQuantity; + isAskFeeNullOffset = askRemainingQuantityOffset + sizeOfAskRemainingQuantity; + askFeeOffset = isAskFeeNullOffset + sizeOfIsAskFeeNull; + isBidCostNullOffset = askFeeOffset + sizeOfAskFee; bidCostOffset = isBidCostNullOffset + sizeOfIsBidCostNull; - timestampOffset = bidCostOffset + sizeOfBidCost; + isBidFeeNullOffset = bidCostOffset + sizeOfBidCost; + bidFeeOffset = isBidFeeNullOffset + sizeOfIsBidFeeNull; + timestampOffset = bidFeeOffset + sizeOfBidFee; sizeOfMessage = timestampOffset + sizeOfTimestamp; } @@ -71,10 +87,10 @@ public static byte[] Serialize(Fill fill) { throw new ArgumentNullException(nameof(fill)); } - return Serialize(fill.MakerOrderId, fill.TakerOrderId, fill.MatchRate, fill.MatchQuantity, fill.AskRemainingQuantity, fill.BidCost, fill.Timestamp); + return Serialize(fill.MakerOrderId, fill.TakerOrderId, fill.MatchRate, fill.MatchQuantity, fill.AskRemainingQuantity, fill.AskFee, fill.BidCost, fill.BidFee, fill.Timestamp); } - public static byte[] Serialize(OrderId makerOrderId, OrderId takerOrderId, Price matchRate, Quantity matchQuantity, Quantity? remainingAskQuantiy, Quantity? bidCost, int timeStamp) + public static byte[] Serialize(OrderId makerOrderId, OrderId takerOrderId, Price matchRate, Quantity matchQuantity, Quantity? remainingAskQuantiy, Quantity? askFee, Quantity? bidCost, Quantity? bidFee, int timeStamp) { byte[] msg = new byte[sizeOfMessage]; Write(msg, messageLengthOffset, sizeOfMessage); @@ -89,11 +105,21 @@ public static byte[] Serialize(OrderId makerOrderId, OrderId takerOrderId, Price if (remainingAskQuantiy.HasValue) Write(msg, askRemainingQuantityOffset, remainingAskQuantiy.Value); + msg[isAskFeeNullOffset] = Convert.ToByte(askFee.HasValue ? true : false); + + if (askFee.HasValue) + Write(msg, askFeeOffset, askFee.Value); + msg[isBidCostNullOffset] = Convert.ToByte(bidCost.HasValue ? true : false); if (bidCost.HasValue) Write(msg, bidCostOffset, bidCost.Value); + msg[isBidFeeNullOffset] = Convert.ToByte(bidFee.HasValue ? true : false); + + if (bidFee.HasValue) + Write(msg, bidFeeOffset, bidFee.Value); + Write(msg, timestampOffset, timeStamp); return msg; } @@ -131,10 +157,16 @@ public static Fill Deserialize(byte[] bytes) if (Convert.ToBoolean(bytes[isAskRemainingNullOffset])) fill.AskRemainingQuantity = ReadQuantity(bytes, askRemainingQuantityOffset); - + + if (Convert.ToBoolean(bytes[isAskFeeNullOffset])) + fill.AskFee = ReadQuantity(bytes, askFeeOffset); + if (Convert.ToBoolean(bytes[isBidCostNullOffset])) fill.BidCost = ReadQuantity(bytes, bidCostOffset); - + + if (Convert.ToBoolean(bytes[isBidFeeNullOffset])) + fill.BidFee = ReadQuantity(bytes, bidFeeOffset); + return fill; } } diff --git a/OrderMatcher/OrderMatcher/Serializers/OrderSerializer.cs b/OrderMatcher/OrderMatcher/Serializers/OrderSerializer.cs index a21bb33..790c880 100644 --- a/OrderMatcher/OrderMatcher/Serializers/OrderSerializer.cs +++ b/OrderMatcher/OrderMatcher/Serializers/OrderSerializer.cs @@ -17,6 +17,7 @@ public class OrderSerializer : Serializer private static readonly int totalQuantityOffset; private static readonly int cancelOnOffset; private static readonly int orderAmountOffset; + private static readonly int feeIdOffset; private static readonly int sizeOfMessageLength; private static readonly int sizeOfMessage; @@ -26,6 +27,7 @@ public class OrderSerializer : Serializer private static readonly int sizeOfSide; private static readonly int sizeOfCancelOn; private static readonly int sizeOfOrderAmount; + private static readonly int sizeOfFeeId; public static int MessageSize => sizeOfMessage; @@ -38,6 +40,7 @@ static OrderSerializer() sizeOfCancelOn = sizeof(int); sizeOfMessagetType = sizeof(MessageType); sizeOfOrderAmount = Quantity.SizeOfQuantity; + sizeOfFeeId = sizeof(short); version = 1; messageLengthOffset = 0; @@ -52,7 +55,8 @@ static OrderSerializer() totalQuantityOffset = stopPriceOffset + Price.SizeOfPrice; cancelOnOffset = totalQuantityOffset + Quantity.SizeOfQuantity; orderAmountOffset = cancelOnOffset + sizeOfCancelOn; - sizeOfMessage = orderAmountOffset + sizeOfOrderAmount; + feeIdOffset = orderAmountOffset + sizeOfOrderAmount; + sizeOfMessage = feeIdOffset + sizeOfFeeId; } public static byte[] Serialize(OrderWrapper order) @@ -80,6 +84,7 @@ public static byte[] Serialize(OrderWrapper order) Write(msg, totalQuantityOffset, order.TotalQuantity); Write(msg, cancelOnOffset, order.Order.CancelOn); Write(msg, orderAmountOffset, order.OrderAmount); + Write(msg, feeIdOffset, order.Order.FeeId); return msg; } @@ -125,6 +130,7 @@ public static OrderWrapper Deserialize(byte[] bytes) order.Order.CancelOn = BitConverter.ToInt32(bytes, cancelOnOffset); order.OrderAmount = ReadQuantity(bytes, orderAmountOffset); + order.Order.FeeId = BitConverter.ToInt16(bytes, feeIdOffset); return order; } } diff --git a/OrderMatcher/OrderMatcher/Serializers/Serializer.cs b/OrderMatcher/OrderMatcher/Serializers/Serializer.cs index ae9b028..d3b4553 100644 --- a/OrderMatcher/OrderMatcher/Serializers/Serializer.cs +++ b/OrderMatcher/OrderMatcher/Serializers/Serializer.cs @@ -128,6 +128,8 @@ public static Quantity ReadQuantity(byte[] array, int start) return MessageType.Fill; else if ((MessageType)data[4] == MessageType.Cancel && messageSize == CancelledOrderSerializer.MessageSize) return MessageType.Cancel; + else if ((MessageType)data[4] == MessageType.OrderAccept && messageSize == OrderAcceptSerializer.MessageSize) + return MessageType.OrderAccept; else if ((MessageType)data[4] == MessageType.OrderTrigger && messageSize == OrderTriggerSerializer.MessageSize) return MessageType.OrderTrigger; else if ((MessageType)data[4] == MessageType.Book)