From e4abba7ee490a3056681d7858521557866a39933 Mon Sep 17 00:00:00 2001 From: Jhonathan Abreu Date: Thu, 25 Jan 2024 09:51:11 -0400 Subject: [PATCH] Minor fixes and new unit tests --- .../SplitEquityRegressionAlgorithm.cs | 2 +- .../LimitIfTouchedRegressionAlgorithm.py | 12 +-- Tests/Common/Orders/OrderTests.cs | 45 ------------ .../BrokerageTransactionHandlerTests.cs | 73 +++++++++++++++++++ 4 files changed, 80 insertions(+), 52 deletions(-) diff --git a/Algorithm.CSharp/SplitEquityRegressionAlgorithm.cs b/Algorithm.CSharp/SplitEquityRegressionAlgorithm.cs index 1f181701aba2..882fb8527c9f 100644 --- a/Algorithm.CSharp/SplitEquityRegressionAlgorithm.cs +++ b/Algorithm.CSharp/SplitEquityRegressionAlgorithm.cs @@ -184,7 +184,7 @@ public override void OnEndOfAlgorithm() {"Estimated Strategy Capacity", "$0"}, {"Lowest Capacity Asset", ""}, {"Portfolio Turnover", "0%"}, - {"OrderListHash", "df486042c4e80663af46c355cb08b220"} + {"OrderListHash", "16b303d07fd2993a588b91c64091bae3"} }; } } diff --git a/Algorithm.Python/LimitIfTouchedRegressionAlgorithm.py b/Algorithm.Python/LimitIfTouchedRegressionAlgorithm.py index 34d36ccbabf0..dcc18f7020c8 100644 --- a/Algorithm.Python/LimitIfTouchedRegressionAlgorithm.py +++ b/Algorithm.Python/LimitIfTouchedRegressionAlgorithm.py @@ -22,9 +22,9 @@ ### class LimitIfTouchedRegressionAlgorithm(QCAlgorithm): _expectedEvents = deque([ - "Time: 10/10/2013 13:31:00 OrderID: 72 EventID: 399 Symbol: SPY Status: Filled Quantity: -1 FillQuantity: -1 FillPrice: 144.6434 USD LimitPrice: 144.3551 TriggerPrice: 143.61 OrderFee: 1 USD", - "Time: 10/10/2013 15:57:00 OrderID: 73 EventID: 156 Symbol: SPY Status: Filled Quantity: -1 FillQuantity: -1 FillPrice: 145.6636 USD LimitPrice: 145.6434 TriggerPrice: 144.89 OrderFee: 1 USD", - "Time: 10/11/2013 15:37:00 OrderID: 74 EventID: 380 Symbol: SPY Status: Filled Quantity: -1 FillQuantity: -1 FillPrice: 146.7185 USD LimitPrice: 146.6723 TriggerPrice: 145.92 OrderFee: 1 USD" ]) + "Time: 10/10/2013 13:31:00 OrderID: 72 EventID: 399 Symbol: SPY Status: Filled Quantity: -1 FillQuantity: -1 FillPrice: $144.6434 LimitPrice: $144.3551 TriggerPrice: $143.61 OrderFee: 1 USD", + "Time: 10/10/2013 15:57:00 OrderID: 73 EventID: 156 Symbol: SPY Status: Filled Quantity: -1 FillQuantity: -1 FillPrice: $145.6636 LimitPrice: $145.6434 TriggerPrice: $144.89 OrderFee: 1 USD", + "Time: 10/11/2013 15:37:00 OrderID: 74 EventID: 380 Symbol: SPY Status: Filled Quantity: -1 FillQuantity: -1 FillPrice: $146.7185 LimitPrice: $146.6723 TriggerPrice: $145.92 OrderFee: 1 USD" ]) def Initialize(self): self.SetStartDate(2013, 10, 7) @@ -51,11 +51,11 @@ def OnData(self, data): return new_quantity = int(self._request.Quantity - self._negative) - self._request.UpdateQuantity(new_quantity, f"LIT - Quantity: {new_quantity}") + self._request.UpdateQuantity(new_quantity, f"LIT - Quantity: {new_quantity}") self._request.UpdateTriggerPrice(Extensions.RoundToSignificantDigits(self._request.Get(OrderField.TriggerPrice), 5)); def OnOrderEvent(self, orderEvent): if orderEvent.Status == OrderStatus.Filled: expected = self._expectedEvents.popleft() - if orderEvent.ToString() != expected: - raise Exception(f"orderEvent {orderEvent.Id} differed from {expected}") + if str(orderEvent) != expected: + raise Exception(f"orderEvent {orderEvent.Id} differed from {expected}. Actual {orderEvent}") diff --git a/Tests/Common/Orders/OrderTests.cs b/Tests/Common/Orders/OrderTests.cs index 2b8f4de0767a..83a63ac6b542 100644 --- a/Tests/Common/Orders/OrderTests.cs +++ b/Tests/Common/Orders/OrderTests.cs @@ -44,51 +44,6 @@ public void GetValueTest(ValueTestParameters parameters) Assert.AreEqual(parameters.ExpectedValue, value); } - [Test] - [TestCase(null)] - [TestCase("")] - public void LimitOrder_SetsDefaultTag(string tag) - { - var order = new LimitOrder(Symbols.SPY, 1m, 123.4567m, DateTime.Today, tag); - Assert.AreEqual(string.Empty, order.Tag); - } - - [Test] - [TestCase(null)] - [TestCase("")] - public void StopLimitOrder_SetsDefaultTag(string tag) - { - var order = new StopLimitOrder(Symbols.SPY, 1m, 123.4567m, 234.5678m, DateTime.Today, tag); - Assert.AreEqual(string.Empty, order.Tag); - } - - [Test] - [TestCase(null)] - [TestCase("")] - public void StopMarketOrder_SetsDefaultTag(string tag) - { - var order = new StopMarketOrder(Symbols.SPY, 1m, 123.4567m, DateTime.Today, tag); - Assert.AreEqual(string.Empty, order.Tag); - } - - [Test] - [TestCase(null)] - [TestCase("")] - public void TrailingStopOrder_SetsDefaultTag(string tag) - { - var order = new TrailingStopOrder(Symbols.SPY, 1m, 0.1m, true, DateTime.Today, tag); - Assert.AreEqual(Messages.TrailingStopOrder.Tag(order), order.Tag); - } - - [Test] - [TestCase(null)] - [TestCase("")] - public void LimitIfTouchedOrder_SetsDefaultTag(string tag) - { - var order = new LimitIfTouchedOrder(Symbols.SPY, 1m, 123.4567m,122.4567m, DateTime.Today, tag); - Assert.AreEqual(string.Empty, order.Tag); - } - [TestCase(OrderDirection.Sell, 300, 0.1, true, 270)] [TestCase(OrderDirection.Sell, 300, 30, false, 270)] [TestCase(OrderDirection.Buy, 300, 0.1, true, 330)] diff --git a/Tests/Engine/BrokerageTransactionHandlerTests/BrokerageTransactionHandlerTests.cs b/Tests/Engine/BrokerageTransactionHandlerTests/BrokerageTransactionHandlerTests.cs index cdc30ac2a09c..40ec881bfe8b 100644 --- a/Tests/Engine/BrokerageTransactionHandlerTests/BrokerageTransactionHandlerTests.cs +++ b/Tests/Engine/BrokerageTransactionHandlerTests/BrokerageTransactionHandlerTests.cs @@ -63,6 +63,79 @@ public void Initialize() Assert.IsNotNull(_handleOptionNotification); } + private static SubmitOrderRequest MakeOrderRequest(Security security, OrderType orderType, DateTime date) + { + var groupOrderManager = new GroupOrderManager(1, 1, 100, orderType == OrderType.ComboLimit ? 100 : 0); + + return orderType switch + { + OrderType.Market => new SubmitOrderRequest(OrderType.Market, security.Type, security.Symbol, 1, 0, 0, date, ""), + OrderType.Limit => new SubmitOrderRequest(OrderType.Limit, security.Type, security.Symbol, 1, 0, 290, date, ""), + OrderType.StopMarket => new SubmitOrderRequest(OrderType.StopMarket, security.Type, security.Symbol, 1, 305, 0, date, ""), + OrderType.StopLimit => new SubmitOrderRequest(OrderType.StopLimit, security.Type, security.Symbol, 1, 305, 295, date, ""), + OrderType.MarketOnOpen => new SubmitOrderRequest(OrderType.MarketOnOpen, security.Type, security.Symbol, 1, 0, 0, date, ""), + OrderType.MarketOnClose => new SubmitOrderRequest(OrderType.MarketOnClose, security.Type, security.Symbol, 1, 0, 0, date, ""), + OrderType.LimitIfTouched => new SubmitOrderRequest(OrderType.LimitIfTouched, security.Type, security.Symbol, 1, 0, 300, 305, date, ""), + OrderType.OptionExercise => new SubmitOrderRequest(OrderType.OptionExercise, security.Type, security.Symbol, 1, 0, 0, date, ""), + OrderType.ComboMarket => new SubmitOrderRequest(OrderType.ComboMarket, security.Type, security.Symbol, 1, 0, 0, date, "", groupOrderManager: groupOrderManager), + OrderType.ComboLimit => new SubmitOrderRequest(OrderType.ComboLimit, security.Type, security.Symbol, 1, 295, 0, date, "", groupOrderManager: groupOrderManager), + OrderType.ComboLegLimit => new SubmitOrderRequest(OrderType.ComboLegLimit, security.Type, security.Symbol, 1, 295, 0, date, "", groupOrderManager: groupOrderManager), + OrderType.TrailingStop => new SubmitOrderRequest(OrderType.TrailingStop, security.Type, security.Symbol, 1, 305, 0, 305, date, ""), + _ => throw new ArgumentOutOfRangeException(nameof(orderType), orderType, null) + }; + } + + [Test] + public void OrderTagIsSetToTheDefaultOne([Values] OrderType orderType) + { + var reference = new DateTime(2024, 01, 25, 10, 0, 0); + + // Initialize the algorithm + var algorithm = new TestAlgorithm { HistoryProvider = new EmptyHistoryProvider() }; + algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); + algorithm.SetCash(100000); + var security = (Security)algorithm.AddEquity("SPY"); + algorithm.SetFinishedWarmingUp(); + + //Initializes the transaction handler + var transactionHandler = new TestBrokerageTransactionHandler(); + using var brokerage = new BacktestingBrokerage(algorithm); + transactionHandler.Initialize(algorithm, brokerage, new BacktestingResultHandler()); + + // Set up security + security.SetMarketPrice(new Tick(reference, security.Symbol, 300, 300)); + if (orderType == OrderType.OptionExercise) + { + algorithm.AddOption(security.Symbol); + security = algorithm.AddOptionContract(Symbol.CreateOption(security.Symbol, Market.USA, OptionStyle.American, OptionRight.Call, + 300, reference.AddDays(4).Date)); + security.SetMarketPrice(new Tick(reference, security.Symbol, 10, 10)); + } + + // Creates the order + var orderRequest = MakeOrderRequest(security, orderType, reference); + + // Mock the order processor + var orderProcessorMock = new Mock(); + orderProcessorMock.Setup(m => m.GetOrderTicket(It.IsAny())).Returns(new OrderTicket(algorithm.Transactions, orderRequest)); + algorithm.Transactions.SetOrderProcessor(orderProcessorMock.Object); + + // Act + var orderTicket = transactionHandler.Process(orderRequest); + Assert.IsTrue(orderTicket.Status == OrderStatus.New); + transactionHandler.HandleOrderRequest(orderRequest); + + // Assert + Assert.IsTrue(orderRequest.Response.IsProcessed); + Assert.IsTrue(orderRequest.Response.IsSuccess); + Assert.AreEqual(OrderStatus.Submitted, orderTicket.Status); + + // Assert the order tag is set to the default one + var order = transactionHandler.GetOpenOrders().Single(); + Assert.AreEqual(orderType, order.Type); + Assert.AreEqual(order.GetDefaultTag(), order.Tag); + } + [Test] public void OrderQuantityIsFlooredToNearestMultipleOfLotSizeWhenLongOrderIsRounded() {