Skip to content

Commit c996e64

Browse files
committed
Logging only once price rounding warnings
1 parent 7fb2465 commit c996e64

File tree

2 files changed

+66
-13
lines changed

2 files changed

+66
-13
lines changed

Engine/TransactionHandlers/BrokerageTransactionHandler.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ public class BrokerageTransactionHandler : ITransactionHandler
5454
private int _totalOrderCount;
5555

5656
// this bool is used to check if the warning message for the rounding of order quantity has been displayed for the first time
57-
private bool _firstRoundOffMessage = false;
57+
private bool _firstRoundOffMessage;
58+
// this bool is used to check if the warning message for price rounding has been displayed for the first time
59+
private bool _hasLoggedPriceRoundingWarning;
5860

5961
// this value is used for determining how confident we are in our cash balance update
6062
private long _lastFillTimeTicks;
@@ -1914,11 +1916,12 @@ private void InvalidateOrders(List<Order> orders, string message)
19141916

19151917
private void SendWarningOnPriceChange(string priceType, decimal priceRound, decimal priceOriginal)
19161918
{
1917-
if (!priceOriginal.Equals(priceRound))
1919+
if (!priceOriginal.Equals(priceRound) && !_hasLoggedPriceRoundingWarning)
19181920
{
19191921
_algorithm.Error(
19201922
$"Warning: To meet brokerage precision requirements, order {priceType.ToStringInvariant()} was rounded to {priceRound.ToStringInvariant()} from {priceOriginal.ToStringInvariant()}"
19211923
);
1924+
_hasLoggedPriceRoundingWarning = true;
19221925
}
19231926
}
19241927

Tests/Engine/BrokerageTransactionHandlerTests/BrokerageTransactionHandlerTests.cs

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,6 @@
1313
* limitations under the License.
1414
*/
1515

16-
using System;
17-
using System.Collections.Generic;
18-
using System.Linq;
19-
using System.Reflection;
20-
using System.Threading;
2116
using Moq;
2217
using NodaTime;
2318
using NUnit.Framework;
@@ -26,19 +21,24 @@
2621
using QuantConnect.Brokerages;
2722
using QuantConnect.Brokerages.Backtesting;
2823
using QuantConnect.Data;
24+
using QuantConnect.Data.Market;
25+
using QuantConnect.Interfaces;
2926
using QuantConnect.Lean.Engine.Results;
3027
using QuantConnect.Lean.Engine.TransactionHandlers;
3128
using QuantConnect.Orders;
32-
using QuantConnect.Securities;
33-
using QuantConnect.Data.Market;
34-
using QuantConnect.Interfaces;
3529
using QuantConnect.Orders.Fees;
3630
using QuantConnect.Packets;
31+
using QuantConnect.Securities;
3732
using QuantConnect.Tests.Engine.DataFeeds;
3833
using QuantConnect.Tests.Engine.Setup;
3934
using QuantConnect.Util;
40-
using HistoryRequest = QuantConnect.Data.HistoryRequest;
35+
using System;
4136
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;
4242

4343
namespace QuantConnect.Tests.Engine.BrokerageTransactionHandlerTests
4444
{
@@ -68,7 +68,7 @@ public void Initialize()
6868
[TearDown]
6969
public void TearDown()
7070
{
71-
_transactionHandler?.Exit();
71+
_transactionHandler?.Exit();
7272
}
7373

7474
private static SubmitOrderRequest MakeOrderRequest(Security security, OrderType orderType, DateTime date)
@@ -714,6 +714,41 @@ public void RoundOff_Long_Fractional_Orders()
714714
Assert.AreEqual(123.12345678m, actual);
715715
}
716716

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+
717752
[Test]
718753
public void RoundOff_Short_Fractional_Orders()
719754
{
@@ -2397,7 +2432,7 @@ public void ProcessesOrdersConcurrently()
23972432
using var finishedEvent = new ManualResetEventSlim(false);
23982433
var transactionHandler = new TestableConcurrentBrokerageTransactionHandler(expectedOrdersCount, finishedEvent);
23992434
transactionHandler.Initialize(algorithm, brokerage, new BacktestingResultHandler());
2400-
2435+
24012436
try
24022437
{
24032438
algorithm.Transactions.SetOrderProcessor(transactionHandler);
@@ -2705,6 +2740,21 @@ protected override void InitializeTransactionThread()
27052740
}
27062741
}
27072742

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+
27082758
private class TestNonShortableProvider : IShortableProvider
27092759
{
27102760
public Dictionary<Symbol, long> AllShortableSymbols(DateTime localTime)

0 commit comments

Comments
 (0)