public void CoarseUniverseRotatesActiveSecurity()
        {
            var startDate = new DateTime(2014, 3, 24);
            var endDate   = new DateTime(2014, 3, 29);

            var timeProvider = new ManualTimeProvider(TimeZones.NewYork);

            timeProvider.SetCurrentTime(startDate);

            var coarseTimes = new List <DateTime>
            {
                new DateTime(2014, 3, 25, 5, 0, 0, 0),
                new DateTime(2014, 3, 26, 5, 0, 0, 0),
                new DateTime(2014, 3, 27, 5, 0, 0, 0),
                new DateTime(2014, 3, 28, 5, 0, 0, 0),
                new DateTime(2014, 3, 29, 5, 0, 0, 0)
            }.ToHashSet();

            var coarseSymbols = new List <Symbol> {
                Symbols.SPY, Symbols.AAPL, Symbols.MSFT
            };

            var emitted          = new AutoResetEvent(false);
            var dataQueueHandler = new FuncDataQueueHandler(fdqh => Enumerable.Empty <BaseData>(), timeProvider);

            var feed = new TestableLiveTradingDataFeed(dataQueueHandler);

            var algorithm = new AlgorithmStub(feed);

            algorithm.SetLiveMode(true);

            var mock = new Mock <ITransactionHandler>();

            mock.Setup(m => m.GetOpenOrders(It.IsAny <Func <Order, bool> >())).Returns(new List <Order>());
            algorithm.Transactions.SetOrderProcessor(mock.Object);

            var synchronizer = new TestableLiveSynchronizer(timeProvider);

            synchronizer.Initialize(algorithm, algorithm.DataManager);

            var mapFileProvider = new LocalDiskMapFileProvider();

            feed.Initialize(algorithm, new LiveNodePacket(), new BacktestingResultHandler(),
                            mapFileProvider, new LocalDiskFactorFileProvider(mapFileProvider), new DefaultDataProvider(), algorithm.DataManager, synchronizer, new DataChannelProvider());

            var symbolIndex = 0;
            var coarseUniverseSelectionCount = 0;

            algorithm.AddUniverse(
                coarse =>
            {
                Log.Trace($"Emitted at {algorithm.Time}. Coarse {coarse.First().Time} to {coarse.First().EndTime}");
                Interlocked.Increment(ref coarseUniverseSelectionCount);
                emitted.Set();

                // rotate single symbol in universe
                if (symbolIndex == coarseSymbols.Count)
                {
                    symbolIndex = 0;
                }

                return(new[] { coarseSymbols[symbolIndex++] });
            });

            algorithm.PostInitialize();

            var cancellationTokenSource = new CancellationTokenSource();

            Exception exceptionThrown = null;

            // create a timer to advance time much faster than realtime
            var timerInterval = TimeSpan.FromMilliseconds(5);
            var timer         = Ref.Create <Timer>(null);

            timer.Value = new Timer(state =>
            {
                try
                {
                    var currentTime = timeProvider.GetUtcNow().ConvertFromUtc(TimeZones.NewYork);

                    if (currentTime.Date > endDate.Date)
                    {
                        feed.Exit();
                        cancellationTokenSource.Cancel();
                        return;
                    }

                    timeProvider.Advance(TimeSpan.FromHours(1));

                    var time = timeProvider.GetUtcNow().ConvertFromUtc(TimeZones.NewYork);
                    algorithm.SetDateTime(timeProvider.GetUtcNow());
                    if (coarseTimes.Contains(time))
                    {
                        // lets wait for coarse to emit
                        if (!emitted.WaitOne(TimeSpan.FromMilliseconds(15000)))
                        {
                            throw new TimeoutException($"Timeout waiting for coarse to emit at {time}");
                        }
                    }
                    var activeSecuritiesCount = algorithm.ActiveSecurities.Count;

                    Assert.That(activeSecuritiesCount <= 1);

                    // restart the timer
                    timer.Value.Change(timerInterval, Timeout.InfiniteTimeSpan);
                }
                catch (Exception exception)
                {
                    Log.Error(exception);
                    exceptionThrown = exception;

                    feed.Exit();
                    cancellationTokenSource.Cancel();
                }
            }, null, timerInterval, Timeout.InfiniteTimeSpan);

            foreach (var _ in synchronizer.StreamData(cancellationTokenSource.Token))
            {
            }

            timer.Value.DisposeSafely();
            algorithm.DataManager.RemoveAllSubscriptions();
            dataQueueHandler.DisposeSafely();
            synchronizer.DisposeSafely();
            emitted.DisposeSafely();

            if (exceptionThrown != null)
            {
                throw new Exception("Exception in timer: ", exceptionThrown);
            }

            Assert.AreEqual(coarseTimes.Count, coarseUniverseSelectionCount, message: "coarseUniverseSelectionCount");
        }
Example #2
0
        public void CoarseUniverseRotatesActiveSecurity()
        {
            var startDate = new DateTime(2014, 3, 24);
            var endDate   = new DateTime(2014, 3, 28);

            var timeProvider = new ManualTimeProvider(TimeZones.NewYork);

            timeProvider.SetCurrentTime(startDate);

            var coarseTimes = new List <DateTime>
            {
                new DateTime(2014, 3, 25),
                new DateTime(2014, 3, 25, 23, 0, 0),
                new DateTime(2014, 3, 27, 1, 0, 0)
            }.ToHashSet();

            var coarseSymbols = new List <Symbol> {
                Symbols.SPY, Symbols.AAPL, Symbols.MSFT
            };

            var coarseUsaSymbol = CoarseFundamental.CreateUniverseSymbol(Market.USA, false);

            var coarseDataEmittedCount = 0;
            var lastTime         = DateTime.MinValue;
            var dataQueueHandler = new FuncDataQueueHandler(fdqh =>
            {
                var time = timeProvider.GetUtcNow().ConvertFromUtc(TimeZones.NewYork);
                if (time != lastTime)
                {
                    lastTime = time;

                    if (coarseTimes.Contains(time))
                    {
                        // emit coarse data at selected times
                        var coarseData = new BaseDataCollection {
                            Symbol = coarseUsaSymbol
                        };
                        foreach (var symbol in coarseSymbols)
                        {
                            coarseData.Data.Add(
                                new CoarseFundamental
                            {
                                Symbol = symbol,
                                Time   = time,
                                Market = Market.USA,
                                Value  = 100
                            });
                        }
                        coarseDataEmittedCount++;
                        return(new List <BaseData> {
                            coarseData
                        });
                    }
                }
                return(Enumerable.Empty <BaseData>());
            });

            var feed = new TestableLiveTradingDataFeed(dataQueueHandler);

            var algorithm = new AlgorithmStub(feed);

            algorithm.SetLiveMode(true);

            var mock = new Mock <ITransactionHandler>();

            mock.Setup(m => m.GetOpenOrders(It.IsAny <Func <Order, bool> >())).Returns(new List <Order>());
            algorithm.Transactions.SetOrderProcessor(mock.Object);

            var synchronizer = new TestableLiveSynchronizer(timeProvider);

            synchronizer.Initialize(algorithm, algorithm.DataManager);

            var mapFileProvider = new LocalDiskMapFileProvider();

            feed.Initialize(algorithm, new LiveNodePacket(), new BacktestingResultHandler(),
                            mapFileProvider, new LocalDiskFactorFileProvider(mapFileProvider), new DefaultDataProvider(), algorithm.DataManager, synchronizer);

            var symbolIndex = 0;
            var coarseUniverseSelectionCount = 0;

            algorithm.AddUniverse(
                coarse =>
            {
                coarseUniverseSelectionCount++;

                // rotate single symbol in universe
                if (symbolIndex == coarseSymbols.Count)
                {
                    symbolIndex = 0;
                }

                return(new[] { coarseSymbols[symbolIndex++] });
            });

            algorithm.PostInitialize();

            var cancellationTokenSource = new CancellationTokenSource();

            Exception exceptionThrown = null;

            // create a timer to advance time much faster than realtime
            var timerInterval = TimeSpan.FromMilliseconds(50);
            var timer         = Ref.Create <Timer>(null);

            timer.Value = new Timer(state =>
            {
                try
                {
                    // stop the timer to prevent reentrancy
                    timer.Value.Change(Timeout.Infinite, Timeout.Infinite);

                    var currentTime = timeProvider.GetUtcNow().ConvertFromUtc(TimeZones.NewYork);

                    if (currentTime.Date > endDate.Date)
                    {
                        feed.Exit();
                        cancellationTokenSource.Cancel();
                        return;
                    }

                    timeProvider.Advance(TimeSpan.FromHours(1));

                    var activeSecuritiesCount = algorithm.ActiveSecurities.Count;

                    Assert.That(activeSecuritiesCount <= 1);

                    // restart the timer
                    timer.Value.Change(timerInterval, timerInterval);
                }
                catch (Exception exception)
                {
                    Log.Error(exception);
                    exceptionThrown = exception;

                    feed.Exit();
                    cancellationTokenSource.Cancel();
                }
            }, null, TimeSpan.FromSeconds(1), timerInterval);

            foreach (var _ in synchronizer.StreamData(cancellationTokenSource.Token))
            {
            }

            timer.Value.Dispose();

            if (exceptionThrown != null)
            {
                throw new Exception("Exception in timer: ", exceptionThrown);
            }

            Assert.AreEqual(coarseTimes.Count, coarseDataEmittedCount);
            Assert.AreEqual(coarseTimes.Count, coarseUniverseSelectionCount);
        }
        public void PreMarketDataSetsCache()
        {
            var dataQueueTest = new FakeDataQueueTest();
            dataQueueTest.ManualTimeProvider.SetCurrentTimeUtc(new DateTime(2020, 09, 03, 10, 0, 0));
            TearDown();
            var liveSynchronizer = new TestableLiveSynchronizer(dataQueueTest.ManualTimeProvider);
            var dataAggregator = new TestAggregationManager(dataQueueTest.ManualTimeProvider);
            SetupImpl(dataQueueTest, liveSynchronizer, dataAggregator);

            _algorithm.SetDateTime(dataQueueTest.ManualTimeProvider.GetUtcNow());
            _algorithm.SetLiveMode(true);
            var added = false;
            var first = true;
            var internalDataCount = 0;
            var tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30));
            foreach (var timeSlice in _synchronizer.StreamData(tokenSource.Token))
            {
                dataQueueTest.ManualTimeProvider.AdvanceSeconds(60);
                _algorithm.SetDateTime(dataQueueTest.ManualTimeProvider.GetUtcNow());
                if (dataQueueTest.ManualTimeProvider.GetUtcNow() >= new DateTime(2020, 09, 03, 13, 0, 0))
                {
                    Assert.Fail("Timeout expect pre market data to set security prices");
                }
                if (!added)
                {
                    added = true;
                    _algorithm.AddEquity("IBM", Resolution.Minute);
                    _algorithm.AddEquity("AAPL", Resolution.Hour);
                }
                else if (!timeSlice.IsTimePulse)
                {
                    if (timeSlice.SecuritiesUpdateData.Count > 0)
                    {
                        internalDataCount += timeSlice.SecuritiesUpdateData.Count(
                            data => data.IsInternalConfig && data.Target.Symbol == Symbols.AAPL
                        );
                    }
                    if (first)
                    {
                        Assert.IsTrue(_algorithm.SubscriptionManager.SubscriptionDataConfigService
                            .GetSubscriptionDataConfigs(Symbols.AAPL, includeInternalConfigs: true).Any(config => config.Resolution == Resolution.Second));
                        Assert.IsFalse(_algorithm.SubscriptionManager.SubscriptionDataConfigService.GetSubscriptionDataConfigs(Symbols.IBM, includeInternalConfigs: true)
                            .Any(config => config.IsInternalFeed && config.Resolution == Resolution.Second));
                        first = false;
                    }
                    else if(_algorithm.Securities["AAPL"].Price != 0 && _algorithm.Securities["IBM"].Price != 0)
                    {
                        _algorithm.SetHoldings("AAPL", 0.01);
                        _algorithm.SetHoldings("IBM", 0.01);

                        var orders = _algorithm.Transactions.GetOpenOrders("AAPL");
                        Assert.AreEqual(1, orders.Count);
                        Assert.AreEqual(Symbols.AAPL, orders[0].Symbol);
                        Assert.AreEqual(OrderStatus.Submitted, orders[0].Status);

                        orders = _algorithm.Transactions.GetOpenOrders("IBM");
                        Assert.AreEqual(1, orders.Count);
                        Assert.AreEqual(Symbols.IBM, orders[0].Symbol);
                        Assert.AreEqual(OrderStatus.Submitted, orders[0].Status);
                        break;
                    }
                }
                _algorithm.OnEndOfTimeStep();
                Thread.Sleep(25);
            }
            Assert.IsFalse(tokenSource.IsCancellationRequested);
            Assert.AreNotEqual(0, internalDataCount);
        }
Example #4
0
        public void FastExitsDoNotThrowUnhandledExceptions()
        {
            var algorithm = new AlgorithmStub();

            // job is used to send into DataQueueHandler
            var job = new LiveNodePacket();

            // result handler is used due to dependency in SubscriptionDataReader
            var resultHandler = new BacktestingResultHandler();

            var feed = new TestableLiveTradingDataFeed();
            var marketHoursDatabase      = MarketHoursDatabase.FromDataFolder();
            var symbolPropertiesDataBase = SymbolPropertiesDatabase.FromDataFolder();
            var securityService          = new SecurityService(
                algorithm.Portfolio.CashBook,
                marketHoursDatabase,
                symbolPropertiesDataBase,
                algorithm);

            algorithm.Securities.SetSecurityService(securityService);
            var dataManager = new DataManager(feed,
                                              new UniverseSelection(algorithm, securityService),
                                              algorithm,
                                              algorithm.TimeKeeper,
                                              marketHoursDatabase,
                                              true);

            algorithm.SubscriptionManager.SetDataManager(dataManager);
            var synchronizer = new TestableLiveSynchronizer();

            synchronizer.Initialize(algorithm, dataManager);
            algorithm.AddSecurities(Resolution.Tick, Enumerable.Range(0, 20).Select(x => x.ToString()).ToList());
            var getNextTicksFunction = Enumerable.Range(0, 20).Select(x => new Tick {
                Symbol = SymbolCache.GetSymbol(x.ToString())
            }).ToList();

            feed.DataQueueHandler = new FuncDataQueueHandler(handler => getNextTicksFunction);
            var mapFileProvider = new LocalDiskMapFileProvider();
            var fileProvider    = new DefaultDataProvider();

            feed.Initialize(
                algorithm,
                job,
                resultHandler,
                mapFileProvider,
                new LocalDiskFactorFileProvider(mapFileProvider),
                fileProvider,
                dataManager,
                synchronizer);

            var unhandledExceptionWasThrown = false;

            try
            {
                feed.Exit();
            }
            catch (Exception ex)
            {
                QuantConnect.Logging.Log.Error(ex.ToString());
                unhandledExceptionWasThrown = true;
            }

            Thread.Sleep(500);
            Assert.IsFalse(unhandledExceptionWasThrown);
        }