/// <summary> /// Adds a new <see cref="Subscription"/> to provide data for the specified security. /// </summary> /// <param name="request">Defines the <see cref="SubscriptionRequest"/> to be added</param> /// <returns>True if the subscription was created and added successfully, false otherwise</returns> public bool AddSubscription(SubscriptionRequest request) { Subscription subscription; if (DataFeedSubscriptions.TryGetValue(request.Configuration, out subscription)) { // duplicate subscription request return(subscription.AddSubscriptionRequest(request)); } subscription = _dataFeed.CreateSubscription(request); if (subscription == null) { Log.Trace($"DataManager.AddSubscription(): Unable to add subscription for: {request.Configuration}"); // subscription will be null when there's no tradeable dates for the security between the requested times, so // don't even try to load the data return(false); } if (_liveMode) { OnSubscriptionAdded(subscription); } LiveDifferentiatedLog($"DataManager.AddSubscription(): Added {request.Configuration}." + $" Start: {request.StartTimeUtc}. End: {request.EndTimeUtc}"); return(DataFeedSubscriptions.TryAdd(subscription)); }
/// <summary> /// Adds a new subscription to provide data for the specified security. /// </summary> /// <param name="request">Defines the subscription to be added, including start/end times the universe and security</param> /// <returns>True if the subscription was created and added successfully, false otherwise</returns> public bool AddSubscription(SubscriptionRequest request) { if (_subscriptions.Contains(request.Configuration)) { // duplicate subscription request return(false); } var subscription = request.IsUniverseSubscription ? CreateUniverseSubscription(request) : CreateSubscription(request); if (subscription == null) { // subscription will be null when there's no tradeable dates for the security between the requested times, so // don't even try to load the data return(false); } Log.Debug("FileSystemDataFeed.AddSubscription(): Added " + request.Configuration + " Start: " + request.StartTimeUtc + " End: " + request.EndTimeUtc); if (_subscriptions.TryAdd(subscription)) { UpdateFillForwardResolution(); } return(true); }
/// <summary> /// Adds a new subscription to provide data for the specified security. /// </summary> /// <param name="universe">The universe the subscription is to be added to</param> /// <param name="security">The security to add a subscription for</param> /// <param name="config">The subscription config to be added</param> /// <param name="utcStartTime">The start time of the subscription</param> /// <param name="utcEndTime">The end time of the subscription</param> public bool AddSubscription(Universe universe, Security security, SubscriptionDataConfig config, DateTime utcStartTime, DateTime utcEndTime) { var subscription = CreateSubscription(universe, security, config, utcStartTime, utcEndTime); if (subscription == null) { // subscription will be null when there's no tradeable dates for the security between the requested times, so // don't even try to load the data return(false); } Log.Debug("FileSystemDataFeed.AddSubscription(): Added " + security.Symbol.ID + " Start: " + utcStartTime + " End: " + utcEndTime); if (_subscriptions.TryAdd(subscription)) { UpdateFillForwardResolution(); } return(true); }
/// <summary> /// Adds a new <see cref="Subscription"/> to provide data for the specified security. /// </summary> /// <param name="request">Defines the <see cref="SubscriptionRequest"/> to be added</param> /// <returns>True if the subscription was created and added successfully, false otherwise</returns> public bool AddSubscription(SubscriptionRequest request) { // guarantee the configuration is present in our config collection // this is related to GH issue 3877: where we added a configuration which we also removed _subscriptionManagerSubscriptions.TryAdd(request.Configuration, request.Configuration); Subscription subscription; if (DataFeedSubscriptions.TryGetValue(request.Configuration, out subscription)) { // duplicate subscription request subscription.AddSubscriptionRequest(request); // only result true if the existing subscription is internal, we actually added something from the users perspective return(subscription.Configuration.IsInternalFeed); } // before adding the configuration to the data feed let's assert it's valid _dataPermissionManager.AssertConfiguration(request.Configuration, request.StartTimeLocal, request.EndTimeLocal); subscription = _dataFeed.CreateSubscription(request); if (subscription == null) { Log.Trace($"DataManager.AddSubscription(): Unable to add subscription for: {request.Configuration}"); // subscription will be null when there's no tradeable dates for the security between the requested times, so // don't even try to load the data return(false); } if (_liveMode) { OnSubscriptionAdded(subscription); Log.Trace($"DataManager.AddSubscription(): Added {request.Configuration}." + $" Start: {request.StartTimeUtc}. End: {request.EndTimeUtc}"); } else if (Log.DebuggingEnabled) { // for performance lets not create the message string if debugging is not enabled // this can be executed many times and its in the algorithm thread Log.Debug($"DataManager.AddSubscription(): Added {request.Configuration}." + $" Start: {request.StartTimeUtc}. End: {request.EndTimeUtc}"); } return(DataFeedSubscriptions.TryAdd(subscription)); }
/// <summary> /// Adds a new <see cref="Subscription"/> to provide data for the specified security. /// </summary> /// <param name="request">Defines the <see cref="SubscriptionRequest"/> to be added</param> /// <returns>True if the subscription was created and added successfully, false otherwise</returns> public bool AddSubscription(SubscriptionRequest request) { if (DataFeedSubscriptions.Contains(request.Configuration)) { // duplicate subscription request return(false); } var subscription = _dataFeed.CreateSubscription(request); if (subscription == null) { Log.Trace($"DataManager.AddSubscription(): Unable to add subscription for: {request.Configuration}"); // subscription will be null when there's no tradeable dates for the security between the requested times, so // don't even try to load the data return(false); } Log.Debug($"DataManager.AddSubscription(): Added {request.Configuration}." + $" Start: {request.StartTimeUtc}. End: {request.EndTimeUtc}"); return(DataFeedSubscriptions.TryAdd(subscription)); }
/// <summary> /// Adds a new <see cref="Subscription"/> to provide data for the specified security. /// </summary> /// <param name="request">Defines the <see cref="SubscriptionRequest"/> to be added</param> /// <returns>True if the subscription was created and added successfully, false otherwise</returns> public bool AddSubscription(SubscriptionRequest request) { Subscription subscription; if (DataFeedSubscriptions.TryGetValue(request.Configuration, out subscription)) { // duplicate subscription request return(subscription.AddSubscriptionRequest(request)); } subscription = _dataFeed.CreateSubscription(request); if (subscription == null) { Log.Trace($"DataManager.AddSubscription(): Unable to add subscription for: {request.Configuration}"); // subscription will be null when there's no tradeable dates for the security between the requested times, so // don't even try to load the data return(false); } if (_liveMode) { OnSubscriptionAdded(subscription); Log.Trace($"DataManager.AddSubscription(): Added {request.Configuration}." + $" Start: {request.StartTimeUtc}. End: {request.EndTimeUtc}"); } else if (Log.DebuggingEnabled) { // for performance lets not create the message string if debugging is not enabled // this can be executed many times and its in the algorithm thread Log.Debug($"DataManager.AddSubscription(): Added {request.Configuration}." + $" Start: {request.StartTimeUtc}. End: {request.EndTimeUtc}"); } return(DataFeedSubscriptions.TryAdd(subscription)); }
/// <summary> /// Initializes the data feed for the specified job and algorithm /// </summary> public void Initialize(IAlgorithm algorithm, AlgorithmNodePacket job, IResultHandler resultHandler, IMapFileProvider mapFileProvider, IFactorFileProvider factorFileProvider) { if (!(job is LiveNodePacket)) { throw new ArgumentException("The LiveTradingDataFeed requires a LiveNodePacket."); } _cancellationTokenSource = new CancellationTokenSource(); _algorithm = algorithm; _job = (LiveNodePacket)job; _resultHandler = resultHandler; _timeProvider = GetTimeProvider(); _dataQueueHandler = GetDataQueueHandler(); _frontierTimeProvider = new ManualTimeProvider(_timeProvider.GetUtcNow()); _customExchange = new BaseDataExchange("CustomDataExchange") { SleepInterval = 10 }; // sleep is controlled on this exchange via the GetNextTicksEnumerator _exchange = new BaseDataExchange("DataQueueExchange") { SleepInterval = 0 }; _exchange.AddEnumerator(DataQueueHandlerSymbol, GetNextTicksEnumerator()); _subscriptions = new SubscriptionCollection(); _bridge = new BusyBlockingCollection <TimeSlice>(); _universeSelection = new UniverseSelection(this, algorithm, job.Controls); // run the exchanges Task.Run(() => _exchange.Start(_cancellationTokenSource.Token)); Task.Run(() => _customExchange.Start(_cancellationTokenSource.Token)); // this value will be modified via calls to AddSubscription/RemoveSubscription var ffres = Time.OneMinute; _fillForwardResolution = Ref.Create(() => ffres, v => ffres = v); // wire ourselves up to receive notifications when universes are added/removed var start = _timeProvider.GetUtcNow(); algorithm.UniverseManager.CollectionChanged += (sender, args) => { switch (args.Action) { case NotifyCollectionChangedAction.Add: foreach (var universe in args.NewItems.OfType <Universe>()) { if (!_subscriptions.Contains(universe.Configuration)) { _subscriptions.TryAdd(CreateUniverseSubscription(universe, start, Time.EndOfTime)); } // Not sure if this is needed but left here because of this: // https://github.com/QuantConnect/Lean/commit/029d70bde6ca83a1eb0c667bb5cc4444bea05678 UpdateFillForwardResolution(); } break; case NotifyCollectionChangedAction.Remove: foreach (var universe in args.OldItems.OfType <Universe>()) { RemoveSubscription(universe.Configuration); } break; default: throw new NotImplementedException("The specified action is not implemented: " + args.Action); } }; }