17 using System.Collections.Generic;
38 private readonly Dictionary<DateTime, Dictionary<Symbol, Security>> _pendingSecurityAdditions =
new Dictionary<DateTime, Dictionary<Symbol, Security>>();
42 private bool _initializedSecurityBenchmark;
44 private bool _anyDoesNotHaveFundamentalDataWarningLogged;
62 _dataProvider = dataProvider;
63 _algorithm = algorithm;
64 _securityService = securityService;
81 if (_dataManager !=
null)
83 throw new Exception(
"UniverseSelection.SetDataManager(): can only be set once");
85 _dataManager = dataManager;
87 _internalSubscriptionManager.Added += (sender, request) =>
91 _internalSubscriptionManager.Removed += (sender, request) =>
105 var algorithmEndDateUtc = _algorithm.EndDate.ConvertToUtc(_algorithm.TimeZone);
106 if (dateTimeUtc > algorithmEndDateUtc)
111 IEnumerable<Symbol> selectSymbolsResult;
117 if (fineFiltered !=
null
124 selectSymbolsResult = universe.
SelectSymbols(dateTimeUtc, universeData);
132 var hasFundamentalData = universeData.
Data.Count > 0 && universeData.
Data[0] is
Fundamental;
133 if(hasFundamentalData)
136 var anyDoesNotHaveFundamentalData =
false;
141 var
set = selectSymbolsResult.ToHashSet();
142 fineCollection.Data.AddRange(universeData.
Data.OfType<
Fundamental>().Where(fundamental => {
144 if (set.Remove(fundamental.Symbol))
146 if (!fundamental.HasFundamentalData)
148 anyDoesNotHaveFundamentalData = true;
156 if (!_anyDoesNotHaveFundamentalDataWarningLogged && anyDoesNotHaveFundamentalData)
158 _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.");
159 _anyDoesNotHaveFundamentalDataWarningLogged =
true;
166 foreach (var symbol
in selectSymbolsResult)
168 fineCollection.Data.Add(
new Fundamental(currentTime, symbol));
172 universeData.
Data = fineCollection.Data;
174 selectSymbolsResult = fineFiltered.
PerformSelection(dateTimeUtc, fineCollection);
180 selectSymbolsResult = universe.PerformSelection(dateTimeUtc, universeData);
186 universe.Selected = selectSymbolsResult.ToHashSet();
191 RemoveSecurityFromUniverse(
192 _pendingRemovalsManager.CheckPendingRemovals(universe.Selected, universe),
194 algorithmEndDateUtc);
203 foreach (var member
in universe.Securities.Values.OrderBy(member => member.Security.Symbol.SecurityType).ThenBy(x => x.Security.Symbol.ID))
205 var security = member.Security;
207 if (universe.Selected.Contains(security.Symbol))
continue;
210 if (!universe.CanRemoveMember(dateTimeUtc, security))
continue;
212 if (!member.Security.IsDelisted)
215 _securityChangesConstructor.Remove(member.Security, member.IsInternal);
218 RemoveSecurityFromUniverse(_pendingRemovalsManager.TryRemoveMember(security, universe),
220 algorithmEndDateUtc);
223 Dictionary<Symbol, Security> pendingAdditions;
224 if (!_pendingSecurityAdditions.TryGetValue(dateTimeUtc, out pendingAdditions))
227 _pendingSecurityAdditions.Clear();
230 pendingAdditions =
new Dictionary<Symbol, Security>();
231 _pendingSecurityAdditions[dateTimeUtc] = pendingAdditions;
235 foreach (var symbol
in universe.Selected)
237 if (universe.Securities.ContainsKey(symbol))
244 if (symbol.HasUnderlying)
246 underlying = GetOrCreateSecurity(pendingAdditions, symbol.Underlying, universe.UniverseSettings);
249 var security = GetOrCreateSecurity(pendingAdditions, symbol, universe.UniverseSettings, underlying);
251 var addedSubscription =
false;
252 var dataFeedAdded =
false;
253 var internalFeed =
true;
254 foreach (var request
in universe.GetSubscriptionRequests(security, dateTimeUtc, algorithmEndDateUtc,
255 _algorithm.SubscriptionManager.SubscriptionDataConfigService))
257 if (security.Symbol == request.Configuration.Symbol
258 && !security.Subscriptions.Contains(request.Configuration))
261 security.AddData(request.Configuration);
264 var toRemove = _currencySubscriptionDataConfigManager.GetSubscriptionDataConfigToRemove(request.Configuration.Symbol);
265 if (toRemove !=
null)
267 Log.
Trace($
"UniverseSelection.ApplyUniverseSelection(): Removing internal currency data feed {toRemove}");
276 if (!request.IsUniverseSubscription)
278 addedSubscription =
true;
280 internalFeed &= request.Configuration.IsInternalFeed;
281 _internalSubscriptionManager.AddedSubscriptionRequest(request);
285 if (addedSubscription)
287 var addedMember = universe.AddMember(dateTimeUtc, security, internalFeed);
289 if (addedMember && dataFeedAdded)
291 _securityChangesConstructor.Add(security, internalFeed);
296 var securityChanges = _securityChangesConstructor.Flush();
299 if (securityChanges.AddedSecurities.Count > 0)
308 Log.
Debug(
"UniverseSelection.ApplyUniverseSelection(): " + dateTimeUtc +
": " + securityChanges);
311 return securityChanges;
322 if (!_initializedSecurityBenchmark)
324 _initializedSecurityBenchmark =
true;
327 if (securityBenchmark !=
null)
332 var subscriptionType = _algorithm.SubscriptionManager.SubscriptionDataConfigService.LookupSubscriptionConfigDataTypes(securityBenchmark.Security.Type, resolution, securityBenchmark.Security.Symbol.IsCanonical()).First();
334 var isCustomData =
false;
340 var symbolDataConfigs = _algorithm.SubscriptionManager.SubscriptionDataConfigService.GetSubscriptionDataConfigs(symbol);
341 if (symbolDataConfigs.Any())
343 subscriptionType =
new Tuple<Type, TickType>(symbolDataConfigs.First().Type,
TickType.Trade);
348 var baseInstance = subscriptionType.Item1.GetBaseDataInstance();
349 baseInstance.Symbol = securityBenchmark.Security.Symbol;
350 var supportedResolutions = baseInstance.SupportedResolutions();
351 if (!supportedResolutions.Contains(resolution))
353 resolution = supportedResolutions.OrderByDescending(x => x).First();
356 var subscriptionList =
new List<Tuple<Type, TickType>>() {subscriptionType};
357 var dataConfig = _algorithm.SubscriptionManager.SubscriptionDataConfigService.Add(
358 securityBenchmark.Security.Symbol,
360 isInternalFeed:
true,
362 isCustomData: isCustomData,
363 subscriptionDataTypes: subscriptionList
369 securityBenchmark.Security.Exchange.Hours,
370 utcStart.ConvertFromUtc(securityBenchmark.Security.Exchange.TimeZone),
374 dataConfig.DataTimeZone,
376 ).ConvertToUtc(securityBenchmark.Security.Exchange.TimeZone);
378 if (dataConfig !=
null)
383 securityBenchmark.Security,
386 _algorithm.EndDate.ConvertToUtc(_algorithm.TimeZone)));
388 Log.
Trace($
"UniverseSelection.AddPendingInternalDataFeeds(): Adding internal benchmark data feed {dataConfig}");
393 if (_currencySubscriptionDataConfigManager.UpdatePendingSubscriptionDataConfigs(_algorithm.BrokerageModel))
395 foreach (var subscriptionDataConfig
in _currencySubscriptionDataConfigManager
396 .GetPendingSubscriptionDataConfigs())
398 var security = _algorithm.Securities[subscriptionDataConfig.Symbol];
403 subscriptionDataConfig,
405 _algorithm.EndDate.ConvertToUtc(_algorithm.TimeZone)));
416 _currencySubscriptionDataConfigManager.EnsureCurrencySubscriptionDataConfigs(securityChanges, _algorithm.BrokerageModel);
424 if (_algorithm.Securities.TryGetValue(data.
Symbol, out var security))
427 security.IsDelisted =
true;
428 security.IsTradable =
false;
430 if (_algorithm.Securities.Remove(data.
Symbol))
432 _securityChangesConstructor.Remove(security, isInternalFeed);
434 return _securityChangesConstructor.Flush();
441 private void RemoveSecurityFromUniverse(
442 List<PendingRemovalsManager.RemovedMember> removedMembers,
443 DateTime dateTimeUtc,
444 DateTime algorithmEndDateUtc)
446 if (removedMembers ==
null)
450 foreach (var removedMember
in removedMembers)
452 var universe = removedMember.Universe;
453 var member = removedMember.Security;
456 universe.RemoveMember(dateTimeUtc, member);
458 var isActive = _algorithm.UniverseManager.ActiveSecurities.ContainsKey(member.Symbol);
459 foreach (var subscription
in universe.GetSubscriptionRequests(member, dateTimeUtc, algorithmEndDateUtc,
460 _algorithm.SubscriptionManager.SubscriptionDataConfigService))
464 _internalSubscriptionManager.RemovedSubscriptionRequest(subscription);
469 member.IsTradable =
false;
474 member.Cache.Reset();
476 _algorithm.Securities.Remove(member.Symbol);
483 private Security GetOrCreateSecurity(Dictionary<Symbol, Security> pendingAdditions, Symbol symbol,
UniverseSettings universeSettings,
Security underlying =
null)
487 if (!pendingAdditions.TryGetValue(symbol, out security) && !_algorithm.Securities.TryGetValue(symbol, out security))
489 security = _securityService.CreateSecurity(symbol,
new List<SubscriptionDataConfig>(), universeSettings.
Leverage, symbol.ID.SecurityType.IsOption(), underlying);
491 pendingAdditions.
Add(symbol, security);