17 using System.Collections.Generic;
38 private readonly Dictionary<DateTime, Dictionary<Symbol, Security>> _pendingSecurityAdditions =
new Dictionary<DateTime, Dictionary<Symbol, Security>>();
42 private bool _initializedSecurityBenchmark;
43 private bool _anyDoesNotHaveFundamentalDataWarningLogged;
61 _algorithm = algorithm;
62 _securityService = securityService;
79 if (_dataManager !=
null)
81 throw new Exception(
"UniverseSelection.SetDataManager(): can only be set once");
83 _dataManager = dataManager;
85 _internalSubscriptionManager.Added += (sender, request) =>
89 _internalSubscriptionManager.Removed += (sender, request) =>
103 var algorithmEndDateUtc = _algorithm.EndDate.ConvertToUtc(_algorithm.TimeZone);
104 if (dateTimeUtc > algorithmEndDateUtc)
109 IEnumerable<Symbol> selectSymbolsResult;
115 if (fineFiltered !=
null
122 selectSymbolsResult = universe.
SelectSymbols(dateTimeUtc, universeData);
130 var hasFundamentalData = universeData.
Data.Count > 0 && universeData.
Data[0] is
Fundamental;
131 if(hasFundamentalData)
134 var anyDoesNotHaveFundamentalData =
false;
139 var
set = selectSymbolsResult.ToHashSet();
140 fineCollection.Data.AddRange(universeData.
Data.OfType<
Fundamental>().Where(fundamental => {
142 if (set.Remove(fundamental.Symbol))
144 if (!fundamental.HasFundamentalData)
146 anyDoesNotHaveFundamentalData = true;
154 if (!_anyDoesNotHaveFundamentalDataWarningLogged && anyDoesNotHaveFundamentalData)
156 _algorithm.Debug(
"Note: Your coarse selection filter was updated to exclude symbols without fine fundamental data. Make sure your coarse filter excludes symbols where HasFundamental is false.");
157 _anyDoesNotHaveFundamentalDataWarningLogged =
true;
164 foreach (var symbol
in selectSymbolsResult)
166 fineCollection.Data.Add(
new Fundamental(currentTime, symbol));
170 universeData.
Data = fineCollection.Data;
172 selectSymbolsResult = fineFiltered.
PerformSelection(dateTimeUtc, fineCollection);
178 selectSymbolsResult = universe.PerformSelection(dateTimeUtc, universeData);
184 universe.Selected = selectSymbolsResult.ToHashSet();
189 RemoveSecurityFromUniverse(
190 _pendingRemovalsManager.CheckPendingRemovals(universe.Selected, universe),
192 algorithmEndDateUtc);
201 foreach (var member
in universe.Securities.Values.OrderBy(member => member.Security.Symbol.SecurityType).ThenBy(x => x.Security.Symbol.ID))
203 var security = member.Security;
205 if (universe.Selected.Contains(security.Symbol))
continue;
208 if (!universe.CanRemoveMember(dateTimeUtc, security))
continue;
210 if (!member.Security.IsDelisted)
213 _securityChangesConstructor.Remove(member.Security, member.IsInternal);
216 RemoveSecurityFromUniverse(_pendingRemovalsManager.TryRemoveMember(security, universe),
218 algorithmEndDateUtc);
221 Dictionary<Symbol, Security> pendingAdditions;
222 if (!_pendingSecurityAdditions.TryGetValue(dateTimeUtc, out pendingAdditions))
225 _pendingSecurityAdditions.Clear();
228 pendingAdditions =
new Dictionary<Symbol, Security>();
229 _pendingSecurityAdditions[dateTimeUtc] = pendingAdditions;
233 foreach (var symbol
in universe.Selected)
235 if (universe.Securities.ContainsKey(symbol))
242 if (symbol.HasUnderlying)
244 underlying = GetOrCreateSecurity(pendingAdditions, symbol.Underlying, universe.UniverseSettings);
247 var security = GetOrCreateSecurity(pendingAdditions, symbol, universe.UniverseSettings, underlying);
249 var addedSubscription =
false;
250 var dataFeedAdded =
false;
251 var internalFeed =
true;
252 foreach (var request
in universe.GetSubscriptionRequests(security, dateTimeUtc, algorithmEndDateUtc,
253 _algorithm.SubscriptionManager.SubscriptionDataConfigService))
255 if (!request.TradableDaysInDataTimeZone.Any())
262 if (security.Symbol == request.Configuration.Symbol
263 && !security.Subscriptions.Contains(request.Configuration))
266 security.AddData(request.Configuration);
269 var toRemove = _currencySubscriptionDataConfigManager.GetSubscriptionDataConfigToRemove(request.Configuration.Symbol);
270 if (toRemove !=
null)
272 Log.
Trace($
"UniverseSelection.ApplyUniverseSelection(): Removing internal currency data feed {toRemove}");
281 if (!request.IsUniverseSubscription)
283 addedSubscription =
true;
285 internalFeed &= request.Configuration.IsInternalFeed;
286 _internalSubscriptionManager.AddedSubscriptionRequest(request);
290 if (addedSubscription)
292 var addedMember = universe.AddMember(dateTimeUtc, security, internalFeed);
294 if (addedMember && dataFeedAdded)
296 _securityChangesConstructor.Add(security, internalFeed);
301 var securityChanges = _securityChangesConstructor.Flush();
304 if (securityChanges.AddedSecurities.Count > 0)
313 Log.
Debug(
"UniverseSelection.ApplyUniverseSelection(): " + dateTimeUtc +
": " + securityChanges);
316 return securityChanges;
327 if (!_initializedSecurityBenchmark)
329 _initializedSecurityBenchmark =
true;
332 if (securityBenchmark !=
null)
337 var subscriptionType = _algorithm.SubscriptionManager.SubscriptionDataConfigService.LookupSubscriptionConfigDataTypes(securityBenchmark.Security.Type, resolution, securityBenchmark.Security.Symbol.IsCanonical()).First();
339 var isCustomData =
false;
345 var symbolDataConfigs = _algorithm.SubscriptionManager.SubscriptionDataConfigService.GetSubscriptionDataConfigs(symbol);
346 if (symbolDataConfigs.Any())
348 subscriptionType =
new Tuple<Type, TickType>(symbolDataConfigs.First().Type,
TickType.Trade);
353 var baseInstance = subscriptionType.Item1.GetBaseDataInstance();
354 baseInstance.Symbol = securityBenchmark.Security.Symbol;
355 var supportedResolutions = baseInstance.SupportedResolutions();
356 if (!supportedResolutions.Contains(resolution))
358 resolution = supportedResolutions.OrderByDescending(x => x).First();
361 var subscriptionList =
new List<Tuple<Type, TickType>>() {subscriptionType};
362 var dataConfig = _algorithm.SubscriptionManager.SubscriptionDataConfigService.Add(
363 securityBenchmark.Security.Symbol,
365 isInternalFeed:
true,
367 isCustomData: isCustomData,
368 subscriptionDataTypes: subscriptionList
374 securityBenchmark.Security.Exchange.Hours,
375 utcStart.ConvertFromUtc(securityBenchmark.Security.Exchange.TimeZone),
379 dataConfig.DataTimeZone,
381 ).ConvertToUtc(securityBenchmark.Security.Exchange.TimeZone);
383 if (dataConfig !=
null)
388 securityBenchmark.Security,
391 _algorithm.EndDate.ConvertToUtc(_algorithm.TimeZone)));
393 Log.
Trace($
"UniverseSelection.AddPendingInternalDataFeeds(): Adding internal benchmark data feed {dataConfig}");
398 if (_currencySubscriptionDataConfigManager.UpdatePendingSubscriptionDataConfigs(_algorithm.BrokerageModel))
400 foreach (var subscriptionDataConfig
in _currencySubscriptionDataConfigManager
401 .GetPendingSubscriptionDataConfigs())
403 var security = _algorithm.Securities[subscriptionDataConfig.Symbol];
408 subscriptionDataConfig,
410 _algorithm.EndDate.ConvertToUtc(_algorithm.TimeZone)));
421 _currencySubscriptionDataConfigManager.EnsureCurrencySubscriptionDataConfigs(securityChanges, _algorithm.BrokerageModel);
429 if (_algorithm.Securities.TryGetValue(data.
Symbol, out var security))
432 security.IsDelisted =
true;
433 security.IsTradable =
false;
437 if (_algorithm.Securities.Remove(data.
Symbol) && !_pendingRemovalsManager.PendingRemovals.Values.Any(x => x.Any(y => y.Symbol == data.
Symbol)))
439 _securityChangesConstructor.Remove(security, isInternalFeed);
441 return _securityChangesConstructor.Flush();
448 private void RemoveSecurityFromUniverse(
449 List<PendingRemovalsManager.RemovedMember> removedMembers,
450 DateTime dateTimeUtc,
451 DateTime algorithmEndDateUtc)
453 if (removedMembers ==
null)
457 foreach (var removedMember
in removedMembers)
459 var universe = removedMember.Universe;
460 var member = removedMember.Security;
463 universe.RemoveMember(dateTimeUtc, member);
465 var isActive = _algorithm.UniverseManager.ActiveSecurities.ContainsKey(member.Symbol);
466 foreach (var subscription
in universe.GetSubscriptionRequests(member, dateTimeUtc, algorithmEndDateUtc,
467 _algorithm.SubscriptionManager.SubscriptionDataConfigService))
471 _internalSubscriptionManager.RemovedSubscriptionRequest(subscription);
476 member.IsTradable =
false;
481 member.Cache.Reset();
483 _algorithm.Securities.Remove(member.Symbol);
490 private Security GetOrCreateSecurity(Dictionary<Symbol, Security> pendingAdditions, Symbol symbol,
UniverseSettings universeSettings,
Security underlying =
null)
494 if (!pendingAdditions.TryGetValue(symbol, out security) && !_algorithm.Securities.TryGetValue(symbol, out security))
496 security = _securityService.CreateSecurity(symbol,
new List<SubscriptionDataConfig>(), universeSettings.
Leverage, symbol.ID.SecurityType.IsOption(), underlying);
498 pendingAdditions.
Add(symbol, security);