Lean  $LEAN_TAG$
Messages.QuantConnect.cs
1 /*
2  * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3  * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14 */
15 
16 using System;
17 using System.Collections.Generic;
18 using System.Runtime.CompilerServices;
19 
20 using Python.Runtime;
21 
23 
24 using static QuantConnect.StringExtensions;
25 
26 namespace QuantConnect
27 {
28  /// <summary>
29  /// Provides user-facing message construction methods and static messages for the <see cref="QuantConnect"/> namespace
30  /// </summary>
31  public static partial class Messages
32  {
33  /// <summary>
34  /// Provides user-facing messages for the <see cref="AlphaRuntimeStatistics"/> class and its consumers or related classes
35  /// </summary>
36  public static class AlphaRuntimeStatistics
37  {
38  /// <summary>
39  /// Returns a string message saying: Return Over Maximum Drawdown
40  /// </summary>
41  public static string ReturnOverMaximumDrawdownKey = "Return Over Maximum Drawdown";
42 
43  /// <summary>
44  /// Returns a string message saying: Portfolio Turnover
45  /// </summary>
46  public static string PortfolioTurnoverKey = "Portfolio Turnover";
47 
48  /// <summary>
49  /// Returns a string message saying: Total Insights Generated
50  /// </summary>
51  public static string TotalInsightsGeneratedKey = "Total Insights Generated";
52 
53  /// <summary>
54  /// Returns a string message saying: Total Insights Closed
55  /// </summary>
56  public static string TotalInsightsClosedKey = "Total Insights Closed";
57 
58  /// <summary>
59  /// Returns a string message saying: Total Insights Analysis Completed
60  /// </summary>
61  public static string TotalInsightsAnalysisCompletedKey = "Total Insights Analysis Completed";
62 
63  /// <summary>
64  /// Returns a string message saying: Long Insight Count
65  /// </summary>
66  public static string LongInsightCountKey = "Long Insight Count";
67 
68  /// <summary>
69  /// Returns a string message saying: Short Insight Count
70  /// </summary>
71  public static string ShortInsightCountKey = "Short Insight Count";
72 
73  /// <summary>
74  /// Returns a string message saying: Long/Short Ratio
75  /// </summary>
76  public static string LongShortRatioKey = "Long/Short Ratio";
77  }
78 
79  /// <summary>
80  /// Provides user-facing messages for the <see cref="QuantConnect.Chart"/> class and its consumers or related classes
81  /// </summary>
82  public static class Chart
83  {
84  /// <summary>
85  /// Returns a string message saying Chart series name already exists
86  /// </summary>
87  public static string ChartSeriesAlreadyExists = "Chart series name already exists";
88  }
89 
90  /// <summary>
91  /// Provides user-facing messages for the <see cref="QuantConnect.ChartPoint"/> class and its consumers or related classes
92  /// </summary>
93  public static class ChartPoint
94  {
95  /// <summary>
96  /// Parses a given ChartPoint object into a string message
97  /// </summary>
98  [MethodImpl(MethodImplOptions.AggressiveInlining)]
99  public static string ToString(QuantConnect.ChartPoint instance)
100  {
101  return Invariant($"{instance.Time:o} - {instance.y}");
102  }
103  }
104 
105  /// <summary>
106  /// Provides user-facing messages for the <see cref="QuantConnect.Candlestick"/> class and its consumers or related classes
107  /// </summary>
108  public static class Candlestick
109  {
110  /// <summary>
111  /// Parses a given Candlestick object into a string message
112  /// </summary>
113  [MethodImpl(MethodImplOptions.AggressiveInlining)]
114  public static string ToString(QuantConnect.Candlestick instance)
115  {
116  return Invariant($@"{instance.Time:o} - (O:{instance.Open} H: {instance.High} L: {
117  instance.Low} C: {instance.Close})");
118  }
119  }
120 
121  /// <summary>
122  /// Provides user-facing messages for the <see cref="QuantConnect.Currencies"/> class and its consumers or related classes
123  /// </summary>
124  public static class Currencies
125  {
126  /// <summary>
127  /// Returns a string message saying the given value cannot be converted to a decimal number
128  /// </summary>
129  [MethodImpl(MethodImplOptions.AggressiveInlining)]
130  public static string FailedConversionToDecimal(string value)
131  {
132  return $"The value {value} cannot be converted to a decimal number";
133  }
134  }
135 
136  /// <summary>
137  /// Provides user-facing messages for the <see cref="QuantConnect.ExtendedDictionary{T}"/> class and its consumers or related classes
138  /// </summary>
139  public static class ExtendedDictionary
140  {
141  /// <summary>
142  /// Returns a string message saying the types deriving from ExtendedDictionary must implement the void Clear() method
143  /// </summary>
144  public static string ClearMethodNotImplemented = "Types deriving from 'ExtendedDictionary' must implement the 'void Clear() method.";
145 
146  /// <summary>
147  /// Returns a string message saying the types deriving from ExtendedDictionary must implement the void Remove(Symbol) method
148  /// </summary>
149  public static string RemoveMethodNotImplemented =
150  "Types deriving from 'ExtendedDictionary' must implement the 'void Remove(Symbol) method.";
151 
152  /// <summary>
153  /// Returns a string message saying the types deriving from ExtendedDictionary must implement the T this[Symbol] method
154  /// </summary>
155  public static string IndexerBySymbolNotImplemented =
156  "Types deriving from 'ExtendedDictionary' must implement the 'T this[Symbol] method.";
157 
158  /// <summary>
159  /// Returns a string message saying Clear/clear method call is an invalid operation. It also says that the given instance
160  /// is a read-only collection
161  /// </summary>
162  [MethodImpl(MethodImplOptions.AggressiveInlining)]
163  public static string ClearInvalidOperation<T>(ExtendedDictionary<T> instance)
164  {
165  return $"Clear/clear method call is an invalid operation. {instance.GetType().Name} is a read-only collection.";
166  }
167 
168  /// <summary>
169  /// Returns a string message saying that Remove/pop call method is an invalid operation. It also says that the given instance
170  /// is a read-only collection
171  /// </summary>
172  [MethodImpl(MethodImplOptions.AggressiveInlining)]
173  public static string RemoveInvalidOperation<T>(ExtendedDictionary<T> instance)
174  {
175  return $"Remove/pop method call is an invalid operation. {instance.GetType().Name} is a read-only collection.";
176  }
177 
178  /// <summary>
179  /// Returns a string message saying that the given ticker was not found in the SymbolCache. It also gives a recommendation
180  /// for solving this problem
181  /// </summary>
182  [MethodImpl(MethodImplOptions.AggressiveInlining)]
183  public static string TickerNotFoundInSymbolCache(string ticker)
184  {
185  return $"The ticker {ticker} was not found in the SymbolCache. Use the Symbol object as key instead. " +
186  "Accessing the securities collection/slice object by string ticker is only available for securities added with " +
187  "the AddSecurity-family methods. For more details, please check out the documentation.";
188  }
189 
190  /// <summary>
191  /// Returns a string message saying that the popitem method is not supported for the given instance
192  /// </summary>
193  [MethodImpl(MethodImplOptions.AggressiveInlining)]
195  {
196  return $"popitem method is not supported for {instance.GetType().Name}";
197  }
198 
199  /// <summary>
200  /// Returns a string message saying that the given symbol wasn't found in the give instance object. It also shows
201  /// a recommendation for solving this problem
202  /// </summary>
203  [MethodImpl(MethodImplOptions.AggressiveInlining)]
205  {
206  return $"'{symbol}' wasn't found in the {instance.GetType().Name} object, likely because there was no-data at this moment in " +
207  "time and it wasn't possible to fillforward historical data. Please check the data exists before accessing it with " +
208  $"data.ContainsKey(\"{symbol}\"). The collection is read-only, cannot set default.";
209  }
210 
211  /// <summary>
212  /// Returns a string message saying the update method call is an invalid operation. It also mentions that the given
213  /// instance is a read-only collection
214  /// </summary>
215  [MethodImpl(MethodImplOptions.AggressiveInlining)]
216  public static string UpdateInvalidOperation<T>(ExtendedDictionary<T> instance)
217  {
218  return $"update method call is an invalid operation. {instance.GetType().Name} is a read-only collection.";
219  }
220  }
221 
222  /// <summary>
223  /// Provides user-facing messages for the <see cref="QuantConnect.Extensions"/> class and its consumers or related classes
224  /// </summary>
225  public static class Extensions
226  {
227  /// <summary>
228  /// Returns a string message saying adjusting a symbol by an offset is currently only supported for non canonical futures
229  /// </summary>
230  public static string ErrorAdjustingSymbolByOffset =
231  "Adjusting a symbol by an offset is currently only supported for non canonical futures";
232 
233  /// <summary>
234  /// Returns a string message saying the provided DataProvider instance is null
235  /// </summary>
236  public static string NullDataProvider =
237  $"The provided '{nameof(IDataProvider)}' instance is null. Are you missing some initialization step?";
238 
239  /// <summary>
240  /// Returns a string message saying the source cannot be null or empty
241  /// </summary>
242  public static string NullOrEmptySourceToConvertToHexString = "Source cannot be null or empty.";
243 
244  /// <summary>
245  /// Returns a string message saying the CreateOptionChain method requires an option symbol
246  /// </summary>
247  public static string CreateOptionChainRequiresOptionSymbol = "CreateOptionChain requires an option symbol.";
248 
249  /// <summary>
250  /// Returns a string message saying the CreateFutureChain method requires a future symbol
251  /// </summary>
252  public static string CreateFutureChainRequiresFutureSymbol = "CreateFutureChain requires a future symbol.";
253 
254  /// <summary>
255  /// Returns a string message saying the list of values cannot be empty
256  /// </summary>
257  public static string GreatestCommonDivisorEmptyList = "The list of values cannot be empty";
258 
259  /// <summary>
260  /// Returns a string message saying the process of downloading data from the given url failed
261  /// </summary>
262  [MethodImpl(MethodImplOptions.AggressiveInlining)]
263  public static string DownloadDataFailed(string url)
264  {
265  return $"failed for: '{url}'";
266  }
267 
268  /// <summary>
269  /// Returns a string message saying the security does not have an accurate price as it has not yet received
270  /// a bar of data, as well as some recommendations
271  /// </summary>
272  [MethodImpl(MethodImplOptions.AggressiveInlining)]
273  public static string ZeroPriceForSecurity(QuantConnect.Symbol symbol)
274  {
275  return $"{symbol}: The security does not have an accurate price as it has not yet received a bar of data. " +
276  "Before placing a trade (or using SetHoldings) warm up your algorithm with SetWarmup, or use slice.Contains(symbol) " +
277  "to confirm the Slice object has price before using the data. Data does not necessarily all arrive at the same " +
278  "time so your algorithm should confirm the data is ready before using it. In live trading this can mean you do " +
279  "not have an active subscription to the asset class you're trying to trade. If using custom data make sure you've " +
280  "set the 'Value' property.";
281  }
282 
283  /// <summary>
284  /// Returns a string message saying: Waiting for the given thread to stop
285  /// </summary>
286  [MethodImpl(MethodImplOptions.AggressiveInlining)]
287  public static string WaitingForThreadToStopSafely(string threadName)
288  {
289  return $"Waiting for '{threadName}' thread to stop...";
290  }
291 
292  /// <summary>
293  /// Returns a string message saying: Timeout waiting for the given thread to stop
294  /// </summary>
295  [MethodImpl(MethodImplOptions.AggressiveInlining)]
296  public static string TimeoutWaitingForThreadToStopSafely(string threadName)
297  {
298  return $"Timeout waiting for '{threadName}' thread to stop";
299  }
300 
301  /// <summary>
302  /// Returns a string message saying the given data type is missing a parameterless constructor
303  /// </summary>
304  [MethodImpl(MethodImplOptions.AggressiveInlining)]
305  public static string DataTypeMissingParameterlessConstructor(Type type)
306  {
307  return $"Data type '{type.Name}' missing parameterless constructor. E.g. public {type.Name}() {{ }}";
308  }
309 
310  /// <summary>
311  /// Returns a string message saying the process of creating an instance of the given type failed
312  /// </summary>
313  [MethodImpl(MethodImplOptions.AggressiveInlining)]
314  public static string FailedToCreateInstanceOfType(Type type)
315  {
316  return $"Failed to create instance of type '{type.Name}'";
317  }
318 
319  /// <summary>
320  /// Returns a string message saying the given data type does not inherit the required BaseData
321  /// methods and/or attributes
322  /// </summary>
323  [MethodImpl(MethodImplOptions.AggressiveInlining)]
324  public static string TypeIsNotBaseData(Type type)
325  {
326  return $"Data type '{type.Name}' does not inherit required {nameof(Data.BaseData)}";
327  }
328 
329  /// <summary>
330  /// Returns a string message saying it is impossible to cast the given non-finite floating-point value
331  /// as a decimal
332  /// </summary>
333  [MethodImpl(MethodImplOptions.AggressiveInlining)]
334  public static string CannotCastNonFiniteFloatingPointValueToDecimal(double input)
335  {
336  return Invariant($@"It is not possible to cast a non-finite floating-point value ({
337  input}) as decimal. Please review math operations and verify the result is valid.");
338  }
339 
340  /// <summary>
341  /// Returns a string message saying it was not able to exactly convert the given time span to resolution
342  /// </summary>
343  [MethodImpl(MethodImplOptions.AggressiveInlining)]
344  public static string UnableToConvertTimeSpanToResolution(TimeSpan timeSpan)
345  {
346  return Invariant($"Unable to exactly convert time span ('{timeSpan}') to resolution.");
347  }
348 
349  /// <summary>
350  /// Returns a string message saying it was attempted to parse the given unknown security type
351  /// </summary>
352  [MethodImpl(MethodImplOptions.AggressiveInlining)]
353  public static string UnableToParseUnknownSecurityType(string value)
354  {
355  return $"Attempted to parse unknown SecurityType: {value}";
356  }
357 
358  /// <summary>
359  /// Returns a string message saying the given security type has no default OptionStyle, because it has no options
360  /// available for it
361  /// </summary>
362  [MethodImpl(MethodImplOptions.AggressiveInlining)]
363  public static string NoDefaultOptionStyleForSecurityType(SecurityType securityType)
364  {
365  return Invariant($"The SecurityType {securityType} has no default OptionStyle, because it has no options available for it");
366  }
367 
368  /// <summary>
369  /// Returns a string message saying the given OptionStyle was unexpected/unknown
370  /// </summary>
371  [MethodImpl(MethodImplOptions.AggressiveInlining)]
372  public static string UnknownOptionStyle(string value)
373  {
374  return $"Unexpected OptionStyle: {value}";
375  }
376 
377  /// <summary>
378  /// Returns a string message saying the given OptionStyle was unexpected/unknown
379  /// </summary>
380  [MethodImpl(MethodImplOptions.AggressiveInlining)]
381  public static string UnknownOptionStyle(OptionStyle value)
382  {
383  return $"Unexpected OptionStyle: {value}";
384  }
385 
386  /// <summary>
387  /// Returns a string message saying the given OptionRight was unexpected/unknown
388  /// </summary>
389  [MethodImpl(MethodImplOptions.AggressiveInlining)]
390  public static string UnknownOptionRight(string value)
391  {
392  return $"Unexpected OptionRight: {value}";
393  }
394 
395  /// <summary>
396  /// Returns a string message saying the given OptionRight was unexpected/unknown
397  /// </summary>
398  [MethodImpl(MethodImplOptions.AggressiveInlining)]
399  public static string UnknownOptionRight(OptionRight value)
400  {
401  return $"Unexpected OptionRight: {value}";
402  }
403 
404  /// <summary>
405  /// Returns a string message saying the given DataMappingMode was unexpected/unknown
406  /// </summary>
407  [MethodImpl(MethodImplOptions.AggressiveInlining)]
408  public static string UnknownDataMappingMode(string value)
409  {
410  return $"Unexpected DataMappingMode: {value}";
411  }
412 
413  /// <summary>
414  /// Returns a string message saying the given method cannot be used to convert a PyObject into the given type
415  /// </summary>
416  [MethodImpl(MethodImplOptions.AggressiveInlining)]
417  public static string ConvertToDelegateCannotConverPyObjectToType(string methodName, Type type)
418  {
419  return $"{methodName} cannot be used to convert a PyObject into {type}.";
420  }
421 
422  /// <summary>
423  /// Returns a string message saying the method ConvertToDictionary cannot be used to convert a given source
424  /// type into another given target type. It also specifies the reason.
425  /// </summary>
426  [MethodImpl(MethodImplOptions.AggressiveInlining)]
427  public static string ConvertToDictionaryFailed(string sourceType, string targetType, string reason)
428  {
429  return $"ConvertToDictionary cannot be used to convert a {sourceType} into {targetType}. Reason: {reason}";
430  }
431 
432  /// <summary>
433  /// Returns a string message saying the given argument type should Symbol or a list of Symbol. It also
434  /// shows the given item as well as its Python type
435  /// </summary>
436  [MethodImpl(MethodImplOptions.AggressiveInlining)]
437  public static string ConvertToSymbolEnumerableFailed(PyObject item)
438  {
439  return $"Argument type should be Symbol or a list of Symbol. Object: {item}. Type: {item.GetPythonType()}";
440  }
441 
442  /// <summary>
443  /// Returns a string message saying the given object is not a C# type
444  /// </summary>
445  [MethodImpl(MethodImplOptions.AggressiveInlining)]
446  public static string ObjectFromPythonIsNotACSharpType(string objectRepr)
447  {
448  return $"{objectRepr} is not a C# Type.";
449  }
450 
451  /// <summary>
452  /// Returns a string message saying there was a RuntimeError at a given time in UTC. It also
453  /// shows the given context
454  /// </summary>
455  [MethodImpl(MethodImplOptions.AggressiveInlining)]
456  public static string RuntimeError(IAlgorithm algorithm, string context)
457  {
458  return Invariant($"RuntimeError at {algorithm.UtcTime} UTC. Context: {context}");
459  }
460  }
461 
462  /// <summary>
463  /// Provides user-facing messages for the <see cref="QuantConnect.Holding"/> class and its consumers or related classes
464  /// </summary>
465  public static class Holding
466  {
467  /// <summary>
468  /// Parses a Holding object into a string message
469  /// </summary>
470  [MethodImpl(MethodImplOptions.AggressiveInlining)]
471  public static string ToString(QuantConnect.Holding instance)
472  {
473  var currencySymbol = instance.CurrencySymbol;
474  if (string.IsNullOrEmpty(currencySymbol))
475  {
476  currencySymbol = "$";
477  }
478  var value = Invariant($@"{instance.Symbol?.Value}: {instance.Quantity} @ {
479  currencySymbol}{instance.AveragePrice} - Market: {currencySymbol}{instance.MarketPrice}");
480 
481  if (instance.ConversionRate.HasValue && instance.ConversionRate != 1m)
482  {
483  value += Invariant($" - Conversion: {instance.ConversionRate}");
484  }
485 
486  return value;
487  }
488  }
489 
490  /// <summary>
491  /// Provides user-facing messages for the <see cref="QuantConnect.AlgorithmControl"/> class and its consumers or related classes
492  /// </summary>
493  public static class AlgorithmControl
494  {
495  /// <summary>
496  /// Returns a string message saying: Strategy Equity
497  /// </summary>
498  public static string ChartSubscription = "Strategy Equity";
499  }
500 
501  /// <summary>
502  /// Provides user-facing messages for the <see cref="QuantConnect.Isolator"/> class and its consumers or related classes
503  /// </summary>
504  public static class Isolator
505  {
506  /// <summary>
507  /// Returns a string message saying: Execution Security Error: Memory Usage Maxed out, with the max memory capacity
508  /// and a last sample of the usage
509  /// </summary>
510  [MethodImpl(MethodImplOptions.AggressiveInlining)]
511  public static string MemoryUsageMaxedOut(string memoryCap, string lastSample)
512  {
513  return $"Execution Security Error: Memory Usage Maxed Out - {memoryCap}MB max, with last sample of {lastSample}MB.";
514  }
515 
516  /// <summary>
517  /// Returns a string message saying: Execution Security Error: Memory usage over 80% capacity, and the last sample taken
518  /// </summary>
519  [MethodImpl(MethodImplOptions.AggressiveInlining)]
520  public static string MemoryUsageOver80Percent(double lastSample)
521  {
522  return Invariant($"Execution Security Error: Memory usage over 80% capacity. Sampled at {lastSample}");
523  }
524 
525  /// <summary>
526  /// Returns a string message with useful information about the memory usage, such us the memory used, the last sample
527  /// the current memory used by the given app and the CPU usage
528  /// </summary>
529  [MethodImpl(MethodImplOptions.AggressiveInlining)]
530  public static string MemoryUsageInfo(string memoryUsed, string lastSample, string memoryUsedByApp, TimeSpan currentTimeStepElapsed,
531  int cpuUsage)
532  {
533  return Invariant($@"Used: {memoryUsed}, Sample: {lastSample}, App: {memoryUsedByApp}, CurrentTimeStepElapsed: {
534  currentTimeStepElapsed:mm':'ss'.'fff}. CPU: {cpuUsage}%");
535  }
536 
537  /// <summary>
538  /// Returns a string message saying: Execution Security Error: Operation timed out, with the maximum amount of minutes
539  /// allowed
540  /// </summary>
541  [MethodImpl(MethodImplOptions.AggressiveInlining)]
542  public static string MemoryUsageMonitorTaskTimedOut(TimeSpan timeout)
543  {
544  return $@"Execution Security Error: Operation timed out - {
545  timeout.TotalMinutes.ToStringInvariant()} minutes max. Check for recursive loops.";
546  }
547  }
548 
549  /// <summary>
550  /// Provides user-facing messages for the <see cref="QuantConnect.Market"/> class and its consumers or related classes
551  /// </summary>
552  public static class Market
553  {
554  /// <summary>
555  /// Returns a string message saying the market identifier is limited to positive values less than the given maximum market identifier
556  /// </summary>
557  [MethodImpl(MethodImplOptions.AggressiveInlining)]
558  public static string InvalidMarketIdentifier(int maxMarketIdentifier)
559  {
560  return $"The market identifier is limited to positive values less than {maxMarketIdentifier.ToStringInvariant()}.";
561  }
562 
563  /// <summary>
564  /// Returns a string message saying it was attempted to add an already added market with a different identifier
565  /// </summary>
566  [MethodImpl(MethodImplOptions.AggressiveInlining)]
567  public static string TriedToAddExistingMarketWithDifferentIdentifier(string market)
568  {
569  return $"Attempted to add an already added market with a different identifier. Market: {market}";
570  }
571 
572  /// <summary>
573  /// Returns a string message saying it was attempted to add a market identifier that is already in use
574  /// </summary>
575  /// <returns></returns>
576  [MethodImpl(MethodImplOptions.AggressiveInlining)]
577  public static string TriedToAddExistingMarketIdentifier(string market, string existingMarket)
578  {
579  return $"Attempted to add a market identifier that is already in use. New Market: {market} Existing Market: {existingMarket}";
580  }
581  }
582 
583  /// <summary>
584  /// Provides user-facing messages for the <see cref="QuantConnect.OS"/> class and its consumers or related classes
585  /// </summary>
586  public static class OS
587  {
588  /// <summary>
589  /// CPU Usage string
590  /// </summary>
591  public static string CPUUsageKey = "CPU Usage";
592 
593  /// <summary>
594  /// Used RAM (MB) string
595  /// </summary>
596  public static string UsedRAMKey = "Used RAM (MB)";
597 
598  /// <summary>
599  /// Total RAM (MB) string
600  /// </summary>
601  public static string TotalRAMKey = "Total RAM (MB)";
602 
603  /// <summary>
604  /// Hostname string
605  /// </summary>
606  public static string HostnameKey = "Hostname";
607 
608  /// <summary>
609  /// LEAN Version string
610  /// </summary>
611  public static string LEANVersionKey = "LEAN Version";
612  }
613 
614  /// <summary>
615  /// Provides user-facing messages for the <see cref="QuantConnect.Parse"/> class and its consumers or related classes
616  /// </summary>
617  public static class Parse
618  {
619  /// <summary>
620  /// Returns a string message saying the provided input was not parseable as the given target type
621  /// </summary>
622  [MethodImpl(MethodImplOptions.AggressiveInlining)]
623  public static string ValueIsNotParseable(string input, Type targetType)
624  {
625  return $"The provided value ({input}) was not parseable as {targetType.Name}";
626  }
627  }
628 
629  /// <summary>
630  /// Provides user-facing messages for the <see cref="QuantConnect.SecurityIdentifier"/> class and its consumers or related classes
631  /// </summary>
632  public static class SecurityIdentifier
633  {
634  /// <summary>
635  /// Returns a string message saying no underlying was specified for certain identifier
636  /// </summary>
637  public static string NoUnderlyingForIdentifier =
638  "No underlying specified for this identifier. Check that HasUnderlying is true before accessing the Underlying property.";
639 
640  /// <summary>
641  /// Returns a string message saying Date is only defined for SecurityType.Equity, SecurityType.Option, SecurityType.Future, SecurityType.FutureOption, SecurityType.IndexOption, and SecurityType.Base
642  /// </summary>
643  public static string DateNotSupportedBySecurityType =
644  "Date is only defined for SecurityType.Equity, SecurityType.Option, SecurityType.Future, SecurityType.FutureOption, SecurityType.IndexOption, and SecurityType.Base";
645 
646  /// <summary>
647  /// Returns a string message saying StrikePrice is only defined for SecurityType.Option, SecurityType.FutureOption, and SecurityType.IndexOption
648  /// </summary>
650  "StrikePrice is only defined for SecurityType.Option, SecurityType.FutureOption, and SecurityType.IndexOption";
651 
652  /// <summary>
653  /// Returns a string message saying OptionRight is only defined for SecurityType.Option, SecurityType.FutureOption, and SecurityType.IndexOption
654  /// </summary>
656  "OptionRight is only defined for SecurityType.Option, SecurityType.FutureOption, and SecurityType.IndexOption";
657 
658  /// <summary>
659  /// Returns a string message saying OptionStyle is only defined for SecurityType.Option, SecurityType.FutureOption, and SecurityType.IndexOption
660  /// </summary>
662  "OptionStyle is only defined for SecurityType.Option, SecurityType.FutureOption, and SecurityType.IndexOption";
663 
664  /// <summary>
665  /// Returns a string message saying SecurityIdentifier requires a non-null string 'symbol'
666  /// </summary>
667  public static string NullSymbol = "SecurityIdentifier requires a non-null string 'symbol'";
668 
669  /// <summary>
670  /// Returns a string message saying Symbol must not contain the characters '|' or ' '
671  /// </summary>
672  public static string SymbolWithInvalidCharacters = "Symbol must not contain the characters '|' or ' '.";
673 
674  /// <summary>
675  /// Returns a string message saying the provided properties do not match with a valid SecurityType
676  /// </summary>
677  public static string PropertiesDoNotMatchAnySecurityType = $"The provided properties do not match with a valid {nameof(SecurityType)}";
678 
679  /// <summary>
680  /// Returns a string message saying the string must be splittable on space into two parts
681  /// </summary>
682  public static string StringIsNotSplittable = "The string must be splittable on space into two parts.";
683 
684  /// <summary>
685  /// Returns a string message saying object must be of type SecurityIdentifier
686  /// </summary>
687  public static string UnexpectedTypeToCompareTo = $"Object must be of type {nameof(SecurityIdentifier)}";
688 
689  /// <summary>
690  /// Returns a string message saying the given parameter must be between 0 and 99
691  /// </summary>
692  [MethodImpl(MethodImplOptions.AggressiveInlining)]
693  public static string InvalidSecurityType(string parameterName)
694  {
695  return $"{parameterName} must be between 0 and 99";
696  }
697 
698  /// <summary>
699  /// Returns a string message saying the given parameter must be either 0 or 1
700  /// </summary>
701  [MethodImpl(MethodImplOptions.AggressiveInlining)]
702  public static string InvalidOptionRight(string parameterName)
703  {
704  return $"{parameterName} must be either 0 or 1";
705  }
706 
707  /// <summary>
708  /// Returns a string message saying the specified strike price's precision is too high
709  /// </summary>
710  [MethodImpl(MethodImplOptions.AggressiveInlining)]
711  public static string InvalidStrikePrice(decimal strikePrice)
712  {
713  return Invariant($"The specified strike price's precision is too high: {strikePrice}");
714  }
715 
716  /// <summary>
717  /// Returns a string message saying there was an error parsing SecurityIdentifier. It also says the given error and exception
718  /// </summary>
719  [MethodImpl(MethodImplOptions.AggressiveInlining)]
720  public static string ErrorParsingSecurityIdentifier(string value, Exception exception)
721  {
722  return Invariant($"Error parsing SecurityIdentifier: '{value}', Exception: {exception}");
723  }
724 
725  /// <summary>
726  /// Returns a string message saying the given market could not be found in the markets lookup
727  /// </summary>
728  [MethodImpl(MethodImplOptions.AggressiveInlining)]
729  public static string MarketNotFound(string market)
730  {
731  return $@"The specified market wasn't found in the markets lookup. Requested: {
732  market}. You can add markets by calling QuantConnect.Market.Add(string,int)";
733  }
734  }
735 
736  /// <summary>
737  /// Provides user-facing messages for the <see cref="QuantConnect.StringExtensions"/> class and its consumers or related classes
738  /// </summary>
739  public static class StringExtensions
740  {
741  /// <summary>
742  /// Returns a string message saying StringExtensinos.ConvertInvariant does not support converting to the given TypeCode
743  /// </summary>
744  [MethodImpl(MethodImplOptions.AggressiveInlining)]
745  public static string ConvertInvariantCannotConvertTo(TypeCode targetTypeCode)
746  {
747  return $"StringExtensions.ConvertInvariant does not support converting to TypeCode.{targetTypeCode}";
748  }
749  }
750 
751  /// <summary>
752  /// Provides user-facing messages for the <see cref="QuantConnect.Symbol"/> class and its consumers or related classes
753  /// </summary>
754  public static class Symbol
755  {
756  /// <summary>
757  /// Returns a string message saying there is insufficient information for creating certain future option symbol
758  /// </summary>
760  "Cannot create future option Symbol using this method (insufficient information). Use `CreateOption(Symbol, ...)` instead.";
761 
762  /// <summary>
763  /// Returns a string message saying Canonical is only defined for SecurityType.Option, SecurityType.Future, SecurityType.FutureOption
764  /// </summary>
765  public static string CanonicalNotDefined =
766  "Canonical is only defined for SecurityType.Option, SecurityType.Future, SecurityType.FutureOption";
767 
768  /// <summary>
769  /// Returns a string message saying certain object must be of type Symbol or string
770  /// </summary>
771  public static string UnexpectedObjectTypeToCompareTo = "Object must be of type Symbol or string.";
772 
773  /// <summary>
774  /// Returns a string message saying the given security type has not been implemented yet
775  /// </summary>
776  [MethodImpl(MethodImplOptions.AggressiveInlining)]
777  public static string SecurityTypeNotImplementedYet(SecurityType securityType)
778  {
779  return Invariant($"The security type has not been implemented yet: {securityType}");
780  }
781 
782  /// <summary>
783  /// Returns a string message saying the given security can not be mapped
784  /// </summary>
785  [MethodImpl(MethodImplOptions.AggressiveInlining)]
786  public static string SecurityTypeCannotBeMapped(SecurityType securityType)
787  {
788  return Invariant($"SecurityType {securityType} can not be mapped.");
789  }
790 
791  /// <summary>
792  /// Returns a string message saying no option type exists for the given underlying SecurityType
793  /// </summary>
794  [MethodImpl(MethodImplOptions.AggressiveInlining)]
795  public static string NoOptionTypeForUnderlying(SecurityType securityType)
796  {
797  return Invariant($"No option type exists for underlying SecurityType: {securityType}");
798  }
799 
800  /// <summary>
801  /// Returns a string message saying no underlying type exists for the given option SecurityType
802  /// </summary>
803  [MethodImpl(MethodImplOptions.AggressiveInlining)]
804  public static string NoUnderlyingForOption(SecurityType securityType)
805  {
806  return Invariant($"No underlying type exists for option SecurityType: {securityType}");
807  }
808 
809  [MethodImpl(MethodImplOptions.AggressiveInlining)]
810  public static string SidNotForOption(QuantConnect.SecurityIdentifier sid)
811  {
812  return Invariant($"The provided SecurityIdentifier is not for an option: {sid}");
813  }
814 
815  [MethodImpl(MethodImplOptions.AggressiveInlining)]
816  public static string UnderlyingSidDoesNotMatch(QuantConnect.SecurityIdentifier sid, QuantConnect.Symbol underlying)
817  {
818  return Invariant($"The provided SecurityIdentifier does not match the underlying symbol: {sid} != {underlying.ID}");
819  }
820  }
821 
822  /// <summary>
823  /// Provides user-facing messages for the <see cref="QuantConnect.SymbolCache"/> class and its consumers or related classes
824  /// </summary>
825  public static class SymbolCache
826  {
827  /// <summary>
828  /// Returns a string message saying the given ticker could not be localized
829  /// </summary>
830  [MethodImpl(MethodImplOptions.AggressiveInlining)]
831  public static string UnableToLocateTicker(string ticker)
832  {
833  return $"We were unable to locate the ticker '{ticker}'.";
834  }
835 
836  /// <summary>
837  /// Returns a string message saying mutiple potentially matching tickers were localized
838  /// </summary>
839  [MethodImpl(MethodImplOptions.AggressiveInlining)]
840  public static string MultipleMatchingTickersLocated(IEnumerable<string> tickers)
841  {
842  return "We located multiple potentially matching tickers. " +
843  "For custom data, be sure to append a dot followed by the custom data type name. " +
844  $"For example: 'BTC.Bitcoin'. Potential Matches: {string.Join(", ", tickers)}";
845  }
846  }
847 
848  /// <summary>
849  /// Provides user-facing messages for the <see cref="QuantConnect.SymbolRepresentation"/> class and its consumers or related classes
850  /// </summary>
851  public static class SymbolRepresentation
852  {
853  /// <summary>
854  /// Returns a string message saying SymbolRepresentation failed to get market for the given ticker and underlying
855  /// </summary>
856  [MethodImpl(MethodImplOptions.AggressiveInlining)]
857  public static string FailedToGetMarketForTickerAndUnderlying(string ticker, string underlying)
858  {
859  return $"Failed to get market for future '{ticker}' and underlying '{underlying}'";
860  }
861 
862  /// <summary>
863  /// Returns a string message saying no market was found for the given ticker
864  /// </summary>
865  [MethodImpl(MethodImplOptions.AggressiveInlining)]
866  public static string NoMarketFound(string ticker)
867  {
868  return $"No market found for '{ticker}'";
869  }
870 
871  /// <summary>
872  /// Returns a string message saying an unexpected security type was received by the given method name
873  /// </summary>
874  [MethodImpl(MethodImplOptions.AggressiveInlining)]
875  public static string UnexpectedSecurityTypeForMethod(string methodName, SecurityType securityType)
876  {
877  return Invariant($"{methodName} expects symbol to be an option, received {securityType}.");
878  }
879 
880  /// <summary>
881  /// Returns a string message saying the given ticker is not in the expected OSI format
882  /// </summary>
883  [MethodImpl(MethodImplOptions.AggressiveInlining)]
884  public static string InvalidOSITickerFormat(string ticker)
885  {
886  return $"Invalid ticker format {ticker}";
887  }
888 
889  /// <summary>
890  /// Returns a string message saying the given security type is not implemented
891  /// </summary>
892  [MethodImpl(MethodImplOptions.AggressiveInlining)]
893  public static string SecurityTypeNotImplemented(SecurityType securityType)
894  {
895  return Invariant($"Security type {securityType} not implemented");
896  }
897  }
898 
899  /// <summary>
900  /// Provides user-facing messages for the <see cref="QuantConnect.SymbolValueJsonConverter"/> class and its consumers or related classes
901  /// </summary>
902  public static class SymbolValueJsonConverter
903  {
904  /// <summary>
905  /// String message saying converter is write only
906  /// </summary>
907  public static string ConverterIsWriteOnly = "The SymbolValueJsonConverter is write-only.";
908 
909  /// <summary>
910  /// String message saying converter is intended to be directly decorated in member
911  /// </summary>
913  "The SymbolValueJsonConverter is intended to be decorated on the appropriate member directly.";
914  }
915 
916  /// <summary>
917  /// Provides user-facing messages for the <see cref="QuantConnect.Time"/> class and its consumers or related classes
918  /// </summary>
919  public static class Time
920  {
921  /// <summary>
922  /// Invalid Bar Size string message
923  /// </summary>
924  public static string InvalidBarSize = "barSize must be greater than TimeSpan.Zero";
925 
926  /// <summary>
927  /// Returns a string message containing the number of securities
928  /// </summary>
929  [MethodImpl(MethodImplOptions.AggressiveInlining)]
930  public static string SecurityCount(int count)
931  {
932  return $"Security Count: {count}";
933  }
934  }
935 
936  /// <summary>
937  /// Provides user-facing messages for the <see cref="QuantConnect.TradingCalendar"/> class and its consumers or related classes
938  /// </summary>
939  public static class TradingCalendar
940  {
941  /// <summary>
942  /// Returns a string message for invalid total days
943  /// </summary>
944  [MethodImpl(MethodImplOptions.AggressiveInlining)]
945  public static string InvalidTotalDays(int totalDays)
946  {
947  return Invariant($@"Total days is negative ({
948  totalDays
949  }), indicating reverse start and end times. Check your usage of TradingCalendar to ensure proper arrangement of variables");
950  }
951  }
952  }
953 }