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;
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);
143 lock (_emptyDirectories)
145 if(!_emptyDirectories.TryGetValue(directoryPath, out var result))
149 if (Directory.Exists(directoryPath))
153 result = !Directory.EnumerateFileSystemEntries(directoryPath).Any();
155 catch (Exception exception)
161 _emptyDirectories[directoryPath] = result;
164 Log.
Trace($
"Extensions.IsDirectoryEmpty(): directory '{directoryPath}' not found or empty");
184 var type = dataTypes.Single();
185 var baseInstance = type.GetBaseDataInstance();
186 baseInstance.Symbol = symbol;
200 if (result !=
null && dataTypes.Any(dataType => dataType.IsAssignableTo(typeof(
BaseChainUniverseData))))
214 return DeserializeList<string>(jsonArray);
225 if (
string.IsNullOrEmpty(jsonArray))
229 return JsonConvert.DeserializeObject<List<T>>(jsonArray);
233 if (ex is not JsonReaderException && ex is not JsonSerializationException)
238 if (typeof(T) == typeof(
string))
240 return new List<T> { (T)Convert.ChangeType(jsonArray, typeof(T), CultureInfo.InvariantCulture) };
242 return new List<T> { JsonConvert.DeserializeObject<T>(jsonArray) };
252 public static string DownloadData(
this HttpClient client,
string url, Dictionary<string, string> headers =
null)
256 foreach (var kvp
in headers)
258 client.DefaultRequestHeaders.Add(kvp.Key, kvp.Value);
263 using (var response = client.GetAsync(url).Result)
265 using (var content = response.Content)
267 return content.ReadAsStringAsync().Result;
271 catch (WebException ex)
273 Log.
Error(ex, $
"DownloadData(): {Messages.Extensions.DownloadDataFailed(url)}");
283 public static string DownloadData(
this string url, Dictionary<string, string> headers =
null)
285 using var client =
new HttpClient();
286 return client.DownloadData(url, headers);
295 using (var wc =
new HttpClient())
299 return wc.GetByteArrayAsync(url).Result;
303 Log.
Error(ex, $
"DownloadByteArray(): {Messages.Extensions.DownloadDataFailed(url)}");
316 const decimal max = decimal.MaxValue / 100m;
317 if (value >= max)
return decimal.MaxValue;
326 [MethodImpl(MethodImplOptions.AggressiveInlining)]
329 return MemoryManager.GetStream(guid);
343 Serializer.Serialize(stream, ticks);
344 result = stream.ToArray();
360 baseData.ProtobufSerialize(stream);
361 result = stream.ToArray();
377 Serializer.SerializeWithLengthPrefix(stream, baseData as
Tick, PrefixStyle.Base128, 1);
380 Serializer.SerializeWithLengthPrefix(stream, baseData as
QuoteBar, PrefixStyle.Base128, 1);
383 Serializer.SerializeWithLengthPrefix(stream, baseData as
TradeBar, PrefixStyle.Base128, 1);
386 Serializer.SerializeWithLengthPrefix(stream, baseData as
BaseData, PrefixStyle.Base128, 1);
405 if (
string.IsNullOrEmpty(value))
410 if (value.Length == 1)
412 return value.ToLowerInvariant();
414 return char.ToLowerInvariant(value[0]) + value.Substring(1);
427 if (resultPackets.Count > 0)
430 resultPacket = resultPackets[0];
431 for (var i = 1; i < resultPackets.Count; i++)
433 var newerPacket = resultPackets[i];
436 if (newerPacket.Insights !=
null)
441 resultPacket.
Insights =
new List<Insight>();
443 resultPacket.
Insights.AddRange(newerPacket.Insights);
447 if (newerPacket.OrderEvents !=
null)
454 resultPacket.
OrderEvents.AddRange(newerPacket.OrderEvents);
458 if (newerPacket.Orders !=
null)
460 if (resultPacket.
Orders ==
null)
463 resultPacket.
Orders =
new List<Order>();
465 resultPacket.
Orders.AddRange(newerPacket.Orders);
469 resultPacket.
Orders = resultPacket.
Orders.GroupBy(order => order.Id)
470 .Select(ordersGroup => ordersGroup.Last()).ToList();
483 public static void StopSafely(
this Thread thread, TimeSpan timeout, CancellationTokenSource token =
null)
489 if (token !=
null && !token.IsCancellationRequested)
493 Log.
Trace($
"StopSafely(): {Messages.Extensions.WaitingForThreadToStopSafely(thread.Name)}");
495 if (!thread.Join(timeout))
497 Log.
Error($
"StopSafely(): {Messages.Extensions.TimeoutWaitingForThreadToStopSafely(thread.Name)}");
500 catch (Exception exception)
513 public static string GetHash(
this IDictionary<int, Order> orders)
515 var joinedOrders =
string.Join(
518 .OrderBy(pair => pair.Key)
522 var order = pair.Value;
523 order.Price = order.Price.SmartRounding();
524 var limit = order as LimitOrder;
527 limit.LimitPrice = limit.LimitPrice.SmartRounding();
530 if (stopLimit !=
null)
532 stopLimit.
LimitPrice = stopLimit.LimitPrice.SmartRounding();
533 stopLimit.StopPrice = stopLimit.StopPrice.SmartRounding();
536 if (trailingStop !=
null)
538 trailingStop.
TrailingAmount = trailingStop.TrailingAmount.SmartRounding();
541 if (stopMarket !=
null)
543 stopMarket.
StopPrice = stopMarket.StopPrice.SmartRounding();
546 if (limitIfTouched !=
null)
548 limitIfTouched.
LimitPrice = limitIfTouched.LimitPrice.SmartRounding();
549 limitIfTouched.TriggerPrice = limitIfTouched.TriggerPrice.SmartRounding();
551 return JsonConvert.SerializeObject(pair.Value, Formatting.None);
556 return joinedOrders.ToMD5();
567 IEnumerator<DateTime> dates =
null;
573 if (!dates.MoveNext())
582 if (timeUtc >= dates.Current)
584 if (!dates.MoveNext())
589 return dates.Current;
591 catch (InvalidOperationException)
604 return series.
Values.Count == 0;
613 return chart.
Series.Values.All(IsEmpty);
629 var snakeCasedNamed = name.ToSnakeCase();
630 if (snakeCasedNamed != name)
632 method = instance.GetPythonMethodWithChecks(snakeCasedNamed);
639 method = instance.GetAttr(name);
640 var pythonType = method.GetPythonType();
641 var isPythonDefined = pythonType.Repr().Equals(
"<class \'method\'>", StringComparison.Ordinal);
662 var objectType = instance.GetPythonType();
663 if (!objectType.HasAttr(name))
668 var
property = instance.GetAttr(name);
669 var pythonType =
property.GetPythonType();
670 var isPythonDefined = pythonType.Repr().Equals(
"<class \'bool\'>", StringComparison.Ordinal);
691 if (!instance.HasAttr(name))
696 return instance.GetPythonBoolProperty(name);
710 if (!instance.HasAttr(name))
715 return instance.GetPythonMethod(name);
727 public static dynamic
GetMethod(
this PyObject instance,
string name)
729 using var _ = Py.GIL();
730 return instance.GetPythonMethodWithChecks(name.ToSnakeCase()) ?? instance.GetAttr(name);
743 var pyArgCount = PyModule.FromString(Guid.NewGuid().ToString(),
744 "from inspect import signature\n" +
745 "def GetArgCount(method):\n" +
746 " return len(signature(method).parameters)\n"
747 ).GetAttr(
"GetArgCount").Invoke(method);
748 pyArgCount.TryConvert(out argCount);
766 this IEnumerable<IPortfolioTarget> targets,
768 bool targetIsDelta =
false)
775 return targets.Select(x =>
777 var security = algorithm.
Securities[x.Symbol];
782 ExistingQuantity = security.Holdings.Quantity
784 .Aggregate(0m, (d, t) => d + t.Quantity - t.QuantityFilled),
788 .Where(x => x.Security.HasData
789 && x.Security.IsTradable
790 && (targetIsDelta ? Math.Abs(x.TargetQuantity) : Math.Abs(x.TargetQuantity - x.ExistingQuantity))
791 >= x.Security.SymbolProperties.LotSize
795 OrderValue = Math.Abs((targetIsDelta ? x.TargetQuantity : (x.TargetQuantity - x.ExistingQuantity)) * x.Security.Price),
796 IsReducingPosition = x.ExistingQuantity != 0
797 && Math.Abs((targetIsDelta ? (x.TargetQuantity + x.ExistingQuantity) : x.TargetQuantity)) < Math.Abs(x.ExistingQuantity)
799 .OrderByDescending(x => x.IsReducingPosition)
800 .ThenByDescending(x => x.OrderValue)
801 .Select(x => x.PortfolioTarget);
813 if (objectActivator ==
null)
818 var instance = objectActivator.Invoke(
new object[] { type });
843 public static T GetAndDispose<T>(
this PyObject instance)
845 if (instance ==
null)
849 var returnInstance = instance.As<T>();
852 return returnInstance;
862 public static void Move<T>(
this List<T> list,
int oldIndex,
int newIndex)
864 var oItem = list[oldIndex];
865 list.RemoveAt(oldIndex);
866 if (newIndex > oldIndex) newIndex--;
867 list.Insert(newIndex, oItem);
877 var bytes =
new byte[str.Length *
sizeof(char)];
878 Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
889 using var memoryStream =
new MemoryStream();
890 stream.CopyTo(memoryStream);
891 return memoryStream.ToArray();
900 public static void Clear<T>(
this ConcurrentQueue<T> queue)
903 while (queue.TryDequeue(out item)) {
914 public static string GetString(
this byte[] bytes, Encoding encoding =
null)
916 if (encoding ==
null) encoding = Encoding.ASCII;
918 return encoding.GetString(bytes);
926 public static string ToMD5(
this string str)
928 var builder =
new StringBuilder(32);
929 var data = MD5.HashData(Encoding.UTF8.GetBytes(str));
930 for (var i = 0; i < 16; i++)
932 builder.Append(data[i].ToStringInvariant(
"x2"));
934 return builder.ToString();
944 var hash =
new StringBuilder(64);
945 var crypto = SHA256.HashData(Encoding.UTF8.GetBytes(data));
946 for (var i = 0; i < 32; i++)
948 hash.Append(crypto[i].ToStringInvariant(
"x2"));
950 return hash.ToString();
958 var stack =
new Stack<char>(15);
961 var value = data % 36;
963 ? (char)(value +
'0')
964 : (char)(value - 10 +
'A');
969 return new string(stack.ToArray());
979 for (var i = symbol.Length - 1; i > -1; i--)
984 var value = (uint)(c <= 57
988 result += baseValue * value;
1002 if (
string.IsNullOrEmpty(text))
1007 byte[] textBytes = Encoding.UTF8.GetBytes(text);
1008 return Convert.ToBase64String(textBytes);
1018 if (
string.IsNullOrEmpty(base64EncodedText))
1020 return base64EncodedText;
1023 byte[] base64EncodedBytes = Convert.FromBase64String(base64EncodedText);
1024 return Encoding.UTF8.GetString(base64EncodedBytes);
1037 var alreadyUpper =
true;
1038 for (
int i = 0; i < data.Length && alreadyUpper; i++)
1040 alreadyUpper =
char.IsUpper(data[i]);
1042 return alreadyUpper ? data : data.ToUpperInvariant();
1055 var alreadyLower =
true;
1056 for (
int i = 0; i < data.Length && alreadyLower; i++)
1058 alreadyLower =
char.IsLower(data[i]);
1060 return alreadyLower ? data : data.ToLowerInvariant();
1072 public static void AddOrUpdate<K, V>(
this ConcurrentDictionary<K, V> dictionary, K key, V value)
1074 dictionary.AddOrUpdate(key, value, (oldkey, oldvalue) => value);
1086 public static TValue AddOrUpdate<TKey, TValue>(
this ConcurrentDictionary<TKey, Lazy<TValue>> dictionary, TKey key, Func<TKey, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory)
1088 var result = dictionary.AddOrUpdate(key,
new Lazy<TValue>(() => addValueFactory(key)), (key2, old) =>
new Lazy<TValue>(() => updateValueFactory(key2, old.Value)));
1089 return result.Value;
1102 public static void Add<TKey, TElement, TCollection>(
this IDictionary<TKey, TCollection> dictionary, TKey key, TElement element)
1103 where TCollection : ICollection<TElement>,
new()
1106 if (!dictionary.TryGetValue(key, out list))
1108 list =
new TCollection();
1109 dictionary.Add(key, list);
1123 public static ImmutableDictionary<TKey, ImmutableHashSet<TElement>> Add<TKey, TElement>(
1124 this ImmutableDictionary<TKey, ImmutableHashSet<TElement>> dictionary,
1129 ImmutableHashSet<TElement>
set;
1130 if (!dictionary.TryGetValue(key, out
set))
1132 set = ImmutableHashSet<TElement>.Empty.Add(element);
1133 return dictionary.Add(key,
set);
1136 return dictionary.SetItem(key,
set.Add(element));
1148 public static ImmutableSortedDictionary<TKey, ImmutableHashSet<TElement>> Add<TKey, TElement>(
1149 this ImmutableSortedDictionary<TKey, ImmutableHashSet<TElement>> dictionary,
1154 ImmutableHashSet<TElement>
set;
1155 if (!dictionary.TryGetValue(key, out
set))
1157 set = ImmutableHashSet<TElement>.Empty.Add(element);
1158 return dictionary.Add(key,
set);
1161 return dictionary.SetItem(key,
set.Add(element));
1174 if (!dictionary.TryGetValue(key, out list))
1176 dictionary[key] = list =
new List<Tick>(1);
1189 if (d == 0)
return 0;
1190 var scale = (decimal)Math.Pow(10, Math.Floor(Math.Log10((
double) Math.Abs(d))) + 1);
1191 return scale * Math.Round(d / scale, digits);
1203 return number.ToStringInvariant();
1209 return (number - 5m).ToString(
"#,.##", CultureInfo.InvariantCulture) +
"K";
1212 if (number < 100000)
1214 return (number - 50m).ToString(
"#,.#", CultureInfo.InvariantCulture) +
"K";
1217 if (number < 1000000)
1219 return (number - 500m).ToString(
"#,.", CultureInfo.InvariantCulture) +
"K";
1222 if (number < 10000000)
1224 return (number - 5000m).ToString(
"#,,.##", CultureInfo.InvariantCulture) +
"M";
1227 if (number < 100000000)
1229 return (number - 50000m).ToString(
"#,,.#", CultureInfo.InvariantCulture) +
"M";
1232 if (number < 1000000000)
1234 return (number - 500000m).ToString(
"#,,.", CultureInfo.InvariantCulture) +
"M";
1237 return (number - 5000000m).ToString(
"#,,,.##", CultureInfo.InvariantCulture) +
"B";
1249 public static decimal
DiscretelyRoundBy(
this decimal value, decimal quanta, MidpointRounding mode = MidpointRounding.AwayFromZero)
1259 var multiplicand = Math.Round(value / quanta, mode);
1260 return quanta * multiplicand;
1271 if (value >= decimal.MaxValue / 1000
1272 || value <= decimal.MinValue / 1000
1278 return Math.Truncate(1000 * value) / 1000;
1287 if (!input.HasValue)
1291 return input.Value.SmartRounding();
1300 input = Normalize(input);
1305 return Math.Round(input, 4);
1309 return input.RoundToSignificantDigits(7).Normalize();
1317 input = Normalize(input);
1323 else if (input <= 10)
1326 return Math.Round(input, 2);
1328 else if (input <= 100)
1331 return Math.Round(input, 1);
1334 return Math.Truncate(input);
1343 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1346 if (input.IsNaNOrInfinity())
1348 throw new ArgumentException(
1351 new NotFiniteNumberException(input)
1355 if (input <= (
double) decimal.MinValue)
return decimal.MinValue;
1356 if (input >= (
double) decimal.MaxValue)
return decimal.MaxValue;
1357 return (decimal) input;
1371 return input / 1.000000000000000000000000000000000m;
1382 return Normalize(input).ToString(CultureInfo.InvariantCulture);
1392 return BitConverter.GetBytes(decimal.GetBits(input)[3])[2];
1406 var decimalPlaces = 0;
1407 var hasDecimals =
false;
1409 var length = str.Length;
1411 while (index < length &&
char.IsWhiteSpace(str[index]))
1416 var isNegative = index < length && str[index] ==
'-';
1422 while (index < length)
1424 var ch = str[index++];
1430 else if (
char.IsWhiteSpace(ch))
1436 value = value * 10 + (ch -
'0');
1441 var lo = (int)value;
1442 var mid = (int)(value >> 32);
1443 return new decimal(lo, mid, 0, isNegative, (
byte)(hasDecimals ? decimalPlaces : 0));
1456 var trimmed = str.Trim();
1457 var value = str.TrimEnd(
'%').ToDecimal();
1458 if (trimmed.EndsWith(
"%"))
1473 return decimal.Parse(str, NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture);
1485 for (var i = 0; i < str.Length; i++)
1490 value = value * 10 + (str[i] -
'0');
1504 for (var i = 0; i < str.Length; i++)
1509 value = value * 10 + (str[i] -
'0');
1520 if (baseDataType == typeof(
TradeBar) || baseDataType == typeof(
QuoteBar) || baseDataType == typeof(
Tick))
1525 var method = baseDataType.GetMethod(
"Reader",
1527 if (method !=
null && method.DeclaringType == baseDataType)
1540 public static List<string>
ToCsv(
this string str,
int size = 4)
1543 var csv =
new List<string>(size);
1544 for (
int i = 0; i < str.Length; i++)
1548 if (last != 0) last = last + 1;
1549 csv.Add(str.Substring(last, i - last));
1553 if (last != 0) last = last + 1;
1554 csv.Add(str.Substring(last));
1565 public static List<string>
ToCsvData(
this string str,
int size = 4,
char delimiter =
',')
1567 var csv =
new List<string>(size);
1571 var textDataField =
false;
1573 for (var i = 0; i < str.Length; i++)
1575 var current = str[i];
1578 textDataField = !textDataField;
1580 else if (!textDataField && current == delimiter)
1582 csv.Add(str.Substring(last + 1, (i - last)).Trim(
' ',
','));
1590 csv.Add(str.Substring(last + 1).Trim());
1603 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1604 public static bool TryGetFromCsv(
this string csvLine,
int index, out ReadOnlySpan<char> result)
1606 result = ReadOnlySpan<char>.Empty;
1607 if (
string.IsNullOrEmpty(csvLine) || index < 0)
1612 var span = csvLine.AsSpan();
1613 for (
int i = 0; i < index; i++)
1615 var commaIndex = span.IndexOf(
',');
1616 if (commaIndex == -1)
1620 span = span.Slice(commaIndex + 1);
1623 var nextCommaIndex = span.IndexOf(
',');
1624 if (nextCommaIndex == -1)
1626 nextCommaIndex = span.Length;
1629 result = span.Slice(0, nextCommaIndex);
1640 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1643 value = decimal.Zero;
1644 if (!csvLine.TryGetFromCsv(index, out var csvValue))
1649 return decimal.TryParse(csvValue, NumberStyles.Any, CultureInfo.InvariantCulture, out value);
1658 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1661 csvLine.TryGetDecimalFromCsv(index, out var value);
1669 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1672 return double.IsNaN(value) ||
double.IsInfinity(value);
1679 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1682 return double.IsNaN(value) || Math.Abs(value) <
double.Epsilon;
1691 return new decimal(1, 0, 0,
false, 27);
1700 var ext = str.Substring(Math.Max(0, str.Length - 4));
1701 var allowedExt =
new List<string> {
".zip",
".csv",
".json",
".tsv" };
1702 if (!allowedExt.Contains(ext))
1716 var stream =
new MemoryStream();
1717 var writer =
new StreamWriter(stream);
1720 stream.Position = 0;
1731 public static TimeSpan
Round(
this TimeSpan time, TimeSpan roundingInterval, MidpointRounding roundingType)
1733 if (roundingInterval == TimeSpan.Zero)
1739 return new TimeSpan(
1740 Convert.ToInt64(Math.Round(
1741 time.Ticks / (decimal)roundingInterval.Ticks,
1743 )) * roundingInterval.Ticks
1754 public static TimeSpan
Round(
this TimeSpan time, TimeSpan roundingInterval)
1756 return Round(time, roundingInterval, MidpointRounding.ToEven);
1769 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1770 public static DateTime
RoundDown(
this DateTime dateTime, TimeSpan interval)
1772 if (interval == TimeSpan.Zero)
1778 var amount = dateTime.Ticks % interval.Ticks;
1781 return dateTime.AddTicks(-amount);
1794 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1795 public static DateTime
RoundDownInTimeZone(
this DateTime dateTime, TimeSpan roundingInterval, DateTimeZone sourceTimeZone, DateTimeZone roundingTimeZone)
1797 var dateTimeInRoundingTimeZone = dateTime.ConvertTo(sourceTimeZone, roundingTimeZone);
1798 var roundedDateTimeInRoundingTimeZone = dateTimeInRoundingTimeZone.RoundDown(roundingInterval);
1799 return roundedDateTimeInRoundingTimeZone.ConvertTo(roundingTimeZone, sourceTimeZone);
1814 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1818 if (interval == TimeSpan.Zero)
return dateTime;
1820 var rounded = dateTime.RoundDown(interval);
1821 while (!exchangeHours.
IsOpen(rounded, rounded + interval, extendedMarketHours))
1823 rounded -= interval;
1839 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1843 if (interval == TimeSpan.Zero)
return dateTime;
1845 var dateTimeInRoundingTimeZone = dateTime.ConvertTo(exchangeHours.
TimeZone, roundingTimeZone);
1846 var roundedDateTimeInRoundingTimeZone = dateTimeInRoundingTimeZone.RoundDown(interval);
1847 var rounded = roundedDateTimeInRoundingTimeZone.ConvertTo(roundingTimeZone, exchangeHours.
TimeZone);
1849 while (!exchangeHours.
IsOpen(rounded, rounded + interval, extendedMarketHours))
1856 dateTimeInRoundingTimeZone -= interval;
1857 roundedDateTimeInRoundingTimeZone = dateTimeInRoundingTimeZone.RoundDown(interval);
1858 rounded = roundedDateTimeInRoundingTimeZone.ConvertTo(roundingTimeZone, exchangeHours.
TimeZone);
1886 var time = utcTime.ConvertFromUtc(exchangeHours.TimeZone);
1888 return exchangeHours.
IsOpen(time, extendedMarketHours);
1897 public static DateTime
Round(
this DateTime datetime, TimeSpan roundingInterval)
1899 return new DateTime((datetime - DateTime.MinValue).Round(roundingInterval).Ticks);
1912 public static DateTime
RoundUp(
this DateTime time, TimeSpan interval)
1914 if (interval == TimeSpan.Zero)
1920 return new DateTime(((time.Ticks + interval.Ticks - 1) / interval.Ticks) * interval.Ticks);
1931 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1932 public static DateTime
ConvertTo(
this DateTime time, DateTimeZone from, DateTimeZone to,
bool strict =
false)
1936 return from.AtStrictly(LocalDateTime.FromDateTime(time)).WithZone(to).ToDateTimeUnspecified();
1940 return LocalDateTime.FromDateTime(time)
1941 .InZone(from, _mappingResolver)
1943 .ToDateTimeUnspecified();
1953 public static DateTime
ConvertFromUtc(
this DateTime time, DateTimeZone to,
bool strict =
false)
1965 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1966 public static DateTime
ConvertToUtc(
this DateTime time, DateTimeZone from,
bool strict =
false)
1970 return from.AtStrictly(LocalDateTime.FromDateTime(time)).ToDateTimeUtc();
1974 return LocalDateTime.FromDateTime(time)
1975 .InZone(from, _mappingResolver)
1986 return (date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday);
1993 public static void Reset(
this Timer timer)
2008 if (type.AssemblyQualifiedName == typeName)
2012 if (type.FullName == typeName)
2016 if (type.Name == typeName)
2032 while (type !=
null && type != typeof(
object))
2035 if (type.IsGenericType && possibleSuperType.IsGenericTypeDefinition)
2037 cur = type.GetGenericTypeDefinition();
2043 if (possibleSuperType == cur)
2047 type = type.BaseType;
2060 string name = type.Name;
2061 if (type.IsGenericType)
2063 var genericArguments = type.GetGenericArguments();
2064 var toBeReplaced =
"`" + (genericArguments.Length);
2065 name = name.Replace(toBeReplaced, $
"<{string.Join(",
", genericArguments.Select(x => x.GetBetterTypeName()))}>");
2075 [MethodImpl(MethodImplOptions.AggressiveInlining)]
2082 return TimeSpan.Zero;
2092 throw new ArgumentOutOfRangeException(nameof(resolution));
2106 if (requireExactMatch)
2108 if (TimeSpan.Zero == timeSpan)
return Resolution.Tick;
2137 if (Enum.TryParse(value, ignoreCase, out securityType))
2142 if (InvalidSecurityTypes.Add(value))
2144 Log.
Error($
"Extensions.TryParseSecurityType(): {Messages.Extensions.UnableToParseUnknownSecurityType(value)}");
2157 public static T ConvertTo<T>(
this string value)
2159 return (T) value.ConvertTo(typeof (T));
2168 public static object ConvertTo(
this string value, Type type)
2172 return Enum.Parse(type, value,
true);
2175 if (typeof (IConvertible).IsAssignableFrom(type))
2177 return Convert.ChangeType(value, type, CultureInfo.InvariantCulture);
2181 var parse = type.GetMethod(
"Parse",
new[] {typeof (
string)});
2184 var result = parse.Invoke(
null,
new object[] {value});
2188 return JsonConvert.DeserializeObject(value, type);
2199 public static bool WaitOne(
this WaitHandle waitHandle, CancellationToken cancellationToken)
2201 return waitHandle.WaitOne(Timeout.Infinite, cancellationToken);
2217 public static bool WaitOne(
this WaitHandle waitHandle, TimeSpan timeout, CancellationToken cancellationToken)
2219 return waitHandle.WaitOne((
int) timeout.TotalMilliseconds, cancellationToken);
2236 public static bool WaitOne(
this WaitHandle waitHandle,
int millisecondsTimeout, CancellationToken cancellationToken)
2238 return WaitHandle.WaitAny(
new[] { waitHandle, cancellationToken.WaitHandle }, millisecondsTimeout) == 0;
2248 using (var md5 = MD5.Create())
2250 return md5.ComputeHash(stream);
2261 var regx =
new Regex(
"http(s)?://([\\w+?\\.\\w+])+([a-zA-Z0-9\\~\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)_\\-\\=\\+\\\\\\/\\?\\.\\:\\;\\'\\,]*([a-zA-Z0-9\\?\\#\\=\\/]){1})?", RegexOptions.IgnoreCase);
2262 var matches = regx.Matches(source);
2263 foreach (Match match
in matches)
2265 source = source.Replace(match.Value, $
"<a href=\'{match.Value}\' target=\'blank\'>{match.Value}</a>");
2279 var startIndex = 1 + value.IndexOf(left);
2280 var length = value.IndexOf(right, startIndex) - startIndex;
2283 value = value.Substring(startIndex, length);
2284 startIndex = 1 + value.IndexOf(left);
2285 return value.Substring(startIndex).Trim();
2287 return string.Empty;
2299 if (names.Count == 1) {
return names.Single(); }
2304 var searchName = algorithmTypeName.Contains(
'.', StringComparison.InvariantCulture) ? algorithmTypeName :
"." + algorithmTypeName;
2305 return names.SingleOrDefault(x => x.EndsWith(searchName));
2315 return @
enum.ToString().ToLowerInvariant();
2326 switch (securityType)
2357 switch (securityType)
2377 switch (securityType)
2397 if (!securityType.HasOptions() && !securityType.IsOption())
2402 switch (securityType)
2421 switch (optionStyle.LazyToLower())
2440 switch (optionRight.LazyToLower())
2459 switch (optionRight)
2467 return optionRight.ToString();
2479 switch (optionRight)
2498 switch (optionStyle)
2517 if (
string.IsNullOrEmpty(dataMappingMode))
2521 switch (dataMappingMode.LazyToLower())
2524 case "lasttradingday":
2527 case "firstdaymonth":
2530 case "openinterest":
2533 case "openinterestannual":
2548 switch (securityType)
2557 return "futureoption";
2559 return "indexoption";
2573 return "cryptofuture";
2576 return securityType.ToLower();
2595 return "openinterest";
2598 return tickType.ToLower();
2624 return resolution.ToLower();
2636 var limitPrice = 0m;
2638 var triggerPrice = 0m;
2639 var trailingAmount = 0m;
2640 var trailingAsPercentage =
false;
2655 limitPrice = stopLimitOrder.LimitPrice;
2659 stopPrice = trailingStopOrder.
StopPrice;
2660 trailingAmount = trailingStopOrder.TrailingAmount;
2661 trailingAsPercentage = trailingStopOrder.TrailingAsPercentage;
2666 limitPrice = limitIfTouched.LimitPrice;
2673 limitPrice = order.
Price;
2674 stopPrice = order.
Price;
2684 throw new ArgumentOutOfRangeException();
2695 trailingAsPercentage,
2701 submitOrderRequest.SetOrderId(order.
Id);
2702 var orderTicket =
new OrderTicket(transactionManager, submitOrderRequest);
2703 orderTicket.SetOrder(order);
2713 public static void ProcessUntilEmpty<T>(
this IProducerConsumerCollection<T> collection, Action<T> handler)
2716 while (collection.TryTake(out item))
2734 if (pyObject.HasAttr(
"to_string"))
2736 var pyValue = pyObject.InvokeMethod(
"to_string");
2737 value = Environment.NewLine + pyValue;
2742 value = pyObject.ToString();
2743 if (
string.IsNullOrWhiteSpace(value))
2745 var pythonType = pyObject.GetPythonType();
2746 if (pythonType.GetType() == typeof(PyObject))
2748 value = pythonType.ToString();
2752 var type = pythonType.As<Type>();
2753 value = pyObject.AsManagedObject(type).ToString();
2755 pythonType.Dispose();
2774 public static bool TryConvert<T>(
this PyObject pyObject, out T result,
bool allowPythonDerivative =
false)
2776 result =
default(T);
2777 var type = typeof(T);
2779 if (pyObject ==
null)
2791 if (allowPythonDerivative)
2793 result = (T)pyObject.AsManagedObject(type);
2798 if (typeof(Type).IsAssignableFrom(type))
2800 result = (T)pyObject.AsManagedObject(type);
2802 if(!pyObject.HasAttr(
"__name__"))
2807 var castedResult = (Type)pyObject.AsManagedObject(type);
2808 var pythonName = pyObject.GetAttr(
"__name__").GetAndDispose<
string>();
2809 return pythonName == castedResult.Name;
2813 if (typeof(IEnumerable).IsAssignableFrom(type))
2815 result = (T)pyObject.AsManagedObject(type);
2819 using var pythonType = pyObject.GetPythonType();
2820 var csharpType = pythonType.As<Type>();
2822 if (!type.IsAssignableFrom(csharpType))
2827 result = (T)pyObject.AsManagedObject(type);
2832 if (result is IPythonDerivedType)
2842 if (PythonReferenceComparer.Instance.Equals(PyType.Get(csharpType), pythonType))
2850 var name = (((dynamic)pythonType).__name__ as PyObject).GetAndDispose<string>();
2851 return name == result.GetType().Name;
2870 public static bool TryConvertToDelegate<T>(
this PyObject pyObject, out T result)
2872 var type = typeof(T);
2875 if (TryConvert<T>(pyObject, out result))
2880 if (!typeof(MulticastDelegate).IsAssignableFrom(type))
2885 result =
default(T);
2887 if (pyObject ==
null)
2892 var code =
string.Empty;
2893 var types = type.GetGenericArguments();
2897 var locals =
new PyDict();
2900 for (var i = 0; i < types.Length; i++)
2902 var iString = i.ToStringInvariant();
2903 code += $
",t{iString}";
2904 locals.SetItem($
"t{iString}", types[i].ToPython());
2907 locals.SetItem(
"pyObject", pyObject);
2909 var name = type.FullName.Substring(0, type.FullName.IndexOf(
'`'));
2910 code = $
"import System; delegate = {name}[{code.Substring(1)}](pyObject)";
2912 PythonEngine.Exec(code,
null, locals);
2913 result = (T)locals.GetItem(
"delegate").AsManagedObject(typeof(T));
2939 if (typeToConvertTo ==
null)
2941 typeToConvertTo = pyObject.GetPythonType().AsManagedObject(typeof(Type)) as Type;
2944 return pyObject.AsManagedObject(typeToConvertTo);
2953 public static Func<IEnumerable<T>, IEnumerable<Symbol>> ConvertPythonUniverseFilterFunction<T>(
this PyObject universeFilterFunc) where T :
BaseData
2955 Func<IEnumerable<T>,
object> convertedFunc;
2956 Func<IEnumerable<T>, IEnumerable<Symbol>> filterFunc =
null;
2958 if (universeFilterFunc !=
null && universeFilterFunc.TryConvertToDelegate(out convertedFunc))
2960 filterFunc = convertedFunc.ConvertToUniverseSelectionSymbolDelegate();
2973 public static Func<IEnumerable<T>, IEnumerable<Symbol>> ConvertToUniverseSelectionSymbolDelegate<T>(
this Func<IEnumerable<T>,
object> selector) where T :
BaseData
2975 if (selector ==
null)
2977 return (dataPoints) => dataPoints.Select(x => x.Symbol);
2979 return selector.ConvertSelectionSymbolDelegate();
2989 public static Func<T, IEnumerable<Symbol>> ConvertSelectionSymbolDelegate<T>(
this Func<T, object> selector)
2993 var result = selector(data);
2996 : ((
object[])result).Select(x =>
2998 if (x is
Symbol castedSymbol)
3000 return castedSymbol;
3014 public static Func<T, IEnumerable<string>> ConvertToUniverseSelectionStringDelegate<T>(
this Func<T, object> selector)
3018 var result = selector(data);
3030 public static T ConvertToDelegate<T>(
this PyObject pyObject)
3033 if (pyObject.TryConvertToDelegate(out result))
3050 public static Dictionary<TKey, TValue> ConvertToDictionary<TKey, TValue>(
this PyObject pyObject)
3052 var result =
new List<KeyValuePair<TKey, TValue>>();
3055 var inputType = pyObject.GetPythonType().ToString();
3056 var targetType = nameof(PyDict);
3060 using (var pyDict =
new PyDict(pyObject))
3062 targetType = $
"{typeof(TKey).Name}: {typeof(TValue).Name}";
3064 foreach (PyObject item
in pyDict.Items())
3066 inputType = $
"{item[0].GetPythonType()}: {item[1].GetPythonType()}";
3068 var key = item[0].As<TKey>();
3069 var value = item[1].As<TValue>();
3071 result.Add(
new KeyValuePair<TKey, TValue>(key, value));
3081 return result.ToDictionary();
3093 Exception exception =
null;
3094 if (!PyList.IsListType(pyObject))
3101 result = ConvertToSymbol(pyObject, dispose:
false);
3103 catch (Exception ex)
3111 yield
return result;
3116 using var iterator = pyObject.GetIterator();
3117 foreach (PyObject item
in iterator)
3122 result = ConvertToSymbol(item, dispose:
true);
3124 catch (Exception ex)
3129 yield
return result;
3134 if (exception !=
null)
3136 if (pyObject.TryConvert(out IEnumerable<Symbol> symbols))
3138 foreach (var symbol
in symbols)
3140 yield
return symbol;
3156 public static PyList
ToPyList(
this IEnumerable enumerable)
3160 return enumerable.ToPyListUnSafe();
3172 var pyList =
new PyList();
3173 foreach (var item
in enumerable)
3175 using (var pyObject = item.ToPython())
3177 pyList.Append(pyObject);
3193 if (pyObject.TryConvert(out type))
3195 return value.ToStringInvariant().ConvertTo(type).ToString();
3201 throw new ArgumentException($
"GetEnumString(): {Messages.Extensions.ObjectFromPythonIsNotACSharpType(pyObject.Repr())}");
3214 if (pyObject.TryConvert(out type))
3220 if (!PythonActivators.TryGetValue(pyObject.Handle, out var pythonType))
3226 if (pyObject.ToString().StartsWith(
"<class '", StringComparison.InvariantCulture))
3228 type = CreateType(pyObject);
3233 type = pythonType.Type;
3246 if (pyObject.TryConvert(out type))
3252 if (!PythonActivators.TryGetValue(pyObject.Handle, out pythonType))
3254 var assemblyName = pyObject.GetAssemblyName();
3255 var typeBuilder = AssemblyBuilder
3256 .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run)
3257 .DefineDynamicModule(
"MainModule")
3259 .DefineType(assemblyName.Name, TypeAttributes.Class | TypeAttributes.Public, type);
3266 PythonActivators.Add(pyObject.Handle, pythonType);
3268 return pythonType.Type;
3280 return new AssemblyName(pyObject.Repr().Split(
'\'')[1]);
3291 public static IEnumerable<List<T>> BatchBy<T>(
this IEnumerable<T> enumerable,
int batchSize)
3293 using (var enumerator = enumerable.GetEnumerator())
3295 List<T> list =
null;
3296 while (enumerator.MoveNext())
3300 list =
new List<T> {enumerator.Current};
3302 else if (list.Count < batchSize)
3304 list.Add(enumerator.Current);
3309 list =
new List<T> {enumerator.Current};
3313 if (list?.Count > 0)
3326 public static TResult SynchronouslyAwaitTaskResult<TResult>(
this Task<TResult> task)
3328 return task.ConfigureAwait(
false).GetAwaiter().GetResult();
3338 task.ConfigureAwait(
false).GetAwaiter().GetResult();
3346 public static T SynchronouslyAwaitTask<T>(
this Task<T> task)
3348 return SynchronouslyAwaitTaskResult(task);
3358 if (task.IsCompleted)
3362 task.ConfigureAwait(
false).GetAwaiter().GetResult();
3370 public static T SynchronouslyAwaitTask<T>(
this ValueTask<T> task)
3372 if (task.IsCompleted)
3376 return task.ConfigureAwait(
false).GetAwaiter().GetResult();
3386 return string.Join(
"&", pairs.Select(pair => $
"{pair.Key}={pair.Value}"));
3397 if (s.EndsWith(ending, StringComparison.InvariantCulture))
3399 return s.Substring(0, s.Length - ending.Length);
3415 if (!
string.IsNullOrEmpty(s) && !
string.IsNullOrEmpty(start) && s.StartsWith(start, StringComparison.InvariantCulture))
3417 return s.Substring(start.Length);
3469 public static bool IsCustomDataType<T>(
this Symbol symbol)
3473 && type.Equals(typeof(T).Name, StringComparison.InvariantCultureIgnoreCase);
3489 var expiration = symbol.
ID.
Date;
3490 for (var i = 0; i < offset; i++)
3493 DateTime newExpiration;
3495 var monthOffset = 0;
3499 newExpiration = expiryFunction(expiration.AddMonths(monthOffset)).Date;
3500 }
while (newExpiration <= expiration);
3502 expiration = newExpiration;
3514 if (dataConfig.
Symbol.TryGetLiveSubscriptionSymbol(out var mappedSymbol))
3526 EventHandler newDataAvailableHandler,
3527 Func<SubscriptionDataConfig, bool> isExpired,
3530 subscribedConfig = dataConfig;
3531 if (dataConfig.
Symbol.TryGetLiveSubscriptionSymbol(out var mappedSymbol))
3537 IEnumerator<BaseData> result =
null;
3538 if (!isExpired(subscribedConfig))
3540 result = dataQueueHandler.
Subscribe(subscribedConfig, newDataAvailableHandler);
3544 Log.
Trace($
"SubscribeWithMapping(): skip live subscription for expired asset {subscribedConfig}");
3546 return result ?? Enumerable.Empty<
BaseData>().GetEnumerator();
3557 if(dataProvider ==
null)
3561 var stream = dataProvider.
Fetch(file);
3567 using (var streamReader =
new StreamReader(stream))
3572 line = streamReader.ReadLine();
3578 while (line !=
null);
3592 public static BaseData Scale(
this BaseData data, Func<decimal, decimal, decimal, decimal> factorFunc, decimal volumeFactor, decimal factor, decimal sumOfDividends)
3598 if (tradeBar !=
null)
3600 tradeBar.
Open = factorFunc(tradeBar.Open, factor, sumOfDividends);
3601 tradeBar.High = factorFunc(tradeBar.High, factor, sumOfDividends);
3602 tradeBar.Low = factorFunc(tradeBar.Low, factor, sumOfDividends);
3603 tradeBar.Close = factorFunc(tradeBar.Close, factor, sumOfDividends);
3604 tradeBar.Volume = Math.Round(tradeBar.Volume * volumeFactor);
3611 !securityType.IsOption())
3616 var tick = data as
Tick;
3617 if (tick ==
null || tick.TickType ==
TickType.OpenInterest)
3622 if (tick.TickType ==
TickType.Trade)
3624 tick.
Value = factorFunc(tick.Value, factor, sumOfDividends);
3625 tick.Quantity = Math.Round(tick.Quantity * volumeFactor);
3629 tick.BidPrice = tick.BidPrice != 0 ? factorFunc(tick.BidPrice, factor, sumOfDividends) : 0;
3630 tick.BidSize = Math.Round(tick.BidSize * volumeFactor);
3631 tick.AskPrice = tick.AskPrice != 0 ? factorFunc(tick.AskPrice, factor, sumOfDividends) : 0;
3632 tick.AskSize = Math.Round(tick.AskSize * volumeFactor);
3634 if (tick.BidPrice == 0)
3636 tick.Value = tick.AskPrice;
3639 if (tick.AskPrice == 0)
3641 tick.Value = tick.BidPrice;
3645 tick.Value = (tick.BidPrice + tick.AskPrice) / 2m;
3649 if (quoteBar !=
null)
3651 if (quoteBar.Ask !=
null)
3653 quoteBar.
Ask.
Open = factorFunc(quoteBar.Ask.Open, factor, sumOfDividends);
3654 quoteBar.Ask.High = factorFunc(quoteBar.Ask.High, factor, sumOfDividends);
3655 quoteBar.Ask.Low = factorFunc(quoteBar.Ask.Low, factor, sumOfDividends);
3656 quoteBar.Ask.Close = factorFunc(quoteBar.Ask.Close, factor, sumOfDividends);
3658 if (quoteBar.Bid !=
null)
3660 quoteBar.Bid.Open = factorFunc(quoteBar.Bid.Open, factor, sumOfDividends);
3661 quoteBar.Bid.High = factorFunc(quoteBar.Bid.High, factor, sumOfDividends);
3662 quoteBar.Bid.Low = factorFunc(quoteBar.Bid.Low, factor, sumOfDividends);
3663 quoteBar.Bid.Close = factorFunc(quoteBar.Bid.Close, factor, sumOfDividends);
3665 quoteBar.Value = quoteBar.Close;
3666 quoteBar.LastAskSize = Math.Round(quoteBar.LastAskSize * volumeFactor);
3667 quoteBar.LastBidSize = Math.Round(quoteBar.LastBidSize * volumeFactor);
3676 throw new ArgumentOutOfRangeException();
3691 switch (normalizationMode)
3696 return data?.Scale(TimesFactor, 1 / factor, factor, decimal.Zero);
3698 return data.Scale(TimesFactor, 1 / factor, factor, sumOfDividends);
3701 return data.Scale(TimesFactor, 1, factor, decimal.Zero);
3703 return data.Scale(AdditionFactor, 1, factor, decimal.Zero);
3705 return data.Scale(AdditionFactor, 1, factor, decimal.Zero);
3716 [MethodImpl(MethodImplOptions.AggressiveInlining)]
3717 private static decimal TimesFactor(decimal target, decimal factor, decimal sumOfDividends)
3719 return target * factor + sumOfDividends;
3725 [MethodImpl(MethodImplOptions.AggressiveInlining)]
3726 private static decimal AdditionFactor(decimal target, decimal factor, decimal _)
3728 return target + factor;
3738 var priceScaleFrontier = data.
Time;
3747 priceScaleFrontier = data.
EndTime;
3749 return priceScaleFrontier;
3751 return DateTime.MinValue;
3758 public static IOrderedEnumerable<KeyValuePair<TSource, TKey>> OrderBySafe<TSource, TKey>(
3759 this ConcurrentDictionary<TSource, TKey> source, Func<KeyValuePair<TSource, TKey>, TSource> keySelector
3762 return source.SafeEnumeration().OrderBy(keySelector);
3769 public static IOrderedEnumerable<KeyValuePair<TSource, TKey>> OrderBySafe<TSource, TKey>(
3770 this ConcurrentDictionary<TSource, TKey> source, Func<KeyValuePair<TSource, TKey>, TKey> keySelector
3773 return source.SafeEnumeration().OrderBy(keySelector);
3780 public static IEnumerable<KeyValuePair<TSource, TKey>> SafeEnumeration<TSource, TKey>(
3781 this ConcurrentDictionary<TSource, TKey> source)
3783 foreach (var kvp
in source)
3794 switch (securityType)
3815 switch (securityType)
3837 if (source ==
null || source.Length == 0)
3842 var hex =
new StringBuilder(source.Length * 2);
3843 foreach (var b
in source)
3845 hex.AppendFormat(CultureInfo.InvariantCulture,
"{0:x2}", b);
3848 return hex.ToString();
3875 var sign = Math.Sign(quantity);
3882 throw new ApplicationException(
3883 $
"The skies are falling and the oceans are rising! Math.Sign({quantity}) returned {sign} :/"
3893 foreach (var security
in securityChanges.AddedSecurities)
3896 algorithm.Securities.Add(security);
3899 var activeSecurities = algorithm.UniverseManager.ActiveSecurities;
3900 foreach (var security
in securityChanges.RemovedSecurities)
3902 if (!activeSecurities.ContainsKey(security.Symbol))
3915 if (security.
Type !=
SecurityType.Index || (security as Securities.Index.Index).ManualSetIsTradable)
3926 Log.
Error(exception, $
"Extensions.SetRuntimeError(): {Messages.Extensions.RuntimeError(algorithm, context)}");
3942 var result = CreateOptionChain(algorithm, symbol, out var option, universeSettings);
3943 option.SetFilter(filter);
3957 var result = CreateOptionChain(algorithm, symbol, out var option, universeSettings);
3958 option.SetFilter(filter);
3979 option = (
Option)algorithm.
AddSecurity(symbol.
Canonical, settings.Resolution, settings.FillForward, settings.Leverage, settings.ExtendedMarketHours);
3993 var result = CreateFutureChain(algorithm, symbol, out var future, universeSettings);
3994 future.SetFilter(filter);
4007 var result = CreateFutureChain(algorithm, symbol, out var future, universeSettings);
4008 future.SetFilter(filter);
4025 var dataNormalizationMode = settings.GetUniverseNormalizationModeOrDefault(symbol.
SecurityType);
4027 future = (
Future)algorithm.
AddSecurity(symbol.
Canonical, settings.Resolution, settings.FillForward, settings.Leverage, settings.ExtendedMarketHours,
4028 settings.DataMappingMode, dataNormalizationMode, settings.ContractDepthOffset);
4034 private static bool _notifiedUniverseSettingsUsed;
4035 private static readonly HashSet<SecurityType> _supportedSecurityTypes =
new()
4059 Action<IReadOnlyCollection<SecurityType>> onError =
null)
4063 if (!_supportedSecurityTypes.Contains(symbol.
SecurityType))
4066 onError?.Invoke(_supportedSecurityTypes);
4075 if (!_notifiedUniverseSettingsUsed)
4078 _notifiedUniverseSettingsUsed =
true;
4080 var leverageMsg = $
" Leverage = {leverage};";
4083 leverageMsg = $
" Leverage = default;";
4085 algorithm.
Debug($
"Will use UniverseSettings for automatically added securities for open orders and holdings. UniverseSettings:" +
4086 $
" Resolution = {resolution};{leverageMsg} FillForward = {fillForward}; ExtendedHours = {extendedHours}");
4089 Log.
Trace(
"GetOrAddUnrequestedSecurity(): Adding unrequested security: " + symbol.
Value);
4094 security = algorithm.
AddOptionContract(symbol, resolution, fillForward, leverage, extendedHours);
4099 security = algorithm.
AddFutureContract(symbol, resolution, fillForward, leverage, extendedHours);
4120 throw new ArgumentOutOfRangeException(nameof(right), right,
null);
4152 request.DataTimeZone,
4153 request.ExchangeHours.TimeZone,
4154 request.FillForwardResolution.HasValue,
4155 request.IncludeExtendedMarketHours,
4157 request.IsCustomData,
4159 isFilteredSubscription,
4160 request.DataNormalizationMode,
4161 request.DataMappingMode,
4162 request.ContractDepthOffset
4191 var type = data.GetType();
4192 var expectedType = type.IsAssignableTo(config.
Type);
4198 if (!configTypeFilter)
4200 return expectedType;
4209 if (isUniverse && !expectedType)
4241 throw new ArgumentOutOfRangeException(nameof(side), side,
null);
4263 throw new ArgumentOutOfRangeException(nameof(direction), direction,
null);
4273 throw new ArgumentOutOfRangeException(nameof(direction), direction,
null);
4280 throw new ArgumentOutOfRangeException(nameof(side), side,
null);
4291 public static bool ListEquals<T>(
this IReadOnlyList<T> left, IReadOnlyList<T> right)
4293 var count = left.Count;
4294 if (count != right.Count)
4299 for (
int i = 0; i < count; i++)
4301 if (!left[i].
Equals(right[i]))
4317 public static int GetListHashCode<T>(
this IReadOnlyList<T> list)
4322 for (
int i = 0; i < list.Count; i++)
4324 hashCode += (hashCode * 397) ^ list[i].GetHashCode();
4368 return profitLoss > 0;
4371 var option = (
Option)security;
4404 foreach (var value
in values)
4406 if (result.HasValue)
4408 result = GreatestCommonDivisor(result.Value, value);
4416 if (!result.HasValue)
4421 return result.Value;
4427 private static int GreatestCommonDivisor(
int a,
int b)
4445 public static decimal
SafeDivision(
this decimal numerator, decimal denominator, decimal failValue = 0)
4449 return (denominator == 0) ? failValue : (numerator / denominator);
4464 if (symbols.Length != 0)
4500 private static Symbol ConvertToSymbol(PyObject item,
bool dispose)
4502 if (PyString.IsStringType(item))
4511 symbol = dispose ? item.GetAndDispose<Symbol>() : item.As<Symbol>();
4515 throw new ArgumentException(Messages.Extensions.ConvertToSymbolEnumerableFailed(item), e);