From ce8dbe6d84d5134812a1e450880309c02c411b17 Mon Sep 17 00:00:00 2001 From: ArjunVachhani-CCM <118927627+ArjunVachhani-CCM@users.noreply.github.com> Date: Fri, 30 Jun 2023 14:54:16 +0530 Subject: [PATCH] refactored types --- .../MatchingEngineBenchmark.cs | 12 ++++---- OrderMatcher/OrderMatcher.Types/Amount.cs | 30 +++++++++++++++++++ OrderMatcher/OrderMatcher.Types/Price.cs | 6 ++++ OrderMatcher/OrderMatcher.Types/Quantity.cs | 10 +++++++ .../DecrementQuantitySerializer.cs | 2 +- OrderMatcher/OrderMatcher/Book.cs | 2 +- OrderMatcher/OrderMatcher/MatchingEngine.cs | 6 ++-- OrderMatcher/OrderMatcher/Side.cs | 2 +- 8 files changed, 59 insertions(+), 11 deletions(-) diff --git a/OrderMatcher/OrderMatcher.Performance/MatchingEngineBenchmark.cs b/OrderMatcher/OrderMatcher.Performance/MatchingEngineBenchmark.cs index 1b64e8e..eb3b3b7 100644 --- a/OrderMatcher/OrderMatcher.Performance/MatchingEngineBenchmark.cs +++ b/OrderMatcher/OrderMatcher.Performance/MatchingEngineBenchmark.cs @@ -5,10 +5,12 @@ [MinColumn, MaxColumn, MeanColumn, MedianColumn, AllStatisticsColumn] public class MatchingEngineBenchmark { + private readonly static Quantity stepSize = new Quantity(0.00000001m); + [Benchmark] public void CreateMatchingEngine() { - MatchingEngine engine = new MatchingEngine(null, null, 0.00000001m, 8); + MatchingEngine engine = new MatchingEngine(null, null, stepSize, 8); } [Benchmark] @@ -36,7 +38,7 @@ public void CreateOrder() [Benchmark] public void AddOrder() { - MatchingEngine engine = new MatchingEngine(null, null, 0.00000001m, 8); + MatchingEngine engine = new MatchingEngine(null, null, stepSize, 8); Order order = new Order() { CancelOn = 0, @@ -63,7 +65,7 @@ public void AddOrder() [Benchmark] public void AddAndCancelOrder() { - MatchingEngine engine = new MatchingEngine(null, null, 0.00000001m, 8); + MatchingEngine engine = new MatchingEngine(null, null, stepSize, 8); Order order = new Order() { CancelOn = 0, @@ -95,7 +97,7 @@ public void AddAndCancelOrder() [Benchmark] public void TenAddOrder() { - MatchingEngine engine = new MatchingEngine(new FakeTradeListener(), new FakeFeeProvider(), 0.00000001m, 8); + MatchingEngine engine = new MatchingEngine(new FakeTradeListener(), new FakeFeeProvider(), stepSize, 8); for (var i = 0; i < 10; i++) { Order order = new Order() @@ -124,7 +126,7 @@ public void TenAddOrder() [Benchmark] public void TenAddAndCancel() { - MatchingEngine engine = new MatchingEngine(new FakeTradeListener(), new FakeFeeProvider(), 0.00000001m, 8); + MatchingEngine engine = new MatchingEngine(new FakeTradeListener(), new FakeFeeProvider(), stepSize, 8); for (var i = 1; i <= 10; i++) { Order order = new Order() diff --git a/OrderMatcher/OrderMatcher.Types/Amount.cs b/OrderMatcher/OrderMatcher.Types/Amount.cs index cfabcb7..144dc0b 100644 --- a/OrderMatcher/OrderMatcher.Types/Amount.cs +++ b/OrderMatcher/OrderMatcher.Types/Amount.cs @@ -47,6 +47,36 @@ public override int GetHashCode() return 92834 + _amount.GetHashCode(); } + public static Amount operator -(Amount left, Amount right) + { + return new Amount(left._amount - right._amount); + } + + public static Amount operator +(Amount left, Amount right) + { + return new Amount(left._amount + right._amount); + } + + public static Quantity operator /(Amount amount, Price price) + { + return new Quantity(amount._amount / price.GetPrice()); + } + + public static Amount operator /(Amount amount, int d) + { + return new Amount(amount._amount / d); + } + + public static Amount operator *(Amount amount, decimal d) + { + return new Amount(amount._amount * d); + } + + public Amount Round(int decimalPlaces) + { + return Math.Round(_amount, decimalPlaces); + } + public static bool operator <(Amount left, Amount right) { return left._amount < right._amount; diff --git a/OrderMatcher/OrderMatcher.Types/Price.cs b/OrderMatcher/OrderMatcher.Types/Price.cs index 75ad6d2..ce16117 100644 --- a/OrderMatcher/OrderMatcher.Types/Price.cs +++ b/OrderMatcher/OrderMatcher.Types/Price.cs @@ -25,6 +25,12 @@ public Price(decimal price) return c._price; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal decimal GetPrice() + { + return _price; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator >(Price a, Price b) { diff --git a/OrderMatcher/OrderMatcher.Types/Quantity.cs b/OrderMatcher/OrderMatcher.Types/Quantity.cs index 2393a81..1b9dde7 100644 --- a/OrderMatcher/OrderMatcher.Types/Quantity.cs +++ b/OrderMatcher/OrderMatcher.Types/Quantity.cs @@ -11,6 +11,11 @@ public Quantity(decimal quantity) _quantity = quantity; } + public static Amount operator *(Quantity q, Price p) + { + return new Amount(q._quantity * p.GetPrice()); + } + public static Quantity operator -(Quantity a, Quantity b) { return a._quantity - b._quantity; @@ -21,6 +26,11 @@ public Quantity(decimal quantity) return a._quantity + b._quantity; } + public static Quantity operator %(Quantity a, Quantity b) + { + return a._quantity % b._quantity; + } + public static implicit operator Quantity(decimal quantity) { return new Quantity(quantity); diff --git a/OrderMatcher/OrderMatcher.Types/Serializers/DecrementQuantitySerializer.cs b/OrderMatcher/OrderMatcher.Types/Serializers/DecrementQuantitySerializer.cs index d629b84..c639a3c 100644 --- a/OrderMatcher/OrderMatcher.Types/Serializers/DecrementQuantitySerializer.cs +++ b/OrderMatcher/OrderMatcher.Types/Serializers/DecrementQuantitySerializer.cs @@ -46,7 +46,7 @@ public static void Serialize(OrderId orderId, UserId userId, Quantity quantityTo Write(bytes.Slice(versionOffset), version); Write(bytes.Slice(orderIdOffset), orderId); Write(bytes.Slice(userIdOffset), userId); - Write(bytes.Slice(quantityToDecrementOffset), quantityToDecrement); + quantityToDecrement.WriteBytes(bytes.Slice(quantityToDecrementOffset)); Write(bytes.Slice(messageSequenceOffset), messageSequence); } diff --git a/OrderMatcher/OrderMatcher/Book.cs b/OrderMatcher/OrderMatcher/Book.cs index bd09e26..cae9783 100644 --- a/OrderMatcher/OrderMatcher/Book.cs +++ b/OrderMatcher/OrderMatcher/Book.cs @@ -139,7 +139,7 @@ internal bool CheckCanFillOrder(bool isBuy, Quantity requestedQuantity, Price li return side.CheckCanBeFilled(requestedQuantity, limitPrice); } - internal bool CheckCanFillMarketOrderAmount(bool isBuy, Quantity orderAmount) + internal bool CheckCanFillMarketOrderAmount(bool isBuy, Amount orderAmount) { var side = isBuy ? _asks : _bids; return side.CheckMarketOrderAmountCanBeFilled(orderAmount); diff --git a/OrderMatcher/OrderMatcher/MatchingEngine.cs b/OrderMatcher/OrderMatcher/MatchingEngine.cs index 3773216..c1c66ab 100644 --- a/OrderMatcher/OrderMatcher/MatchingEngine.cs +++ b/OrderMatcher/OrderMatcher/MatchingEngine.cs @@ -379,13 +379,13 @@ static void CancelIncomingOrder(Order incomingOrder, ITradeListener? tradeListen throw new OrderMatcherException(Constant.NOT_EXPECTED); } - var cost = Math.Round(maxQuantity * matchPrice, _quoteCurrencyDecimalPlaces); + var cost = (maxQuantity * matchPrice).Round(_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); + restingOrder.Fee += ((cost * restingFee.MakerFee) / 100).Round(_quoteCurrencyDecimalPlaces); + incomingOrder.Fee += ((cost * incomingFee.TakerFee) / 100).Round(_quoteCurrencyDecimalPlaces); bool orderFilled = _book.FillOrder(restingOrder, maxQuantity); bool isRestingTipAdded = false; if (orderFilled && restingOrder.IsTip) diff --git a/OrderMatcher/OrderMatcher/Side.cs b/OrderMatcher/OrderMatcher/Side.cs index 1d0c409..45fb0f6 100644 --- a/OrderMatcher/OrderMatcher/Side.cs +++ b/OrderMatcher/OrderMatcher/Side.cs @@ -102,7 +102,7 @@ public bool CheckCanBeFilled(Quantity requestedQuantity, Price limitPrice) return false; } - public bool CheckMarketOrderAmountCanBeFilled(Quantity orderAmount) + public bool CheckMarketOrderAmountCanBeFilled(Amount orderAmount) { Amount cummulativeOrderAmount = 0; foreach (var priceLevel in _priceLevels)