示例#1
0
 private static IEnumerator <BaseData> GetNextTicksEnumerator(IDataQueueHandler dataQueueHandler)
 {
     while (true)
     {
         int ticks = 0;
         foreach (var data in dataQueueHandler.GetNextTicks())
         {
             ticks++;
             yield return(data);
         }
         if (ticks == 0)
         {
             Thread.Sleep(1);
         }
     }
 }
示例#2
0
 /// <summary>
 /// Provides an <see cref="IEnumerator{BaseData}"/> that will continually dequeue data
 /// from the data queue handler while we're not cancelled
 /// </summary>
 /// <returns></returns>
 private IEnumerator <BaseData> GetNextTicksEnumerator()
 {
     while (!_cancellationTokenSource.IsCancellationRequested)
     {
         int ticks = 0;
         foreach (var data in _dataQueueHandler.GetNextTicks())
         {
             ticks++;
             yield return(data);
         }
         if (ticks == 0)
         {
             Thread.Sleep(1);
         }
     }
 }
示例#3
0
        /// <summary>
        /// Stream Store Consumer uses the GetNextTicks() function to get current ticks from a data source and
        /// then uses the stream store to compile them into trade bars.
        /// </summary>
        public void StreamStoreConsumer()
        {
            //Initialize
            var update = new Dictionary <int, DateTime>();

            //Scan for the required time period to stream:
            Log.Trace("LiveTradingDataFeed.Stream(): Waiting for updated market hours...", true);

            //Awake:
            Log.Trace("LiveTradingDataFeed.Stream(): Market open, starting stream for " + string.Join(",", _symbols));

            //Micro-thread for polling for new data from data source:
            var liveThreadTask = new Task(() =>
            {
                if (_isDynamicallyLoadedData.All(x => x))
                {
                    // if we're all custom data data don't waste CPU cycle with this thread
                    return;
                }

                //Blocking ForEach - Should stay within this loop as long as there is a data-connection
                while (true)
                {
                    var dataCollection = _dataQueue.GetNextTicks();

                    int ticksCount = 0;
                    foreach (var point in dataCollection)
                    {
                        ticksCount++;

                        //Get the stream store with this symbol:
                        for (var i = 0; i < Subscriptions.Count; i++)
                        {
                            if (_subscriptions[i].Symbol != point.Symbol)
                            {
                                continue;
                            }

                            var tick = point as Tick;
                            if (tick != null)
                            {
                                if (_subscriptions[i].Resolution == Resolution.Tick)
                                {
                                    // put ticks directly into the bridge
                                    AddSingleItemToBridge(tick, i);
                                }
                                else
                                {
                                    // Update our internal counter
                                    _streamStores[i].Update(tick);
                                    // Update the realtime price stream value
                                    _realtimePrices[i] = point.Value;
                                }
                            }
                            else
                            {
                                // reset the start time so it goes in sync with other data
                                point.Time = DateTime.Now.RoundDown(_subscriptions[i].Increment);

                                //If its not a tick, inject directly into bridge for this symbol:
                                //Bridge[i].Enqueue(new List<BaseData> {point});
                                AddSingleItemToBridge(point, i);
                            }
                        }
                    }

                    if (_exitTriggered)
                    {
                        return;
                    }
                    if (ticksCount == 0)
                    {
                        Thread.Sleep(5);
                    }
                }
            });

            // Micro-thread for custom data/feeds. This only supports polling at this time. todo: Custom data sockets
            var customFeedsTask = new Task(() =>
            {
                // used to help prevent future data from entering the algorithm
                // initial to all true, when we get future data, flip flag to false to prevent move next
                var needsMoveNext = Enumerable.Range(0, Subscriptions.Count).Select(x => true).ToArray();
                while (true)
                {
                    for (var i = 0; i < Subscriptions.Count; i++)
                    {
                        if (_isDynamicallyLoadedData[i])
                        {
                            if (!update.ContainsKey(i))
                            {
                                update.Add(i, new DateTime());
                            }

                            if (DateTime.Now > update[i])
                            {
                                //Now Time has passed -> Trigger a refresh,

                                if (needsMoveNext[i])
                                {
                                    // if we didn't emit the previous value it's because it was in
                                    // the future, so don't call MoveNext, just perform the date range
                                    // checks below again

                                    // in live mode subscription reader will move next but return null for current since nothing is there
                                    _subscriptionManagers[i].MoveNext();
                                    // true success defined as if we got a non-null value
                                    if (_subscriptionManagers[i].Current == null)
                                    {
                                        // we failed to get new data for this guy, try again next second
                                        update[i] = DateTime.Now.Add(Time.OneSecond);
                                        continue;
                                    }
                                }

                                // if we didn't get anything keep going
                                var data = _subscriptionManagers[i].Current;
                                if (data == null)
                                {
                                    // heuristically speaking this should already be true, but no harm in explicitly setting it
                                    needsMoveNext[i] = true;
                                    continue;
                                }

                                // check to see if the data is too far in the past
                                // this is useful when using custom remote files that may stretch far into the past,
                                // so this if block will cause us to fast forward the reader until its recent increment
                                if (data.EndTime < DateTime.Now.Subtract(_subscriptions[i].Increment.Add(Time.OneSecond)))
                                {
                                    // repeat this subscription, we're in the past still
                                    i--;
                                    continue;
                                }

                                // don't emit data in the future
                                if (data.EndTime < DateTime.Now)
                                {
                                    if (_subscriptions[i].Resolution == Resolution.Tick)
                                    {
                                        // put ticks directly into the bridge
                                        AddSingleItemToBridge(data, i);
                                    }
                                    else
                                    {
                                        _streamStores[i].Update(data);   //Update bar builder.
                                        _realtimePrices[i] = data.Value; //Update realtime price value.
                                        needsMoveNext[i]   = true;
                                    }
                                }
                                else
                                {
                                    // since this data is in the future and we didn't emit it,
                                    // don't call MoveNext again and we'll keep performing time checks
                                    // until its end time has passed and we can emit it into the bridge
                                    needsMoveNext[i] = false;
                                }

                                // REVIEW:: We may want to set update to 'just before' the time, I'm thinking of daily data, so we
                                //          ask for it at midnight, let's assume it's there, did we get it into the stream store
                                //          before we called trigger archive?? I hope so, otherwise the data is always a full day late
                                update[i] = DateTime.Now.Add(_subscriptions[i].Increment).RoundDown(_subscriptions[i].Increment);
                            }
                        }
                    }

                    if (_exitTriggered)
                    {
                        return;
                    }
                    Thread.Sleep(10);
                }
            });

            //Wait for micro-threads to break before continuing
            liveThreadTask.Start();

            // define what tasks we're going to wait on, we use a task from result in place of the custom task, just in case we never start it
            var tasks = new [] { liveThreadTask, Task.FromResult(1) };

            // if we have any dynamically loaded data, start the custom thread
            if (_isDynamicallyLoadedData.Any(x => x))
            {
                //Start task and set it as the second one we want to monitor:
                customFeedsTask.Start();
                tasks[1] = customFeedsTask;
            }

            Task.WaitAll(tasks);

            //Once we're here the tasks have died, signal
            if (!_exitTriggered)
            {
                _endOfBridges = true;
            }

            Log.Trace(string.Format("LiveTradingDataFeed.Stream(): Stream Task Completed. Exit Signal: {0}", _exitTriggered));
        }
示例#4
0
        /// <summary>
        /// Stream Store Consumer uses the GetNextTicks() function to get current ticks from a data source and
        /// then uses the stream store to compile them into trade bars.
        /// </summary>
        public void StreamStoreConsumer()
        {
            //Scan for the required time period to stream:
            Log.Trace("LiveTradingDataFeed.Stream(): Waiting for updated market hours...", true);

            var symbols = (from security in _algorithm.Securities.Values
                           where !security.SubscriptionDataConfig.IsCustomData && (security.Type == SecurityType.Equity || security.Type == SecurityType.Forex)
                           select security.Symbol.Permtick).ToList <string>();

            Log.Trace("LiveTradingDataFeed.Stream(): Market open, starting stream for " + string.Join(",", symbols));

            //Micro-thread for polling for new data from data source:
            var liveThreadTask = new Task(() =>
            {
                if (_subscriptions.All(x => x.Value.IsCustomData))
                {
                    // if we're all custom data data don't waste CPU cycle with this thread
                    return;
                }

                //Blocking ForEach - Should stay within this loop as long as there is a data-connection
                while (true)
                {
                    var dataCollection = _dataQueue.GetNextTicks();

                    int ticksCount = 0;
                    foreach (var point in dataCollection)
                    {
                        ticksCount++;

                        foreach (var kvp in _subscriptions)
                        {
                            var subscription = kvp.Value;

                            if (subscription.Configuration.Symbol != point.Symbol)
                            {
                                continue;
                            }

                            var tick = point as Tick;
                            if (tick != null)
                            {
                                // Update the realtime price stream value
                                subscription.SetRealtimePrice(point.Value);

                                if (subscription.Configuration.Resolution == Resolution.Tick)
                                {
                                    // put ticks directly into the bridge
                                    AddSingleItemToBridge(subscription, tick);
                                }
                                else
                                {
                                    // Update our internal counter
                                    subscription.StreamStore.Update(tick);
                                }
                            }
                            else
                            {
                                // reset the start time so it goes in sync with other data
                                point.Time = DateTime.UtcNow.ConvertFromUtc(subscription.TimeZone).RoundDown(subscription.Configuration.Increment);

                                //If its not a tick, inject directly into bridge for this symbol:
                                //Bridge[i].Enqueue(new List<BaseData> {point});
                                AddSingleItemToBridge(subscription, point);
                            }
                        }
                    }

                    if (_cancellationTokenSource.IsCancellationRequested)
                    {
                        return;
                    }
                    if (ticksCount == 0)
                    {
                        Thread.Sleep(5);
                    }
                }
            }, TaskCreationOptions.LongRunning);

            // Micro-thread for custom data/feeds. This only supports polling at this time. todo: Custom data sockets
            var customFeedsTask = new Task(() =>
            {
                while (true)
                {
                    foreach (var kvp in _subscriptions)
                    {
                        var subscription = kvp.Value;

                        // custom only thread
                        if (!subscription.IsCustomData)
                        {
                            continue;
                        }
                        // wait for when it's time to update
                        if (!subscription.NeedsUpdate)
                        {
                            continue;
                        }

                        var repeat    = true;
                        BaseData data = null;
                        while (repeat && TryMoveNext(subscription, out data))
                        {
                            if (data == null)
                            {
                                break;
                            }

                            // check to see if the data is too far in the past
                            // this is useful when using custom remote files that may stretch far into the past,
                            // so this if block will cause us to fast forward the reader until its recent increment
                            var earliestExpectedFirstPoint = DateTime.UtcNow.Subtract(subscription.Configuration.Increment.Add(Time.OneSecond));
                            repeat = data.EndTime.ConvertToUtc(subscription.TimeZone) < earliestExpectedFirstPoint;
                        }

                        if (data == null)
                        {
                            continue;
                        }

                        // don't emit data in the future
                        // TODO : Move this concern into LiveSubscription, maybe a CustomLiveSubscription, end goal just enumerate the damn thing at it works
                        if (data.EndTime.ConvertToUtc(subscription.TimeZone) < DateTime.UtcNow)
                        {
                            if (subscription.Configuration.Resolution == Resolution.Tick)
                            {
                                // put ticks directly into the bridge
                                AddSingleItemToBridge(subscription, data);
                            }
                            else
                            {
                                Log.Trace("LiveTradingDataFeed.Custom(): Add to stream store.");
                                subscription.StreamStore.Update(data);     //Update bar builder.
                                subscription.SetRealtimePrice(data.Value); //Update realtime price value.
                                subscription.NeedsMoveNext = true;
                            }
                        }
                        else
                        {
                            // since this data is in the future and we didn't emit it,
                            // don't call MoveNext again and we'll keep performing time checks
                            // until its end time has passed and we can emit it into the bridge
                            subscription.NeedsMoveNext = false;
                        }
                    }

                    if (_cancellationTokenSource.IsCancellationRequested)
                    {
                        return;
                    }
                    Thread.Sleep(10);
                }
            }, TaskCreationOptions.LongRunning);

            //Wait for micro-threads to break before continuing
            liveThreadTask.Start();

            // define what tasks we're going to wait on, we use a task from result in place of the custom task, just in case we never start it
            var tasks = new [] { liveThreadTask, Task.FromResult(1) };

            // if we have any dynamically loaded data, start the custom thread
            if (_subscriptions.Any(x => x.Value.IsCustomData))
            {
                //Start task and set it as the second one we want to monitor:
                customFeedsTask.Start();
                tasks[1] = customFeedsTask;
            }

            Task.WaitAll(tasks);

            //Once we're here the tasks have died, signal
            if (!_cancellationTokenSource.IsCancellationRequested)
            {
                _endOfBridges = true;
            }

            Log.Trace(string.Format("LiveTradingDataFeed.Stream(): Stream Task Completed. Exit Signal: {0}", _cancellationTokenSource.IsCancellationRequested));
        }
示例#5
0
 private static IEnumerator<BaseData> GetNextTicksEnumerator(IDataQueueHandler dataQueueHandler)
 {
     while (true)
     {
         int ticks = 0;
         foreach (var data in dataQueueHandler.GetNextTicks())
         {
             ticks++;
             yield return data;
         }
         if (ticks == 0) Thread.Sleep(1);
     }
 }
示例#6
0
 /// <summary>
 /// Gets the next ticks from the live trading feed
 /// </summary>
 /// <returns>The next ticks to be processed</returns>
 public override IEnumerable <Tick> GetNextTicks()
 {
     return(_queue.GetNextTicks());
 }
示例#7
0
 /// <summary>
 /// Returns the next ticks from the data source. The data source itself is defined in the derived class's
 /// implementation of this function. For example, if obtaining data from a brokerage, say IB, then the derived
 /// implementation would ask the IB API for the next ticks
 /// </summary>
 /// <returns>The next ticks to be aggregated and sent to algoithm</returns>
 public virtual IEnumerable <BaseData> GetNextTicks()
 {
     return(_dataQueue.GetNextTicks());
 }