public void EntrySignal(QuoteBars data, Rule signal)
 {
     if (verbose && signal.IsTrue())
     {
         Log(string.Format("signal symbol:: {0}", signal.Symbol));
     }
     if (!Portfolio[signal.Symbol].Invested)
     {
         if (signal.IsTrue())
         {
             var openPrice   = Securities[signal.Symbol].Price;
             var entryValues = RiskManager.CalculateEntryOrders(data, signal.Symbol, AgentAction.GoLong);
             if (entryValues.Item1 != 0)
             {
                 tookPartialProfit[signal.Symbol] = false;
                 var ticket = MarketOrder(signal.Symbol, entryValues.Item1);
                 StopMarketOrder(signal.Symbol, -entryValues.Item1, entryValues.Item2, tag: entryValues.Item3.ToString("0.000000"));
                 if (verbose)
                 {
                     Log(string.Format("MarketOrder:: {0} {1}", signal.Symbol, entryValues.Item1));
                 }
             }
             //MarketOrder(signal.Symbol, size, false, "");
         }
     }
 }
Exemplo n.º 2
0
        public void OnData(QuoteBars data)
        {
            long l  = (30 * 24 * 60 * 60);
            long le = (10 * 24 * 60 * 60);

            foreach (var rule in trades)
            {
                if (data.ContainsKey(rule.Symbol))
                {
                    var candleStartTime = Utils.ToUnixTimestamp(data[rule.Symbol].Time.ConvertToUtc(Securities[rule.Symbol].Exchange.TimeZone));
                    var candleEndTime   = Utils.ToUnixTimestamp(data[rule.Symbol].EndTime.ConvertToUtc(Securities[rule.Symbol].Exchange.TimeZone));

                    if (candleStartTime > (rule.setupTime - l) && (candleStartTime < Math.Max(rule.exitTime, rule.expirationTime) + le))
                    {
                        rule.Serie.Add(new LocalQuote
                        {
                            date  = Utils.ToUnixTimestamp(data[rule.Symbol].Time.ConvertToUtc(Securities[rule.Symbol].Exchange.TimeZone)),
                            open  = data[rule.Symbol].Open,
                            close = data[rule.Symbol].Close,
                            high  = data[rule.Symbol].High,
                            low   = data[rule.Symbol].Low
                        });
                    }
                }
            }
        }
Exemplo n.º 3
0
            public IEnumerable <TimeSlice> GetTimeSlices()
            {
                var bars            = new TradeBars();
                var quotes          = new QuoteBars();
                var ticks           = new Ticks();
                var options         = new OptionChains();
                var futures         = new FuturesChains();
                var splits          = new Splits();
                var dividends       = new Dividends();
                var delistings      = new Delistings();
                var symbolChanges   = new SymbolChangedEvents();
                var dataFeedPackets = new List <DataFeedPacket>();
                var cashUpdateData  = new List <UpdateData <Cash> >();
                var customData      = new List <UpdateData <Security> >();
                var changes         = SecurityChanges.None;

                do
                {
                    var slice     = new Slice(default(DateTime), _data, bars, quotes, ticks, options, futures, splits, dividends, delistings, symbolChanges);
                    var timeSlice = new TimeSlice(_frontierUtc, _data.Count, slice, dataFeedPackets, cashUpdateData, securitiesUpdateData, _consolidatorUpdateData, customData, changes);
                    yield return(timeSlice);

                    _frontierUtc += FrontierStepSize;
                }while (_frontierUtc <= _endTimeUtc);
            }
Exemplo n.º 4
0
        public void OnData(QuoteBars data)
        {
            long l  = (30 * 24 * 60 * 60);
            long le = (10 * 24 * 60 * 60);

            foreach (var rule in trades)
            {
                if (data.ContainsKey(rule.Symbol))
                {
                    var candleStartTime = Utils.ToUnixTimestamp(data[rule.Symbol].Time.ConvertToUtc(Securities[rule.Symbol].Exchange.TimeZone));
                    var candleEndTime   = Utils.ToUnixTimestamp(data[rule.Symbol].EndTime.ConvertToUtc(Securities[rule.Symbol].Exchange.TimeZone));

                    if ((rule._Serie.Count == 0 && (rule.setupTime - l) > candleStartTime) || (rule._Serie.Count > 0 && (rule.exitTime + le > candleStartTime || rule.expirationTime + le > candleStartTime)))
                    {
                        List <LocalQuote> serie = new List <LocalQuote>();
                        rule._Serie.Add(new LocalQuote
                        {
                            date  = Utils.ToUnixTimestamp(data[rule.Symbol].Time.ConvertToUtc(Securities[rule.Symbol].Exchange.TimeZone)),
                            open  = data[rule.Symbol].Open,
                            close = data[rule.Symbol].Close,
                            high  = data[rule.Symbol].High,
                            low   = data[rule.Symbol].Low
                        });
                    }
                }
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Merge two slice with same Time
        /// </summary>
        /// <param name="inputSlice">slice instance</param>
        /// <remarks> Will change the input collection for re-use</remarks>
        public void MergeSlice(Slice inputSlice)
        {
            if (UtcTime != inputSlice.UtcTime)
            {
                throw new InvalidOperationException($"Slice with time {UtcTime} can't be merged with given slice with different {inputSlice.UtcTime}");
            }

            _bars                = (TradeBars)UpdateCollection(_bars, inputSlice.Bars);
            _quoteBars           = (QuoteBars)UpdateCollection(_quoteBars, inputSlice.QuoteBars);
            _ticks               = (Ticks)UpdateCollection(_ticks, inputSlice.Ticks);
            _optionChains        = (OptionChains)UpdateCollection(_optionChains, inputSlice.OptionChains);
            _futuresChains       = (FuturesChains)UpdateCollection(_futuresChains, inputSlice.FuturesChains);
            _splits              = (Splits)UpdateCollection(_splits, inputSlice.Splits);
            _dividends           = (Dividends)UpdateCollection(_dividends, inputSlice.Dividends);
            _delistings          = (Delistings)UpdateCollection(_delistings, inputSlice.Delistings);
            _symbolChangedEvents = (SymbolChangedEvents)UpdateCollection(_symbolChangedEvents, inputSlice.SymbolChangedEvents);

            if (inputSlice._rawDataList.Count != 0)
            {
                if (_rawDataList.Count == 0)
                {
                    _rawDataList = inputSlice._rawDataList;
                    _data        = inputSlice._data;
                }
                else
                {
                    // Should keep this._rawDataList last so that selected data points are not overriden
                    // while creating _data
                    inputSlice._rawDataList.AddRange(_rawDataList);
                    _rawDataList = inputSlice._rawDataList;
                    _data        = new Lazy <DataDictionary <SymbolData> >(() => CreateDynamicDataDictionary(_rawDataList));
                }
            }
        }
Exemplo n.º 6
0
        public void AccessesTradeBarAndQuoteBarForSameSymbol()
        {
            var tradeBar = new TradeBar(DateTime.Now, Symbols.BTCUSD,
                3000, 3000, 3000, 3000, 100, Time.OneMinute);

            var quoteBar = new QuoteBar(DateTime.Now, Symbols.BTCUSD,
                    new Bar(3100, 3100, 3100, 3100), 0,
                    new Bar(3101, 3101, 3101, 3101), 0,
                    Time.OneMinute);

            var tradeBars = new TradeBars { { Symbols.BTCUSD, tradeBar } };
            var quoteBars = new QuoteBars { { Symbols.BTCUSD, quoteBar } };

            var slice = new Slice(DateTime.Now, new BaseData[] { tradeBar, quoteBar }, tradeBars, quoteBars, null, null, null, null, null, null, null);

            var tradeBarData = slice.Get<TradeBar>();
            Assert.AreEqual(1, tradeBarData.Count);
            Assert.AreEqual(3000, tradeBarData[Symbols.BTCUSD].Close);

            var quoteBarData = slice.Get<QuoteBar>();
            Assert.AreEqual(1, quoteBarData.Count);
            Assert.AreEqual(3100, quoteBarData[Symbols.BTCUSD].Bid.Close);
            Assert.AreEqual(3101, quoteBarData[Symbols.BTCUSD].Ask.Close);

            slice = new Slice(DateTime.Now, new BaseData[] { tradeBar, quoteBar });

            tradeBarData = slice.Get<TradeBar>();
            Assert.AreEqual(1, tradeBarData.Count);
            Assert.AreEqual(3000, tradeBarData[Symbols.BTCUSD].Close);

            quoteBarData = slice.Get<QuoteBar>();
            Assert.AreEqual(1, quoteBarData.Count);
            Assert.AreEqual(3100, quoteBarData[Symbols.BTCUSD].Bid.Close);
            Assert.AreEqual(3101, quoteBarData[Symbols.BTCUSD].Ask.Close);
        }
Exemplo n.º 7
0
 public void OnData(QuoteBars data)
 {
     try
     {
         foreach (var symbol in Symbols.Where(s => data.ContainsKey(s)))
         {
             _tradingAssets[symbol].Scan(data[symbol], ((AverageTrueRangeVolatilityModel)Securities[symbol].VolatilityModel).IsWarmingUp);
         }
     }
     catch (Exception ex)
     {
         Log("Error: " + ex.Message);
     }
 }
Exemplo n.º 8
0
 public Slice(DateTime time, IEnumerable <BaseData> data, TradeBars tradeBars, QuoteBars quoteBars, Ticks ticks, OptionChains optionChains, Splits splits, Dividends dividends, Delistings delistings, SymbolChangedEvents symbolChanges, bool?hasData = null)
 {
     Time                 = time;
     _dataByType          = new Dictionary <Type, Lazy <object> >();
     _data                = new Lazy <DataDictionary <SymbolData> >(() => CreateDynamicDataDictionary(data));
     HasData              = hasData ?? _data.Value.Count > 0;
     _ticks               = CreateTicksCollection(ticks);
     _bars                = CreateCollection <TradeBars, TradeBar>(tradeBars);
     _quoteBars           = CreateCollection <QuoteBars, QuoteBar>(quoteBars);
     _optionChains        = CreateCollection <OptionChains, OptionChain>(optionChains);
     _splits              = CreateCollection <Splits, Split>(splits);
     _dividends           = CreateCollection <Dividends, Dividend>(dividends);
     _delistings          = CreateCollection <Delistings, Delisting>(delistings);
     _symbolChangedEvents = CreateCollection <SymbolChangedEvents, SymbolChangedEvent>(symbolChanges);
 }
Exemplo n.º 9
0
        public void OnData(QuoteBars data)
        {
            if (!Portfolio.HoldStock)
            {
                SetHoldings("EURUSD", 10);
            }

            lastOpenPrice  = data["EURUSD"].Open;
            lastClosePrice = data["EURUSD"].Close;
            Plot("Trade Plot", "Open", lastOpenPrice);
            Plot("Trade Plot", "Close", lastClosePrice);

            if (EMASlow.IsReady)
            {
                Plot("Trade Plot", "FastMA", EMAFast);
                Plot("Trade Plot", "SlowMA", EMASlow);
            }
        }
Exemplo n.º 10
0
 public void OnData(QuoteBars data)
 {
     foreach (var entry in _entry)
     {
         if (entry.IsReady())
         {
             EntrySignal(data, entry);
         }
     }
     foreach (var entry in _exit)
     {
         if (entry.IsReady())
         {
             ExitSignal(entry);
         }
     }
     RiskManager.UpdateTrailingStopOrders(data);
 }
Exemplo n.º 11
0
        /// <summary>
        /// Calculates the entry orders and stop-loss price.
        /// </summary>
        /// <param name="pair">The Forex pair Symbol.</param>
        /// <param name="action">The order direction.</param>
        /// <returns>a Tuple with the quantity as Item1 and the stop-loss price as Item2. If quantity is zero, then means that no trade must be done.</returns>
        public Tuple <int, decimal, decimal> CalculateEntryOrders(QuoteBars data, Symbol pair, AgentAction action)
        {
            // If exposure is greater than the max exposure, then return zero.
            if (_portfolio.TotalMarginUsed > _portfolio.TotalPortfolioValue * _maxExposure)
            {
                return(Tuple.Create(0, 0m, 0m));
            }
            var closePrice   = _portfolio.Securities[pair].Price;
            var leverage     = _portfolio.Securities[pair].Leverage;
            var exchangeRate = _portfolio.Securities[pair].QuoteCurrency.ConversionRate;
            var volatility   = _portfolio.Securities[pair].VolatilityModel.Volatility;

            // Estimate the maximum entry order quantity given the risk per trade.
            var moneyAtRisk = _portfolio.TotalPortfolioValue * _riskPerTrade;
            var quantity    = action == AgentAction.GoLong ? _lotSize : -_lotSize;

            if ((volatility * exchangeRate) > 0)
            {
                var maxQuantitybyRisk = moneyAtRisk / (volatility * exchangeRate);
                // Estimate the maximum entry order quantity given the exposure per trade.
                var maxBuySize            = Math.Min(_portfolio.MarginRemaining, _portfolio.TotalPortfolioValue * _maxExposurePerTrade) * leverage;
                var maxQuantitybyExposure = maxBuySize / (closePrice * exchangeRate);
                // The final quantity is the lowest of both.
                quantity = (int)(Math.Round(Math.Min(maxQuantitybyRisk, maxQuantitybyExposure) / _lotSize, 0) * _lotSize);
                // If the final quantity is lower than the minimum quantity of the given lot size, then return zero.
                if (quantity < _lotSize * _minQuantity)
                {
                    return(Tuple.Create(0, 0m, 0m));
                }

                quantity = action == AgentAction.GoLong ? quantity : -quantity;
            }

            var stopLossPrice = closePrice + (action == AgentAction.GoLong ? -volatility : volatility);
            var increment     = _portfolio.Securities[pair].PriceVariationModel.GetMinimumPriceVariation(_portfolio.Securities[pair]);

            if (increment != 0)
            {
                stopLossPrice = Math.Round(stopLossPrice / increment) * increment;
            }

            return(Tuple.Create(quantity, stopLossPrice, action == AgentAction.GoLong ? data[pair].Ask.Close : data[pair].Bid.Close));
        }
Exemplo n.º 12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Slice"/> class
        /// </summary>
        /// <param name="time">The timestamp for this slice of data</param>
        /// <param name="data">The raw data in this slice</param>
        /// <param name="tradeBars">The trade bars for this slice</param>
        /// <param name="quoteBars">The quote bars for this slice</param>
        /// <param name="ticks">This ticks for this slice</param>
        /// <param name="optionChains">The option chains for this slice</param>
        /// <param name="futuresChains">The futures chains for this slice</param>
        /// <param name="splits">The splits for this slice</param>
        /// <param name="dividends">The dividends for this slice</param>
        /// <param name="delistings">The delistings for this slice</param>
        /// <param name="symbolChanges">The symbol changed events for this slice</param>
        /// <param name="hasData">true if this slice contains data</param>
        public Slice(DateTime time, IEnumerable <BaseData> data, TradeBars tradeBars, QuoteBars quoteBars, Ticks ticks, OptionChains optionChains, FuturesChains futuresChains, Splits splits, Dividends dividends, Delistings delistings, SymbolChangedEvents symbolChanges, bool?hasData = null)
        {
            Time = time;

            // market data
            _data = new Lazy <DataDictionary <SymbolData> >(() => CreateDynamicDataDictionary(data));

            HasData = hasData ?? _data.Value.Count > 0;

            _ticks         = ticks;
            _bars          = tradeBars;
            _quoteBars     = quoteBars;
            _optionChains  = optionChains;
            _futuresChains = futuresChains;

            // auxiliary data
            _splits              = splits;
            _dividends           = dividends;
            _delistings          = delistings;
            _symbolChangedEvents = symbolChanges;
        }
Exemplo n.º 13
0
        /// <summary>
        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        /// </summary>
        /// <param name="data">TradeBars IDictionary object with your stock data</param>
        public void OnData(QuoteBars data)
        {
            SetHoldings(_symbol, 1);
            return;

            // only once per day
            if (_previous.Date == Time.Date)
            {
                return;
            }

            if (!_macd.IsReady)
            {
                return;
            }

            var holding = Portfolio[_symbol];

            var signalDeltaPercent = (_macd - _macd.Signal) / _macd.Fast;
            var tolerance          = 0.00025m;

            // if our macd is greater than our signal, then let's go long
            if (holding.Quantity <= 0 && signalDeltaPercent > tolerance) // 0.01%
            {
                // longterm says buy as well
                SetHoldings(_symbol, 1.0);
            }
            // of our macd is less than our signal, then let's go short
            else if (holding.Quantity >= 0 && signalDeltaPercent < -tolerance)
            {
                Liquidate(_symbol);
            }

            // plot both lines
            Plot("MACD", _macd, _macd.Signal);
            Plot(_symbol, "Open", data[_symbol].Open);
            Plot(_symbol, _macd.Fast, _macd.Slow);

            _previous = Time;
        }
Exemplo n.º 14
0
        /// <summary>
        /// Initializes a new instance used by the <see cref="PythonSlice"/>
        /// </summary>
        /// <param name="slice">slice object to wrap</param>
        /// <remarks>This is required so that python slice enumeration works correctly since it relies on the private <see cref="_data"/> collection</remarks>
        protected Slice(Slice slice)
        {
            Time = slice.Time;

            _dataByType = slice._dataByType;

            _data = slice._data;

            HasData = slice.HasData;

            _ticks         = slice._ticks;
            _bars          = slice._bars;
            _quoteBars     = slice._quoteBars;
            _optionChains  = slice._optionChains;
            _futuresChains = slice._futuresChains;

            // auxiliary data
            _splits              = slice._splits;
            _dividends           = slice._dividends;
            _delistings          = slice._delistings;
            _symbolChangedEvents = slice._symbolChangedEvents;
        }
Exemplo n.º 15
0
        /// <summary>
        /// Adds the specified <see cref="BaseData"/> instance to the appropriate <see cref="DataDictionary{T}"/>
        /// </summary>
        private static void PopulateDataDictionaries(BaseData baseData, Ticks ticks, TradeBars tradeBars, QuoteBars quoteBars, OptionChains optionChains, FuturesChains futuresChains)
        {
            var symbol = baseData.Symbol;

            // populate data dictionaries
            switch (baseData.DataType)
            {
            case MarketDataType.Tick:
                ticks.Add(symbol, (Tick)baseData);
                break;

            case MarketDataType.TradeBar:
                tradeBars[symbol] = (TradeBar)baseData;
                break;

            case MarketDataType.QuoteBar:
                quoteBars[symbol] = (QuoteBar)baseData;
                break;

            case MarketDataType.OptionChain:
                optionChains[symbol] = (OptionChain)baseData;
                break;

            case MarketDataType.FuturesChain:
                futuresChains[symbol] = (FuturesChain)baseData;
                break;
            }
        }
Exemplo n.º 16
0
        /// <summary>
        /// Creates a new <see cref="TimeSlice"/> for the specified time using the specified data
        /// </summary>
        /// <param name="utcDateTime">The UTC frontier date time</param>
        /// <param name="algorithmTimeZone">The algorithm's time zone, required for computing algorithm and slice time</param>
        /// <param name="cashBook">The algorithm's cash book, required for generating cash update pairs</param>
        /// <param name="data">The data in this <see cref="TimeSlice"/></param>
        /// <param name="changes">The new changes that are seen in this time slice as a result of universe selection</param>
        /// <returns>A new <see cref="TimeSlice"/> containing the specified data</returns>
        public static TimeSlice Create(DateTime utcDateTime, DateTimeZone algorithmTimeZone, CashBook cashBook, List <DataFeedPacket> data, SecurityChanges changes)
        {
            int count               = 0;
            var security            = new List <UpdateData <Security> >();
            var custom              = new List <UpdateData <Security> >();
            var consolidator        = new List <UpdateData <SubscriptionDataConfig> >();
            var allDataForAlgorithm = new List <BaseData>(data.Count);
            var cash = new List <UpdateData <Cash> >(cashBook.Count);

            var cashSecurities = new HashSet <Symbol>();

            foreach (var cashItem in cashBook.Values)
            {
                cashSecurities.Add(cashItem.SecuritySymbol);
            }

            Split              split;
            Dividend           dividend;
            Delisting          delisting;
            SymbolChangedEvent symbolChange;

            // we need to be able to reference the slice being created in order to define the
            // evaluation of option price models, so we define a 'future' that can be referenced
            // in the option price model evaluation delegates for each contract
            Slice slice       = null;
            var   sliceFuture = new Lazy <Slice>(() => slice);

            var algorithmTime = utcDateTime.ConvertFromUtc(algorithmTimeZone);
            var tradeBars     = new TradeBars(algorithmTime);
            var quoteBars     = new QuoteBars(algorithmTime);
            var ticks         = new Ticks(algorithmTime);
            var splits        = new Splits(algorithmTime);
            var dividends     = new Dividends(algorithmTime);
            var delistings    = new Delistings(algorithmTime);
            var optionChains  = new OptionChains(algorithmTime);
            var futuresChains = new FuturesChains(algorithmTime);
            var symbolChanges = new SymbolChangedEvents(algorithmTime);

            foreach (var packet in data)
            {
                var list   = packet.Data;
                var symbol = packet.Security.Symbol;

                if (list.Count == 0)
                {
                    continue;
                }

                // keep count of all data points
                if (list.Count == 1 && list[0] is BaseDataCollection)
                {
                    var baseDataCollectionCount = ((BaseDataCollection)list[0]).Data.Count;
                    if (baseDataCollectionCount == 0)
                    {
                        continue;
                    }
                    count += baseDataCollectionCount;
                }
                else
                {
                    count += list.Count;
                }

                if (!packet.Configuration.IsInternalFeed && packet.Configuration.IsCustomData)
                {
                    // This is all the custom data
                    custom.Add(new UpdateData <Security>(packet.Security, packet.Configuration.Type, list));
                }

                var securityUpdate     = new List <BaseData>(list.Count);
                var consolidatorUpdate = new List <BaseData>(list.Count);
                for (int i = 0; i < list.Count; i++)
                {
                    var baseData = list[i];
                    if (!packet.Configuration.IsInternalFeed)
                    {
                        // this is all the data that goes into the algorithm
                        allDataForAlgorithm.Add(baseData);
                    }
                    // don't add internal feed data to ticks/bars objects
                    if (baseData.DataType != MarketDataType.Auxiliary)
                    {
                        if (!packet.Configuration.IsInternalFeed)
                        {
                            PopulateDataDictionaries(baseData, ticks, tradeBars, quoteBars, optionChains, futuresChains);

                            // special handling of options data to build the option chain
                            if (packet.Security.Type == SecurityType.Option)
                            {
                                if (baseData.DataType == MarketDataType.OptionChain)
                                {
                                    optionChains[baseData.Symbol] = (OptionChain)baseData;
                                }
                                else if (!HandleOptionData(algorithmTime, baseData, optionChains, packet.Security, sliceFuture))
                                {
                                    continue;
                                }
                            }

                            // special handling of futures data to build the futures chain
                            if (packet.Security.Type == SecurityType.Future)
                            {
                                if (baseData.DataType == MarketDataType.FuturesChain)
                                {
                                    futuresChains[baseData.Symbol] = (FuturesChain)baseData;
                                }
                                else if (!HandleFuturesData(algorithmTime, baseData, futuresChains, packet.Security))
                                {
                                    continue;
                                }
                            }


                            // this is data used to update consolidators
                            consolidatorUpdate.Add(baseData);
                        }

                        // this is the data used set market prices
                        // do not add it if it is a Suspicious tick
                        var tick = baseData as Tick;
                        if (tick != null && tick.Suspicious)
                        {
                            continue;
                        }

                        securityUpdate.Add(baseData);
                    }
                    // include checks for various aux types so we don't have to construct the dictionaries in Slice
                    else if ((delisting = baseData as Delisting) != null)
                    {
                        delistings[symbol] = delisting;
                    }
                    else if ((dividend = baseData as Dividend) != null)
                    {
                        dividends[symbol] = dividend;
                    }
                    else if ((split = baseData as Split) != null)
                    {
                        splits[symbol] = split;
                    }
                    else if ((symbolChange = baseData as SymbolChangedEvent) != null)
                    {
                        // symbol changes is keyed by the requested symbol
                        symbolChanges[packet.Configuration.Symbol] = symbolChange;
                    }
                }

                if (securityUpdate.Count > 0)
                {
                    // check for 'cash securities' if we found valid update data for this symbol
                    // and we need this data to update cash conversion rates, long term we should
                    // have Cash hold onto it's security, then he can update himself, or rather, just
                    // patch through calls to conversion rate to compue it on the fly using Security.Price
                    if (cashSecurities.Contains(packet.Security.Symbol))
                    {
                        foreach (var cashKvp in cashBook)
                        {
                            if (cashKvp.Value.SecuritySymbol == packet.Security.Symbol)
                            {
                                var cashUpdates = new List <BaseData> {
                                    securityUpdate[securityUpdate.Count - 1]
                                };
                                cash.Add(new UpdateData <Cash>(cashKvp.Value, packet.Configuration.Type, cashUpdates));
                            }
                        }
                    }

                    security.Add(new UpdateData <Security>(packet.Security, packet.Configuration.Type, securityUpdate));
                }
                if (consolidatorUpdate.Count > 0)
                {
                    consolidator.Add(new UpdateData <SubscriptionDataConfig>(packet.Configuration, packet.Configuration.Type, consolidatorUpdate));
                }
            }

            slice = new Slice(algorithmTime, allDataForAlgorithm, tradeBars, quoteBars, ticks, optionChains, futuresChains, splits, dividends, delistings, symbolChanges, allDataForAlgorithm.Count > 0);

            return(new TimeSlice(utcDateTime, count, slice, data, cash, security, consolidator, custom, changes));
        }
Exemplo n.º 17
0
        /// <summary>
        /// Creates a new <see cref="TimeSlice"/> for the specified time using the specified data
        /// </summary>
        /// <param name="utcDateTime">The UTC frontier date time</param>
        /// <param name="data">The data in this <see cref="TimeSlice"/></param>
        /// <param name="changes">The new changes that are seen in this time slice as a result of universe selection</param>
        /// <param name="universeData"></param>
        /// <returns>A new <see cref="TimeSlice"/> containing the specified data</returns>
        public TimeSlice Create(DateTime utcDateTime,
                                List <DataFeedPacket> data,
                                SecurityChanges changes,
                                Dictionary <Universe, BaseDataCollection> universeData)
        {
            int count    = 0;
            var security = new List <UpdateData <ISecurityPrice> >(data.Count);
            List <UpdateData <ISecurityPrice> > custom = null;
            var consolidator            = new List <UpdateData <SubscriptionDataConfig> >(data.Count);
            var allDataForAlgorithm     = new List <BaseData>(data.Count);
            var optionUnderlyingUpdates = new Dictionary <Symbol, BaseData>();

            Split              split;
            Dividend           dividend;
            Delisting          delisting;
            SymbolChangedEvent symbolChange;

            // we need to be able to reference the slice being created in order to define the
            // evaluation of option price models, so we define a 'future' that can be referenced
            // in the option price model evaluation delegates for each contract
            Slice slice       = null;
            var   sliceFuture = new Lazy <Slice>(() => slice);

            var                 algorithmTime = utcDateTime.ConvertFromUtc(_timeZone);
            TradeBars           tradeBars     = null;
            QuoteBars           quoteBars     = null;
            Ticks               ticks         = null;
            Splits              splits        = null;
            Dividends           dividends     = null;
            Delistings          delistings    = null;
            OptionChains        optionChains  = null;
            FuturesChains       futuresChains = null;
            SymbolChangedEvents symbolChanges = null;

            UpdateEmptyCollections(algorithmTime);

            if (universeData.Count > 0)
            {
                // count universe data
                foreach (var kvp in universeData)
                {
                    count += kvp.Value.Data.Count;
                }
            }

            // ensure we read equity data before option data, so we can set the current underlying price
            foreach (var packet in data)
            {
                // filter out packets for removed subscriptions
                if (packet.IsSubscriptionRemoved)
                {
                    continue;
                }

                var list   = packet.Data;
                var symbol = packet.Configuration.Symbol;

                if (list.Count == 0)
                {
                    continue;
                }

                // keep count of all data points
                if (list.Count == 1 && list[0] is BaseDataCollection)
                {
                    var baseDataCollectionCount = ((BaseDataCollection)list[0]).Data.Count;
                    if (baseDataCollectionCount == 0)
                    {
                        continue;
                    }
                    count += baseDataCollectionCount;
                }
                else
                {
                    count += list.Count;
                }

                if (!packet.Configuration.IsInternalFeed && packet.Configuration.IsCustomData)
                {
                    if (custom == null)
                    {
                        custom = new List <UpdateData <ISecurityPrice> >(1);
                    }
                    // This is all the custom data
                    custom.Add(new UpdateData <ISecurityPrice>(packet.Security, packet.Configuration.Type, list, packet.Configuration.IsInternalFeed));
                }

                var securityUpdate          = new List <BaseData>(list.Count);
                var consolidatorUpdate      = new List <BaseData>(list.Count);
                var containsFillForwardData = false;
                for (var i = 0; i < list.Count; i++)
                {
                    var baseData = list[i];
                    if (!packet.Configuration.IsInternalFeed)
                    {
                        // this is all the data that goes into the algorithm
                        allDataForAlgorithm.Add(baseData);
                    }

                    containsFillForwardData |= baseData.IsFillForward;

                    // don't add internal feed data to ticks/bars objects
                    if (baseData.DataType != MarketDataType.Auxiliary)
                    {
                        var tick = baseData as Tick;

                        if (!packet.Configuration.IsInternalFeed)
                        {
                            // populate data dictionaries
                            switch (baseData.DataType)
                            {
                            case MarketDataType.Tick:
                                if (ticks == null)
                                {
                                    ticks = new Ticks(algorithmTime);
                                }
                                ticks.Add(baseData.Symbol, (Tick)baseData);
                                break;

                            case MarketDataType.TradeBar:
                                if (tradeBars == null)
                                {
                                    tradeBars = new TradeBars(algorithmTime);
                                }

                                var      newTradeBar = (TradeBar)baseData;
                                TradeBar existingTradeBar;
                                // if we have an existing bar keep the highest resolution one
                                // e.g Hour and Minute resolution subscriptions for the same symbol
                                // see CustomUniverseWithBenchmarkRegressionAlgorithm
                                if (!tradeBars.TryGetValue(baseData.Symbol, out existingTradeBar) ||
                                    existingTradeBar.Period > newTradeBar.Period)
                                {
                                    tradeBars[baseData.Symbol] = newTradeBar;
                                }
                                break;

                            case MarketDataType.QuoteBar:
                                if (quoteBars == null)
                                {
                                    quoteBars = new QuoteBars(algorithmTime);
                                }

                                var      newQuoteBar = (QuoteBar)baseData;
                                QuoteBar existingQuoteBar;
                                // if we have an existing bar keep the highest resolution one
                                // e.g Hour and Minute resolution subscriptions for the same symbol
                                // see CustomUniverseWithBenchmarkRegressionAlgorithm
                                if (!quoteBars.TryGetValue(baseData.Symbol, out existingQuoteBar) ||
                                    existingQuoteBar.Period > newQuoteBar.Period)
                                {
                                    quoteBars[baseData.Symbol] = newQuoteBar;
                                }
                                break;

                            case MarketDataType.OptionChain:
                                if (optionChains == null)
                                {
                                    optionChains = new OptionChains(algorithmTime);
                                }
                                optionChains[baseData.Symbol] = (OptionChain)baseData;
                                break;

                            case MarketDataType.FuturesChain:
                                if (futuresChains == null)
                                {
                                    futuresChains = new FuturesChains(algorithmTime);
                                }
                                futuresChains[baseData.Symbol] = (FuturesChain)baseData;
                                break;
                            }

                            // this is data used to update consolidators
                            // do not add it if it is a Suspicious tick
                            if (tick == null || !tick.Suspicious)
                            {
                                consolidatorUpdate.Add(baseData);
                            }
                        }

                        // special handling of options data to build the option chain
                        if (symbol.SecurityType.IsOption())
                        {
                            // internal feeds, like open interest, will not create the chain but will update it if it exists
                            // this is because the open interest could arrive at some closed market hours in which there is no other data and we don't
                            // want to generate a chain object in this case
                            if (optionChains == null && !packet.Configuration.IsInternalFeed)
                            {
                                optionChains = new OptionChains(algorithmTime);
                            }

                            if (baseData.DataType == MarketDataType.OptionChain)
                            {
                                optionChains[baseData.Symbol] = (OptionChain)baseData;
                            }
                            else if (optionChains != null && !HandleOptionData(algorithmTime, baseData, optionChains, packet.Security, sliceFuture, optionUnderlyingUpdates))
                            {
                                continue;
                            }
                        }

                        // special handling of futures data to build the futures chain
                        if (symbol.SecurityType == SecurityType.Future)
                        {
                            // internal feeds, like open interest, will not create the chain but will update it if it exists
                            // this is because the open interest could arrive at some closed market hours in which there is no other data and we don't
                            // want to generate a chain object in this case
                            if (futuresChains == null && !packet.Configuration.IsInternalFeed)
                            {
                                futuresChains = new FuturesChains(algorithmTime);
                            }
                            if (baseData.DataType == MarketDataType.FuturesChain)
                            {
                                futuresChains[baseData.Symbol] = (FuturesChain)baseData;
                            }
                            else if (futuresChains != null && !HandleFuturesData(algorithmTime, baseData, futuresChains, packet.Security))
                            {
                                continue;
                            }
                        }

                        // this is the data used set market prices
                        // do not add it if it is a Suspicious tick
                        if (tick != null && tick.Suspicious)
                        {
                            continue;
                        }

                        securityUpdate.Add(baseData);

                        // option underlying security update
                        if (!packet.Configuration.IsInternalFeed)
                        {
                            optionUnderlyingUpdates[symbol] = baseData;
                        }
                    }
                    else if (!packet.Configuration.IsInternalFeed)
                    {
                        // include checks for various aux types so we don't have to construct the dictionaries in Slice
                        if ((delisting = baseData as Delisting) != null)
                        {
                            if (delistings == null)
                            {
                                delistings = new Delistings(algorithmTime);
                            }
                            delistings[symbol] = delisting;
                        }
                        else if ((dividend = baseData as Dividend) != null)
                        {
                            if (dividends == null)
                            {
                                dividends = new Dividends(algorithmTime);
                            }
                            dividends[symbol] = dividend;
                        }
                        else if ((split = baseData as Split) != null)
                        {
                            if (splits == null)
                            {
                                splits = new Splits(algorithmTime);
                            }
                            splits[symbol] = split;
                        }
                        else if ((symbolChange = baseData as SymbolChangedEvent) != null)
                        {
                            if (symbolChanges == null)
                            {
                                symbolChanges = new SymbolChangedEvents(algorithmTime);
                            }
                            // symbol changes is keyed by the requested symbol
                            symbolChanges[packet.Configuration.Symbol] = symbolChange;
                        }
                    }
                }

                if (securityUpdate.Count > 0)
                {
                    security.Add(new UpdateData <ISecurityPrice>(packet.Security, packet.Configuration.Type, securityUpdate, packet.Configuration.IsInternalFeed, containsFillForwardData));
                }
                if (consolidatorUpdate.Count > 0)
                {
                    consolidator.Add(new UpdateData <SubscriptionDataConfig>(packet.Configuration, packet.Configuration.Type, consolidatorUpdate, packet.Configuration.IsInternalFeed, containsFillForwardData));
                }
            }

            slice = new Slice(algorithmTime, allDataForAlgorithm, tradeBars ?? _emptyTradeBars, quoteBars ?? _emptyQuoteBars, ticks ?? _emptyTicks, optionChains ?? _emptyOptionChains, futuresChains ?? _emptyFuturesChains, splits ?? _emptySplits, dividends ?? _emptyDividends, delistings ?? _emptyDelistings, symbolChanges ?? _emptySymbolChangedEvents, allDataForAlgorithm.Count > 0);

            return(new TimeSlice(utcDateTime, count, slice, data, security, consolidator, custom ?? _emptyCustom, changes, universeData));
        }
Exemplo n.º 18
0
 private DataUpdates(DateTime occuredutc, DataPoint[] dataPoints, Delistings delistings, Dividends dividends,
                     Earnings earnings, Financials financials, KeyStats keystats, QuoteBars quotebars, Splits splits,
                     TradeBars tradebars, TradingStatusUpdates tradingStatusUpdates,
                     Ticks ticks)
 {
     //TODO: for cloning this object (so it becomes immutable)
     throw new NotImplementedException();
 }
Exemplo n.º 19
0
        /// <summary>
        /// Adds the specified <see cref="BaseData"/> instance to the appropriate <see cref="DataDictionary{T}"/>
        /// </summary>
        private static void PopulateDataDictionaries(BaseData baseData, Ticks ticks, TradeBars tradeBars, QuoteBars quoteBars, OptionChains optionChains)
        {
            var symbol = baseData.Symbol;

            // populate data dictionaries
            switch (baseData.DataType)
            {
                case MarketDataType.Tick:
                    ticks.Add(symbol, (Tick)baseData);
                    break;

                case MarketDataType.TradeBar:
                    tradeBars[symbol] = (TradeBar) baseData;
                    break;

                case MarketDataType.QuoteBar:
                    quoteBars[symbol] = (QuoteBar) baseData;
                    break;

                case MarketDataType.OptionChain:
                    optionChains[symbol] = (OptionChain) baseData;
                    break;
            }
        }
Exemplo n.º 20
0
        /// <summary>
        /// Creates a new <see cref="TimeSlice"/> for the specified time using the specified data
        /// </summary>
        /// <param name="utcDateTime">The UTC frontier date time</param>
        /// <param name="algorithmTimeZone">The algorithm's time zone, required for computing algorithm and slice time</param>
        /// <param name="cashBook">The algorithm's cash book, required for generating cash update pairs</param>
        /// <param name="data">The data in this <see cref="TimeSlice"/></param>
        /// <param name="changes">The new changes that are seen in this time slice as a result of universe selection</param>
        /// <returns>A new <see cref="TimeSlice"/> containing the specified data</returns>
        public static TimeSlice Create(DateTime utcDateTime, DateTimeZone algorithmTimeZone, CashBook cashBook, List<DataFeedPacket> data, SecurityChanges changes)
        {
            int count = 0;
            var security = new List<UpdateData<Security>>();
            var custom = new List<UpdateData<Security>>();
            var consolidator = new List<UpdateData<SubscriptionDataConfig>>();
            var allDataForAlgorithm = new List<BaseData>(data.Count);
            var cash = new List<UpdateData<Cash>>(cashBook.Count);

            var cashSecurities = new HashSet<Symbol>();
            foreach (var cashItem in cashBook.Values)
            {
                cashSecurities.Add(cashItem.SecuritySymbol);
            }

            Split split;
            Dividend dividend;
            Delisting delisting;
            SymbolChangedEvent symbolChange;

            // we need to be able to reference the slice being created in order to define the
            // evaluation of option price models, so we define a 'future' that can be referenced
            // in the option price model evaluation delegates for each contract
            Slice slice = null;
            var sliceFuture = new Lazy<Slice>(() => slice);

            var algorithmTime = utcDateTime.ConvertFromUtc(algorithmTimeZone);
            var tradeBars = new TradeBars(algorithmTime);
            var quoteBars = new QuoteBars(algorithmTime);
            var ticks = new Ticks(algorithmTime);
            var splits = new Splits(algorithmTime);
            var dividends = new Dividends(algorithmTime);
            var delistings = new Delistings(algorithmTime);
            var optionChains = new OptionChains(algorithmTime);
            var symbolChanges = new SymbolChangedEvents(algorithmTime);

            foreach (var packet in data)
            {
                var list = packet.Data;
                var symbol = packet.Security.Symbol;

                if (list.Count == 0) continue;
                
                // keep count of all data points
                if (list.Count == 1 && list[0] is BaseDataCollection)
                {
                    var baseDataCollectionCount = ((BaseDataCollection)list[0]).Data.Count;
                    if (baseDataCollectionCount == 0)
                    {
                        continue;
                    }
                    count += baseDataCollectionCount;
                }
                else
                {
                    count += list.Count;
                }

                if (!packet.Configuration.IsInternalFeed && packet.Configuration.IsCustomData)
                {
                    // This is all the custom data
                    custom.Add(new UpdateData<Security>(packet.Security, packet.Configuration.Type, list));
                }

                var securityUpdate = new List<BaseData>(list.Count);
                var consolidatorUpdate = new List<BaseData>(list.Count);
                for (int i = 0; i < list.Count; i++)
                {
                    var baseData = list[i];
                    if (!packet.Configuration.IsInternalFeed)
                    {
                        // this is all the data that goes into the algorithm
                        allDataForAlgorithm.Add(baseData);
                    }
                    // don't add internal feed data to ticks/bars objects
                    if (baseData.DataType != MarketDataType.Auxiliary)
                    {
                        if (!packet.Configuration.IsInternalFeed)
                        {
                            PopulateDataDictionaries(baseData, ticks, tradeBars, quoteBars, optionChains);

                            // special handling of options data to build the option chain
                            if (packet.Security.Type == SecurityType.Option)
                            {
                                if (baseData.DataType == MarketDataType.OptionChain)
                                {
                                    optionChains[baseData.Symbol] = (OptionChain) baseData;
                                }
                                else if (!HandleOptionData(algorithmTime, baseData, optionChains, packet.Security, sliceFuture))
                                {
                                    continue;
                                }
                            }

                            // this is data used to update consolidators
                            consolidatorUpdate.Add(baseData);
                        }

                        // this is the data used set market prices
                        securityUpdate.Add(baseData);
                    }
                    // include checks for various aux types so we don't have to construct the dictionaries in Slice
                    else if ((delisting = baseData as Delisting) != null)
                    {
                        delistings[symbol] = delisting;
                    }
                    else if ((dividend = baseData as Dividend) != null)
                    {
                        dividends[symbol] = dividend;
                    }
                    else if ((split = baseData as Split) != null)
                    {
                        splits[symbol] = split;
                    }
                    else if ((symbolChange = baseData as SymbolChangedEvent) != null)
                    {
                        // symbol changes is keyed by the requested symbol
                        symbolChanges[packet.Configuration.Symbol] = symbolChange;
                    }
                }

                if (securityUpdate.Count > 0)
                {
                    // check for 'cash securities' if we found valid update data for this symbol
                    // and we need this data to update cash conversion rates, long term we should
                    // have Cash hold onto it's security, then he can update himself, or rather, just
                    // patch through calls to conversion rate to compue it on the fly using Security.Price
                    if (cashSecurities.Contains(packet.Security.Symbol))
                    {
                        foreach (var cashKvp in cashBook)
                        {
                            if (cashKvp.Value.SecuritySymbol == packet.Security.Symbol)
                            {
                                var cashUpdates = new List<BaseData> {securityUpdate[securityUpdate.Count - 1]};
                                cash.Add(new UpdateData<Cash>(cashKvp.Value, packet.Configuration.Type, cashUpdates));
                            }
                        }
                    }

                    security.Add(new UpdateData<Security>(packet.Security, packet.Configuration.Type, securityUpdate));
                }
                if (consolidatorUpdate.Count > 0)
                {
                    consolidator.Add(new UpdateData<SubscriptionDataConfig>(packet.Configuration, packet.Configuration.Type, consolidatorUpdate));
                }
            }

            slice = new Slice(algorithmTime, allDataForAlgorithm, tradeBars, quoteBars, ticks, optionChains, splits, dividends, delistings, symbolChanges, allDataForAlgorithm.Count > 0);

            return new TimeSlice(utcDateTime, count, slice, data, cash, security, consolidator, custom, changes);
        }
Exemplo n.º 21
0
 public void OnData(QuoteBars data)
 {
 }
Exemplo n.º 22
0
        /// <summary>
        /// Updates the stop-loss price of all open StopMarketOrders.
        /// </summary>
        public void UpdateTrailingStopOrders(QuoteBars data)
        {
            // Get all the spot-loss orders.
            var openStopLossOrders = _portfolio.Transactions.GetOrderTickets(o => o.OrderType == OrderType.StopMarket && o.Status == OrderStatus.Submitted);

            foreach (var ticket in openStopLossOrders)
            {
                var stopLossPrice = ticket.SubmitRequest.StopPrice;
                var volatility    = _portfolio.Securities[ticket.Symbol].VolatilityModel.Volatility;
                var actualPrice   = _portfolio.Securities[ticket.Symbol].Price;
                // The StopLossOrder has the opposite direction of the original order.
                var originalOrderDirection = ticket.Quantity > 0 ? OrderDirection.Sell : OrderDirection.Buy;
                if (originalOrderDirection == OrderDirection.Sell)
                {
                    actualPrice = data[ticket.Symbol].Ask.Close;
                }
                if (originalOrderDirection == OrderDirection.Buy)
                {
                    actualPrice = data[ticket.Symbol].Bid.Close;
                }
                var newStopLossPrice = actualPrice + (volatility * (originalOrderDirection == OrderDirection.Buy ? -1 : 1));
                var increment        = _portfolio.Securities[ticket.Symbol].PriceVariationModel.GetMinimumPriceVariation(_portfolio.Securities[ticket.Symbol]);
                if (increment != 0)
                {
                    newStopLossPrice = Math.Round(newStopLossPrice / increment) * increment;
                }

                if ((originalOrderDirection == OrderDirection.Buy && newStopLossPrice > stopLossPrice) ||
                    (originalOrderDirection == OrderDirection.Sell && newStopLossPrice < stopLossPrice))
                {
                    /*
                     * if (originalOrderDirection == OrderDirection.Sell && data[ticket.Symbol].Ask.Close < System.Convert.ToDecimal(ticket.SubmitRequest.Tag))
                     * {
                     *  if(newStopLossPrice>System.Convert.ToDecimal(ticket.SubmitRequest.Tag))
                     *  {
                     *      newStopLossPrice =  System.Convert.ToDecimal(ticket.SubmitRequest.Tag);
                     *  }
                     * }
                     * if (originalOrderDirection == OrderDirection.Buy && data[ticket.Symbol].Bid.Close > System.Convert.ToDecimal(ticket.SubmitRequest.Tag))
                     * {
                     *  //price is on right direction
                     *  if(newStopLossPrice<System.Convert.ToDecimal(ticket.SubmitRequest.Tag))
                     *  {
                     *      newStopLossPrice =  System.Convert.ToDecimal(ticket.SubmitRequest.Tag);
                     *  }
                     * }
                     */
                    ticket.Update(new UpdateOrderFields {
                        Quantity = -(_portfolio[ticket.Symbol].Quantity), StopPrice = newStopLossPrice
                    });
                }
                else if (!_portfolio[ticket.Symbol].Invested)
                {
                    ticket.Cancel();
                }
                else if (Math.Abs(_portfolio[ticket.Symbol].Quantity) != Math.Abs(ticket.Quantity))
                {
                    ticket.Update(new UpdateOrderFields {
                        Quantity = -(_portfolio[ticket.Symbol].Quantity)
                    });
                }
            }
        }
Exemplo n.º 23
0
        /// <summary>
        /// Creates a new <see cref="TimeSlice"/> for the specified time using the specified data
        /// </summary>
        /// <param name="utcDateTime">The UTC frontier date time</param>
        /// <param name="algorithmTimeZone">The algorithm's time zone, required for computing algorithm and slice time</param>
        /// <param name="cashBook">The algorithm's cash book, required for generating cash update pairs</param>
        /// <param name="data">The data in this <see cref="TimeSlice"/></param>
        /// <param name="changes">The new changes that are seen in this time slice as a result of universe selection</param>
        /// <param name="universeData"></param>
        /// <returns>A new <see cref="TimeSlice"/> containing the specified data</returns>
        public static TimeSlice Create(DateTime utcDateTime,
                                       DateTimeZone algorithmTimeZone,
                                       CashBook cashBook,
                                       List <DataFeedPacket> data,
                                       SecurityChanges changes,
                                       Dictionary <Universe, BaseDataCollection> universeData)
        {
            int count                   = 0;
            var security                = new List <UpdateData <Security> >();
            var custom                  = new List <UpdateData <Security> >();
            var consolidator            = new List <UpdateData <SubscriptionDataConfig> >();
            var allDataForAlgorithm     = new List <BaseData>(data.Count);
            var optionUnderlyingUpdates = new Dictionary <Symbol, BaseData>();

            Split              split;
            Dividend           dividend;
            Delisting          delisting;
            SymbolChangedEvent symbolChange;

            // we need to be able to reference the slice being created in order to define the
            // evaluation of option price models, so we define a 'future' that can be referenced
            // in the option price model evaluation delegates for each contract
            Slice slice       = null;
            var   sliceFuture = new Lazy <Slice>(() => slice);

            var algorithmTime = utcDateTime.ConvertFromUtc(algorithmTimeZone);
            var tradeBars     = new TradeBars(algorithmTime);
            var quoteBars     = new QuoteBars(algorithmTime);
            var ticks         = new Ticks(algorithmTime);
            var splits        = new Splits(algorithmTime);
            var dividends     = new Dividends(algorithmTime);
            var delistings    = new Delistings(algorithmTime);
            var optionChains  = new OptionChains(algorithmTime);
            var futuresChains = new FuturesChains(algorithmTime);
            var symbolChanges = new SymbolChangedEvents(algorithmTime);

            if (universeData.Count > 0)
            {
                // count universe data
                foreach (var kvp in universeData)
                {
                    count += kvp.Value.Data.Count;
                }
            }

            // ensure we read equity data before option data, so we can set the current underlying price
            foreach (var packet in data)
            {
                // filter out packets for removed subscriptions
                if (packet.IsSubscriptionRemoved)
                {
                    continue;
                }

                var list   = packet.Data;
                var symbol = packet.Security.Symbol;

                if (list.Count == 0)
                {
                    continue;
                }

                // keep count of all data points
                if (list.Count == 1 && list[0] is BaseDataCollection)
                {
                    var baseDataCollectionCount = ((BaseDataCollection)list[0]).Data.Count;
                    if (baseDataCollectionCount == 0)
                    {
                        continue;
                    }
                    count += baseDataCollectionCount;
                }
                else
                {
                    count += list.Count;
                }

                if (!packet.Configuration.IsInternalFeed && packet.Configuration.IsCustomData)
                {
                    // This is all the custom data
                    custom.Add(new UpdateData <Security>(packet.Security, packet.Configuration.Type, list));
                }

                var securityUpdate     = new List <BaseData>(list.Count);
                var consolidatorUpdate = new List <BaseData>(list.Count);
                for (int i = 0; i < list.Count; i++)
                {
                    var baseData = list[i];
                    if (!packet.Configuration.IsInternalFeed)
                    {
                        // this is all the data that goes into the algorithm
                        allDataForAlgorithm.Add(baseData);
                    }
                    // don't add internal feed data to ticks/bars objects
                    if (baseData.DataType != MarketDataType.Auxiliary)
                    {
                        if (!packet.Configuration.IsInternalFeed)
                        {
                            PopulateDataDictionaries(baseData, ticks, tradeBars, quoteBars, optionChains, futuresChains);

                            // special handling of options data to build the option chain
                            if (packet.Security.Type == SecurityType.Option)
                            {
                                if (baseData.DataType == MarketDataType.OptionChain)
                                {
                                    optionChains[baseData.Symbol] = (OptionChain)baseData;
                                }
                                else if (!HandleOptionData(algorithmTime, baseData, optionChains, packet.Security, sliceFuture, optionUnderlyingUpdates))
                                {
                                    continue;
                                }
                            }

                            // special handling of futures data to build the futures chain
                            if (packet.Security.Type == SecurityType.Future)
                            {
                                if (baseData.DataType == MarketDataType.FuturesChain)
                                {
                                    futuresChains[baseData.Symbol] = (FuturesChain)baseData;
                                }
                                else if (!HandleFuturesData(algorithmTime, baseData, futuresChains, packet.Security))
                                {
                                    continue;
                                }
                            }

                            // this is data used to update consolidators
                            consolidatorUpdate.Add(baseData);
                        }

                        // this is the data used set market prices
                        // do not add it if it is a Suspicious tick
                        var tick = baseData as Tick;
                        if (tick != null && tick.Suspicious)
                        {
                            continue;
                        }

                        securityUpdate.Add(baseData);

                        // option underlying security update
                        if (packet.Security.Symbol.SecurityType == SecurityType.Equity)
                        {
                            optionUnderlyingUpdates[packet.Security.Symbol] = baseData;
                        }
                    }
                    // include checks for various aux types so we don't have to construct the dictionaries in Slice
                    else if ((delisting = baseData as Delisting) != null)
                    {
                        delistings[symbol] = delisting;
                    }
                    else if ((dividend = baseData as Dividend) != null)
                    {
                        dividends[symbol] = dividend;
                    }
                    else if ((split = baseData as Split) != null)
                    {
                        splits[symbol] = split;
                    }
                    else if ((symbolChange = baseData as SymbolChangedEvent) != null)
                    {
                        // symbol changes is keyed by the requested symbol
                        symbolChanges[packet.Configuration.Symbol] = symbolChange;
                    }
                }

                if (securityUpdate.Count > 0)
                {
                    security.Add(new UpdateData <Security>(packet.Security, packet.Configuration.Type, securityUpdate));
                }
                if (consolidatorUpdate.Count > 0)
                {
                    consolidator.Add(new UpdateData <SubscriptionDataConfig>(packet.Configuration, packet.Configuration.Type, consolidatorUpdate));
                }
            }

            slice = new Slice(algorithmTime, allDataForAlgorithm, tradeBars, quoteBars, ticks, optionChains, futuresChains, splits, dividends, delistings, symbolChanges, allDataForAlgorithm.Count > 0);

            return(new TimeSlice(utcDateTime, count, slice, data, security, consolidator, custom, changes, universeData));
        }