/// <summary> /// Creates the universes for this algorithm. /// Called at algorithm start. /// </summary> /// <returns>The universes defined by this model</returns> public override IEnumerable <Universe> CreateUniverses(QCAlgorithmFramework algorithm) { var universeSettings = _universeSettings ?? algorithm.UniverseSettings; var securityInitializer = _securityInitializer ?? algorithm.SecurityInitializer; var resolution = universeSettings.Resolution; var type = resolution == Resolution.Tick ? typeof(Tick) : typeof(TradeBar); // universe per security type/market foreach (var grp in _symbols.GroupBy(s => new { s.ID.Market, s.SecurityType })) { MarketHoursDatabase.Entry entry; var market = grp.Key.Market; var securityType = grp.Key.SecurityType; var universeSymbol = Symbol.Create($"manual-universe-selection-model-{securityType}-{market}", securityType, market); if (securityType == SecurityType.Base) { // add an entry for this custom universe symbol -- we don't really know the time zone for sure, // but we set it to TimeZones.NewYork in AddData, also, since this is a manual universe, the time // zone doesn't actually matter since this universe specifically doesn't do anything with data. var symbolString = MarketHoursDatabase.GetDatabaseSymbolKey(universeSymbol); var alwaysOpen = SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork); entry = MarketHours.SetEntry(market, symbolString, securityType, alwaysOpen, TimeZones.NewYork); } else { entry = MarketHours.GetEntry(market, (string)null, securityType); } var config = new SubscriptionDataConfig(type, universeSymbol, resolution, entry.DataTimeZone, entry.ExchangeHours.TimeZone, false, false, true); yield return(new ManualUniverse(config, universeSettings, grp)); } }
/// <summary> /// Adds the security to the user defined universe for the specified /// </summary> private void AddToUserDefinedUniverse(Security security) { // if we are adding a non-internal security which already has an internal feed, we remove it first Security existingSecurity; if (Securities.TryGetValue(security.Symbol, out existingSecurity)) { if (!security.IsInternalFeed() && existingSecurity.IsInternalFeed()) { var securityUniverse = UniverseManager.Select(x => x.Value).OfType <UserDefinedUniverse>().FirstOrDefault(x => x.Members.ContainsKey(security.Symbol)); securityUniverse?.Remove(security.Symbol); Securities.Remove(security.Symbol); } } Securities.Add(security); // add this security to the user defined universe Universe universe; var subscription = security.Subscriptions.First(); var universeSymbol = UserDefinedUniverse.CreateSymbol(subscription.SecurityType, subscription.Market); if (!UniverseManager.TryGetValue(universeSymbol, out universe)) { // create a new universe, these subscription settings don't currently get used // since universe selection proper is never invoked on this type of universe var uconfig = new SubscriptionDataConfig(subscription, symbol: universeSymbol, isInternalFeed: true, fillForward: false); if (security.Type == SecurityType.Base) { // set entry in market hours database for the universe subscription to match the custom data var symbolString = MarketHoursDatabase.GetDatabaseSymbolKey(uconfig.Symbol); MarketHoursDatabase.SetEntry(uconfig.Market, symbolString, uconfig.SecurityType, security.Exchange.Hours, uconfig.DataTimeZone); } universe = new UserDefinedUniverse(uconfig, new UniverseSettings(security.Resolution, security.Leverage, security.IsFillDataForward, security.IsExtendedMarketHours, TimeSpan.Zero), SecurityInitializer, QuantConnect.Time.MaxTimeSpan, new List <Symbol> { security.Symbol } ); UniverseManager.Add(universeSymbol, universe); } var userDefinedUniverse = universe as UserDefinedUniverse; if (userDefinedUniverse != null) { userDefinedUniverse.Add(security.Symbol); } else { // should never happen, someone would need to add a non-user defined universe with this symbol throw new Exception("Expected universe with symbol '" + universeSymbol.Value + "' to be of type UserDefinedUniverse."); } }
public void FuturesOptionsGetDatabaseSymbolKey(string ticker, string market, string expected) { var future = Symbol.Create(ticker, SecurityType.Future, market); var option = Symbol.CreateOption( future, market, default(OptionStyle), default(OptionRight), default(decimal), SecurityIdentifier.DefaultDate); Assert.AreEqual(expected, MarketHoursDatabase.GetDatabaseSymbolKey(option)); }
/// <summary> /// Adds the security to the user defined universe /// </summary> /// <param name="security">The security to add</param> /// <param name="configurations">The <see cref="SubscriptionDataConfig"/> instances we want to add</param> private Security AddToUserDefinedUniverse( Security security, List <SubscriptionDataConfig> configurations) { var subscription = configurations.First(); // if we are adding a non-internal security which already has an internal feed, we remove it first if (Securities.TryGetValue(security.Symbol, out var existingSecurity)) { if (!subscription.IsInternalFeed && existingSecurity.IsInternalFeed()) { var securityUniverse = UniverseManager.Select(x => x.Value).OfType <UserDefinedUniverse>().FirstOrDefault(x => x.Members.ContainsKey(security.Symbol)); securityUniverse?.Remove(security.Symbol); Securities.Remove(security.Symbol); Securities.Add(security); } else { var isTradable = security.IsTradable; // We will reuse existing so we return it to the user. // We will use the IsTradable flag of the new security, since existing could of been set to false when removed security = existingSecurity; security.IsTradable = isTradable; } } else { Securities.Add(security); } // add this security to the user defined universe Universe universe; var universeSymbol = UserDefinedUniverse.CreateSymbol(security.Type, security.Symbol.ID.Market); lock (_pendingUniverseAdditionsLock) { if (!UniverseManager.TryGetValue(universeSymbol, out universe)) { universe = _pendingUniverseAdditions.FirstOrDefault(x => x.Configuration.Symbol == universeSymbol); if (universe == null) { // create a new universe, these subscription settings don't currently get used // since universe selection proper is never invoked on this type of universe var uconfig = new SubscriptionDataConfig(subscription, symbol: universeSymbol, isInternalFeed: true, fillForward: false, exchangeTimeZone: DateTimeZone.Utc, dataTimeZone: DateTimeZone.Utc); // this is the universe symbol, has no real entry in the mhdb, will default to market and security type // set entry in market hours database for the universe subscription to match the config var symbolString = MarketHoursDatabase.GetDatabaseSymbolKey(uconfig.Symbol); MarketHoursDatabase.SetEntry(uconfig.Market, symbolString, uconfig.SecurityType, SecurityExchangeHours.AlwaysOpen(uconfig.ExchangeTimeZone), uconfig.DataTimeZone); universe = new UserDefinedUniverse(uconfig, new UniverseSettings( subscription.Resolution, security.Leverage, subscription.FillDataForward, subscription.ExtendedMarketHours, TimeSpan.Zero), QuantConnect.Time.MaxTimeSpan, new List <Symbol>()); AddUniverse(universe); } } } var userDefinedUniverse = universe as UserDefinedUniverse; if (userDefinedUniverse != null) { lock (_pendingUniverseAdditionsLock) { _pendingUserDefinedUniverseSecurityAdditions.Add( new UserDefinedUniverseAddition(userDefinedUniverse, configurations, security)); } } else { // should never happen, someone would need to add a non-user defined universe with this symbol throw new Exception($"Expected universe with symbol '{universeSymbol.Value}' to be of type {nameof(UserDefinedUniverse)} but was {universe.GetType().Name}."); } return(security); }
public override void OnEndOfAlgorithm() { // Reset our Symbol property value, for testing purposes. SymbolPropertiesDatabase.SetEntry(Market.USA, MarketHoursDatabase.GetDatabaseSymbolKey(_bitcoin.Symbol), SecurityType.Base, SymbolProperties.GetDefault("USD")); }