|
13 | 13 | * limitations under the License. |
14 | 14 | */ |
15 | 15 |
|
16 | | -using System; |
17 | | -using System.Collections.Generic; |
18 | | -using System.Linq; |
19 | | -using System.Reflection; |
20 | | -using System.Threading; |
21 | 16 | using Moq; |
22 | 17 | using NodaTime; |
23 | 18 | using NUnit.Framework; |
|
26 | 21 | using QuantConnect.Brokerages; |
27 | 22 | using QuantConnect.Brokerages.Backtesting; |
28 | 23 | using QuantConnect.Data; |
| 24 | +using QuantConnect.Data.Market; |
| 25 | +using QuantConnect.Interfaces; |
29 | 26 | using QuantConnect.Lean.Engine.Results; |
30 | 27 | using QuantConnect.Lean.Engine.TransactionHandlers; |
31 | 28 | using QuantConnect.Orders; |
32 | | -using QuantConnect.Securities; |
33 | | -using QuantConnect.Data.Market; |
34 | | -using QuantConnect.Interfaces; |
35 | 29 | using QuantConnect.Orders.Fees; |
36 | 30 | using QuantConnect.Packets; |
| 31 | +using QuantConnect.Securities; |
37 | 32 | using QuantConnect.Tests.Engine.DataFeeds; |
38 | 33 | using QuantConnect.Tests.Engine.Setup; |
39 | 34 | using QuantConnect.Util; |
40 | | -using HistoryRequest = QuantConnect.Data.HistoryRequest; |
| 35 | +using System; |
41 | 36 | using System.Collections.Concurrent; |
| 37 | +using System.Collections.Generic; |
| 38 | +using System.Linq; |
| 39 | +using System.Reflection; |
| 40 | +using System.Threading; |
| 41 | +using HistoryRequest = QuantConnect.Data.HistoryRequest; |
42 | 42 |
|
43 | 43 | namespace QuantConnect.Tests.Engine.BrokerageTransactionHandlerTests |
44 | 44 | { |
@@ -68,7 +68,7 @@ public void Initialize() |
68 | 68 | [TearDown] |
69 | 69 | public void TearDown() |
70 | 70 | { |
71 | | - _transactionHandler?.Exit(); |
| 71 | + _transactionHandler?.Exit(); |
72 | 72 | } |
73 | 73 |
|
74 | 74 | private static SubmitOrderRequest MakeOrderRequest(Security security, OrderType orderType, DateTime date) |
@@ -714,6 +714,41 @@ public void RoundOff_Long_Fractional_Orders() |
714 | 714 | Assert.AreEqual(123.12345678m, actual); |
715 | 715 | } |
716 | 716 |
|
| 717 | + [Test] |
| 718 | + public void PriceRoundingWarningLogsOnlyOnceWithMultipleOrders() |
| 719 | + { |
| 720 | + var algo = new QCAlgorithm(); |
| 721 | + algo.SubscriptionManager.SetDataManager(new DataManagerStub(algo)); |
| 722 | + algo.SetBrokerageModel(BrokerageName.Default); |
| 723 | + |
| 724 | + var security = algo.AddSecurity(SecurityType.Equity, "SPY", Resolution.Minute, Market.USA, false, 1m, false); |
| 725 | + security.PriceVariationModel = new TestPriceVariationModel(0.01m); |
| 726 | + |
| 727 | + var transactionHandler = new TestBrokerageTransactionHandler(); |
| 728 | + using var brokerage = new BacktestingBrokerage(algo); |
| 729 | + transactionHandler.Initialize(algo, brokerage, new BacktestingResultHandler()); |
| 730 | + var hasLoggedField = typeof(BrokerageTransactionHandler).GetField("_hasLoggedPriceRoundingWarning", BindingFlags.NonPublic | BindingFlags.Instance); |
| 731 | + var hasLogged = (bool)hasLoggedField.GetValue(transactionHandler); |
| 732 | + |
| 733 | + Assert.IsFalse(hasLogged); |
| 734 | + |
| 735 | + var date = new DateTime(2013, 10, 7, 9, 35, 0); |
| 736 | + var orders = new[] |
| 737 | + { |
| 738 | + new LimitOrder(security.Symbol, 1000, 123.252m, date), |
| 739 | + new LimitOrder(security.Symbol, 1000, 234.259m, date.AddDays(1)), |
| 740 | + new LimitOrder(security.Symbol, 1000, 345.225m, date.AddDays(2)), |
| 741 | + new LimitOrder(security.Symbol, 1000, 456.235m, date.AddDays(3)) |
| 742 | + }; |
| 743 | + |
| 744 | + for (int i = 0; i < orders.Length; i++) |
| 745 | + { |
| 746 | + transactionHandler.RoundOrderPrices(orders[i], security); |
| 747 | + hasLogged = (bool)hasLoggedField.GetValue(transactionHandler); |
| 748 | + Assert.IsTrue(hasLogged); |
| 749 | + } |
| 750 | + } |
| 751 | + |
717 | 752 | [Test] |
718 | 753 | public void RoundOff_Short_Fractional_Orders() |
719 | 754 | { |
@@ -2397,7 +2432,7 @@ public void ProcessesOrdersConcurrently() |
2397 | 2432 | using var finishedEvent = new ManualResetEventSlim(false); |
2398 | 2433 | var transactionHandler = new TestableConcurrentBrokerageTransactionHandler(expectedOrdersCount, finishedEvent); |
2399 | 2434 | transactionHandler.Initialize(algorithm, brokerage, new BacktestingResultHandler()); |
2400 | | - |
| 2435 | + |
2401 | 2436 | try |
2402 | 2437 | { |
2403 | 2438 | algorithm.Transactions.SetOrderProcessor(transactionHandler); |
@@ -2705,6 +2740,21 @@ protected override void InitializeTransactionThread() |
2705 | 2740 | } |
2706 | 2741 | } |
2707 | 2742 |
|
| 2743 | + private class TestPriceVariationModel : IPriceVariationModel |
| 2744 | + { |
| 2745 | + private readonly decimal _increment; |
| 2746 | + |
| 2747 | + public TestPriceVariationModel(decimal increment) |
| 2748 | + { |
| 2749 | + _increment = increment; |
| 2750 | + } |
| 2751 | + |
| 2752 | + public decimal GetMinimumPriceVariation(GetMinimumPriceVariationParameters parameters) |
| 2753 | + { |
| 2754 | + return _increment; |
| 2755 | + } |
| 2756 | + } |
| 2757 | + |
2708 | 2758 | private class TestNonShortableProvider : IShortableProvider |
2709 | 2759 | { |
2710 | 2760 | public Dictionary<Symbol, long> AllShortableSymbols(DateTime localTime) |
|
0 commit comments