diff --git a/Algorithm/QCAlgorithm.History.cs b/Algorithm/QCAlgorithm.History.cs index 41caa59528cc..077b4cbda32f 100644 --- a/Algorithm/QCAlgorithm.History.cs +++ b/Algorithm/QCAlgorithm.History.cs @@ -1474,7 +1474,7 @@ private void SetWarmup(int? barCount, TimeSpan? timeSpan, Resolution? resolution { if (_locked) { - throw new InvalidOperationException("QCAlgorithm.SetWarmup(): This method cannot be used after algorithm initialized"); + throw new InvalidOperationException(Messages.QCAlgorithm.SetWarmupAlreadyInitialized()); } _warmupTimeSpan = timeSpan; diff --git a/Algorithm/QCAlgorithm.cs b/Algorithm/QCAlgorithm.cs index 28ae1f6e0802..28f1c352f359 100644 --- a/Algorithm/QCAlgorithm.cs +++ b/Algorithm/QCAlgorithm.cs @@ -1315,7 +1315,7 @@ public void SetTimeZone(DateTimeZone timeZone) { if (_locked) { - throw new InvalidOperationException("Algorithm.SetTimeZone(): Cannot change time zone after algorithm running."); + throw new InvalidOperationException(Messages.QCAlgorithm.SetTimeZoneAlreadyRunning()); } if (timeZone == null) throw new ArgumentNullException(nameof(timeZone)); @@ -1450,7 +1450,7 @@ public void SetBenchmark(SecurityType securityType, string symbol) { if (_locked) { - throw new InvalidOperationException("Algorithm.SetBenchmark(): Cannot change Benchmark after algorithm initialized."); + throw new InvalidOperationException(Messages.QCAlgorithm.SetBenchmarkAlreadyInitialized()); } var market = GetMarket(null, symbol, securityType, defaultMarket: Market.USA); @@ -1503,7 +1503,7 @@ public void SetBenchmark(Symbol symbol) { if (_locked) { - throw new InvalidOperationException("Algorithm.SetBenchmark(): Cannot change Benchmark after algorithm initialized."); + throw new InvalidOperationException(Messages.QCAlgorithm.SetBenchmarkAlreadyInitialized()); } // Create our security benchmark @@ -1522,7 +1522,7 @@ public void SetBenchmark(Func benchmark) { if (_locked) { - throw new InvalidOperationException("Algorithm.SetBenchmark(): Cannot change Benchmark after algorithm initialized."); + throw new InvalidOperationException(Messages.QCAlgorithm.SetBenchmarkAlreadyInitialized()); } Benchmark = new FuncBenchmark(benchmark); @@ -1599,8 +1599,7 @@ public void SetAccountCurrency(string accountCurrency, decimal? startingCash = n { if (_locked) { - throw new InvalidOperationException("Algorithm.SetAccountCurrency(): " + - "Cannot change AccountCurrency after algorithm initialized."); + throw new InvalidOperationException(Messages.QCAlgorithm.SetAccountCurrencyAlreadyInitialized()); } if (startingCash == null) @@ -1653,7 +1652,7 @@ public void SetCash(decimal startingCash) } else { - throw new InvalidOperationException("Algorithm.SetCash(): Cannot change cash available after algorithm initialized."); + throw new InvalidOperationException(Messages.QCAlgorithm.SetCashAlreadyInitialized()); } } @@ -1672,7 +1671,7 @@ public void SetCash(string symbol, decimal startingCash, decimal conversionRate } else { - throw new InvalidOperationException("Algorithm.SetCash(): Cannot change cash available after algorithm initialized."); + throw new InvalidOperationException(Messages.QCAlgorithm.SetCashAlreadyInitialized()); } } @@ -1778,7 +1777,7 @@ public void SetStartDate(DateTime start) } else { - throw new InvalidOperationException("Algorithm.SetStartDate(): Cannot change start date after algorithm initialized."); + throw new InvalidOperationException(Messages.QCAlgorithm.SetStartDateAlreadyInitialized()); } } @@ -1797,7 +1796,7 @@ public void SetEndDate(DateTime end) //1. Check not locked already: if (_locked) { - throw new InvalidOperationException("Algorithm.SetEndDate(): Cannot change end date after algorithm initialized."); + throw new InvalidOperationException(Messages.QCAlgorithm.SetEndDateAlreadyInitialized()); } //Validate: diff --git a/AlgorithmFactory/Python/Wrappers/AlgorithmPythonWrapper.cs b/AlgorithmFactory/Python/Wrappers/AlgorithmPythonWrapper.cs index 6af94c1b877b..5ca48bfb1dd8 100644 --- a/AlgorithmFactory/Python/Wrappers/AlgorithmPythonWrapper.cs +++ b/AlgorithmFactory/Python/Wrappers/AlgorithmPythonWrapper.cs @@ -177,6 +177,8 @@ public AlgorithmPythonWrapper(string moduleName) { throw new Exception("Please ensure that one class inherits from QCAlgorithm."); } + + Messages.SetAlgorithmLanguage(Language.Python); } } catch (Exception e) @@ -901,7 +903,7 @@ public void OnMarginCall(List requests) // If the method does not return or returns a non-iterable PyObject, throw an exception if (result == null || !result.IsIterable()) { - throw new Exception("OnMarginCall must return a non-empty list of SubmitOrderRequest"); + throw new Exception(Messages.AlgorithmPythonWrapper.OnMarginCallMustReturnNonEmptyList()); } requests.Clear(); @@ -919,7 +921,7 @@ public void OnMarginCall(List requests) // If the PyObject is an empty list or its items are not SubmitOrderRequest objects, throw an exception if (requests.Count == 0) { - throw new Exception("OnMarginCall must return a non-empty list of SubmitOrderRequest"); + throw new Exception(Messages.AlgorithmPythonWrapper.OnMarginCallMustReturnNonEmptyList()); } } } diff --git a/Common/Messages/Messages.Algorithm.Framework.Portfolio.cs b/Common/Messages/Messages.Algorithm.Framework.Portfolio.cs index 18e71e6036dd..6eb3f850ae16 100644 --- a/Common/Messages/Messages.Algorithm.Framework.Portfolio.cs +++ b/Common/Messages/Messages.Algorithm.Framework.Portfolio.cs @@ -39,8 +39,8 @@ public static class PortfolioTarget public static string InvalidTargetPercent(IAlgorithm algorithm, decimal percent) { return Invariant($@"The portfolio target percent: { - percent}, does not comply with the current 'Algorithm.Settings' 'MaxAbsolutePortfolioTargetPercentage': { - algorithm.Settings.MaxAbsolutePortfolioTargetPercentage} or 'MinAbsolutePortfolioTargetPercentage': { + percent}, does not comply with the current 'QCAlgorithm.{FormatCode("Settings")}' '{FormatCode("MaxAbsolutePortfolioTargetPercentage")}': { + algorithm.Settings.MaxAbsolutePortfolioTargetPercentage} or '{FormatCode("MinAbsolutePortfolioTargetPercentage")}': { algorithm.Settings.MinAbsolutePortfolioTargetPercentage}. Skipping"); } diff --git a/Common/Messages/Messages.Algorithm.cs b/Common/Messages/Messages.Algorithm.cs new file mode 100644 index 000000000000..ef7f2d19613a --- /dev/null +++ b/Common/Messages/Messages.Algorithm.cs @@ -0,0 +1,110 @@ +/* + * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. + * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +using System.Runtime.CompilerServices; + +namespace QuantConnect +{ + /// + /// Provides user-facing message construction methods and static messages for the namespace + /// + public static partial class Messages + { + /// + /// Provides user-facing messages for the class and its consumers or related classes + /// + public static class QCAlgorithm + { + /// + /// Returns a string message saying the time zone cannot be changed after the algorithm is running + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string SetTimeZoneAlreadyRunning() + { + return $"QCAlgorithm.{FormatCode("SetTimeZone")}(): Cannot change time zone after algorithm running."; + } + + /// + /// Returns a string message saying the benchmark cannot be changed after the algorithm is initialized + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string SetBenchmarkAlreadyInitialized() + { + return $"QCAlgorithm.{FormatCode("SetBenchmark")}(): Cannot change Benchmark after algorithm initialized."; + } + + /// + /// Returns a string message saying the account currency cannot be changed after the algorithm is initialized + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string SetAccountCurrencyAlreadyInitialized() + { + return $"QCAlgorithm.{FormatCode("SetAccountCurrency")}(): Cannot change AccountCurrency after algorithm initialized."; + } + + /// + /// Returns a string message saying the cash cannot be changed after the algorithm is initialized + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string SetCashAlreadyInitialized() + { + return $"QCAlgorithm.{FormatCode("SetCash")}(): Cannot change cash available after algorithm initialized."; + } + + /// + /// Returns a string message saying the start date cannot be changed after the algorithm is initialized + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string SetStartDateAlreadyInitialized() + { + return $"QCAlgorithm.{FormatCode("SetStartDate")}(): Cannot change start date after algorithm initialized."; + } + + /// + /// Returns a string message saying the end date cannot be changed after the algorithm is initialized + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string SetEndDateAlreadyInitialized() + { + return $"QCAlgorithm.{FormatCode("SetEndDate")}(): Cannot change end date after algorithm initialized."; + } + + /// + /// Returns a string message saying SetWarmup cannot be used after the algorithm is initialized + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string SetWarmupAlreadyInitialized() + { + return $"QCAlgorithm.{FormatCode("SetWarmup")}(): This method cannot be used after algorithm initialized"; + } + } + + /// + /// Provides user-facing messages for the class + /// and its consumers or related classes + /// + public static class AlgorithmPythonWrapper + { + /// + /// Returns a string message saying OnMarginCall must return a non-empty list of SubmitOrderRequest + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string OnMarginCallMustReturnNonEmptyList() + { + return $"{FormatCode("OnMarginCall")} must return a non-empty list of SubmitOrderRequest"; + } + } + } +} diff --git a/Common/Messages/Messages.Brokerages.cs b/Common/Messages/Messages.Brokerages.cs index b1095cacbef5..5e7c58618950 100644 --- a/Common/Messages/Messages.Brokerages.cs +++ b/Common/Messages/Messages.Brokerages.cs @@ -411,7 +411,7 @@ public static class FxcmBrokerageModel [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string InvalidOrderQuantityForLotSize(Securities.Security security) { - return Invariant($"The order quantity must be a multiple of LotSize: [{security.SymbolProperties.LotSize}]."); + return Invariant($"The order quantity must be a multiple of {FormatCode("LotSize")}: [{security.SymbolProperties.LotSize}]."); } /// diff --git a/Common/Messages/Messages.Orders.cs b/Common/Messages/Messages.Orders.cs index 47033d5192eb..749d51416bd3 100644 --- a/Common/Messages/Messages.Orders.cs +++ b/Common/Messages/Messages.Orders.cs @@ -354,7 +354,7 @@ public static string ZeroQuantity(Orders.OrderRequest request) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string MissingSecurity(Orders.SubmitOrderRequest request) { - return Invariant($"You haven't requested {request.Symbol} data. Add this with AddSecurity() in the Initialize() Method."); + return Invariant($"You haven't requested {request.Symbol} data. Add this with {FormatCode("AddSecurity")}() in the {FormatCode("Initialize")}() method."); } /// @@ -365,8 +365,8 @@ public static string MissingSecurity(Orders.SubmitOrderRequest request) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string WarmingUp(Orders.OrderRequest request) { - return Invariant($@"This operation is not allowed in Initialize or during warm up: OrderRequest.{ - request.OrderRequestType}. Please move this code to the OnWarmupFinished() method."); + return Invariant($@"This operation is not allowed in {FormatCode("Initialize")} or during warm up: OrderRequest.{ + FormatCode(request.OrderRequestType)}. Please move this code to the {FormatCode("OnWarmupFinished")}() method."); } } diff --git a/Common/Messages/Messages.QuantConnect.cs b/Common/Messages/Messages.QuantConnect.cs index 9dec38803b95..7965c1bdac9f 100644 --- a/Common/Messages/Messages.QuantConnect.cs +++ b/Common/Messages/Messages.QuantConnect.cs @@ -15,6 +15,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Runtime.CompilerServices; using Python.Runtime; @@ -30,6 +31,34 @@ namespace QuantConnect /// public static partial class Messages { + private static Language _algorithmLanguage = Language.CSharp; + + /// + /// Sets the algorithm language used to format code identifiers in error messages. + /// + public static void SetAlgorithmLanguage(Language language) + { + _algorithmLanguage = language; + } + + /// + /// Returns the code identifier formatted for the current algorithm language. + /// For Python, converts PascalCase/camelCase to snake_case. + /// + private static string FormatCode(string code) + { + return _algorithmLanguage switch + { + Language.Python => code.ToSnakeCase(), + _ => code + }; + } + + private static string FormatCode(T value) where T : Enum + { + return string.Join(", ", value.ToString().Split(", ").Select(FormatCode)); + } + /// /// Provides user-facing messages for the class and its consumers or related classes /// @@ -113,8 +142,7 @@ public static class Candlestick [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string ToString(QuantConnect.Candlestick instance) { - return Invariant($@"{instance.Time:o} - (O:{instance.Open} H: {instance.High} L: { - instance.Low} C: {instance.Close})"); + return Invariant($@"{instance.Time:o} - (O:{instance.Open} H: {instance.High} L: {instance.Low} C: {instance.Close})"); } } @@ -183,8 +211,8 @@ public static string RemoveInvalidOperation(ExtendedDictionary @@ -278,7 +306,7 @@ public static string DownloadDataFailed(string url) public static string ZeroPriceForSecurity(QuantConnect.Symbol symbol) { return $"{symbol}: The security does not have an accurate price as it has not yet received a bar of data. " + - "Before placing a trade (or using SetHoldings) warm up your algorithm with SetWarmup, or use slice.Contains(symbol) " + + $"Before placing a trade (or using {FormatCode("SetHoldings")}) warm up your algorithm with {FormatCode("SetWarmup")}, or use slice.{FormatCode("Contains")}(symbol) " + "to confirm the Slice object has price before using the data. Data does not necessarily all arrive at the same " + "time so your algorithm should confirm the data is ready before using it. In live trading this can mean you do " + "not have an active subscription to the asset class you're trying to trade. If using custom data make sure you've " + @@ -338,8 +366,7 @@ public static string TypeIsNotBaseData(Type type) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string CannotCastNonFiniteFloatingPointValueToDecimal(double input) { - return Invariant($@"It is not possible to cast a non-finite floating-point value ({ - input}) as decimal. Please review math operations and verify the result is valid."); + return Invariant($@"It is not possible to cast a non-finite floating-point value ({input}) as decimal. Please review math operations and verify the result is valid."); } /// @@ -471,8 +498,7 @@ public static string ToString(QuantConnect.Holding instance) { currencySymbol = "$"; } - var value = Invariant($@"{instance.Symbol?.Value}: {instance.Quantity} @ { - currencySymbol}{instance.AveragePrice} - Market: {currencySymbol}{instance.MarketPrice}"); + var value = Invariant($@"{instance.Symbol?.Value}: {instance.Quantity} @ {currencySymbol}{instance.AveragePrice} - Market: {currencySymbol}{instance.MarketPrice}"); if (instance.ConversionRate.HasValue && instance.ConversionRate != 1m) { @@ -526,8 +552,7 @@ public static string MemoryUsageOver80Percent(double lastSample) public static string MemoryUsageInfo(string memoryUsed, string lastSample, string memoryUsedByApp, TimeSpan currentTimeStepElapsed, int cpuUsage) { - return Invariant($@"Used: {memoryUsed}, Sample: {lastSample}, App: {memoryUsedByApp}, CurrentTimeStepElapsed: { - currentTimeStepElapsed:mm':'ss'.'fff}. CPU: {cpuUsage}%"); + return Invariant($@"Used: {memoryUsed}, Sample: {lastSample}, App: {memoryUsedByApp}, CurrentTimeStepElapsed: {currentTimeStepElapsed:mm':'ss'.'fff}. CPU: {cpuUsage}%"); } /// @@ -537,8 +562,7 @@ public static string MemoryUsageInfo(string memoryUsed, string lastSample, strin [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string MemoryUsageMonitorTaskTimedOut(TimeSpan timeout) { - return $@"Execution Security Error: Operation timed out - { - timeout.TotalMinutes.ToStringInvariant()} minutes max. Check for recursive loops."; + return $@"Execution Security Error: Operation timed out - {timeout.TotalMinutes.ToStringInvariant()} minutes max. Check for recursive loops."; } } @@ -724,8 +748,7 @@ public static string ErrorParsingSecurityIdentifier(string value, Exception exce [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string MarketNotFound(string market) { - return $@"The specified market wasn't found in the markets lookup. Requested: { - market}. You can add markets by calling QuantConnect.Market.Add(string,int)"; + return $@"The specified market wasn't found in the markets lookup. Requested: {market}. You can add markets by calling QuantConnect.Market.{FormatCode("Add")}(string,int)"; } } @@ -940,9 +963,7 @@ public static class TradingCalendar [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string InvalidTotalDays(int totalDays) { - return Invariant($@"Total days is negative ({ - totalDays - }), indicating reverse start and end times. Check your usage of TradingCalendar to ensure proper arrangement of variables"); + return Invariant($@"Total days is negative ({totalDays}), indicating reverse start and end times. Check your usage of TradingCalendar to ensure proper arrangement of variables"); } } } diff --git a/Common/Messages/Messages.Securities.cs b/Common/Messages/Messages.Securities.cs index 79542d7dd204..f262d186f502 100644 --- a/Common/Messages/Messages.Securities.cs +++ b/Common/Messages/Messages.Securities.cs @@ -110,7 +110,7 @@ public static string TargetOrderMarginNotAboveMinimum(decimal absDifferenceOfMar public static string TargetOrderMarginNotAboveMinimum() { return "Warning: Portfolio rebalance result ignored as it resulted in a single share trade recommendation which can generate high fees." + - " To disable minimum order size checks please set Settings.MinimumOrderMarginPortfolioPercentage = 0."; + $" To disable minimum order size checks please set {FormatCode("Settings")}.{FormatCode("MinimumOrderMarginPortfolioPercentage")} = 0."; } /// @@ -886,15 +886,21 @@ public static class SecurityPortfolioManager /// Returns a string message saying the AccountCurrency cannot be changed after adding a Security and that the method /// SetAccountCurrency() should be moved before AddSecurity() /// - public static string CannotChangeAccountCurrencyAfterAddingSecurity = - "Cannot change AccountCurrency after adding a Security. Please move SetAccountCurrency() before AddSecurity()."; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string CannotChangeAccountCurrencyAfterAddingSecurity() + { + return $"Cannot change AccountCurrency after adding a Security. Please move {FormatCode("SetAccountCurrency")}() before {FormatCode("AddSecurity")}()."; + } /// /// Returns a string message saying the AccountCurrency cannot be changed after setting cash and that the method /// SetAccountCurrency() should be moved before SetCash() /// - public static string CannotChangeAccountCurrencyAfterSettingCash = - "Cannot change AccountCurrency after setting cash. Please move SetAccountCurrency() before SetCash()."; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string CannotChangeAccountCurrencyAfterSettingCash() + { + return $"Cannot change AccountCurrency after setting cash. Please move {FormatCode("SetAccountCurrency")}() before {FormatCode("SetCash")}()."; + } /// /// Returns a string message saying the AccountCurrency has already been set and that the new value for this property @@ -958,8 +964,11 @@ public static class SecurityTransactionManager /// /// Returns a string message saying CancelOpenOrders operation is not allowed in Initialize or during warm up /// - public static string CancelOpenOrdersNotAllowedOnInitializeOrWarmUp = - "This operation is not allowed in Initialize or during warm up: CancelOpenOrders. Please move this code to the OnWarmupFinished() method."; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string CancelOpenOrdersNotAllowedOnInitializeOrWarmUp() + { + return $"This operation is not allowed in {FormatCode("Initialize")} or during warm up: {FormatCode("CancelOpenOrders")}. Please move this code to the {FormatCode("OnWarmupFinished")}() method."; + } /// /// Returns a string message saying the order was canceled by the CancelOpenOrders() at the given time @@ -997,17 +1006,29 @@ public static class SymbolProperties /// /// String message saying the SymbolProperties LotSize can not be less than or equal to 0 /// - public static string InvalidLotSize = "SymbolProperties LotSize can not be less than or equal to 0"; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string InvalidLotSize() + { + return $"{FormatCode("SymbolProperties")} {FormatCode("LotSize")} can not be less than or equal to 0"; + } /// /// String message saying the SymbolProperties PriceMagnifier can not be less than or equal to 0 /// - public static string InvalidPriceMagnifier = "SymbolProprties PriceMagnifier can not be less than or equal to 0"; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string InvalidPriceMagnifier() + { + return $"{FormatCode("SymbolProperties")} {FormatCode("PriceMagnifier")} can not be less than or equal to 0"; + } /// /// String message saying the SymbolProperties StrikeMultiplier can not be less than or equal to 0 /// - public static string InvalidStrikeMultiplier = "SymbolProperties StrikeMultiplier can not be less than or equal to 0"; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string InvalidStrikeMultiplier() + { + return $"{FormatCode("SymbolProperties")} {FormatCode("StrikeMultiplier")} can not be less than or equal to 0"; + } /// /// Parses a given SymbolProperties object into a string message diff --git a/Common/Securities/SecurityPortfolioManager.cs b/Common/Securities/SecurityPortfolioManager.cs index 2cbd6fee5b19..cda52d0f5d4d 100644 --- a/Common/Securities/SecurityPortfolioManager.cs +++ b/Common/Securities/SecurityPortfolioManager.cs @@ -642,13 +642,13 @@ public void SetAccountCurrency(string accountCurrency, decimal? startingCash = n if (Securities.Count > 0) { throw new InvalidOperationException("SecurityPortfolioManager.SetAccountCurrency(): " + - Messages.SecurityPortfolioManager.CannotChangeAccountCurrencyAfterAddingSecurity); + Messages.SecurityPortfolioManager.CannotChangeAccountCurrencyAfterAddingSecurity()); } if (_setCashWasCalled) { throw new InvalidOperationException("SecurityPortfolioManager.SetAccountCurrency(): " + - Messages.SecurityPortfolioManager.CannotChangeAccountCurrencyAfterSettingCash); + Messages.SecurityPortfolioManager.CannotChangeAccountCurrencyAfterSettingCash()); } Log.Trace("SecurityPortfolioManager.SetAccountCurrency(): " + diff --git a/Common/Securities/SecurityTransactionManager.cs b/Common/Securities/SecurityTransactionManager.cs index 4917cd2048f9..6c19823fafc2 100644 --- a/Common/Securities/SecurityTransactionManager.cs +++ b/Common/Securities/SecurityTransactionManager.cs @@ -251,7 +251,7 @@ public List CancelOpenOrders() { if (_algorithm != null && _algorithm.IsWarmingUp) { - throw new InvalidOperationException(Messages.SecurityTransactionManager.CancelOpenOrdersNotAllowedOnInitializeOrWarmUp); + throw new InvalidOperationException(Messages.SecurityTransactionManager.CancelOpenOrdersNotAllowedOnInitializeOrWarmUp()); } var cancelledOrders = new List(); @@ -273,7 +273,7 @@ public List CancelOpenOrders(Symbol symbol, string tag = null) { if (_algorithm != null && _algorithm.IsWarmingUp) { - throw new InvalidOperationException(Messages.SecurityTransactionManager.CancelOpenOrdersNotAllowedOnInitializeOrWarmUp); + throw new InvalidOperationException(Messages.SecurityTransactionManager.CancelOpenOrdersNotAllowedOnInitializeOrWarmUp()); } var cancelledOrders = new List(); diff --git a/Common/Securities/SymbolProperties.cs b/Common/Securities/SymbolProperties.cs index 9c3db7e38b65..d17642b4f27a 100644 --- a/Common/Securities/SymbolProperties.cs +++ b/Common/Securities/SymbolProperties.cs @@ -171,7 +171,7 @@ public SymbolPropertiesHolder(string description, string quoteCurrency, decimal if (LotSize <= 0) { - throw new ArgumentException(Messages.SymbolProperties.InvalidLotSize); + throw new ArgumentException(Messages.SymbolProperties.InvalidLotSize()); } MarketTicker = marketTicker; @@ -180,13 +180,13 @@ public SymbolPropertiesHolder(string description, string quoteCurrency, decimal PriceMagnifier = priceMagnifier; if (PriceMagnifier <= 0) { - throw new ArgumentException(Messages.SymbolProperties.InvalidPriceMagnifier); + throw new ArgumentException(Messages.SymbolProperties.InvalidPriceMagnifier()); } StrikeMultiplier = strikeMultiplier; if (strikeMultiplier <= 0) { - throw new ArgumentException(Messages.SymbolProperties.InvalidStrikeMultiplier); + throw new ArgumentException(Messages.SymbolProperties.InvalidStrikeMultiplier()); } } } diff --git a/Tests/Common/Orders/OrderTicketTests.cs b/Tests/Common/Orders/OrderTicketTests.cs index 86a07f11486a..e15963cad5f0 100644 --- a/Tests/Common/Orders/OrderTicketTests.cs +++ b/Tests/Common/Orders/OrderTicketTests.cs @@ -26,10 +26,16 @@ public class OrderTicketTests { private DateTime _requestTime = new DateTime(2022, 08, 25, 15, 0, 0); + [TearDown] + public void TearDown() + { + Messages.SetAlgorithmLanguage(Language.CSharp); + } + [Test] public void TestInvalidUpdateOrderId() { - var updateFields = new UpdateOrderFields { Quantity = 99, Tag = "Pepe", StopPrice = 77 , LimitPrice = 55 }; + var updateFields = new UpdateOrderFields { Quantity = 99, Tag = "Pepe", StopPrice = 77, LimitPrice = 55 }; var updateRequest = new UpdateOrderRequest(_requestTime, 11, updateFields); var ticket = OrderTicket.InvalidUpdateOrderId(null, updateRequest); Assert.AreEqual(11, ticket.OrderId); @@ -101,6 +107,10 @@ public void TestInvalidWarmingUp() Assert.AreEqual(1000, ticket.SubmitRequest.Quantity); Assert.AreEqual("Pepe", ticket.SubmitRequest.Tag); Assert.AreEqual("This operation is not allowed in Initialize or during warm up: OrderRequest.Submit. Please move this code to the OnWarmupFinished() method.", ticket.SubmitRequest.Response.ErrorMessage); + // Verify Python snake_case formatting + Messages.SetAlgorithmLanguage(Language.Python); + var pythonResponse = OrderResponse.WarmingUp(orderRequest); + Assert.AreEqual("This operation is not allowed in initialize or during warm up: OrderRequest.submit. Please move this code to the on_warmup_finished() method.", pythonResponse.ErrorMessage); } [TestCase(8, 0, true, Description = "8 AM - valid submission")]