Ejemplo n.º 1
0
 /// <summary>
 /// Event invocator for the <see cref="UniverseSelection"/> event
 /// </summary>
 /// <param name="universe">The universe to perform selection on the data</param>
 /// <param name="config">The configuration of the universe</param>
 /// <param name="dateTimeUtc">The current date time in UTC</param>
 /// <param name="data">The universe selection data to be operated on</param>
 protected virtual void OnUniverseSelection(Universe universe, SubscriptionDataConfig config, DateTime dateTimeUtc, IReadOnlyList <BaseData> data)
 {
     if (UniverseSelection != null)
     {
         var eventArgs = new UniverseSelectionEventArgs(universe, config, dateTimeUtc, data);
         var multicast = (MulticastDelegate)UniverseSelection;
         foreach (UniverseSelectionHandler handler in multicast.GetInvocationList())
         {
             _changes += handler(this, eventArgs);
         }
     }
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Applies universe selection the the data feed and algorithm
        /// </summary>
        /// <param name="args">The arguments from a universe selection event, containing the universe and
        /// the data produced for selection</param>
        public SecurityChanges ApplyUniverseSelection(UniverseSelectionEventArgs args)
        {
            var universe = args.Universe;
            var settings = universe.SubscriptionSettings;

            var limit      = 1000; //daily/hourly limit
            var resolution = settings.Resolution;

            switch (resolution)
            {
            case Resolution.Tick:
                limit = _algorithm.Securities.TickLimit;
                break;

            case Resolution.Second:
                limit = _algorithm.Securities.SecondLimit;
                break;

            case Resolution.Minute:
                limit = _algorithm.Securities.MinuteLimit;
                break;
            }

            // subtract current subscriptions that can't be removed
            limit -= _algorithm.Securities.Count(x => x.Value.Resolution == resolution && x.Value.HoldStock);

            if (limit < 1)
            {
                // if we don't have room for more securities then we can't really do anything here.
                _algorithm.Error("Unable to add  more securities from universe selection due to holding stock.");
                return(SecurityChanges.None);
            }

            // perform initial filtering and limit the result
            var selections = universe.SelectSymbols(args.Data).Take(limit).ToHashSet();

            // create a hash set of our existing subscriptions by sid
            var existingSubscriptions = _dataFeed.Subscriptions.ToHashSet(x => x.Security.Symbol);

            var additions = new List <Security>();
            var removals  = new List <Security>();

            // determine which data subscriptions need to be removed for this market
            foreach (var subscription in _dataFeed.Subscriptions)
            {
                // universes can only remove members of their own
                if (!universe.ContainsMember(subscription.Security))
                {
                    continue;
                }

                // never remove universe selection subscriptions
                if (subscription.IsUniverseSelectionSubscription)
                {
                    continue;
                }

                var config = subscription.Configuration;

                // never remove internal feeds
                if (config.IsInternalFeed)
                {
                    continue;
                }

                // if we've selected this subscription again, keep it
                if (selections.Contains(config.Symbol))
                {
                    continue;
                }

                // let the algorithm know this security has been removed from the universe
                removals.Add(subscription.Security);

                // but don't physically remove it from the algorithm if we hold stock or have open orders against it
                var openOrders = _algorithm.Transactions.GetOrders(x => x.Status.IsOpen() && x.Symbol == config.Symbol);
                if (!subscription.Security.HoldStock && !openOrders.Any())
                {
                    // we need to mark this security as untradeable while it has no data subscription
                    // it is expected that this function is called while in sync with the algo thread,
                    // so we can make direct edits to the security here
                    subscription.Security.Cache.Reset();

                    if (_dataFeed.RemoveSubscription(subscription))
                    {
                        universe.RemoveMember(subscription.Security);
                    }
                }
            }

            // find new selections and add them to the algorithm
            foreach (var symbol in selections)
            {
                // we already have a subscription for this symbol so don't re-add it
                if (existingSubscriptions.Contains(symbol))
                {
                    continue;
                }

                // create the new security, the algorithm thread will add this at the appropriate time
                Security security;
                if (!_algorithm.Securities.TryGetValue(symbol, out security))
                {
                    security = SecurityManager.CreateSecurity(_algorithm.Portfolio, _algorithm.SubscriptionManager, _marketHoursDatabase,
                                                              symbol,
                                                              settings.Resolution,
                                                              settings.FillForward,
                                                              settings.Leverage,
                                                              settings.ExtendedMarketHours,
                                                              false,
                                                              false);
                }

                additions.Add(security);

                // add the new subscriptions to the data feed
                if (_dataFeed.AddSubscription(universe, security, args.DateTimeUtc, _algorithm.EndDate.ConvertToUtc(_algorithm.TimeZone)))
                {
                    universe.AddMember(security);
                }
            }

            // return None if there's no changes, otherwise return what we've modified
            return(additions.Count + removals.Count != 0
                ? new SecurityChanges(additions, removals)
                : SecurityChanges.None);
        }
 /// <summary>
 /// Event invocator for the <see cref="UniverseSelection"/> event
 /// </summary>
 /// <param name="universe">The universe to perform selection on the data</param>
 /// <param name="config">The configuration of the universe</param>
 /// <param name="dateTimeUtc">The current date time in UTC</param>
 /// <param name="data">The universe selection data to be operated on</param>
 protected virtual void OnUniverseSelection(Universe universe, SubscriptionDataConfig config, DateTime dateTimeUtc, IReadOnlyList<BaseData> data)
 {
     if (UniverseSelection != null)
     {
         var eventArgs = new UniverseSelectionEventArgs(universe, config, dateTimeUtc, data);
         var multicast = (MulticastDelegate)UniverseSelection;
         foreach (UniverseSelectionHandler handler in multicast.GetInvocationList())
         {
             _changes += handler(this, eventArgs);
         }
     }
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Applies universe selection the the data feed and algorithm
        /// </summary>
        /// <param name="args">The arguments from a universe selection event, containing the universe and
        /// the data produced for selection</param>
        public SecurityChanges ApplyUniverseSelection(UniverseSelectionEventArgs args)
        {
            var universe = args.Universe;
            var settings = universe.SubscriptionSettings;

            var limit = 1000; //daily/hourly limit
            var resolution = settings.Resolution;
            switch (resolution)
            {
                case Resolution.Tick:
                    limit = _algorithm.Securities.TickLimit;
                    break;
                case Resolution.Second:
                    limit = _algorithm.Securities.SecondLimit;
                    break;
                case Resolution.Minute:
                    limit = _algorithm.Securities.MinuteLimit;
                    break;
            }

            // subtract current subscriptions that can't be removed
            limit -= _algorithm.Securities.Count(x => x.Value.Resolution == resolution && x.Value.HoldStock);

            if (limit < 1)
            {
                // if we don't have room for more securities then we can't really do anything here.
                _algorithm.Error("Unable to add  more securities from universe selection due to holding stock.");
                return SecurityChanges.None;
            }

            // perform initial filtering and limit the result
            var selections = universe.SelectSymbols(args.Data).Take(limit).ToHashSet();

            // create a hash set of our existing subscriptions by sid
            var existingSubscriptions = _dataFeed.Subscriptions.ToHashSet(x => x.Security.Symbol);

            var additions = new List<Security>();
            var removals = new List<Security>();

            // determine which data subscriptions need to be removed for this market
            foreach (var subscription in _dataFeed.Subscriptions)
            {
                // universes can only remove members of their own
                if (!universe.ContainsMember(subscription.Security)) continue;

                // never remove universe selection subscriptions
                if (subscription.IsUniverseSelectionSubscription) continue;

                var config = subscription.Configuration;

                // never remove internal feeds
                if (config.IsInternalFeed) continue;

                // if we've selected this subscription again, keep it
                if (selections.Contains(config.Symbol)) continue;

                // let the algorithm know this security has been removed from the universe
                removals.Add(subscription.Security);

                // but don't physically remove it from the algorithm if we hold stock or have open orders against it
                var openOrders = _algorithm.Transactions.GetOrders(x => x.Status.IsOpen() && x.Symbol == config.Symbol);
                if (!subscription.Security.HoldStock && !openOrders.Any())
                {
                    // we need to mark this security as untradeable while it has no data subscription
                    // it is expected that this function is called while in sync with the algo thread,
                    // so we can make direct edits to the security here
                    subscription.Security.Cache.Reset();

                    if (_dataFeed.RemoveSubscription(subscription))
                    {
                        universe.RemoveMember(subscription.Security);
                    }
                }
            }

            // find new selections and add them to the algorithm
            foreach (var symbol in selections)
            {
                // we already have a subscription for this symbol so don't re-add it
                if (existingSubscriptions.Contains(symbol)) continue;

                // create the new security, the algorithm thread will add this at the appropriate time
                Security security;
                if (!_algorithm.Securities.TryGetValue(symbol, out security))
                {
                    security = SecurityManager.CreateSecurity(_algorithm.Portfolio, _algorithm.SubscriptionManager, _marketHoursDatabase,
                        symbol,
                        settings.Resolution,
                        settings.FillForward,
                        settings.Leverage,
                        settings.ExtendedMarketHours,
                        false,
                        false);
                }

                additions.Add(security);

                // add the new subscriptions to the data feed
                if (_dataFeed.AddSubscription(universe, security, args.DateTimeUtc, _algorithm.EndDate.ConvertToUtc(_algorithm.TimeZone)))
                {
                    universe.AddMember(security);
                }
            }

            // return None if there's no changes, otherwise return what we've modified
            return additions.Count + removals.Count != 0
                ? new SecurityChanges(additions, removals)
                : SecurityChanges.None;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Applies universe selection the the data feed and algorithm
        /// </summary>
        /// <param name="args">The arguments from a universe selection event, containing the universe and
        /// the data produced for selection</param>
        public SecurityChanges ApplyUniverseSelection(UniverseSelectionEventArgs args)
        {
            var limit = 1000; //daily/hourly limit
            var resolution = _algorithm.UniverseSettings.Resolution;
            switch (resolution)
            {
                case Resolution.Tick:
                    limit = _algorithm.Securities.TickLimit;
                    break;
                case Resolution.Second:
                    limit = _algorithm.Securities.SecondLimit;
                    break;
                case Resolution.Minute:
                    limit = _algorithm.Securities.MinuteLimit;
                    break;
            }

            // subtract current subscriptions that can't be removed
            limit -= _algorithm.Securities.Count(x => x.Value.Resolution == resolution && x.Value.HoldStock);

            if (limit < 1)
            {
                // if we don't have room for more securities then we can't really do anything here.
                _algorithm.Error("Unable to add  more securities from universe selection due to holding stock.");
                return SecurityChanges.None;
            }

            // perform initial filtering and limit the result
            var initialSelections = args.Universe.SelectSymbols(args.Data).Take(limit).ToHashSet();

            // create a hash set of our existing subscriptions by sid
            var existingSubscriptions = _dataFeed.Subscriptions.ToHashSet(x => x.Security.Symbol);

            // create a map of each selection to its 'unique' first symbol/date
            var selectedSubscriptions = initialSelections.ToHashSet();

            var additions = new List<Security>();
            var removals = new List<Security>();

            // determine which data subscriptions need to be removed for this market
            foreach (var subscription in _dataFeed.Subscriptions)
            {
                // never remove subscriptions set explicitly by the user
                if (subscription.IsUserDefined) continue;

                // never remove universe selection subscriptions
                if (subscription.IsUniverseSelectionSubscription) continue;

                var config = subscription.Configuration;

                // never remove internal feeds
                if (config.IsInternalFeed) continue;

                // don't remove subscriptions for different markets and non-equity types
                if (config.Market != args.Configuration.Market || config.SecurityType != SecurityType.Equity) continue;

                // if we've selected this subscription again, keep it
                if (selectedSubscriptions.Contains(config.Symbol)) continue;

                // let the algorithm know this security has been removed from the universe
                removals.Add(subscription.Security);

                // but don't physically remove it from the algorithm if we hold stock or have open orders against it
                var openOrders = _algorithm.Transactions.GetOrders(x => x.Status.IsOpen() && x.Symbol == config.Symbol);
                if (!subscription.Security.HoldStock && !openOrders.Any())
                {
                    // we need to mark this security as untradeable while it has no data subscription
                    // it is expected that this function is called while in sync with the algo thread,
                    // so we can make direct edits to the security here
                    subscription.Security.Cache.Reset();

                    _dataFeed.RemoveSubscription(subscription.Security);
                }
            }

            var settings = _algorithm.UniverseSettings;

            // find new selections and add them to the algorithm
            foreach (var sid in selectedSubscriptions)
            {
                // we already have a subscription for this symbol so don't re-add it
                if (existingSubscriptions.Contains(sid)) continue;

                // create the new security, the algorithm thread will add this at the appropriate time
                var security = SecurityManager.CreateSecurity(_algorithm.Portfolio, _algorithm.SubscriptionManager, _hoursProvider,
                    SecurityType.Equity,
                    sid,
                    settings.Resolution,
                    args.Configuration.Market,
                    settings.FillForward,
                    settings.Leverage,
                    settings.ExtendedMarketHours,
                    false,
                    false);

                additions.Add(security);;

                // add the new subscriptions to the data feed -- TODO : this conversion keeps the behavior the same but stinks like a bug!
                _dataFeed.AddSubscription(security, args.DateTimeUtc.ConvertFromUtc(args.Configuration.TimeZone), _algorithm.EndDate, false);
            }

            // return None if there's no changes, otherwise return what we've modified
            return additions.Count + removals.Count != 0
                ? new SecurityChanges(additions, removals)
                : SecurityChanges.None;
        }