コード例 #1
0
        public SimpleTimer(Splits splits, SplitEditor parent)
        {
            InitializeComponent();

            SaveOnSplit = true;

            _parent = parent;
            _splits = splits;
            _splitIndex = 0;

            _timer = new Timer();
            _timer.Interval = 10;
            _timer.Tick += Render;
            _timer.Start();

            _keyLogger = new KeyLogger(_toggleStartKey, _splitNowKey, _selectPreviousSplitKey, _selectNextSplitKey);
            _keyLogger.OnKeyPressed += OnKeyPressedThreadSafe;
            _keyLogger.Start();

            this.PerformRecursive((control) =>
            {
                control.MouseClick += HandleClick;
            });

            Render();
        }
コード例 #2
0
        public void Close()
        {
            if (Server == null)             // EMULATOR
            {
                if (_tickerHighPrecisionTimer != null)
                {
                    _tickerHighPrecisionTimer.Dispose();
                }

                return;
            }

            PlayerNetworkSession session;

            if (!Server.ServerInfo.PlayerSessions.TryRemove(EndPoint, out session))
            {
                return;
            }

            if (PlayerAckQueue.Count > 0)
            {
                Thread.Sleep(50);
            }

            if (_tickerHighPrecisionTimer != null)
            {
                _tickerHighPrecisionTimer.Dispose();
            }

            State          = ConnectionState.Unconnected;
            Evicted        = true;
            MessageHandler = null;

            SendQueue();

            _cancellationToken.Cancel();
            _waitEvent.Set();
            _mainWaitEvent.Set();
            _queue.Clear();

            var queue = WaitingForAcksQueue;

            foreach (var kvp in queue)
            {
                Datagram datagram;
                if (queue.TryRemove(kvp.Key, out datagram))
                {
                    datagram.PutPool();
                }
            }

            foreach (var kvp in Splits)
            {
                SplitPartPackage[] splitPartPackagese;
                if (Splits.TryRemove(kvp.Key, out splitPartPackagese))
                {
                    if (splitPartPackagese == null)
                    {
                        continue;
                    }

                    foreach (SplitPartPackage package in splitPartPackagese)
                    {
                        if (package != null)
                        {
                            package.PutPool();
                        }
                    }
                }
            }

            queue.Clear();
            Splits.Clear();

            try
            {
                _processingThread = null;
                _cancellationToken.Dispose();
                _waitEvent.Close();
                _mainWaitEvent.Close();
            }
            catch (Exception e)
            {
            }

            if (Log.IsDebugEnabled)
            {
                Log.Warn($"Closed network session for player {Username}");
            }
        }
コード例 #3
0
 public static void Remove(Window window)
 {
     lock (locker) {
         Splits.Remove(window);
     }
 }
コード例 #4
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;

            _dataByType = new Dictionary <Type, Lazy <object> >();

            // market data
            _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);
            _futuresChains = CreateCollection <FuturesChains, FuturesChain>(futuresChains);

            // auxiliary data
            _splits              = CreateCollection <Splits, Split>(splits);
            _dividends           = CreateCollection <Dividends, Dividend>(dividends);
            _delistings          = CreateCollection <Delistings, Delisting>(delistings);
            _symbolChangedEvents = CreateCollection <SymbolChangedEvents, SymbolChangedEvent>(symbolChanges);
        }
コード例 #5
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));
        }
コード例 #6
0
ファイル: AlgorithmManager.cs プロジェクト: weimerben/Lean
        /// <summary>
        /// Launch the algorithm manager to run this strategy
        /// </summary>
        /// <param name="job">Algorithm job</param>
        /// <param name="algorithm">Algorithm instance</param>
        /// <param name="feed">Datafeed object</param>
        /// <param name="transactions">Transaction manager object</param>
        /// <param name="results">Result handler object</param>
        /// <param name="realtime">Realtime processing object</param>
        /// <param name="token">Cancellation token</param>
        /// <remarks>Modify with caution</remarks>
        public void Run(AlgorithmNodePacket job, IAlgorithm algorithm, IDataFeed feed, ITransactionHandler transactions, IResultHandler results, IRealTimeHandler realtime, CancellationToken token)
        {
            //Initialize:
            _dataPointCount = 0;
            var startingPortfolioValue = algorithm.Portfolio.TotalPortfolioValue;
            var backtestMode           = (job.Type == PacketType.BacktestNode);
            var methodInvokers         = new Dictionary <Type, MethodInvoker>();
            var marginCallFrequency    = TimeSpan.FromMinutes(5);
            var nextMarginCallTime     = DateTime.MinValue;
            var delistingTickets       = new List <OrderTicket>();

            //Initialize Properties:
            _algorithmId    = job.AlgorithmId;
            _algorithmState = AlgorithmStatus.Running;
            _previousTime   = algorithm.StartDate.Date;

            //Create the method accessors to push generic types into algorithm: Find all OnData events:

            // Algorithm 2.0 data accessors
            var hasOnDataTradeBars = AddMethodInvoker <TradeBars>(algorithm, methodInvokers);
            var hasOnDataTicks     = AddMethodInvoker <Ticks>(algorithm, methodInvokers);

            // dividend and split events
            var hasOnDataDividends  = AddMethodInvoker <Dividends>(algorithm, methodInvokers);
            var hasOnDataSplits     = AddMethodInvoker <Splits>(algorithm, methodInvokers);
            var hasOnDataDelistings = AddMethodInvoker <Delistings>(algorithm, methodInvokers);

            // Algorithm 3.0 data accessors
            var hasOnDataSlice = algorithm.GetType().GetMethods()
                                 .Where(x => x.Name == "OnData" && x.GetParameters().Length == 1 && x.GetParameters()[0].ParameterType == typeof(Slice))
                                 .FirstOrDefault(x => x.DeclaringType == algorithm.GetType()) != null;

            //Go through the subscription types and create invokers to trigger the event handlers for each custom type:
            foreach (var config in feed.Subscriptions)
            {
                //If type is a tradebar, combine tradebars and ticks into unified array:
                if (config.Type.Name != "TradeBar" && config.Type.Name != "Tick")
                {
                    //Get the matching method for this event handler - e.g. public void OnData(Quandl data) { .. }
                    var genericMethod = (algorithm.GetType()).GetMethod("OnData", new[] { config.Type });

                    //If we already have this Type-handler then don't add it to invokers again.
                    if (methodInvokers.ContainsKey(config.Type))
                    {
                        continue;
                    }

                    //If we couldnt find the event handler, let the user know we can't fire that event.
                    if (genericMethod == null && !hasOnDataSlice)
                    {
                        algorithm.RunTimeError = new Exception("Data event handler not found, please create a function matching this template: public void OnData(" + config.Type.Name + " data) {  }");
                        _algorithmState        = AlgorithmStatus.RuntimeError;
                        return;
                    }
                    if (genericMethod != null)
                    {
                        methodInvokers.Add(config.Type, genericMethod.DelegateForCallMethod());
                    }
                }
            }

            //Loop over the queues: get a data collection, then pass them all into relevent methods in the algorithm.
            Log.Trace("AlgorithmManager.Run(): Begin DataStream - Start: " + algorithm.StartDate + " Stop: " + algorithm.EndDate);
            foreach (var timeSlice in feed.Bridge.GetConsumingEnumerable(token))
            {
                // reset our timer on each loop
                _currentTimeStepTime = DateTime.UtcNow;

                //Check this backtest is still running:
                if (_algorithmState != AlgorithmStatus.Running)
                {
                    Log.Error(string.Format("AlgorithmManager.Run(): Algorthm state changed to {0} at {1}", _algorithmState, timeSlice.Time));
                    break;
                }

                //Execute with TimeLimit Monitor:
                if (token.IsCancellationRequested)
                {
                    Log.Error("AlgorithmManager.Run(): CancellationRequestion at " + timeSlice.Time);
                    return;
                }

                var time    = timeSlice.Time;
                var newData = timeSlice.Data;

                //If we're in backtest mode we need to capture the daily performance. We do this here directly
                //before updating the algorithm state with the new data from this time step, otherwise we'll
                //produce incorrect samples (they'll take into account this time step's new price values)
                if (backtestMode)
                {
                    //On day-change sample equity and daily performance for statistics calculations
                    if (_previousTime.Date != time.Date)
                    {
                        //Sample the portfolio value over time for chart.
                        results.SampleEquity(_previousTime, Math.Round(algorithm.Portfolio.TotalPortfolioValue, 4));

                        //Check for divide by zero
                        if (startingPortfolioValue == 0m)
                        {
                            results.SamplePerformance(_previousTime.Date, 0);
                        }
                        else
                        {
                            results.SamplePerformance(_previousTime.Date, Math.Round((algorithm.Portfolio.TotalPortfolioValue - startingPortfolioValue) * 100 / startingPortfolioValue, 10));
                        }
                        startingPortfolioValue = algorithm.Portfolio.TotalPortfolioValue;
                    }
                }

                //Update algorithm state after capturing performance from previous day

                //Set the algorithm and real time handler's time
                algorithm.SetDateTime(time);
                realtime.SetTime(algorithm.Time);

                //On each time step push the real time prices to the cashbook so we can have updated conversion rates
                algorithm.Portfolio.CashBook.Update(newData);

                //Update the securities properties: first before calling user code to avoid issues with data
                algorithm.Securities.Update(time, newData);

                // process fill models on the updated data before entering algorithm, applies to all non-market orders
                transactions.ProcessSynchronousEvents();

                if (delistingTickets.Count != 0)
                {
                    for (int i = 0; i < delistingTickets.Count; i++)
                    {
                        var ticket = delistingTickets[i];
                        if (ticket.Status == OrderStatus.Filled)
                        {
                            algorithm.Securities.Remove(ticket.Symbol);
                            delistingTickets.RemoveAt(i--);
                            Log.Trace("AlgorithmManager.Run(): Security removed: " + ticket.Symbol);
                        }
                    }
                }

                //Check if the user's signalled Quit: loop over data until day changes.
                if (algorithm.GetQuit())
                {
                    _algorithmState = AlgorithmStatus.Quit;
                    Log.Trace("AlgorithmManager.Run(): Algorithm quit requested.");
                    break;
                }
                if (algorithm.RunTimeError != null)
                {
                    _algorithmState = AlgorithmStatus.RuntimeError;
                    Log.Trace(string.Format("AlgorithmManager.Run(): Algorithm encountered a runtime error at {0}. Error: {1}", timeSlice.Time, algorithm.RunTimeError));
                    break;
                }

                // perform margin calls, in live mode we can also use realtime to emit these
                if (time >= nextMarginCallTime || (_liveMode && nextMarginCallTime > DateTime.Now))
                {
                    // determine if there are possible margin call orders to be executed
                    bool issueMarginCallWarning;
                    var  marginCallOrders = algorithm.Portfolio.ScanForMarginCall(out issueMarginCallWarning);
                    if (marginCallOrders.Count != 0)
                    {
                        try
                        {
                            // tell the algorithm we're about to issue the margin call
                            algorithm.OnMarginCall(marginCallOrders);
                        }
                        catch (Exception err)
                        {
                            algorithm.RunTimeError = err;
                            _algorithmState        = AlgorithmStatus.RuntimeError;
                            Log.Error("AlgorithmManager.Run(): RuntimeError: OnMarginCall: " + err.Message + " STACK >>> " + err.StackTrace);
                            return;
                        }

                        // execute the margin call orders
                        var executedTickets = algorithm.Portfolio.MarginCallModel.ExecuteMarginCall(marginCallOrders);
                        foreach (var ticket in executedTickets)
                        {
                            algorithm.Error(string.Format("{0} - Executed MarginCallOrder: {1} - Quantity: {2} @ {3}", algorithm.Time, ticket.Symbol, ticket.Quantity, ticket.OrderEvents.Last().FillPrice));
                        }
                    }
                    // we didn't perform a margin call, but got the warning flag back, so issue the warning to the algorithm
                    else if (issueMarginCallWarning)
                    {
                        try
                        {
                            algorithm.OnMarginCallWarning();
                        }
                        catch (Exception err)
                        {
                            algorithm.RunTimeError = err;
                            _algorithmState        = AlgorithmStatus.RuntimeError;
                            Log.Error("AlgorithmManager.Run(): RuntimeError: OnMarginCallWarning: " + err.Message + " STACK >>> " + err.StackTrace);
                        }
                    }

                    nextMarginCallTime = time + marginCallFrequency;
                }

                //Trigger the data events: Invoke the types we have data for:
                var newBars       = new TradeBars(algorithm.Time);
                var newTicks      = new Ticks(algorithm.Time);
                var newDividends  = new Dividends(algorithm.Time);
                var newSplits     = new Splits(algorithm.Time);
                var newDelistings = new Delistings(algorithm.Time);

                //Invoke all non-tradebars, non-ticks methods and build up the TradeBars and Ticks dictionaries
                // --> i == Subscription Configuration Index, so we don't need to compare types.
                foreach (var i in newData.Keys)
                {
                    //Data point and config of this point:
                    var dataPoints = newData[i];
                    var config     = feed.Subscriptions[i];

                    //Keep track of how many data points we've processed
                    _dataPointCount += dataPoints.Count;

                    //We don't want to pump data that we added just for currency conversions
                    if (config.IsInternalFeed)
                    {
                        continue;
                    }

                    //Create TradeBars Unified Data --> OR --> invoke generic data event. One loop.
                    //  Aggregate Dividends and Splits -- invoke portfolio application methods
                    foreach (var dataPoint in dataPoints)
                    {
                        var dividend = dataPoint as Dividend;
                        if (dividend != null)
                        {
                            Log.Trace("AlgorithmManager.Run(): Applying Dividend for " + dividend.Symbol);
                            // if this is a dividend apply to portfolio
                            algorithm.Portfolio.ApplyDividend(dividend);
                            if (hasOnDataDividends)
                            {
                                // and add to our data dictionary to pump into OnData(Dividends data)
                                newDividends.Add(dividend);
                            }
                            continue;
                        }

                        var split = dataPoint as Split;
                        if (split != null)
                        {
                            Log.Trace("AlgorithmManager.Run(): Applying Split for " + split.Symbol);
                            // if this is a split apply to portfolio
                            algorithm.Portfolio.ApplySplit(split);
                            if (hasOnDataSplits)
                            {
                                // and add to our data dictionary to pump into OnData(Splits data)
                                newSplits.Add(split);
                            }
                            continue;
                        }

                        var delisting = dataPoint as Delisting;
                        if (delisting != null)
                        {
                            if (hasOnDataDelistings)
                            {
                                // add to out data dictonary to pump into OnData(Delistings data)
                                newDelistings.Add(delisting);
                            }
                        }

                        //Update registered consolidators for this symbol index
                        try
                        {
                            for (var j = 0; j < config.Consolidators.Count; j++)
                            {
                                config.Consolidators[j].Update(dataPoint);
                            }
                        }
                        catch (Exception err)
                        {
                            algorithm.RunTimeError = err;
                            _algorithmState        = AlgorithmStatus.RuntimeError;
                            Log.Error("AlgorithmManager.Run(): RuntimeError: Consolidators update: " + err.Message);
                            return;
                        }

                        // TRADEBAR -- add to our dictionary
                        if (dataPoint.DataType == MarketDataType.TradeBar)
                        {
                            var bar = dataPoint as TradeBar;
                            if (bar != null)
                            {
                                newBars[bar.Symbol] = bar;
                                continue;
                            }
                        }

                        // TICK -- add to our dictionary
                        if (dataPoint.DataType == MarketDataType.Tick)
                        {
                            var tick = dataPoint as Tick;
                            if (tick != null)
                            {
                                List <Tick> ticks;
                                if (!newTicks.TryGetValue(tick.Symbol, out ticks))
                                {
                                    ticks = new List <Tick>(3);
                                    newTicks.Add(tick.Symbol, ticks);
                                }
                                ticks.Add(tick);
                                continue;
                            }
                        }

                        // if it was nothing else then it must be custom data

                        // CUSTOM DATA -- invoke on data method
                        //Send data into the generic algorithm event handlers
                        try
                        {
                            MethodInvoker methodInvoker;
                            if (methodInvokers.TryGetValue(config.Type, out methodInvoker))
                            {
                                methodInvoker(algorithm, dataPoint);
                            }
                        }
                        catch (Exception err)
                        {
                            algorithm.RunTimeError = err;
                            _algorithmState        = AlgorithmStatus.RuntimeError;
                            Log.Error("AlgorithmManager.Run(): RuntimeError: Custom Data: " + err.Message + " STACK >>> " + err.StackTrace);
                            return;
                        }
                    }
                }

                try
                {
                    // fire off the dividend and split events before pricing events
                    if (hasOnDataDividends && newDividends.Count != 0)
                    {
                        methodInvokers[typeof(Dividends)](algorithm, newDividends);
                    }
                    if (hasOnDataSplits && newSplits.Count != 0)
                    {
                        methodInvokers[typeof(Splits)](algorithm, newSplits);
                    }
                    if (hasOnDataDelistings && newDelistings.Count != 0)
                    {
                        methodInvokers[typeof(Delistings)](algorithm, newDelistings);
                    }
                }
                catch (Exception err)
                {
                    algorithm.RunTimeError = err;
                    _algorithmState        = AlgorithmStatus.RuntimeError;
                    Log.Error("AlgorithmManager.Run(): RuntimeError: Dividends/Splits/Delistings: " + err.Message + " STACK >>> " + err.StackTrace);
                    return;
                }

                // run the delisting logic after firing delisting events
                HandleDelistedSymbols(algorithm, newDelistings, delistingTickets);

                //After we've fired all other events in this second, fire the pricing events:
                try
                {
                    if (hasOnDataTradeBars && newBars.Count > 0)
                    {
                        methodInvokers[typeof(TradeBars)](algorithm, newBars);
                    }
                    if (hasOnDataTicks && newTicks.Count > 0)
                    {
                        methodInvokers[typeof(Ticks)](algorithm, newTicks);
                    }
                }
                catch (Exception err)
                {
                    algorithm.RunTimeError = err;
                    _algorithmState        = AlgorithmStatus.RuntimeError;
                    Log.Error("AlgorithmManager.Run(): RuntimeError: New Style Mode: " + err.Message + " STACK >>> " + err.StackTrace);
                    return;
                }

                // EVENT HANDLER v3.0 -- all data in a single event
                var slice = new Slice(algorithm.Time, newData.Values.SelectMany(x => x),
                                      newBars.Count == 0 ? null : newBars,
                                      newTicks.Count == 0 ? null : newTicks,
                                      newSplits.Count == 0 ? null : newSplits,
                                      newDividends.Count == 0 ? null : newDividends,
                                      newDelistings.Count == 0 ? null : newDelistings
                                      );

                try
                {
                    algorithm.OnData(slice);
                }
                catch (Exception err)
                {
                    algorithm.RunTimeError = err;
                    _algorithmState        = AlgorithmStatus.RuntimeError;
                    Log.Error("AlgorithmManager.Run(): RuntimeError: Slice: " + err.Message + " STACK >>> " + err.StackTrace);
                    return;
                }

                //If its the historical/paper trading models, wait until market orders have been "filled"
                // Manually trigger the event handler to prevent thread switch.
                transactions.ProcessSynchronousEvents();

                //Save the previous time for the sample calculations
                _previousTime = time;

                // Process any required events of the results handler such as sampling assets, equity, or stock prices.
                results.ProcessSynchronousEvents();
            } // End of ForEach feed.Bridge.GetConsumingEnumerable

            // stop timing the loops
            _currentTimeStepTime = DateTime.MinValue;

            //Stream over:: Send the final packet and fire final events:
            Log.Trace("AlgorithmManager.Run(): Firing On End Of Algorithm...");
            try
            {
                algorithm.OnEndOfAlgorithm();
            }
            catch (Exception err)
            {
                _algorithmState        = AlgorithmStatus.RuntimeError;
                algorithm.RunTimeError = new Exception("Error running OnEndOfAlgorithm(): " + err.Message, err.InnerException);
                Log.Error("AlgorithmManager.OnEndOfAlgorithm(): " + err.Message + " STACK >>> " + err.StackTrace);
                return;
            }

            // Process any required events of the results handler such as sampling assets, equity, or stock prices.
            results.ProcessSynchronousEvents(forceProcess: true);

            //Liquidate Holdings for Calculations:
            if (_algorithmState == AlgorithmStatus.Liquidated && _liveMode)
            {
                Log.Trace("AlgorithmManager.Run(): Liquidating algorithm holdings...");
                algorithm.Liquidate();
                results.LogMessage("Algorithm Liquidated");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Liquidated);
            }

            //Manually stopped the algorithm
            if (_algorithmState == AlgorithmStatus.Stopped)
            {
                Log.Trace("AlgorithmManager.Run(): Stopping algorithm...");
                results.LogMessage("Algorithm Stopped");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Stopped);
            }

            //Backtest deleted.
            if (_algorithmState == AlgorithmStatus.Deleted)
            {
                Log.Trace("AlgorithmManager.Run(): Deleting algorithm...");
                results.DebugMessage("Algorithm Id:(" + job.AlgorithmId + ") Deleted by request.");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Deleted);
            }

            //Algorithm finished, send regardless of commands:
            results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Completed);

            //Take final samples:
            results.SampleRange(algorithm.GetChartUpdates());
            results.SampleEquity(_previousTime, Math.Round(algorithm.Portfolio.TotalPortfolioValue, 4));
            results.SamplePerformance(_previousTime, Math.Round((algorithm.Portfolio.TotalPortfolioValue - startingPortfolioValue) * 100 / startingPortfolioValue, 10));
        } // End of Run();
コード例 #7
0
 public bool HasSplit(SplitName split)
 {
     return(Splits.Contains(split));
 }
コード例 #8
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();
 }
コード例 #9
0
ファイル: SubAlgo.cs プロジェクト: scilear/Lean
 public virtual void OnData(Splits data)
 {
 }
コード例 #10
0
 private void Open(object s = null, EventArgs e = null)
 {
     string path;
     if (OpenFileDialog(out path))
     {
         SelectedSplits = Splits.Open(path.ToForwardPath());
     }
 }
コード例 #11
0
        void MemoryReadThread()
        {
            Debug.WriteLine("[NoLoads] MemoryReadThread");
            _settings_SplitsChanged(null, null);

            while (!_cancelSource.IsCancellationRequested)
            {
                try
                {
                    Debug.WriteLine("[NoLoads] Waiting for thief.exe or thief2.exe...");

                    Process game;
                    while ((game = GetGameProcess()) == null)
                    {
                        if (_cancelSource.IsCancellationRequested)
                        {
                            return;
                        }
                    }

                    Debug.WriteLine("[NoLoads] Got games process!");

                    uint frameCounter = 0;

                    while (!game.HasExited)
                    {
                        isLoading = _isLoadingPtr.ReadBool();
                        if (_levelCompleteCounter != null)
                        {
                            LevelCompletedCounter = _levelCompleteCounter.ReadInteger();
                        }
                        string tempRead = _levelName.ReadString(StringReadLenght, SuisReader.StringType.UTF8).ToString();
                        if (tempRead != "")
                        {
                            CurrentMap = tempRead.ToLower();
                        }
                        if (CurrentMap.EndsWith(".mis"))
                        {
                            CurrentMap = CurrentMap.Substring(0, CurrentMap.Length - 4);
                        }

                        if (isLoading != prevIsLoading)
                        {
                            if (isLoading)
                            {
                                Debug.WriteLine(String.Format("[NoLoads] Load Start - {0}", frameCounter));

                                loadingStarted = true;

                                // pause game timer
                                _uiThread.Post(d =>
                                {
                                    if (this.OnLoadStarted != null)
                                    {
                                        this.OnLoadStarted(this, EventArgs.Empty);
                                    }
                                }, null);
                            }
                            else
                            {
                                Debug.WriteLine(String.Format("[NoLoads] Load End - {0}", frameCounter));

                                if (loadingStarted)
                                {
                                    loadingStarted = false;


                                    // unpause game timer
                                    _uiThread.Post(d =>
                                    {
                                        if (this.OnLoadFinished != null)
                                        {
                                            this.OnLoadFinished(this, EventArgs.Empty);
                                        }
                                    }, null);
                                }

                                if (Splits != null && Splits.Length > 0 && CurrentMap == Splits[0].MapName)
                                {
                                    // StartTimer
                                    _uiThread.Post(d =>
                                    {
                                        if (this.OnPlayerGainedControl != null)
                                        {
                                            this.OnFirstLevelLoading(this, EventArgs.Empty);
                                            this.OnPlayerGainedControl(this, EventArgs.Empty);
                                        }
                                    }, null);
                                }
                            }
                        }

                        if (CurrentMap != prevMap && CurrentMap != "" || prevLevelCompletedCounter != LevelCompletedCounter)
                        {
                            for (int i = 1; i < Splits.Length; i++)
                            {
                                if (Splits[i].Checked && Splits[i].MapName == CurrentMap && Splits[i - 1].MapName == prevMap)
                                {
                                    Split(i, frameCounter);
                                    break;
                                }
                            }
                            Debug.WriteLine("[NOLOADS] Map changed from \"" + prevMap + "\" to \"" + CurrentMap + "\"");

                            if (SplitOnLastSplit)
                            {
                                if (Splits.Last().MapName == CurrentMap && LevelCompletedCounter > prevLevelCompletedCounter)
                                {
                                    Split(SplitStates.Length - 1, frameCounter);
                                }
                            }
                        }

                        prevMap                   = CurrentMap;
                        prevIsLoading             = isLoading;
                        prevLevelCompletedCounter = LevelCompletedCounter;
                        frameCounter++;

                        Thread.Sleep(15);

                        if (_cancelSource.IsCancellationRequested)
                        {
                            return;
                        }
                    }

                    // pause game timer on exit or crash
                    _uiThread.Post(d =>
                    {
                        if (this.OnLoadStarted != null)
                        {
                            this.OnLoadStarted(this, EventArgs.Empty);
                        }
                    }, null);
                    isLoading = true;
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.ToString());
                    Thread.Sleep(1000);
                }
            }
        }
コード例 #12
0
 private void NewEmpty(object s = null, EventArgs e = null)
 {
     SelectedSplits = Splits.NewEmpty();
 }
コード例 #13
0
 /// <summary>
 /// Constructor method. Builds an instance of MSDataGridHelperLayoutInfo with 
 /// the specified values for its properties.
 /// </summary>
 /// <param name="gridSplits">GridSplits property value.</param>
 /// <param name="gridColumns">GridColumns property value.</param>
 /// <param name="lastUpdate">LastUpdate property value.</param>
 public MSDataGridHelperLayoutInfo(Splits gridSplits, Columns gridColumns, string lastUpdate)
 {
     _gridSplits = gridSplits;
     _gridColumns = gridColumns;
     _lastUpdate = lastUpdate;
 }
コード例 #14
0
ファイル: TimeSlice.cs プロジェクト: jensyeager/Lean
        /// <summary>
        /// Creates a new <see cref="TimeSlice"/> for the specified time using the specified data
        /// </summary>
        /// <param name="algorithm">The algorithm we're creating <see cref="TimeSlice"/> instances for</param>
        /// <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>
        /// <returns>A new <see cref="TimeSlice"/> containing the specified data</returns>
        public static TimeSlice Create(IAlgorithm algorithm, DateTime utcDateTime, List <KeyValuePair <Security, List <BaseData> > > data, SecurityChanges changes)
        {
            int count               = 0;
            var security            = new List <KeyValuePair <Security, BaseData> >();
            var custom              = new List <KeyValuePair <Security, List <BaseData> > >();
            var consolidator        = new List <KeyValuePair <SubscriptionDataConfig, List <BaseData> > >();
            var allDataForAlgorithm = new List <BaseData>(data.Count);
            var cash = new List <KeyValuePair <Cash, BaseData> >(algorithm.Portfolio.CashBook.Count);

            var cashSecurities = new HashSet <string>();

            foreach (var cashItem in algorithm.Portfolio.CashBook.Values)
            {
                cashSecurities.Add(cashItem.SecuritySymbol);
            }

            Split     split;
            Dividend  dividend;
            Delisting delisting;

            var algorithmTime = utcDateTime.ConvertFromUtc(algorithm.TimeZone);
            var tradeBars     = new TradeBars(algorithmTime);
            var ticks         = new Ticks(algorithmTime);
            var splits        = new Splits(algorithmTime);
            var dividends     = new Dividends(algorithmTime);
            var delistings    = new Delistings(algorithmTime);

            foreach (var kvp in data)
            {
                var list   = kvp.Value;
                var symbol = kvp.Key.Symbol;

                // keep count of all data points
                count += list.Count;

                BaseData update             = null;
                var      consolidatorUpdate = new List <BaseData>(list.Count);
                for (int i = list.Count - 1; i > -1; i--)
                {
                    var baseData = list[i];
                    if (!kvp.Key.SubscriptionDataConfig.IsInternalFeed)
                    {
                        // this is all the data that goes into the algorithm
                        allDataForAlgorithm.Add(baseData);
                    }
                    if (kvp.Key.IsDynamicallyLoadedData)
                    {
                        // this is all the custom data
                        custom.Add(kvp);
                    }
                    if (baseData.DataType != MarketDataType.Auxiliary)
                    {
                        // populate ticks and tradebars dictionaries with no aux data
                        if (baseData.DataType == MarketDataType.Tick)
                        {
                            List <Tick> ticksList;
                            if (!ticks.TryGetValue(symbol, out ticksList))
                            {
                                ticksList = new List <Tick> {
                                    (Tick)baseData
                                };
                                ticks[symbol] = ticksList;
                            }
                            ticksList.Add((Tick)baseData);
                        }
                        else if (baseData.DataType == MarketDataType.TradeBar)
                        {
                            tradeBars[symbol] = (TradeBar)baseData;
                        }

                        // this is data used to update consolidators
                        consolidatorUpdate.Add(baseData);
                        if (update == null)
                        {
                            // this is the data used set market prices
                            update = 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;
                    }
                }

                // 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 (update != null && cashSecurities.Contains(kvp.Key.Symbol))
                {
                    foreach (var cashKvp in algorithm.Portfolio.CashBook)
                    {
                        if (cashKvp.Value.SecuritySymbol == kvp.Key.Symbol)
                        {
                            cash.Add(new KeyValuePair <Cash, BaseData>(cashKvp.Value, update));
                        }
                    }
                }

                security.Add(new KeyValuePair <Security, BaseData>(kvp.Key, update));
                consolidator.Add(new KeyValuePair <SubscriptionDataConfig, List <BaseData> >(kvp.Key.SubscriptionDataConfig, consolidatorUpdate));
            }

            var slice = new Slice(utcDateTime.ConvertFromUtc(algorithm.TimeZone), allDataForAlgorithm, tradeBars, ticks, splits, dividends, delistings);

            return(new TimeSlice(utcDateTime, count, slice, data, cash, security, consolidator, custom, changes));
        }
コード例 #15
0
        /// <summary>
        /// Entfernt den obersten VertexSplit von dem VertexSplit Stack und führt ihn
        /// durch.
        /// </summary>
        /// <returns>
        /// true, wenn ein VertexSplit aus dem Stack entnommen wurde und durchgeführt
        /// wurde; andernfalls false, d.h. der Stack war schon leer.
        /// </returns>
        /// <remarks>
        /// Das Durchführen einer VertexSplit Operation hat immer das Pushen seiner
        /// Umkehroperation auf den Contraction Stack zur Folge.
        /// </remarks>
        public bool PerformVertexSplit()
        {
            if (Splits.Count == 0)
            {
                return(false);
            }
            if (incidentFaces == null)
            {
                incidentFaces = ComputeIncidentFaces();
                // Einmalig alle Vertexnormalen bestimmen.
//				ComputeNormals(_faces);
            }
            var split = Splits.Pop();

            // 1. Vertex s wird an neue Position verschoben.
            Vertices[split.S] = new Vertex()
            {
                Position = split.SPosition
            };
            // 2. Vertex t wird neu zur Mesh hinzugefügt.
            Vertices[NumberOfVertices] = new Vertex()
            {
                Position = split.TPosition
            };
            uint t = (uint)NumberOfVertices;

            // 3. Umkehroperation des VertexSplits auf Contraction Stack pushen.
            Contractions.Push(new Contraction()
            {
                S           = split.S,
                Position    = Vertices[split.S].Position, faceOffset = NumberOfFaces,
                VertexSplit = split
            });
            NumberOfVertices++;
            // 4. Alle Facetten von s, die ursprünglich t "gehört" haben, auf t zurückbiegen.
            var facesOfS = incidentFaces[split.S];
            var facesOfT = new HashSet <Face>();

            incidentFaces.Add(t, facesOfT);
            var removeFromS = new HashSet <Face>();

            foreach (var f in facesOfS)
            {
                var _c = IsOriginalFaceOfT(t, f, split);
                if (_c < 0)
                {
                    continue;
                }
                f[_c] = t;
                facesOfT.Add(f);
                removeFromS.Add(f);
            }
            foreach (var r in removeFromS)
            {
                facesOfS.Remove(r);
            }
            // 5. Etwaige gemeinsame Facetten von s und t der Mesh neu hinzufügen.
            foreach (var f in split.Faces)
            {
                if (!f.Indices.Contains(split.S))
                {
                    continue;
                }
                var newFace = new Face(f.Indices, FlatFaces, NumberOfFaces * 3);
                NumberOfFaces++;
                for (int c = 0; c < 3; c++)
                {
                    incidentFaces[newFace[c]].Add(newFace);
                }
            }
            // Normalen aller betroffenen Vertices neuberechnen.
            ComputeNormals(incidentFaces[split.S].Union(incidentFaces[t]));
            return(true);
        }
コード例 #16
0
        public bool IsValid(Transactions transaction)
        {
            if (this.AccountId != -1)
            {
                if (this.AccountId != transaction.Account)
                {
                    return(false);
                }
            }

            if (this.CategoryIds.Any())
            {
                if (transaction.Category == Categories.SplitCategoryId())
                {
                    List <Splits> splits = Splits.GetSplitsForTransaction(transaction.Id);
                    bool          categoryFoundInSplits = false;
                    foreach (Splits split in splits)
                    {
                        if (this.CategoryIds.Contains(split.Category))
                        {
                            categoryFoundInSplits = true;
                            break;
                        }
                    }
                    if (!categoryFoundInSplits)
                    {
                        return(false);
                    }
                }
                else
                {
                    if (!this.CategoryIds.Contains(transaction.Category))
                    {
                        return(false);
                    }
                }
            }

            if (this.PayeeId != -1)
            {
                if (this.PayeeId != transaction.Payee)
                {
                    return(false);
                }
            }

            if (this.Amount != null)
            {
                if (this.Amount != transaction.Amount)
                {
                    return(false);
                }
            }

            if (this.Year != null)
            {
                if (this.Year != transaction.DateTime.Year)
                {
                    return(false);
                }
            }

            if (this.DateText != string.Empty)
            {
                if (this.DateText != transaction.DateAsText)
                {
                    return(false);
                }
            }

            if (this.SearchText != string.Empty && this.SearchText != null)
            {
                if (!transaction.IsTextMatch(this.SearchText))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #17
0
ファイル: TimeSlice.cs プロジェクト: beezy3601/lean2
        /// <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 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);

            // ensure we read equity data before option data, so we can set the current underlying price
            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, 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));
        }
コード例 #18
0
ファイル: Slice.cs プロジェクト: zhangxia85/Lean
        /// <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="ticks">This ticks 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>
        public Slice(DateTime time, IEnumerable <BaseData> data, TradeBars tradeBars, Ticks ticks, Splits splits, Dividends dividends, Delistings delistings, SymbolChangedEvents symbolChanges)
        {
            Time = time;

            _dataByType = new Dictionary <Type, Lazy <object> >();

            // market data
            _data  = CreateDynamicDataDictionary(data);
            _ticks = CreateTicksCollection(ticks);
            _bars  = CreateCollection <TradeBars, TradeBar>(tradeBars);

            // auxiliary data
            _splits              = CreateCollection <Splits, Split>(splits);
            _dividends           = CreateCollection <Dividends, Dividend>(dividends);
            _delistings          = CreateCollection <Delistings, Delisting>(delistings);
            _symbolChangedEvents = CreateCollection <SymbolChangedEvents, SymbolChangedEvent>(symbolChanges);
        }
コード例 #19
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;
        }
コード例 #20
0
ファイル: AlgorithmManager.cs プロジェクト: michaelqc/Lean
        /********************************************************
         * CLASS METHODS
         *********************************************************/
        /// <summary>
        /// Launch the algorithm manager to run this strategy
        /// </summary>
        /// <param name="job">Algorithm job</param>
        /// <param name="algorithm">Algorithm instance</param>
        /// <param name="feed">Datafeed object</param>
        /// <param name="transactions">Transaction manager object</param>
        /// <param name="results">Result handler object</param>
        /// <param name="setup">Setup handler object</param>
        /// <param name="realtime">Realtime processing object</param>
        /// <remarks>Modify with caution</remarks>
        public static void Run(AlgorithmNodePacket job, IAlgorithm algorithm, IDataFeed feed, ITransactionHandler transactions, IResultHandler results, ISetupHandler setup, IRealTimeHandler realtime)
        {
            //Initialize:
            _dataPointCount = 0;
            var startingPortfolioValue = setup.StartingCapital;
            var backtestMode           = (job.Type == PacketType.BacktestNode);
            var methodInvokers         = new Dictionary <Type, MethodInvoker>();
            var marginCallFrequency    = TimeSpan.FromMinutes(5);
            var nextMarginCallTime     = DateTime.MinValue;

            //Initialize Properties:
            _frontier       = setup.StartingDate;
            _algorithmId    = job.AlgorithmId;
            _algorithmState = AlgorithmStatus.Running;
            _previousTime   = setup.StartingDate.Date;

            //Create the method accessors to push generic types into algorithm: Find all OnData events:

            // Algorithm 1.0 data accessors
            var hasOnTradeBar = AddMethodInvoker <Dictionary <string, TradeBar> >(algorithm, methodInvokers, "OnTradeBar");
            var hasOnTick     = AddMethodInvoker <Dictionary <string, List <Tick> > >(algorithm, methodInvokers, "OnTick");

            // Algorithm 2.0 data accessors
            var hasOnDataTradeBars = AddMethodInvoker <TradeBars>(algorithm, methodInvokers);
            var hasOnDataTicks     = AddMethodInvoker <Ticks>(algorithm, methodInvokers);

            // determine what mode we're in
            var backwardsCompatibilityMode = !hasOnDataTradeBars && !hasOnDataTicks;

            // dividend and split events
            var hasOnDataDividends = AddMethodInvoker <Dividends>(algorithm, methodInvokers);
            var hasOnDataSplits    = AddMethodInvoker <Splits>(algorithm, methodInvokers);

            //Go through the subscription types and create invokers to trigger the event handlers for each custom type:
            foreach (var config in feed.Subscriptions)
            {
                //If type is a tradebar, combine tradebars and ticks into unified array:
                if (config.Type.Name != "TradeBar" && config.Type.Name != "Tick")
                {
                    //Get the matching method for this event handler - e.g. public void OnData(Quandl data) { .. }
                    var genericMethod = (algorithm.GetType()).GetMethod("OnData", new[] { config.Type });

                    //If we already have this Type-handler then don't add it to invokers again.
                    if (methodInvokers.ContainsKey(config.Type))
                    {
                        continue;
                    }

                    //If we couldnt find the event handler, let the user know we can't fire that event.
                    if (genericMethod == null)
                    {
                        algorithm.RunTimeError = new Exception("Data event handler not found, please create a function matching this template: public void OnData(" + config.Type.Name + " data) {  }");
                        _algorithmState        = AlgorithmStatus.RuntimeError;
                        return;
                    }
                    methodInvokers.Add(config.Type, genericMethod.DelegateForCallMethod());
                }
            }

            //Loop over the queues: get a data collection, then pass them all into relevent methods in the algorithm.
            Log.Debug("AlgorithmManager.Run(): Algorithm initialized, launching time loop.");
            foreach (var newData in DataStream.GetData(feed, setup.StartingDate))
            {
                //Check this backtest is still running:
                if (_algorithmState != AlgorithmStatus.Running)
                {
                    break;
                }

                //Go over each time stamp we've collected, pass it into the algorithm in order:
                foreach (var time in newData.Keys)
                {
                    //Set the time frontier:
                    _frontier = time;

                    //Execute with TimeLimit Monitor:
                    if (Isolator.IsCancellationRequested)
                    {
                        return;
                    }

                    //If we're in backtest mode we need to capture the daily performance. We do this here directly
                    //before updating the algorithm state with the new data from this time step, otherwise we'll
                    //produce incorrect samples (they'll take into account this time step's new price values)
                    if (backtestMode)
                    {
                        //Refresh the realtime event monitor:
                        //in backtest mode use the algorithms clock as realtime.
                        realtime.SetTime(time);

                        //On day-change sample equity and daily performance for statistics calculations
                        if (_previousTime.Date != time.Date)
                        {
                            //Sample the portfolio value over time for chart.
                            results.SampleEquity(_previousTime, Math.Round(algorithm.Portfolio.TotalPortfolioValue, 4));

                            //Check for divide by zero
                            if (startingPortfolioValue == 0m)
                            {
                                results.SamplePerformance(_previousTime.Date, 0);
                            }
                            else
                            {
                                results.SamplePerformance(_previousTime.Date, Math.Round((algorithm.Portfolio.TotalPortfolioValue - startingPortfolioValue) * 100 / startingPortfolioValue, 10));
                            }
                            startingPortfolioValue = algorithm.Portfolio.TotalPortfolioValue;
                        }
                    }

                    //Update algorithm state after capturing performance from previous day

                    //On each time step push the real time prices to the cashbook so we can have updated conversion rates
                    algorithm.Portfolio.CashBook.Update(newData[time]);

                    //Update the securities properties: first before calling user code to avoid issues with data
                    algorithm.Securities.Update(time, newData[time]);

                    // perform margin calls
                    if (time >= nextMarginCallTime)
                    {
                        // determine if there are possible margin call orders to be executed
                        var marginCallOrders = algorithm.Portfolio.ScanForMarginCall();
                        if (marginCallOrders.Count != 0)
                        {
                            // execute the margin call orders
                            var executedOrders = algorithm.Portfolio.MarginCallModel.ExecuteMarginCall(marginCallOrders);
                            foreach (var order in executedOrders)
                            {
                                algorithm.Error(string.Format("Executed MarginCallOrder: {0} - Quantity: {1} @ {2}", order.Symbol, order.Quantity, order.Price));
                            }
                        }

                        nextMarginCallTime = time + marginCallFrequency;
                    }


                    //Check if the user's signalled Quit: loop over data until day changes.
                    if (algorithm.GetQuit())
                    {
                        _algorithmState = AlgorithmStatus.Quit;
                        break;
                    }

                    //Pass in the new time first:
                    algorithm.SetDateTime(time);

                    //Trigger the data events: Invoke the types we have data for:
                    var oldBars      = new Dictionary <string, TradeBar>();
                    var oldTicks     = new Dictionary <string, List <Tick> >();
                    var newBars      = new TradeBars(time);
                    var newTicks     = new Ticks(time);
                    var newDividends = new Dividends(time);
                    var newSplits    = new Splits(time);

                    //Invoke all non-tradebars, non-ticks methods and build up the TradeBars and Ticks dictionaries
                    // --> i == Subscription Configuration Index, so we don't need to compare types.
                    foreach (var i in newData[time].Keys)
                    {
                        //Data point and config of this point:
                        var dataPoints = newData[time][i];
                        var config     = feed.Subscriptions[i];

                        //Keep track of how many data points we've processed
                        _dataPointCount += dataPoints.Count;

                        //We don't want to pump data that we added just for currency conversions
                        if (config.IsInternalFeed)
                        {
                            continue;
                        }

                        //Create TradeBars Unified Data --> OR --> invoke generic data event. One loop.
                        //  Aggregate Dividends and Splits -- invoke portfolio application methods
                        foreach (var dataPoint in dataPoints)
                        {
                            var dividend = dataPoint as Dividend;
                            if (dividend != null)
                            {
                                // if this is a dividend apply to portfolio
                                algorithm.Portfolio.ApplyDividend(dividend);
                                if (hasOnDataDividends)
                                {
                                    // and add to our data dictionary to pump into OnData(Dividends data)
                                    newDividends.Add(dividend);
                                }
                                continue;
                            }

                            var split = dataPoint as Split;
                            if (split != null)
                            {
                                // if this is a split apply to portfolio
                                algorithm.Portfolio.ApplySplit(split);
                                if (hasOnDataSplits)
                                {
                                    // and add to our data dictionary to pump into OnData(Splits data)
                                    newSplits.Add(split);
                                }
                                continue;
                            }

                            //Update registered consolidators for this symbol index
                            try
                            {
                                for (var j = 0; j < config.Consolidators.Count; j++)
                                {
                                    config.Consolidators[j].Update(dataPoint);
                                }
                            }
                            catch (Exception err)
                            {
                                algorithm.RunTimeError = err;
                                _algorithmState        = AlgorithmStatus.RuntimeError;
                                Log.Error("AlgorithmManager.Run(): RuntimeError: Consolidators update: " + err.Message);
                                return;
                            }

                            // TRADEBAR -- add to our dictionary
                            var bar = dataPoint as TradeBar;
                            if (bar != null)
                            {
                                try
                                {
                                    if (backwardsCompatibilityMode)
                                    {
                                        oldBars[bar.Symbol] = bar;
                                    }
                                    else
                                    {
                                        newBars[bar.Symbol] = bar;
                                    }
                                }
                                catch (Exception err)
                                {
                                    Log.Error(time.ToLongTimeString() + " >> " + bar.Time.ToLongTimeString() + " >> " + bar.Symbol + " >> " + bar.Value.ToString("C"));
                                    Log.Error("AlgorithmManager.Run(): Failed to add TradeBar (" + bar.Symbol + ") Time: (" + time.ToLongTimeString() + ") Count:(" + newBars.Count + ") " + err.Message);
                                }
                                continue;
                            }
                            // TICK -- add to our dictionary
                            var tick = dataPoint as Tick;
                            if (tick != null)
                            {
                                if (backwardsCompatibilityMode)
                                {
                                    List <Tick> ticks;
                                    if (!oldTicks.TryGetValue(tick.Symbol, out ticks))
                                    {
                                        ticks = new List <Tick>(3);
                                        oldTicks.Add(tick.Symbol, ticks);
                                    }
                                    ticks.Add(tick);
                                }
                                else
                                {
                                    List <Tick> ticks;
                                    if (!newTicks.TryGetValue(tick.Symbol, out ticks))
                                    {
                                        ticks = new List <Tick>(3);
                                        newTicks.Add(tick.Symbol, ticks);
                                    }
                                    ticks.Add(tick);
                                }
                                continue;
                            }

                            // if it was nothing else then it must be custom data

                            // CUSTOM DATA -- invoke on data method
                            //Send data into the generic algorithm event handlers
                            try
                            {
                                methodInvokers[config.Type](algorithm, dataPoint);
                            }
                            catch (Exception err)
                            {
                                algorithm.RunTimeError = err;
                                _algorithmState        = AlgorithmStatus.RuntimeError;
                                Log.Debug("AlgorithmManager.Run(): RuntimeError: Custom Data: " + err.Message + " STACK >>> " + err.StackTrace);
                                return;
                            }
                        }
                    }

                    try
                    {
                        // fire off the dividend and split events before pricing events
                        if (hasOnDataDividends && newDividends.Count != 0)
                        {
                            methodInvokers[typeof(Dividends)](algorithm, newDividends);
                        }
                        if (hasOnDataSplits && newSplits.Count != 0)
                        {
                            methodInvokers[typeof(Splits)](algorithm, newSplits);
                        }
                    }
                    catch (Exception err)
                    {
                        algorithm.RunTimeError = err;
                        _algorithmState        = AlgorithmStatus.RuntimeError;
                        Log.Debug("AlgorithmManager.Run(): RuntimeError: Dividends/Splits: " + err.Message + " STACK >>> " + err.StackTrace);
                        return;
                    }

                    //After we've fired all other events in this second, fire the pricing events:
                    if (backwardsCompatibilityMode)
                    {
                        //Log.Debug("AlgorithmManager.Run(): Invoking v1.0 Event Handlers...");
                        try
                        {
                            if (hasOnTradeBar && oldBars.Count > 0)
                            {
                                methodInvokers[typeof(TradeBars)](algorithm, oldBars);
                            }
                            if (hasOnTick && oldTicks.Count > 0)
                            {
                                methodInvokers[typeof(Ticks)](algorithm, oldTicks);
                            }
                        }
                        catch (Exception err)
                        {
                            algorithm.RunTimeError = err;
                            _algorithmState        = AlgorithmStatus.RuntimeError;
                            Log.Debug("AlgorithmManager.Run(): RuntimeError: Backwards Compatibility Mode: " + err.Message + " STACK >>> " + err.StackTrace);
                            return;
                        }
                    }
                    else
                    {
                        //Log.Debug("AlgorithmManager.Run(): Invoking v2.0 Event Handlers...");
                        try
                        {
                            if (hasOnDataTradeBars && newBars.Count > 0)
                            {
                                methodInvokers[typeof(TradeBars)](algorithm, newBars);
                            }
                            if (hasOnDataTicks && newTicks.Count > 0)
                            {
                                methodInvokers[typeof(Ticks)](algorithm, newTicks);
                            }
                        }
                        catch (Exception err)
                        {
                            algorithm.RunTimeError = err;
                            _algorithmState        = AlgorithmStatus.RuntimeError;
                            Log.Debug("AlgorithmManager.Run(): RuntimeError: New Style Mode: " + err.Message + " STACK >>> " + err.StackTrace);
                            return;
                        }
                    }

                    //If its the historical/paper trading models, wait until market orders have been "filled"
                    // Manually trigger the event handler to prevent thread switch.
                    transactions.ProcessSynchronousEvents();

                    //Save the previous time for the sample calculations
                    _previousTime = time;

                    // Process any required events of the results handler such as sampling assets, equity, or stock prices.
                    results.ProcessSynchronousEvents();
                } // End of Time Loop
            }     // End of ForEach DataStream

            //Stream over:: Send the final packet and fire final events:
            Log.Trace("AlgorithmManager.Run(): Firing On End Of Algorithm...");
            try
            {
                algorithm.OnEndOfAlgorithm();
            }
            catch (Exception err)
            {
                _algorithmState        = AlgorithmStatus.RuntimeError;
                algorithm.RunTimeError = new Exception("Error running OnEndOfAlgorithm(): " + err.Message, err.InnerException);
                Log.Debug("AlgorithmManager.OnEndOfAlgorithm(): " + err.Message + " STACK >>> " + err.StackTrace);
                return;
            }

            // Process any required events of the results handler such as sampling assets, equity, or stock prices.
            results.ProcessSynchronousEvents(forceProcess: true);

            //Liquidate Holdings for Calculations:
            if (_algorithmState == AlgorithmStatus.Liquidated || !Engine.LiveMode)
            {
                Log.Trace("AlgorithmManager.Run(): Liquidating algorithm holdings...");
                algorithm.Liquidate();
                results.LogMessage("Algorithm Liquidated");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Liquidated);
            }

            //Manually stopped the algorithm
            if (_algorithmState == AlgorithmStatus.Stopped)
            {
                Log.Trace("AlgorithmManager.Run(): Stopping algorithm...");
                results.LogMessage("Algorithm Stopped");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Stopped);
            }

            //Backtest deleted.
            if (_algorithmState == AlgorithmStatus.Deleted)
            {
                Log.Trace("AlgorithmManager.Run(): Deleting algorithm...");
                results.DebugMessage("Algorithm Id:(" + job.AlgorithmId + ") Deleted by request.");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Deleted);
            }

            //Algorithm finished, send regardless of commands:
            results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Completed);

            //Take final samples:
            results.SampleRange(algorithm.GetChartUpdates());
            results.SampleEquity(_frontier, Math.Round(algorithm.Portfolio.TotalPortfolioValue, 4));
            results.SamplePerformance(_frontier, Math.Round((algorithm.Portfolio.TotalPortfolioValue - startingPortfolioValue) * 100 / startingPortfolioValue, 10));
        } // End of Run();
コード例 #21
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 <KeyValuePair <Security, BaseData> >();
            var custom              = new List <KeyValuePair <Security, IEnumerable <BaseData> > >();
            var consolidator        = new List <KeyValuePair <SubscriptionDataConfig, List <BaseData> > >();
            var allDataForAlgorithm = new List <BaseData>(data.Count);
            var cash = new List <KeyValuePair <Cash, BaseData> >(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;

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

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

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

                BaseData update             = null;
                var      consolidatorUpdate = new List <BaseData>(list.Count);
                for (int i = 0; i < list.Count; i++)
                {
                    var baseData = list[i];
                    if (!packet.Security.SubscriptionDataConfig.IsInternalFeed)
                    {
                        // this is all the data that goes into the algorithm
                        allDataForAlgorithm.Add(baseData);
                        if (packet.Security.SubscriptionDataConfig.IsCustomData)
                        {
                            // this is all the custom data
                            custom.Add(new KeyValuePair <Security, IEnumerable <BaseData> >(packet.Security, list));
                        }
                    }
                    // don't add internal feed data to ticks/bars objects
                    if (baseData.DataType != MarketDataType.Auxiliary)
                    {
                        if (!packet.Security.SubscriptionDataConfig.IsInternalFeed)
                        {
                            // populate ticks and tradebars dictionaries with no aux data
                            switch (baseData.DataType)
                            {
                            case MarketDataType.Tick:
                                List <Tick> ticksList;
                                if (!ticks.TryGetValue(symbol, out ticksList))
                                {
                                    ticksList = new List <Tick> {
                                        (Tick)baseData
                                    };
                                    ticks[symbol] = ticksList;
                                }
                                ticksList.Add((Tick)baseData);
                                break;

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

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

                        // this is the data used set market prices
                        update = 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.Security.SubscriptionDataConfig.Symbol] = symbolChange;
                    }
                }

                // 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 (update != null && cashSecurities.Contains(packet.Security.Symbol))
                {
                    foreach (var cashKvp in cashBook)
                    {
                        if (cashKvp.Value.SecuritySymbol == packet.Security.Symbol)
                        {
                            cash.Add(new KeyValuePair <Cash, BaseData>(cashKvp.Value, update));
                        }
                    }
                }

                security.Add(new KeyValuePair <Security, BaseData>(packet.Security, update));
                consolidator.Add(new KeyValuePair <SubscriptionDataConfig, List <BaseData> >(packet.Security.SubscriptionDataConfig, consolidatorUpdate));
            }

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

            return(new TimeSlice(utcDateTime, count, slice, data, cash, security, consolidator, custom, changes));
        }
コード例 #22
0
        public void OnData(Splits data)
        {
            var split = data["MSFT"];

            Console.WriteLine("{0} >> SPLIT >> {1} - {2} - {3} - {4}", split.Time.ToString("o"), split.Symbol, split.SplitFactor, Portfolio.Cash, Portfolio["MSFT"].Quantity);
        }
コード例 #23
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="ticks">This ticks 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>
        public Slice(DateTime time, IEnumerable <BaseData> data, TradeBars tradeBars, Ticks ticks, Splits splits, Dividends dividends, Delistings delistings)
        {
            Time = time;

            _dataByType = new Dictionary <Type, Lazy <object> >();

            // market data
            _ticks = new Lazy <Ticks>(() => CreateTicksCollection(ticks));
            _bars  = new Lazy <TradeBars>(() => CreateTradeBarsCollection(tradeBars));
            _data  = new Lazy <DataDictionary <SymbolData> >(() => CreateDynamicDataDictionary(data));

            // auxiliary data
            _splits     = new Lazy <Splits>(() => CreateSplitsCollection(splits));
            _dividends  = new Lazy <Dividends>(() => CreateDividendsCollection(dividends));
            _delistings = new Lazy <Delistings>(() => CreateDelistingsCollection(delistings));
        }
コード例 #24
0
 public void Dispose()
 {
     Splits.DisposeEverything();
     DisposeHelper.Dispose(ref _rasterizerState);
     DisposeHelper.Dispose(ref _depthStencilState);
 }
コード例 #25
0
ファイル: TimeSlice.cs プロジェクト: bizcad/LeanJJN
        /// <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<KeyValuePair<Security, List<BaseData>>> data, SecurityChanges changes)
        {
            int count = 0;
            var security = new List<KeyValuePair<Security, BaseData>>();
            var custom = new List<KeyValuePair<Security, List<BaseData>>>();
            var consolidator = new List<KeyValuePair<SubscriptionDataConfig, List<BaseData>>>();
            var allDataForAlgorithm = new List<BaseData>(data.Count);
            var cash = new List<KeyValuePair<Cash, BaseData>>(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;

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

            foreach (var kvp in data)
            {
                var list = kvp.Value;
                var symbol = kvp.Key.Symbol;
                
                // keep count of all data points
                if (list.Count == 1 && list[0] is BaseDataCollection)
                {
                    count += ((BaseDataCollection) list[0]).Data.Count;
                }
                else
                {
                    count += list.Count;
                }

                BaseData update = null;
                var consolidatorUpdate = new List<BaseData>(list.Count);
                for (int i = 0; i < list.Count; i++)
                {
                    var baseData = list[i];
                    if (!kvp.Key.SubscriptionDataConfig.IsInternalFeed)
                    {
                        // this is all the data that goes into the algorithm
                        allDataForAlgorithm.Add(baseData);
                        if (kvp.Key.SubscriptionDataConfig.IsCustomData)
                        {
                            // this is all the custom data
                            custom.Add(kvp);
                        }
                    }
                    // don't add internal feed data to ticks/bars objects
                    if (baseData.DataType != MarketDataType.Auxiliary)
                    {
                        if (!kvp.Key.SubscriptionDataConfig.IsInternalFeed)
                        {
                            // populate ticks and tradebars dictionaries with no aux data
                            if (baseData.DataType == MarketDataType.Tick)
                            {
                                List<Tick> ticksList;
                                if (!ticks.TryGetValue(symbol, out ticksList))
                                {
                                    ticksList = new List<Tick> {(Tick) baseData};
                                    ticks[symbol] = ticksList;
                                }
                                ticksList.Add((Tick) baseData);
                            }
                            else if (baseData.DataType == MarketDataType.TradeBar)
                            {
                                tradeBars[symbol] = (TradeBar) baseData;
                            }

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

                        // this is the data used set market prices
                        update = 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[kvp.Key.SubscriptionDataConfig.Symbol] = symbolChange;
                    }
                }

                // 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 (update != null && cashSecurities.Contains(kvp.Key.Symbol))
                {
                    foreach (var cashKvp in cashBook)
                    {
                        if (cashKvp.Value.SecuritySymbol == kvp.Key.Symbol)
                        {
                            cash.Add(new KeyValuePair<Cash, BaseData>(cashKvp.Value, update));
                        }
                    }
                }

                security.Add(new KeyValuePair<Security, BaseData>(kvp.Key, update));
                consolidator.Add(new KeyValuePair<SubscriptionDataConfig, List<BaseData>>(kvp.Key.SubscriptionDataConfig, consolidatorUpdate));
            }

            var slice = new Slice(utcDateTime.ConvertFromUtc(algorithmTimeZone), allDataForAlgorithm, tradeBars, ticks, splits, dividends, delistings, symbolChanges, allDataForAlgorithm.Count > 0);

            return new TimeSlice(utcDateTime, count, slice, data, cash, security, consolidator, custom, changes);
        }
コード例 #26
0
 /// <summary>
 /// Constructor method. Builds an instance of MSDataGridHelperLayoutInfo with
 /// the specified values for its properties.
 /// </summary>
 /// <param name="gridSplits">GridSplits property value.</param>
 /// <param name="gridColumns">GridColumns property value.</param>
 /// <param name="lastUpdate">LastUpdate property value.</param>
 public MSDataGridHelperLayoutInfo(Splits gridSplits, Columns gridColumns, string lastUpdate)
 {
     _gridSplits  = gridSplits;
     _gridColumns = gridColumns;
     _lastUpdate  = lastUpdate;
 }
コード例 #27
0
ファイル: Order.cs プロジェクト: ucdavis/Purchasing
 public virtual void AddSplit(Split split)
 {
     split.Order = this;
     Splits.Add(split);
 }
コード例 #28
0
ファイル: TimeSlice.cs プロジェクト: AlexCatarino/Lean
        /// <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);
        }
コード例 #29
0
ファイル: DividendAlgorithm.cs プロジェクト: skyfyl/Lean
 /// <summary>
 /// Raises the data event.
 /// </summary>
 /// <param name="data">Data.</param>
 public void OnData(Splits data)
 {
     Debug("MSFT: " + Securities["MSFT"].Price);
     var split = data["MSFT"];
     Console.WriteLine("{0} >> SPLIT >> {1} - {2} - {3} - {4}", split.Time.ToString("o"), split.Symbol, split.SplitFactor, Portfolio.Cash, Portfolio["MSFT"].Quantity);
 }
コード例 #30
0
        private void ShowView()
        {
            var scroll = new ScrollView()
            {
                BackgroundColor = Color.White,
            };

            {
                int horizontalMargins = App.IsSmallDevice() ? 5 : 40;

                var stack = new StackLayout()
                {
                    Padding           = new Thickness(horizontalMargins, 10, horizontalMargins, 0),
                    Orientation       = StackOrientation.Vertical,
                    VerticalOptions   = LayoutOptions.Center,
                    HorizontalOptions = LayoutOptions.FillAndExpand,
                };

                scroll.Content = stack;

                // Account
                stack.Children.Add(
                    this.CreateViewCaptionValue(
                        "#Account",
                        null,
                        this.transaction.AccountAsText,
                        async() =>
                {
                    var filter = new Filter {
                        AccountId = this.transaction.Account
                    };
                    await Navigation.PushAsync(new PageTransactions(filter));
                })
                    );

                // Date
                stack.Children.Add(
                    this.CreateViewCaptionValue(
                        "#Date",
                        null,
                        this.transaction.DateAsText,
                        async() =>
                {
                    var filter = new Filter {
                        DateText = this.transaction.DateAsText
                    };
                    await Navigation.PushAsync(new PageTransactions(filter));
                })
                    );

                // Amount

                stack.Children.Add(
                    this.CreateViewCaptionValue(
                        "#Amount",
                        null,
                        this.transaction.Amount,
                        async() =>
                {
                    var filter = new Filter {
                        Amount = this.transaction.Amount
                    };
                    await Navigation.PushAsync(new PageTransactions(filter));
                })
                    );


                // Payee
                stack.Children.Add(
                    this.CreateViewCaptionValue(
                        "#Payee",
                        null,
                        this.transaction.PayeeAsText,
                        async() =>
                {
                    var filter = new Filter {
                        PayeeId = this.transaction.Payee
                    };
                    await Navigation.PushAsync(new PageTransactions(filter));
                })
                    );

                // Category
                stack.Children.Add(
                    this.CreateViewCaptionValue(
                        "#Category",
                        null,
                        this.transaction.CategoryAsText,
                        async() =>
                {
                    var filter = new Filter();
                    filter.CategoryIds.Add(this.transaction.Category);
                    await Navigation.PushAsync(new PageTransactions(filter));
                })
                    );

                // Memo
                stack.Children.Add(new Label {
                    Text = this.transaction.Memo, TextColor = Color.Gray, FontAttributes = FontAttributes.Italic
                });


                // Splits
                if (this.transaction.IsSplit)
                {
                    stack.Children.Add(CreateSeparatorHorizontal(10));

                    var splits = Splits.GetSplitsForTransaction(this.transaction.Id);

                    foreach (var split in splits)
                    {
                        stack.Children.Add(CreateViewHeaderCaptionAndValue(split.CategoryAsText, split.Amount));
                        stack.Children.Add(new Label {
                            Text = split.Memo, TextColor = Color.Gray, FontAttributes = FontAttributes.Italic, Margin = new Thickness(0, 0, 0, 5)
                        });
                    }
                }
            }

            this.Content = scroll;
        }
コード例 #31
0
ファイル: TimeSlice.cs プロジェクト: theone-pang/Lean
        /// <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;
                }

                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);
                        if (packet.Configuration.IsCustomData)
                        {
                            // this is all the custom data
                            custom.Add(new UpdateData <Security>(packet.Security, packet.Configuration.Type, list));
                        }
                    }
                    // 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));
        }
コード例 #32
0
ファイル: SplitsBLL.cs プロジェクト: alexit2013/PSS
 /// <summary>
 /// 修改【---事务---】
 /// </summary>
 /// <param name="dp"></param>
 /// <returns></returns>
 public static int EdiStocks(Splits dep, List <SplitDetail> list)
 {
     return(SplitsDAL.EdiStocks(dep, list));
 }