17 using System.Collections;
18 using System.Collections.Concurrent;
19 using System.Collections.Generic;
20 using System.Collections.Immutable;
21 using System.Globalization;
25 using System.Net.Http;
26 using System.Reflection;
27 using System.Reflection.Emit;
28 using System.Runtime.CompilerServices;
29 using System.Security.Cryptography;
31 using System.Text.RegularExpressions;
32 using System.Threading;
33 using System.Threading.Tasks;
34 using Newtonsoft.Json;
51 using Timer = System.Timers.Timer;
53 using NodaTime.TimeZones;
61 using Newtonsoft.Json.Linq;
70 private static readonly Regex LeanPathRegex =
new Regex(
"(?:\\S*?\\\\pythonnet\\\\)|(?:\\S*?\\\\Lean\\\\)|(?:\\S*?/Lean/)|(?:\\S*?/pythonnet/)", RegexOptions.Compiled);
71 private static readonly Dictionary<string, bool> _emptyDirectories =
new ();
72 private static readonly HashSet<string> InvalidSecurityTypes =
new HashSet<string>();
73 private static readonly Regex DateCheck =
new Regex(
@"\d{8}", RegexOptions.Compiled);
74 private static RecyclableMemoryStreamManager MemoryManager =
new RecyclableMemoryStreamManager();
75 private static readonly
int DataUpdatePeriod =
Config.
GetInt(
"downloader-data-update-period", 7);
77 private static readonly Dictionary<IntPtr, PythonActivator> PythonActivators
78 =
new Dictionary<IntPtr, PythonActivator>();
88 private static readonly ZoneLocalMappingResolver _mappingResolver = Resolvers.CreateMappingResolver(Resolvers.ReturnLater, Resolvers.ReturnStartOfIntervalAfter);
114 var jValue = jObject[name];
115 if (jValue !=
null && jValue.Type != JTokenType.Null)
117 result = jValue.Value<T>();
130 var fileName = Path.GetFileName(filepath);
132 return !DateCheck.IsMatch(fileName) && DateTime.Now - TimeSpan.FromDays(DataUpdatePeriod) >
File.GetLastWriteTime(filepath);
142 if (
string.IsNullOrEmpty(error))
146 return LeanPathRegex.Replace(error,
string.Empty);
157 lock (_emptyDirectories)
159 if(!_emptyDirectories.TryGetValue(directoryPath, out var result))
163 if (Directory.Exists(directoryPath))
167 result = !Directory.EnumerateFileSystemEntries(directoryPath).Any();
169 catch (Exception exception)
175 _emptyDirectories[directoryPath] = result;
178 Log.
Trace($
"Extensions.IsDirectoryEmpty(): directory '{directoryPath}' not found or empty");
198 var type = dataTypes.Single();
199 var baseInstance = type.GetBaseDataInstance();
200 baseInstance.Symbol = symbol;
217 List<string> result =
new();
220 result = JsonConvert.DeserializeObject<List<string>>(jsonArray);
222 catch(JsonReaderException)
224 result.Add(jsonArray);
236 public static string DownloadData(
this HttpClient client,
string url, Dictionary<string, string> headers =
null)
240 foreach (var kvp
in headers)
242 client.DefaultRequestHeaders.Add(kvp.Key, kvp.Value);
247 using (var response = client.GetAsync(url).Result)
249 using (var content = response.Content)
251 return content.ReadAsStringAsync().Result;
255 catch (WebException ex)
257 Log.
Error(ex, $
"DownloadData(): {Messages.Extensions.DownloadDataFailed(url)}");
267 public static string DownloadData(
this string url, Dictionary<string, string> headers =
null)
269 using var client =
new HttpClient();
270 return client.DownloadData(url, headers);
279 using (var wc =
new HttpClient())
283 return wc.GetByteArrayAsync(url).Result;
287 Log.
Error(ex, $
"DownloadByteArray(): {Messages.Extensions.DownloadDataFailed(url)}");
300 const decimal max = decimal.MaxValue / 100m;
301 if (value >= max)
return decimal.MaxValue;
310 [MethodImpl(MethodImplOptions.AggressiveInlining)]
313 return MemoryManager.GetStream(guid);
327 Serializer.Serialize(stream, ticks);
328 result = stream.ToArray();
344 baseData.ProtobufSerialize(stream);
345 result = stream.ToArray();
361 Serializer.SerializeWithLengthPrefix(stream, baseData as
Tick, PrefixStyle.Base128, 1);
364 Serializer.SerializeWithLengthPrefix(stream, baseData as
QuoteBar, PrefixStyle.Base128, 1);
367 Serializer.SerializeWithLengthPrefix(stream, baseData as
TradeBar, PrefixStyle.Base128, 1);
370 Serializer.SerializeWithLengthPrefix(stream, baseData as
BaseData, PrefixStyle.Base128, 1);
389 if (
string.IsNullOrEmpty(value))
394 if (value.Length == 1)
396 return value.ToLowerInvariant();
398 return char.ToLowerInvariant(value[0]) + value.Substring(1);
411 if (resultPackets.Count > 0)
414 resultPacket = resultPackets[0];
415 for (var i = 1; i < resultPackets.Count; i++)
417 var newerPacket = resultPackets[i];
420 if (newerPacket.Insights !=
null)
425 resultPacket.
Insights =
new List<Insight>();
427 resultPacket.
Insights.AddRange(newerPacket.Insights);
431 if (newerPacket.OrderEvents !=
null)
438 resultPacket.
OrderEvents.AddRange(newerPacket.OrderEvents);
442 if (newerPacket.Orders !=
null)
444 if (resultPacket.
Orders ==
null)
447 resultPacket.
Orders =
new List<Order>();
449 resultPacket.
Orders.AddRange(newerPacket.Orders);
453 resultPacket.
Orders = resultPacket.
Orders.GroupBy(order => order.Id)
454 .Select(ordersGroup => ordersGroup.Last()).ToList();
467 public static void StopSafely(
this Thread thread, TimeSpan timeout, CancellationTokenSource token =
null)
473 if (token !=
null && !token.IsCancellationRequested)
477 Log.
Trace($
"StopSafely(): {Messages.Extensions.WaitingForThreadToStopSafely(thread.Name)}");
479 if (!thread.Join(timeout))
481 Log.
Error($
"StopSafely(): {Messages.Extensions.TimeoutWaitingForThreadToStopSafely(thread.Name)}");
484 catch (Exception exception)
497 public static string GetHash(
this IDictionary<int, Order> orders)
499 var joinedOrders =
string.Join(
502 .OrderBy(pair => pair.Key)
506 var order = pair.Value;
507 order.Price = order.Price.SmartRounding();
508 var limit = order as LimitOrder;
511 limit.LimitPrice = limit.LimitPrice.SmartRounding();
514 if (stopLimit !=
null)
516 stopLimit.
LimitPrice = stopLimit.LimitPrice.SmartRounding();
517 stopLimit.StopPrice = stopLimit.StopPrice.SmartRounding();
520 if (trailingStop !=
null)
522 trailingStop.
TrailingAmount = trailingStop.TrailingAmount.SmartRounding();
525 if (stopMarket !=
null)
527 stopMarket.
StopPrice = stopMarket.StopPrice.SmartRounding();
530 if (limitIfTouched !=
null)
532 limitIfTouched.
LimitPrice = limitIfTouched.LimitPrice.SmartRounding();
533 limitIfTouched.TriggerPrice = limitIfTouched.TriggerPrice.SmartRounding();
535 return JsonConvert.SerializeObject(pair.Value, Formatting.None);
540 return joinedOrders.ToMD5();
551 IEnumerator<DateTime> dates =
null;
557 if (!dates.MoveNext())
566 if (timeUtc >= dates.Current)
568 if (!dates.MoveNext())
573 return dates.Current;
575 catch (InvalidOperationException)
588 return series.
Values.Count == 0;
597 return chart.
Series.Values.All(IsEmpty);
613 var snakeCasedNamed = name.ToSnakeCase();
614 if (snakeCasedNamed != name)
616 method = instance.GetPythonMethodWithChecks(snakeCasedNamed);
623 method = instance.GetAttr(name);
624 var pythonType = method.GetPythonType();
625 var isPythonDefined = pythonType.Repr().Equals(
"<class \'method\'>", StringComparison.Ordinal);
648 if (!instance.HasAttr(name))
653 return instance.GetPythonMethod(name);
665 public static dynamic
GetMethod(
this PyObject instance,
string name)
667 using var _ = Py.GIL();
668 return instance.GetPythonMethodWithChecks(name.ToSnakeCase()) ?? instance.GetAttr(name);
681 var pyArgCount = PyModule.FromString(Guid.NewGuid().ToString(),
682 "from inspect import signature\n" +
683 "def GetArgCount(method):\n" +
684 " return len(signature(method).parameters)\n"
685 ).GetAttr(
"GetArgCount").Invoke(method);
686 pyArgCount.TryConvert(out argCount);
704 this IEnumerable<IPortfolioTarget> targets,
706 bool targetIsDelta =
false)
713 return targets.Select(x =>
715 var security = algorithm.
Securities[x.Symbol];
720 ExistingQuantity = security.Holdings.Quantity
722 .Aggregate(0m, (d, t) => d + t.Quantity - t.QuantityFilled),
726 .Where(x => x.Security.HasData
727 && x.Security.IsTradable
728 && (targetIsDelta ? Math.Abs(x.TargetQuantity) : Math.Abs(x.TargetQuantity - x.ExistingQuantity))
729 >= x.Security.SymbolProperties.LotSize
733 OrderValue = Math.Abs((targetIsDelta ? x.TargetQuantity : (x.TargetQuantity - x.ExistingQuantity)) * x.Security.Price),
734 IsReducingPosition = x.ExistingQuantity != 0
735 && Math.Abs((targetIsDelta ? (x.TargetQuantity + x.ExistingQuantity) : x.TargetQuantity)) < Math.Abs(x.ExistingQuantity)
737 .OrderByDescending(x => x.IsReducingPosition)
738 .ThenByDescending(x => x.OrderValue)
739 .Select(x => x.PortfolioTarget);
751 if (objectActivator ==
null)
753 throw new ArgumentException(
Messages.
Extensions.DataTypeMissingParameterlessConstructor(type));
756 var instance = objectActivator.Invoke(
new object[] { type });
781 public static T GetAndDispose<T>(
this PyObject instance)
783 if (instance ==
null)
787 var returnInstance = instance.As<T>();
790 return returnInstance;
800 public static void Move<T>(
this List<T> list,
int oldIndex,
int newIndex)
802 var oItem = list[oldIndex];
803 list.RemoveAt(oldIndex);
804 if (newIndex > oldIndex) newIndex--;
805 list.Insert(newIndex, oItem);
815 var bytes =
new byte[str.Length *
sizeof(char)];
816 Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
827 using var memoryStream =
new MemoryStream();
828 stream.CopyTo(memoryStream);
829 return memoryStream.ToArray();
838 public static void Clear<T>(
this ConcurrentQueue<T> queue)
841 while (queue.TryDequeue(out item)) {
852 public static string GetString(
this byte[] bytes, Encoding encoding =
null)
854 if (encoding ==
null) encoding = Encoding.ASCII;
856 return encoding.GetString(bytes);
864 public static string ToMD5(
this string str)
866 var builder =
new StringBuilder(32);
867 using (var md5Hash = MD5.Create())
869 var data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(str));
870 for (var i = 0; i < 16; i++)
872 builder.Append(data[i].ToStringInvariant(
"x2"));
875 return builder.ToString();
885 var hash =
new StringBuilder(64);
886 using (var crypt = SHA256.Create())
888 var crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(data));
889 for (var i = 0; i < 32; i++)
891 hash.Append(crypto[i].ToStringInvariant(
"x2"));
894 return hash.ToString();
902 var stack =
new Stack<char>(15);
905 var value = data % 36;
907 ? (char)(value +
'0')
908 : (char)(value - 10 +
'A');
913 return new string(stack.ToArray());
923 for (var i = symbol.Length - 1; i > -1; i--)
928 var value = (uint)(c <= 57
932 result += baseValue * value;
946 if (
string.IsNullOrEmpty(text))
951 byte[] textBytes = Encoding.UTF8.GetBytes(text);
952 return Convert.ToBase64String(textBytes);
962 if (
string.IsNullOrEmpty(base64EncodedText))
964 return base64EncodedText;
967 byte[] base64EncodedBytes = Convert.FromBase64String(base64EncodedText);
968 return Encoding.UTF8.GetString(base64EncodedBytes);
981 var alreadyUpper =
true;
982 for (
int i = 0; i < data.Length && alreadyUpper; i++)
984 alreadyUpper =
char.IsUpper(data[i]);
986 return alreadyUpper ? data : data.ToUpperInvariant();
999 var alreadyLower =
true;
1000 for (
int i = 0; i < data.Length && alreadyLower; i++)
1002 alreadyLower =
char.IsLower(data[i]);
1004 return alreadyLower ? data : data.ToLowerInvariant();
1016 public static void AddOrUpdate<K, V>(
this ConcurrentDictionary<K, V> dictionary, K key, V value)
1018 dictionary.AddOrUpdate(key, value, (oldkey, oldvalue) => value);
1030 public static TValue AddOrUpdate<TKey, TValue>(
this ConcurrentDictionary<TKey, Lazy<TValue>> dictionary, TKey key, Func<TKey, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory)
1032 var result = dictionary.AddOrUpdate(key,
new Lazy<TValue>(() => addValueFactory(key)), (key2, old) =>
new Lazy<TValue>(() => updateValueFactory(key2, old.Value)));
1033 return result.Value;
1046 public static void Add<TKey, TElement, TCollection>(
this IDictionary<TKey, TCollection> dictionary, TKey key, TElement element)
1047 where TCollection : ICollection<TElement>,
new()
1050 if (!dictionary.TryGetValue(key, out list))
1052 list =
new TCollection();
1053 dictionary.Add(key, list);
1067 public static ImmutableDictionary<TKey, ImmutableHashSet<TElement>> Add<TKey, TElement>(
1068 this ImmutableDictionary<TKey, ImmutableHashSet<TElement>> dictionary,
1073 ImmutableHashSet<TElement>
set;
1074 if (!dictionary.TryGetValue(key, out
set))
1076 set = ImmutableHashSet<TElement>.Empty.Add(element);
1077 return dictionary.Add(key,
set);
1080 return dictionary.SetItem(key,
set.Add(element));
1092 public static ImmutableSortedDictionary<TKey, ImmutableHashSet<TElement>> Add<TKey, TElement>(
1093 this ImmutableSortedDictionary<TKey, ImmutableHashSet<TElement>> dictionary,
1098 ImmutableHashSet<TElement>
set;
1099 if (!dictionary.TryGetValue(key, out
set))
1101 set = ImmutableHashSet<TElement>.Empty.Add(element);
1102 return dictionary.Add(key,
set);
1105 return dictionary.SetItem(key,
set.Add(element));
1118 if (!dictionary.TryGetValue(key, out list))
1120 dictionary[key] = list =
new List<Tick>(1);
1133 if (d == 0)
return 0;
1134 var scale = (decimal)Math.Pow(10, Math.Floor(Math.Log10((
double) Math.Abs(d))) + 1);
1135 return scale * Math.Round(d / scale, digits);
1147 return number.ToStringInvariant();
1153 return (number - 5m).ToString(
"#,.##", CultureInfo.InvariantCulture) +
"K";
1156 if (number < 100000)
1158 return (number - 50m).ToString(
"#,.#", CultureInfo.InvariantCulture) +
"K";
1161 if (number < 1000000)
1163 return (number - 500m).ToString(
"#,.", CultureInfo.InvariantCulture) +
"K";
1166 if (number < 10000000)
1168 return (number - 5000m).ToString(
"#,,.##", CultureInfo.InvariantCulture) +
"M";
1171 if (number < 100000000)
1173 return (number - 50000m).ToString(
"#,,.#", CultureInfo.InvariantCulture) +
"M";
1176 if (number < 1000000000)
1178 return (number - 500000m).ToString(
"#,,.", CultureInfo.InvariantCulture) +
"M";
1181 return (number - 5000000m).ToString(
"#,,,.##", CultureInfo.InvariantCulture) +
"B";
1193 public static decimal
DiscretelyRoundBy(
this decimal value, decimal quanta, MidpointRounding mode = MidpointRounding.AwayFromZero)
1203 var multiplicand = Math.Round(value / quanta, mode);
1204 return quanta * multiplicand;
1215 if (value >= decimal.MaxValue / 1000
1216 || value <= decimal.MinValue / 1000
1222 return Math.Truncate(1000 * value) / 1000;
1231 if (!input.HasValue)
1235 return input.Value.SmartRounding();
1244 input = Normalize(input);
1249 return Math.Round(input, 4);
1253 return input.RoundToSignificantDigits(7).Normalize();
1262 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1265 if (input.IsNaNOrInfinity())
1267 throw new ArgumentException(
1270 new NotFiniteNumberException(input)
1274 if (input <= (
double) decimal.MinValue)
return decimal.MinValue;
1275 if (input >= (
double) decimal.MaxValue)
return decimal.MaxValue;
1276 return (decimal) input;
1290 return input / 1.000000000000000000000000000000000m;
1301 return Normalize(input).ToString(CultureInfo.InvariantCulture);
1311 return BitConverter.GetBytes(decimal.GetBits(input)[3])[2];
1325 var decimalPlaces = 0;
1326 var hasDecimals =
false;
1328 var length = str.Length;
1330 while (index < length &&
char.IsWhiteSpace(str[index]))
1335 var isNegative = index < length && str[index] ==
'-';
1341 while (index < length)
1343 var ch = str[index++];
1349 else if (
char.IsWhiteSpace(ch))
1355 value = value * 10 + (ch -
'0');
1360 var lo = (int)value;
1361 var mid = (int)(value >> 32);
1362 return new decimal(lo, mid, 0, isNegative, (
byte)(hasDecimals ? decimalPlaces : 0));
1375 var trimmed = str.Trim();
1376 var value = str.TrimEnd(
'%').ToDecimal();
1377 if (trimmed.EndsWith(
"%"))
1392 return decimal.Parse(str, NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture);
1404 for (var i = 0; i < str.Length; i++)
1409 value = value * 10 + (str[i] -
'0');
1423 for (var i = 0; i < str.Length; i++)
1428 value = value * 10 + (str[i] -
'0');
1439 if (baseDataType == typeof(
TradeBar) || baseDataType == typeof(
QuoteBar) || baseDataType == typeof(
Tick))
1444 var method = baseDataType.GetMethod(
"Reader",
1446 if (method !=
null && method.DeclaringType == baseDataType)
1459 public static List<string>
ToCsv(
this string str,
int size = 4)
1462 var csv =
new List<string>(size);
1463 for (
int i = 0; i < str.Length; i++)
1467 if (last != 0) last = last + 1;
1468 csv.Add(str.Substring(last, i - last));
1472 if (last != 0) last = last + 1;
1473 csv.Add(str.Substring(last));
1484 public static List<string>
ToCsvData(
this string str,
int size = 4,
char delimiter =
',')
1486 var csv =
new List<string>(size);
1490 var textDataField =
false;
1492 for (var i = 0; i < str.Length; i++)
1494 var current = str[i];
1497 textDataField = !textDataField;
1499 else if (!textDataField && current == delimiter)
1501 csv.Add(str.Substring(last + 1, (i - last)).Trim(
' ',
','));
1509 csv.Add(str.Substring(last + 1).Trim());
1519 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1522 return double.IsNaN(value) ||
double.IsInfinity(value);
1529 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1532 return double.IsNaN(value) || Math.Abs(value) <
double.Epsilon;
1541 return new decimal(1, 0, 0,
false, 27);
1550 var ext = str.Substring(Math.Max(0, str.Length - 4));
1551 var allowedExt =
new List<string> {
".zip",
".csv",
".json",
".tsv" };
1552 if (!allowedExt.Contains(ext))
1566 var stream =
new MemoryStream();
1567 var writer =
new StreamWriter(stream);
1570 stream.Position = 0;
1581 public static TimeSpan
Round(
this TimeSpan time, TimeSpan roundingInterval, MidpointRounding roundingType)
1583 if (roundingInterval == TimeSpan.Zero)
1589 return new TimeSpan(
1590 Convert.ToInt64(Math.Round(
1591 time.Ticks / (decimal)roundingInterval.Ticks,
1593 )) * roundingInterval.Ticks
1604 public static TimeSpan
Round(
this TimeSpan time, TimeSpan roundingInterval)
1606 return Round(time, roundingInterval, MidpointRounding.ToEven);
1619 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1620 public static DateTime
RoundDown(
this DateTime dateTime, TimeSpan interval)
1622 if (interval == TimeSpan.Zero)
1628 var amount = dateTime.Ticks % interval.Ticks;
1631 return dateTime.AddTicks(-amount);
1644 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1645 public static DateTime
RoundDownInTimeZone(
this DateTime dateTime, TimeSpan roundingInterval, DateTimeZone sourceTimeZone, DateTimeZone roundingTimeZone)
1647 var dateTimeInRoundingTimeZone = dateTime.ConvertTo(sourceTimeZone, roundingTimeZone);
1648 var roundedDateTimeInRoundingTimeZone = dateTimeInRoundingTimeZone.RoundDown(roundingInterval);
1649 return roundedDateTimeInRoundingTimeZone.ConvertTo(roundingTimeZone, sourceTimeZone);
1664 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1668 if (interval == TimeSpan.Zero)
return dateTime;
1670 var rounded = dateTime.RoundDown(interval);
1671 while (!exchangeHours.
IsOpen(rounded, rounded + interval, extendedMarketHours))
1673 rounded -= interval;
1689 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1693 if (interval == TimeSpan.Zero)
return dateTime;
1695 var dateTimeInRoundingTimeZone = dateTime.ConvertTo(exchangeHours.
TimeZone, roundingTimeZone);
1696 var roundedDateTimeInRoundingTimeZone = dateTimeInRoundingTimeZone.RoundDown(interval);
1697 var rounded = roundedDateTimeInRoundingTimeZone.ConvertTo(roundingTimeZone, exchangeHours.
TimeZone);
1699 while (!exchangeHours.
IsOpen(rounded, rounded + interval, extendedMarketHours))
1706 dateTimeInRoundingTimeZone -= interval;
1707 roundedDateTimeInRoundingTimeZone = dateTimeInRoundingTimeZone.RoundDown(interval);
1708 rounded = roundedDateTimeInRoundingTimeZone.ConvertTo(roundingTimeZone, exchangeHours.
TimeZone);
1736 var time = utcTime.ConvertFromUtc(exchangeHours.TimeZone);
1738 return exchangeHours.
IsOpen(time, extendedMarketHours);
1747 public static DateTime
Round(
this DateTime datetime, TimeSpan roundingInterval)
1749 return new DateTime((datetime - DateTime.MinValue).Round(roundingInterval).Ticks);
1762 public static DateTime
RoundUp(
this DateTime time, TimeSpan interval)
1764 if (interval == TimeSpan.Zero)
1770 return new DateTime(((time.Ticks + interval.Ticks - 1) / interval.Ticks) * interval.Ticks);
1781 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1782 public static DateTime
ConvertTo(
this DateTime time, DateTimeZone from, DateTimeZone to,
bool strict =
false)
1786 return from.AtStrictly(LocalDateTime.FromDateTime(time)).WithZone(to).ToDateTimeUnspecified();
1790 return LocalDateTime.FromDateTime(time)
1791 .InZone(from, _mappingResolver)
1793 .ToDateTimeUnspecified();
1803 public static DateTime
ConvertFromUtc(
this DateTime time, DateTimeZone to,
bool strict =
false)
1815 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1816 public static DateTime
ConvertToUtc(
this DateTime time, DateTimeZone from,
bool strict =
false)
1820 return from.AtStrictly(LocalDateTime.FromDateTime(time)).ToDateTimeUtc();
1824 return LocalDateTime.FromDateTime(time)
1825 .InZone(from, _mappingResolver)
1836 return (date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday);
1843 public static void Reset(
this Timer timer)
1858 if (type.AssemblyQualifiedName == typeName)
1862 if (type.FullName == typeName)
1866 if (type.Name == typeName)
1882 while (type !=
null && type != typeof(
object))
1885 if (type.IsGenericType && possibleSuperType.IsGenericTypeDefinition)
1887 cur = type.GetGenericTypeDefinition();
1893 if (possibleSuperType == cur)
1897 type = type.BaseType;
1910 string name = type.Name;
1911 if (type.IsGenericType)
1913 var genericArguments = type.GetGenericArguments();
1914 var toBeReplaced =
"`" + (genericArguments.Length);
1915 name = name.Replace(toBeReplaced, $
"<{string.Join(",
", genericArguments.Select(x => x.GetBetterTypeName()))}>");
1925 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1932 return TimeSpan.Zero;
1942 throw new ArgumentOutOfRangeException(nameof(resolution));
1956 if (requireExactMatch)
1958 if (TimeSpan.Zero == timeSpan)
return Resolution.Tick;
1963 throw new InvalidOperationException(
Messages.
Extensions.UnableToConvertTimeSpanToResolution(timeSpan));
1987 if (Enum.TryParse(value, ignoreCase, out securityType))
1992 if (InvalidSecurityTypes.Add(value))
1994 Log.
Error($
"Extensions.TryParseSecurityType(): {Messages.Extensions.UnableToParseUnknownSecurityType(value)}");
2007 public static T ConvertTo<T>(
this string value)
2009 return (T) value.ConvertTo(typeof (T));
2018 public static object ConvertTo(
this string value, Type type)
2022 return Enum.Parse(type, value,
true);
2025 if (typeof (IConvertible).IsAssignableFrom(type))
2027 return Convert.ChangeType(value, type, CultureInfo.InvariantCulture);
2031 var parse = type.GetMethod(
"Parse",
new[] {typeof (
string)});
2034 var result = parse.Invoke(
null,
new object[] {value});
2038 return JsonConvert.DeserializeObject(value, type);
2049 public static bool WaitOne(
this WaitHandle waitHandle, CancellationToken cancellationToken)
2051 return waitHandle.WaitOne(Timeout.Infinite, cancellationToken);
2067 public static bool WaitOne(
this WaitHandle waitHandle, TimeSpan timeout, CancellationToken cancellationToken)
2069 return waitHandle.WaitOne((
int) timeout.TotalMilliseconds, cancellationToken);
2086 public static bool WaitOne(
this WaitHandle waitHandle,
int millisecondsTimeout, CancellationToken cancellationToken)
2088 return WaitHandle.WaitAny(
new[] { waitHandle, cancellationToken.WaitHandle }, millisecondsTimeout) == 0;
2098 using (var md5 = MD5.Create())
2100 return md5.ComputeHash(stream);
2111 var regx =
new Regex(
"http(s)?://([\\w+?\\.\\w+])+([a-zA-Z0-9\\~\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)_\\-\\=\\+\\\\\\/\\?\\.\\:\\;\\'\\,]*([a-zA-Z0-9\\?\\#\\=\\/]){1})?", RegexOptions.IgnoreCase);
2112 var matches = regx.Matches(source);
2113 foreach (Match match
in matches)
2115 source = source.Replace(match.Value, $
"<a href=\'{match.Value}\' target=\'blank\'>{match.Value}</a>");
2129 var startIndex = 1 + value.IndexOf(left);
2130 var length = value.IndexOf(right, startIndex) - startIndex;
2133 value = value.Substring(startIndex, length);
2134 startIndex = 1 + value.IndexOf(left);
2135 return value.Substring(startIndex).Trim();
2137 return string.Empty;
2149 if (names.Count == 1) {
return names.Single(); }
2154 var searchName = algorithmTypeName.Contains(
".") ? algorithmTypeName :
"." + algorithmTypeName;
2155 return names.SingleOrDefault(x => x.EndsWith(searchName));
2165 return @
enum.ToString().ToLowerInvariant();
2176 switch (securityType)
2207 switch (securityType)
2227 switch (securityType)
2247 if (!securityType.HasOptions() && !securityType.IsOption())
2249 throw new ArgumentException(
Messages.
Extensions.NoDefaultOptionStyleForSecurityType(securityType));
2252 switch (securityType)
2271 switch (optionStyle.LazyToLower())
2290 switch (optionRight.LazyToLower())
2309 switch (optionRight)
2317 return optionRight.ToString();
2329 switch (optionRight)
2348 switch (optionStyle)
2367 if (
string.IsNullOrEmpty(dataMappingMode))
2371 switch (dataMappingMode.LazyToLower())
2374 case "lasttradingday":
2377 case "firstdaymonth":
2380 case "openinterest":
2383 case "openinterestannual":
2386 throw new ArgumentException(
Messages.
Extensions.UnknownDataMappingMode(dataMappingMode));
2398 switch (securityType)
2407 return "futureoption";
2409 return "indexoption";
2423 return "cryptofuture";
2426 return securityType.ToLower();
2445 return "openinterest";
2448 return tickType.ToLower();
2474 return resolution.ToLower();
2486 var limitPrice = 0m;
2488 var triggerPrice = 0m;
2489 var trailingAmount = 0m;
2490 var trailingAsPercentage =
false;
2505 limitPrice = stopLimitOrder.LimitPrice;
2509 stopPrice = trailingStopOrder.
StopPrice;
2510 trailingAmount = trailingStopOrder.TrailingAmount;
2511 trailingAsPercentage = trailingStopOrder.TrailingAsPercentage;
2516 limitPrice = limitIfTouched.LimitPrice;
2523 limitPrice = order.
Price;
2524 stopPrice = order.
Price;
2534 throw new ArgumentOutOfRangeException();
2545 trailingAsPercentage,
2551 submitOrderRequest.SetOrderId(order.
Id);
2552 var orderTicket =
new OrderTicket(transactionManager, submitOrderRequest);
2553 orderTicket.SetOrder(order);
2563 public static void ProcessUntilEmpty<T>(
this IProducerConsumerCollection<T> collection, Action<T> handler)
2566 while (collection.TryTake(out item))
2584 if (pyObject.HasAttr(
"to_string"))
2586 var pyValue = pyObject.InvokeMethod(
"to_string");
2587 value = Environment.NewLine + pyValue;
2592 value = pyObject.ToString();
2593 if (
string.IsNullOrWhiteSpace(value))
2595 var pythonType = pyObject.GetPythonType();
2596 if (pythonType.GetType() == typeof(PyObject))
2598 value = pythonType.ToString();
2602 var type = pythonType.As<Type>();
2603 value = pyObject.AsManagedObject(type).ToString();
2605 pythonType.Dispose();
2624 public static bool TryConvert<T>(
this PyObject pyObject, out T result,
bool allowPythonDerivative =
false)
2626 result =
default(T);
2627 var type = typeof(T);
2629 if (pyObject ==
null)
2641 if (allowPythonDerivative)
2643 result = (T)pyObject.AsManagedObject(type);
2648 if (typeof(Type).IsAssignableFrom(type))
2650 result = (T)pyObject.AsManagedObject(type);
2652 if(!pyObject.HasAttr(
"__name__"))
2657 var castedResult = (Type)pyObject.AsManagedObject(type);
2658 var pythonName = pyObject.GetAttr(
"__name__").GetAndDispose<
string>();
2659 return pythonName == castedResult.Name;
2663 if (typeof(IEnumerable).IsAssignableFrom(type))
2665 result = (T)pyObject.AsManagedObject(type);
2669 var pythonType = pyObject.GetPythonType();
2670 var csharpType = pythonType.As<Type>();
2672 if (!type.IsAssignableFrom(csharpType))
2674 pythonType.Dispose();
2678 result = (T)pyObject.AsManagedObject(type);
2683 if (result is IPythonDerivedType)
2685 pythonType.Dispose();
2692 var name = (((dynamic) pythonType).__name__ as PyObject).GetAndDispose<string>();
2693 pythonType.Dispose();
2694 return name == result.GetType().Name;
2713 public static bool TryConvertToDelegate<T>(
this PyObject pyObject, out T result)
2715 var type = typeof(T);
2717 if (!typeof(MulticastDelegate).IsAssignableFrom(type))
2719 throw new ArgumentException(
Messages.
Extensions.ConvertToDelegateCannotConverPyObjectToType(
"TryConvertToDelegate", type));
2722 result =
default(T);
2724 if (pyObject ==
null)
2729 var code =
string.Empty;
2730 var types = type.GetGenericArguments();
2734 var locals =
new PyDict();
2737 for (var i = 0; i < types.Length; i++)
2739 var iString = i.ToStringInvariant();
2740 code += $
",t{iString}";
2741 locals.SetItem($
"t{iString}", types[i].ToPython());
2744 locals.SetItem(
"pyObject", pyObject);
2746 var name = type.FullName.Substring(0, type.FullName.IndexOf(
'`'));
2747 code = $
"import System; delegate = {name}[{code.Substring(1)}](pyObject)";
2749 PythonEngine.Exec(code,
null, locals);
2750 result = (T)locals.GetItem(
"delegate").AsManagedObject(typeof(T));
2776 if (typeToConvertTo ==
null)
2778 typeToConvertTo = pyObject.GetPythonType().AsManagedObject(typeof(Type)) as Type;
2781 return pyObject.AsManagedObject(typeToConvertTo);
2790 public static Func<IEnumerable<T>, IEnumerable<Symbol>> ConvertPythonUniverseFilterFunction<T>(
this PyObject universeFilterFunc) where T :
BaseData
2792 Func<IEnumerable<T>,
object> convertedFunc;
2793 Func<IEnumerable<T>, IEnumerable<Symbol>> filterFunc =
null;
2795 if (universeFilterFunc !=
null && universeFilterFunc.TryConvertToDelegate(out convertedFunc))
2797 filterFunc = convertedFunc.ConvertToUniverseSelectionSymbolDelegate();
2810 public static Func<IEnumerable<T>, IEnumerable<Symbol>> ConvertToUniverseSelectionSymbolDelegate<T>(
this Func<IEnumerable<T>,
object> selector) where T :
BaseData
2812 if (selector ==
null)
2814 return (dataPoints) => dataPoints.Select(x => x.Symbol);
2816 return selector.ConvertSelectionSymbolDelegate();
2826 public static Func<T, IEnumerable<Symbol>> ConvertSelectionSymbolDelegate<T>(
this Func<T, object> selector)
2830 var result = selector(data);
2833 : ((
object[])result).Select(x =>
2835 if (x is
Symbol castedSymbol)
2837 return castedSymbol;
2851 public static Func<T, IEnumerable<string>> ConvertToUniverseSelectionStringDelegate<T>(
this Func<T, object> selector)
2855 var result = selector(data);
2867 public static T ConvertToDelegate<T>(
this PyObject pyObject)
2870 if (pyObject.TryConvertToDelegate(out result))
2876 throw new ArgumentException(
Messages.
Extensions.ConvertToDelegateCannotConverPyObjectToType(
"ConvertToDelegate", typeof(T)));
2887 public static Dictionary<TKey, TValue> ConvertToDictionary<TKey, TValue>(
this PyObject pyObject)
2889 var result =
new List<KeyValuePair<TKey, TValue>>();
2892 var inputType = pyObject.GetPythonType().ToString();
2893 var targetType = nameof(PyDict);
2897 using (var pyDict =
new PyDict(pyObject))
2899 targetType = $
"{typeof(TKey).Name}: {typeof(TValue).Name}";
2901 foreach (PyObject item
in pyDict.Items())
2903 inputType = $
"{item[0].GetPythonType()}: {item[1].GetPythonType()}";
2905 var key = item[0].As<TKey>();
2906 var value = item[1].As<TValue>();
2908 result.Add(
new KeyValuePair<TKey, TValue>(key, value));
2914 throw new ArgumentException(
Messages.
Extensions.ConvertToDictionaryFailed(inputType, targetType, e.Message), e);
2918 return result.ToDictionary();
2930 if (!PyList.IsListType(pyObject))
2932 pyObject =
new PyList(
new[] {pyObject});
2935 using var iterator = pyObject.GetIterator();
2936 foreach (PyObject item
in iterator)
2938 if (PyString.IsStringType(item))
2947 symbol = item.GetAndDispose<
Symbol>();
2951 throw new ArgumentException(
Messages.
Extensions.ConvertToSymbolEnumerableFailed(item), e);
2954 yield
return symbol;
2965 public static PyList
ToPyList(
this IEnumerable enumerable)
2969 return enumerable.ToPyListUnSafe();
2981 var pyList =
new PyList();
2982 foreach (var item
in enumerable)
2984 using (var pyObject = item.ToPython())
2986 pyList.Append(pyObject);
3002 if (pyObject.TryConvert(out type))
3004 return value.ToStringInvariant().ConvertTo(type).ToString();
3010 throw new ArgumentException($
"GetEnumString(): {Messages.Extensions.ObjectFromPythonIsNotACSharpType(pyObject.Repr())}");
3023 if (pyObject.TryConvert(out type))
3029 if (!PythonActivators.TryGetValue(pyObject.Handle, out var pythonType))
3035 if (pyObject.ToString().StartsWith(
"<class '", StringComparison.InvariantCulture))
3037 type = CreateType(pyObject);
3042 type = pythonType.Type;
3055 if (pyObject.TryConvert(out type))
3061 if (!PythonActivators.TryGetValue(pyObject.Handle, out pythonType))
3063 var assemblyName = pyObject.GetAssemblyName();
3064 var typeBuilder = AssemblyBuilder
3065 .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run)
3066 .DefineDynamicModule(
"MainModule")
3068 .DefineType(assemblyName.Name, TypeAttributes.Class | TypeAttributes.Public, type);
3075 PythonActivators.Add(pyObject.Handle, pythonType);
3077 return pythonType.Type;
3089 return new AssemblyName(pyObject.Repr().Split(
'\'')[1]);
3100 public static IEnumerable<List<T>> BatchBy<T>(
this IEnumerable<T> enumerable,
int batchSize)
3102 using (var enumerator = enumerable.GetEnumerator())
3104 List<T> list =
null;
3105 while (enumerator.MoveNext())
3109 list =
new List<T> {enumerator.Current};
3111 else if (list.Count < batchSize)
3113 list.Add(enumerator.Current);
3118 list =
new List<T> {enumerator.Current};
3122 if (list?.Count > 0)
3135 public static TResult SynchronouslyAwaitTaskResult<TResult>(
this Task<TResult> task)
3137 return task.ConfigureAwait(
false).GetAwaiter().GetResult();
3147 task.ConfigureAwait(
false).GetAwaiter().GetResult();
3155 public static T SynchronouslyAwaitTask<T>(
this Task<T> task)
3157 return task.ConfigureAwait(
false).GetAwaiter().GetResult();
3167 return string.Join(
"&", pairs.Select(pair => $
"{pair.Key}={pair.Value}"));
3178 if (s.EndsWith(ending, StringComparison.InvariantCulture))
3180 return s.Substring(0, s.Length - ending.Length);
3196 if (!
string.IsNullOrEmpty(s) && !
string.IsNullOrEmpty(start) && s.StartsWith(start, StringComparison.InvariantCulture))
3198 return s.Substring(start.Length);
3250 public static bool IsCustomDataType<T>(
this Symbol symbol)
3254 && type.Equals(typeof(T).Name, StringComparison.InvariantCultureIgnoreCase);
3267 throw new InvalidOperationException(
Messages.
Extensions.ErrorAdjustingSymbolByOffset);
3270 var expiration = symbol.
ID.
Date;
3271 for (var i = 0; i < offset; i++)
3274 DateTime newExpiration;
3276 var monthOffset = 0;
3280 newExpiration = expiryFunction(expiration.AddMonths(monthOffset)).Date;
3281 }
while (newExpiration <= expiration);
3283 expiration = newExpiration;
3295 if (dataConfig.
Symbol.TryGetLiveSubscriptionSymbol(out var mappedSymbol))
3307 EventHandler newDataAvailableHandler,
3308 Func<SubscriptionDataConfig, bool> isExpired,
3311 subscribedConfig = dataConfig;
3312 if (dataConfig.
Symbol.TryGetLiveSubscriptionSymbol(out var mappedSymbol))
3318 IEnumerator<BaseData> result =
null;
3319 if (!isExpired(subscribedConfig))
3321 result = dataQueueHandler.
Subscribe(subscribedConfig, newDataAvailableHandler);
3325 Log.
Trace($
"SubscribeWithMapping(): skip live subscription for expired asset {subscribedConfig}");
3327 return result ?? Enumerable.Empty<
BaseData>().GetEnumerator();
3338 if(dataProvider ==
null)
3342 var stream = dataProvider.
Fetch(file);
3348 using (var streamReader =
new StreamReader(stream))
3353 line = streamReader.ReadLine();
3359 while (line !=
null);
3373 public static BaseData Scale(
this BaseData data, Func<decimal, decimal, decimal, decimal> factorFunc, decimal volumeFactor, decimal factor, decimal sumOfDividends)
3379 if (tradeBar !=
null)
3381 tradeBar.
Open = factorFunc(tradeBar.Open, factor, sumOfDividends);
3382 tradeBar.High = factorFunc(tradeBar.High, factor, sumOfDividends);
3383 tradeBar.Low = factorFunc(tradeBar.Low, factor, sumOfDividends);
3384 tradeBar.Close = factorFunc(tradeBar.Close, factor, sumOfDividends);
3385 tradeBar.Volume = Math.Round(tradeBar.Volume * volumeFactor);
3392 !securityType.IsOption())
3397 var tick = data as
Tick;
3398 if (tick ==
null || tick.TickType ==
TickType.OpenInterest)
3403 if (tick.TickType ==
TickType.Trade)
3405 tick.
Value = factorFunc(tick.Value, factor, sumOfDividends);
3406 tick.Quantity = Math.Round(tick.Quantity * volumeFactor);
3410 tick.BidPrice = tick.BidPrice != 0 ? factorFunc(tick.BidPrice, factor, sumOfDividends) : 0;
3411 tick.BidSize = Math.Round(tick.BidSize * volumeFactor);
3412 tick.AskPrice = tick.AskPrice != 0 ? factorFunc(tick.AskPrice, factor, sumOfDividends) : 0;
3413 tick.AskSize = Math.Round(tick.AskSize * volumeFactor);
3415 if (tick.BidPrice == 0)
3417 tick.Value = tick.AskPrice;
3420 if (tick.AskPrice == 0)
3422 tick.Value = tick.BidPrice;
3426 tick.Value = (tick.BidPrice + tick.AskPrice) / 2m;
3430 if (quoteBar !=
null)
3432 if (quoteBar.Ask !=
null)
3434 quoteBar.
Ask.
Open = factorFunc(quoteBar.Ask.Open, factor, sumOfDividends);
3435 quoteBar.Ask.High = factorFunc(quoteBar.Ask.High, factor, sumOfDividends);
3436 quoteBar.Ask.Low = factorFunc(quoteBar.Ask.Low, factor, sumOfDividends);
3437 quoteBar.Ask.Close = factorFunc(quoteBar.Ask.Close, factor, sumOfDividends);
3439 if (quoteBar.Bid !=
null)
3441 quoteBar.Bid.Open = factorFunc(quoteBar.Bid.Open, factor, sumOfDividends);
3442 quoteBar.Bid.High = factorFunc(quoteBar.Bid.High, factor, sumOfDividends);
3443 quoteBar.Bid.Low = factorFunc(quoteBar.Bid.Low, factor, sumOfDividends);
3444 quoteBar.Bid.Close = factorFunc(quoteBar.Bid.Close, factor, sumOfDividends);
3446 quoteBar.Value = quoteBar.Close;
3447 quoteBar.LastAskSize = Math.Round(quoteBar.LastAskSize * volumeFactor);
3448 quoteBar.LastBidSize = Math.Round(quoteBar.LastBidSize * volumeFactor);
3457 throw new ArgumentOutOfRangeException();
3472 switch (normalizationMode)
3477 return data?.Scale(TimesFactor, 1 / factor, factor, decimal.Zero);
3479 return data.Scale(TimesFactor, 1 / factor, factor, sumOfDividends);
3482 return data.Scale(TimesFactor, 1, factor, decimal.Zero);
3484 return data.Scale(AdditionFactor, 1, factor, decimal.Zero);
3486 return data.Scale(AdditionFactor, 1, factor, decimal.Zero);
3497 [MethodImpl(MethodImplOptions.AggressiveInlining)]
3498 private static decimal TimesFactor(decimal target, decimal factor, decimal sumOfDividends)
3500 return target * factor + sumOfDividends;
3506 [MethodImpl(MethodImplOptions.AggressiveInlining)]
3507 private static decimal AdditionFactor(decimal target, decimal factor, decimal _)
3509 return target + factor;
3519 var priceScaleFrontier = data.
Time;
3528 priceScaleFrontier = data.
EndTime;
3530 return priceScaleFrontier;
3532 return DateTime.MinValue;
3539 public static IOrderedEnumerable<KeyValuePair<TSource, TKey>> OrderBySafe<TSource, TKey>(
3540 this ConcurrentDictionary<TSource, TKey> source, Func<KeyValuePair<TSource, TKey>, TSource> keySelector
3543 return source.SafeEnumeration().OrderBy(keySelector);
3550 public static IOrderedEnumerable<KeyValuePair<TSource, TKey>> OrderBySafe<TSource, TKey>(
3551 this ConcurrentDictionary<TSource, TKey> source, Func<KeyValuePair<TSource, TKey>, TKey> keySelector
3554 return source.SafeEnumeration().OrderBy(keySelector);
3561 public static IEnumerable<KeyValuePair<TSource, TKey>> SafeEnumeration<TSource, TKey>(
3562 this ConcurrentDictionary<TSource, TKey> source)
3564 foreach (var kvp
in source)
3575 switch (securityType)
3597 if (source ==
null || source.Length == 0)
3599 throw new ArgumentException(
Messages.
Extensions.NullOrEmptySourceToConvertToHexString);
3602 var hex =
new StringBuilder(source.Length * 2);
3603 foreach (var b
in source)
3605 hex.AppendFormat(CultureInfo.InvariantCulture,
"{0:x2}", b);
3608 return hex.ToString();
3635 var sign = Math.Sign(quantity);
3642 throw new ApplicationException(
3643 $
"The skies are falling and the oceans are rising! Math.Sign({quantity}) returned {sign} :/"
3653 foreach (var security
in securityChanges.AddedSecurities)
3655 security.IsTradable =
true;
3658 algorithm.Securities.Add(security);
3661 var activeSecurities = algorithm.UniverseManager.ActiveSecurities;
3662 foreach (var security
in securityChanges.RemovedSecurities)
3664 if (!activeSecurities.ContainsKey(security.Symbol))
3666 security.IsTradable =
false;
3676 Log.
Error(exception, $
"Extensions.SetRuntimeError(): {Messages.Extensions.RuntimeError(algorithm, context)}");
3692 var result = CreateOptionChain(algorithm, symbol, out var option, universeSettings);
3693 option.SetFilter(filter);
3707 var result = CreateOptionChain(algorithm, symbol, out var option, universeSettings);
3708 option.SetFilter(filter);
3723 throw new ArgumentException(
Messages.
Extensions.CreateOptionChainRequiresOptionSymbol);
3729 option = (
Option)algorithm.
AddSecurity(symbol.
Canonical, settings.Resolution, settings.FillForward, settings.Leverage, settings.ExtendedMarketHours);
3743 var result = CreateFutureChain(algorithm, symbol, out var future, universeSettings);
3744 future.SetFilter(filter);
3757 var result = CreateFutureChain(algorithm, symbol, out var future, universeSettings);
3758 future.SetFilter(filter);
3769 throw new ArgumentException(
Messages.
Extensions.CreateFutureChainRequiresFutureSymbol);
3775 var dataNormalizationMode = settings.GetUniverseNormalizationModeOrDefault(symbol.
SecurityType);
3777 future = (
Future)algorithm.
AddSecurity(symbol.
Canonical, settings.Resolution, settings.FillForward, settings.Leverage, settings.ExtendedMarketHours,
3778 settings.DataMappingMode, dataNormalizationMode, settings.ContractDepthOffset);
3784 private static bool _notifiedUniverseSettingsUsed;
3785 private static readonly HashSet<SecurityType> _supportedSecurityTypes =
new()
3809 Action<IReadOnlyCollection<SecurityType>> onError =
null)
3813 if (!_supportedSecurityTypes.Contains(symbol.
SecurityType))
3816 onError?.Invoke(_supportedSecurityTypes);
3825 if (!_notifiedUniverseSettingsUsed)
3828 _notifiedUniverseSettingsUsed =
true;
3830 var leverageMsg = $
" Leverage = {leverage};";
3833 leverageMsg = $
" Leverage = default;";
3835 algorithm.
Debug($
"Will use UniverseSettings for automatically added securities for open orders and holdings. UniverseSettings:" +
3836 $
" Resolution = {resolution};{leverageMsg} FillForward = {fillForward}; ExtendedHours = {extendedHours}");
3839 Log.
Trace(
"GetOrAddUnrequestedSecurity(): Adding unrequested security: " + symbol.
Value);
3844 security = algorithm.
AddOptionContract(symbol, resolution, fillForward, leverage, extendedHours);
3849 security = algorithm.
AddFutureContract(symbol, resolution, fillForward, leverage, extendedHours);
3870 throw new ArgumentOutOfRangeException(nameof(right), right,
null);
3902 request.DataTimeZone,
3903 request.ExchangeHours.TimeZone,
3904 request.FillForwardResolution.HasValue,
3905 request.IncludeExtendedMarketHours,
3907 request.IsCustomData,
3909 isFilteredSubscription,
3910 request.DataNormalizationMode,
3911 request.DataMappingMode,
3912 request.ContractDepthOffset
3941 var type = data.GetType();
3942 var expectedType = type.IsAssignableTo(config.
Type);
3948 if (!configTypeFilter)
3950 return expectedType;
3959 if (isUniverse && !expectedType)
3986 throw new ArgumentOutOfRangeException(nameof(side), side,
null);
4008 throw new ArgumentOutOfRangeException(nameof(direction), direction,
null);
4018 throw new ArgumentOutOfRangeException(nameof(direction), direction,
null);
4025 throw new ArgumentOutOfRangeException(nameof(side), side,
null);
4036 public static bool ListEquals<T>(
this IReadOnlyList<T> left, IReadOnlyList<T> right)
4038 var count = left.Count;
4039 if (count != right.Count)
4044 for (
int i = 0; i < count; i++)
4046 if (!left[i].
Equals(right[i]))
4062 public static int GetListHashCode<T>(
this IReadOnlyList<T> list)
4067 for (
int i = 0; i < list.Count; i++)
4069 hashCode += (hashCode * 397) ^ list[i].GetHashCode();
4113 return profitLoss > 0;
4116 var option = (
Option)security;
4149 foreach (var value
in values)
4151 if (result.HasValue)
4153 result = GreatestCommonDivisor(result.Value, value);
4161 if (!result.HasValue)
4166 return result.Value;
4172 private static int GreatestCommonDivisor(
int a,
int b)
4190 public static decimal
SafeDivision(
this decimal numerator, decimal denominator, decimal failValue = 0)
4194 return (denominator == 0) ? failValue : (numerator / denominator);