public void PortfolioBiasIsRespected(Language language, PortfolioBias bias) { SetPortfolioConstruction(language, _algorithm, bias); var now = new DateTime(2018, 7, 31); SetUtcTime(now.ConvertFromUtc(_algorithm.TimeZone)); var appl = _algorithm.AddEquity("AAPL"); appl.SetMarketPrice(new Tick(now, appl.Symbol, 10, 10)); var spy = _algorithm.AddEquity("SPY"); spy.SetMarketPrice(new Tick(now, spy.Symbol, 20, 20)); var ibm = _algorithm.AddEquity("IBM"); ibm.SetMarketPrice(new Tick(now, ibm.Symbol, 30, 30)); var aig = _algorithm.AddEquity("AIG"); aig.SetMarketPrice(new Tick(now, aig.Symbol, 30, 30)); var qqq = _algorithm.AddEquity("QQQ"); qqq.SetMarketPrice(new Tick(now, qqq.Symbol, 30, 30)); var insights = new[] { new Insight(now, appl.Symbol, TimeSpan.FromDays(1), InsightType.Price, InsightDirection.Up, 0.1d, null), new Insight(now, spy.Symbol, TimeSpan.FromDays(1), InsightType.Price, InsightDirection.Down, -0.1d, null), new Insight(now, ibm.Symbol, TimeSpan.FromDays(1), InsightType.Price, InsightDirection.Down, 0d, null), new Insight(now, aig.Symbol, TimeSpan.FromDays(1), InsightType.Price, InsightDirection.Down, -0.1d, null), new Insight(now, qqq.Symbol, TimeSpan.FromDays(1), InsightType.Price, InsightDirection.Up, 0.1d, null) }; _algorithm.PortfolioConstruction.OnSecuritiesChanged(_algorithm, SecurityChanges.Added(appl, spy, ibm, aig, qqq)); var createdValidTarget = false; foreach (var target in _algorithm.PortfolioConstruction.CreateTargets(_algorithm, insights)) { QuantConnect.Logging.Log.Trace($"{target.Symbol}: {target.Quantity}"); if (target.Quantity == 0) { continue; } createdValidTarget = true; Assert.AreEqual(Math.Sign((int)bias), Math.Sign(target.Quantity)); } Assert.IsTrue(createdValidTarget); }
public void ValueIsCalculatedCorrectly() { var algorithm = new QCAlgorithm(); var initialDate = new DateTime(2018, 1, 1); algorithm.SetStartDate(initialDate); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); algorithm.AddEquity("SPY"); var fitnessScore = new FitnessScoreManager(); fitnessScore.Initialize(algorithm); algorithm.SetDateTime(initialDate.AddDays(1)); IncreaseCashAmount(algorithm, 0.05); IncreaseSalesVolumeAmount(algorithm); fitnessScore.UpdateScores(); var score = fitnessScore.FitnessScore; // FitnessScore: 1 * (5 + 5) Assert.AreEqual(1m, score); algorithm.SetDateTime(initialDate.AddDays(1)); IncreaseCashAmount(algorithm, -0.20); fitnessScore.UpdateScores(); algorithm.SetDateTime(initialDate.AddDays(1)); IncreaseCashAmount(algorithm, -0.20); // FitnessScore: 0.333 * (-3.299 + -5) fitnessScore.UpdateScores(); score = fitnessScore.FitnessScore; Assert.AreEqual(0.028m, score); }
private FakeOrderProcessor InitializeAndGetFakeOrderProcessor(QCAlgorithm algo) { algo.SubscriptionManager.SetDataManager(new DataManager()); algo.SetFinishedWarmingUp(); algo.SetCash(100000); algo.AddEquity("SPY"); var fakeOrderProcessor = new FakeOrderProcessor(); algo.Transactions.SetOrderProcessor(fakeOrderProcessor); algo.Portfolio["SPY"].SetHoldings(1, 10); var security = algo.Securities["SPY"]; security.SetMarketPrice(new TradeBar { Time = DateTime.Now, Symbol = security.Symbol, Open = 20, High = 20, Low = 20, Close = 20 }); Assert.IsTrue(fakeOrderProcessor.ProcessedOrdersRequests.IsNullOrEmpty()); return(fakeOrderProcessor); }
public void IndicatorsOfDifferentTypeDiplaySameCurrentTime() { var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); var spy = algorithm.AddEquity("SPY"); var indicatorTimeList = new List <DateTime>(); // RSI is a DataPointIndicator algorithm.RSI(spy.Symbol, 14).Updated += (_, e) => indicatorTimeList.Add(e.EndTime); // STO is a BarIndicator algorithm.STO(spy.Symbol, 14, 2, 2).Updated += (_, e) => indicatorTimeList.Add(e.EndTime); // MFI is a TradeBarIndicator algorithm.MFI(spy.Symbol, 14).Updated += (_, e) => indicatorTimeList.Add(e.EndTime); var consolidators = spy.Subscriptions.SelectMany(x => x.Consolidators).ToList(); Assert.AreEqual(3, consolidators.Count); // One consolidator for each indicator var bars = new[] { 30, 31 }.Select(d => new TradeBar(new DateTime(2020, 03, 04, 9, d, 0), spy.Symbol, 100, 100, 100, 100, 1000)); foreach (var bar in bars) { foreach (var consolidator in consolidators) { consolidator.Update(bar); } } // All indicators should have the same EndTime Assert.AreEqual(1, indicatorTimeList.Distinct().Count()); }
private static Security InitAndGetSecurity(QCAlgorithm algo, decimal fee, SecurityType securityType = SecurityType.Equity, string symbol = "SPY") { algo.SubscriptionManager.SetDataManager(new DataManagerStub(algo)); Security security; if (securityType == SecurityType.Equity) { security = algo.AddEquity(symbol); _symbol = security.Symbol; } else if (securityType == SecurityType.Option) { security = algo.AddOption(symbol); _symbol = security.Symbol; } else if (securityType == SecurityType.Future) { security = algo.AddFuture(symbol); _symbol = security.Symbol; } else { throw new Exception("SecurityType not implemented"); } security.TransactionModel = new ConstantFeeTransactionModel(fee); Update(algo.Portfolio.CashBook, security, 25); return(security); }
private static Security InitAndGetSecurity(QCAlgorithm algo, decimal fee, SecurityType securityType = SecurityType.Equity, string symbol = "SPY", DateTime?time = null) { algo.SubscriptionManager.SetDataManager(new DataManagerStub(algo)); Security security; if (securityType == SecurityType.Equity) { security = algo.AddEquity(symbol); _symbol = security.Symbol; } else if (securityType == SecurityType.Option) { security = algo.AddOption(symbol); _symbol = security.Symbol; } else if (securityType == SecurityType.Future) { security = algo.AddFuture(symbol == "SPY" ? "ES" : symbol); _symbol = security.Symbol; } else { throw new Exception("SecurityType not implemented"); } security.FeeModel = new ConstantFeeModel(fee); Update(security, 25, time); return(security); }
public void SetBuyingPowerModelSuccess(bool isChild) { var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); algorithm.SetDateTime(new DateTime(2018, 8, 20, 15, 0, 0)); algorithm.Transactions.SetOrderProcessor(new FakeOrderProcessor()); var spy = algorithm.AddEquity("SPY", Resolution.Daily); spy.SetMarketPrice(new Tick(algorithm.Time, Symbols.SPY, 100m, 100m)); // Test two custom buying power models. // The first inherits from C# SecurityMarginModel and the other is 100% python var code = isChild ? CreateCustomBuyingPowerModelFromSecurityMarginModelCode() : CreateCustomBuyingPowerModelCode(); spy.SetBuyingPowerModel(CreateCustomBuyingPowerModel(code)); Assert.IsAssignableFrom <BuyingPowerModelPythonWrapper>(spy.MarginModel); Assert.AreEqual(1, spy.MarginModel.GetLeverage(spy)); spy.SetLeverage(2); Assert.AreEqual(2, spy.MarginModel.GetLeverage(spy)); var quantity = algorithm.CalculateOrderQuantity(spy.Symbol, 1m); Assert.AreEqual(isChild ? 100 : 200, quantity); }
public void TickResolutionSubscriptionHistoryRequestOtherResolution(Resolution resolution) { var start = new DateTime(2013, 10, 07); _algorithm = GetAlgorithm(start.AddDays(1)); _algorithm.AddEquity(Symbols.SPY, Resolution.Tick); // Trades and quotes var result = _algorithm.History(new [] { Symbols.SPY }, start, _algorithm.Time, resolution).ToList(); Assert.IsNotEmpty(result); Assert.IsTrue(result.All(slice => { foreach (var bar in slice.Bars.Values) { return((bar.EndTime - bar.Time) == resolution.ToTimeSpan()); } foreach (var bar in slice.QuoteBars.Values) { return((bar.EndTime - bar.Time) == resolution.ToTimeSpan()); } return(false); })); }
public void DefaultBrokerageModel_IsUSA_ForEquity() { var equity = _algo.AddEquity(Sym); Assert.IsTrue(equity.Symbol.ID.Market == Market.USA); Assert.IsTrue(_algo.BrokerageModel.GetType() == typeof(DefaultBrokerageModel)); }
public void PythonCallSetBrokerageModel() { using (Py.GIL()) { var model = PythonEngine.ModuleFromString("testModule", @" from AlgorithmImports import * class Test(AlphaStreamsBrokerageModel): def GetLeverage(self, security): return 12").GetAttr("Test"); _algo.SetBrokerageModel(model.Invoke()); var equity = _algo.AddEquity(Sym); Assert.DoesNotThrow(() => _algo.BrokerageModel.ApplySplit(new List <OrderTicket>(), new Split())); Assert.AreEqual(12m, _algo.BrokerageModel.GetLeverage(equity)); } }
public void PartiallyFilledOrdersAreTakenIntoAccount(Language language) { var actualOrdersSubmitted = new List <SubmitOrderRequest>(); var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); algorithm.SetPandasConverter(); var security = algorithm.AddEquity(Symbols.AAPL.Value); security.SetMarketPrice(new TradeBar { Value = 250 }); algorithm.SetFinishedWarmingUp(); var openOrderRequest = new SubmitOrderRequest(OrderType.Market, SecurityType.Equity, Symbols.AAPL, 100, 0, 0, DateTime.MinValue, ""); openOrderRequest.SetOrderId(1); var openOrderTicket = new OrderTicket(algorithm.Transactions, openOrderRequest); openOrderTicket.AddOrderEvent(new OrderEvent(1, Symbols.AAPL, DateTime.MinValue, OrderStatus.PartiallyFilled, OrderDirection.Buy, 250, 70, OrderFee.Zero)); var orderProcessor = new Mock <IOrderProcessor>(); orderProcessor.Setup(m => m.Process(It.IsAny <SubmitOrderRequest>())) .Returns((SubmitOrderRequest request) => new OrderTicket(algorithm.Transactions, request)) .Callback((SubmitOrderRequest request) => actualOrdersSubmitted.Add(request)); orderProcessor.Setup(m => m.GetOpenOrders(It.IsAny <Func <Order, bool> >())) .Returns(new List <Order> { new MarketOrder(Symbols.AAPL, 100, DateTime.MinValue) }); orderProcessor.Setup(m => m.GetOpenOrderTickets(It.IsAny <Func <OrderTicket, bool> >())) .Returns(new List <OrderTicket> { openOrderTicket }); algorithm.Transactions.SetOrderProcessor(orderProcessor.Object); var model = GetExecutionModel(language); algorithm.SetExecution(model); var changes = new SecurityChanges(Enumerable.Empty <Security>(), Enumerable.Empty <Security>()); model.OnSecuritiesChanged(algorithm, changes); var targets = new IPortfolioTarget[] { new PortfolioTarget(Symbols.AAPL, 80) }; model.Execute(algorithm, targets); Assert.AreEqual(1, actualOrdersSubmitted.Count); // Remaining quantity for partially filled order = 100 - 70 = 30 // Quantity submitted = 80 - 30 = 50 Assert.AreEqual(50, actualOrdersSubmitted.Sum(x => x.Quantity)); }
public void AllPythonRegisterIndicatorCases() { //This test covers all three cases of registering a indicator through Python //Setup algorithm and Equity var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); var spy = algorithm.AddEquity("SPY").Symbol; //Setup Python Indicator and Consolidator using (Py.GIL()) { var module = PythonEngine.ModuleFromString(Guid.NewGuid().ToString(), "from clr import AddReference\n" + "AddReference(\"QuantConnect.Common\")\n" + "AddReference(\"QuantConnect.Indicators\")\n" + "from QuantConnect import *\n" + "from QuantConnect.Data.Market import *\n" + "from QuantConnect.Data.Consolidators import *\n" + "from QuantConnect.Indicators import *\n" + "from QuantConnect.Python import *\n" + "from datetime import *\n" + "consolidator = QuoteBarConsolidator(timedelta(days = 5)) \n" + "timeDelta = timedelta(days=2)\n" + "class CustomIndicator(PythonIndicator):\n" + " def __init__(self):\n" + " self.Value = 0\n" + " def Update(self, input):\n" + " self.Value = input.Value\n" + " return True\n" + "class CustomConsolidator(PythonConsolidator):\n" + " def __init__(self):\n" + " self.InputType = QuoteBar\n" + " self.OutputType = QuoteBar\n" + " self.Consolidated = None\n" + " self.WorkingData = None\n" ); //Get our variables from Python var PyIndicator = module.GetAttr("CustomIndicator").Invoke(); var PyConsolidator = module.GetAttr("CustomConsolidator").Invoke(); var Consolidator = module.GetAttr("consolidator"); algorithm.SubscriptionManager.AddConsolidator(spy, Consolidator); var TimeDelta = module.GetAttr("timeDelta"); //Test 1: Using a C# Consolidator; Should convert consolidator into IDataConsolidator Assert.DoesNotThrow(() => algorithm.RegisterIndicator(spy, PyIndicator, Consolidator)); //Test 2: Using a Python Consolidator; Should wrap consolidator Assert.DoesNotThrow(() => algorithm.RegisterIndicator(spy, PyIndicator, PyConsolidator)); //Test 3: Using a timedelta object; Should convert timedelta to timespan Assert.DoesNotThrow(() => algorithm.RegisterIndicator(spy, PyIndicator, TimeDelta)); } }
public void FillsOnTradesOnlyRespectingExchangeOpen(Language language, int expectedOrdersSubmitted, decimal expectedTotalQuantity, bool exchangeOpen) { var actualOrdersSubmitted = new List <SubmitOrderRequest>(); var time = new DateTime(2018, 8, 2, 0, 0, 0); if (exchangeOpen) { time = time.AddHours(14); } var algorithm = new QCAlgorithm(); algorithm.SetPandasConverter(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); algorithm.SetDateTime(time.AddMinutes(5)); var security = algorithm.AddEquity(Symbols.AAPL.Value); security.SetMarketPrice(new TradeBar { Value = 250 }); algorithm.SetFinishedWarmingUp(); var orderProcessor = new Mock <IOrderProcessor>(); orderProcessor.Setup(m => m.Process(It.IsAny <SubmitOrderRequest>())) .Returns((SubmitOrderRequest request) => new OrderTicket(algorithm.Transactions, request)) .Callback((OrderRequest request) => actualOrdersSubmitted.Add((SubmitOrderRequest)request)); orderProcessor.Setup(m => m.GetOpenOrders(It.IsAny <Func <Order, bool> >())) .Returns(new List <Order>()); algorithm.Transactions.SetOrderProcessor(orderProcessor.Object); var model = GetExecutionModel(language); algorithm.SetExecution(model); var changes = new SecurityChanges(new[] { security }, Enumerable.Empty <Security>()); model.OnSecuritiesChanged(algorithm, changes); var targets = new IPortfolioTarget[] { new PortfolioTarget(Symbols.AAPL, 10) }; model.Execute(algorithm, targets); Assert.AreEqual(expectedOrdersSubmitted, actualOrdersSubmitted.Count); Assert.AreEqual(expectedTotalQuantity, actualOrdersSubmitted.Sum(x => x.Quantity)); if (actualOrdersSubmitted.Count == 1) { var request = actualOrdersSubmitted[0]; Assert.AreEqual(expectedTotalQuantity, request.Quantity); Assert.AreEqual(algorithm.UtcTime, request.Time); } }
public void AddsEquityWithExpectedDataNormalizationMode(DataNormalizationMode dataNormalizationMode) { var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(_dataFeed, algorithm)); var equity = algorithm.AddEquity("AAPL", dataNormalizationMode: dataNormalizationMode); Assert.That(algorithm.SubscriptionManager.Subscriptions.Where(x => x.Symbol == equity.Symbol).Select(x => x.DataNormalizationMode), Has.All.EqualTo(dataNormalizationMode)); }
public void TradeBarToTradeBar() { var algorithm = new QCAlgorithm(); var security = algorithm.AddEquity("SPY"); var consolidator = algorithm.ResolveConsolidator("SPY", Resolution.Minute); var inputType = security.SubscriptionDataConfig.Type; var outputType = consolidator.OutputType; Assert.AreEqual(inputType, outputType); }
public void OnSecuritiesChangeDoesNotThrow( Language language, double[] historicalPrices, MarketDataType marketDataType) { var time = new DateTime(2018, 8, 2, 16, 0, 0); Func <double, int, BaseData> func = (x, i) => { var price = Convert.ToDecimal(x); switch (marketDataType) { case MarketDataType.TradeBar: return(new TradeBar(time.AddMinutes(i), Symbols.AAPL, price, price, price, price, 100m)); case MarketDataType.QuoteBar: var bar = new Bar(price, price, price, price); return(new QuoteBar(time.AddMinutes(i), Symbols.AAPL, bar, 10m, bar, 10m)); default: throw new ArgumentException($"Invalid MarketDataType: {marketDataType}"); } }; var historyProvider = new Mock <IHistoryProvider>(); historyProvider.Setup(m => m.GetHistory(It.IsAny <IEnumerable <HistoryRequest> >(), It.IsAny <DateTimeZone>())) .Returns(historicalPrices.Select((x, i) => new Slice(time.AddMinutes(i), new List <BaseData> { func(x, i) }))); var algorithm = new QCAlgorithm(); algorithm.SetPandasConverter(); algorithm.SetHistoryProvider(historyProvider.Object); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); algorithm.SetDateTime(time.AddMinutes(5)); var security = algorithm.AddEquity(Symbols.AAPL.Value); security.SetMarketPrice(new TradeBar { Value = 250 }); algorithm.SetFinishedWarmingUp(); var model = GetExecutionModel(language); algorithm.SetExecution(model); var changes = new SecurityChanges(new[] { security }, Enumerable.Empty <Security>()); Assert.DoesNotThrow(() => model.OnSecuritiesChanged(algorithm, changes)); }
public void TickTypeTradeToTradeBar() { var algorithm = new QCAlgorithm(); var security = algorithm.AddEquity("SPY", Resolution.Tick); var consolidator = algorithm.ResolveConsolidator("SPY", Resolution.Minute); var tickType = security.SubscriptionDataConfig.TickType; var outputType = consolidator.OutputType; Assert.AreEqual(TickType.Trade, tickType); Assert.AreEqual(typeof(TradeBar), outputType); }
public void ZeroTargetWithZeroHoldingsIsNotAnError() { var algorithm = new QCAlgorithm(); var security = algorithm.AddEquity("SPY"); var model = new SecurityMarginModel(); var result = model.GetMaximumOrderQuantityForTargetValue(algorithm.Portfolio, security, 0); Assert.AreEqual(0, result.Quantity); Assert.AreEqual(string.Empty, result.Reason); Assert.AreEqual(false, result.IsError); }
public override IEnumerable <Universe> CreateUniverses(QCAlgorithm algorithm) { // Adds the benchmark to the user defined universe var benchmark = algorithm.AddEquity(_benchmark, Resolution.Daily); // Defines a schedule universe that fires after market open when the month starts yield return(new ScheduledUniverse( benchmark.Exchange.TimeZone, algorithm.DateRules.MonthStart(benchmark.Symbol), algorithm.TimeRules.AfterMarketOpen(benchmark.Symbol), datetime => SelectPair(algorithm, datetime), algorithm.UniverseSettings)); }
public void TradeBarToTradeBar() { var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); var security = algorithm.AddEquity("SPY"); var consolidator = algorithm.ResolveConsolidator("SPY", Resolution.Minute); var inputType = security.Subscriptions.Single(s => s.TickType == LeanData.GetCommonTickType(SecurityType.Equity)).Type; var outputType = consolidator.OutputType; Assert.AreEqual(inputType, outputType); }
public void ZeroTargetWithNonZeroHoldingsReturnsNegativeOfQuantity() { var algorithm = new QCAlgorithm(); var security = algorithm.AddEquity("SPY"); security.Holdings.SetHoldings(200, 10); var model = new SecurityMarginModel(); var result = model.GetMaximumOrderQuantityForTargetValue(algorithm.Portfolio, security, 0); Assert.AreEqual(-10, result.Quantity); Assert.AreEqual(string.Empty, result.Reason); Assert.AreEqual(false, result.IsError); }
public void Setup() { _algorithm = new QCAlgorithm(); _spy = _algorithm.AddEquity("SPY").Symbol; _indicatorTestsTypes = from type in GetType().Assembly.GetTypes() where type.IsPublic && !type.IsAbstract where typeof(CommonIndicatorTests <TradeBar>).IsAssignableFrom(type) || typeof(CommonIndicatorTests <IBaseDataBar>).IsAssignableFrom(type) || typeof(CommonIndicatorTests <IndicatorDataPoint>).IsAssignableFrom(type) select type; }
public void DoesNotReturnTargetsIfSecurityPriceIsZero(Language language) { var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); algorithm.AddEquity(Symbols.SPY.Value); algorithm.SetDateTime(DateTime.MinValue.ConvertToUtc(Algorithm.TimeZone)); SetPortfolioConstruction(language); var insights = new[] { GetInsight(Symbols.SPY, InsightDirection.Up, algorithm.UtcTime) }; var actualTargets = algorithm.PortfolioConstruction.CreateTargets(algorithm, insights); Assert.AreEqual(0, actualTargets.Count()); }
public void TickTypeTradeToTick() { var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub()); var security = algorithm.AddEquity("SPY", Resolution.Tick); var consolidator = algorithm.ResolveConsolidator("SPY", Resolution.Tick); var tickType = security.SubscriptionDataConfig.TickType; var inputType = security.SubscriptionDataConfig.Type; var outputType = consolidator.OutputType; Assert.AreEqual(TickType.Trade, tickType); Assert.AreEqual(inputType, outputType); }
private static QCAlgorithm GetAlgorithm(out Security security, decimal fee) { SymbolCache.Clear(); // Initialize algorithm var algo = new QCAlgorithm(); algo.SetCash(100000); algo.SetFinishedWarmingUp(); _fakeOrderProcessor = new FakeOrderProcessor(); algo.Transactions.SetOrderProcessor(_fakeOrderProcessor); security = algo.AddEquity("SPY"); security.TransactionModel = new ConstantFeeTransactionModel(fee); Update(algo.Portfolio.CashBook, security, 25); return(algo); }
public void RemoveConsolidatorClearsEventHandlers() { bool eventHandlerFired = false; var algorithm = new QCAlgorithm(); var security = algorithm.AddEquity("SPY"); var consolidator = new IdentityDataConsolidator <BaseData>(); consolidator.DataConsolidated += (sender, consolidated) => eventHandlerFired = true; security.Subscriptions.First().Consolidators.Add(consolidator); algorithm.SubscriptionManager.RemoveConsolidator(security.Symbol, consolidator); consolidator.Update(new Tick()); Assert.IsFalse(eventHandlerFired); }
public void MisalignedBenchmarkAndAlgorithmTimeZones(Resolution resolution, bool useUniverseSubscription = false) { // Verify that if we have algorithm: // - subscribed to a daily resolution via universe or directly // - a benchmark with timezone that is not algorithm time zone // that we post an warning via log that statistics will be affected // Setup a empty algorithm for the test var algorithm = new QCAlgorithm(); var dataManager = new DataManagerStub(algorithm, new MockDataFeed(), liveMode: true); algorithm.SubscriptionManager.SetDataManager(dataManager); if (useUniverseSubscription) { // Change our universe resolution algorithm.UniverseSettings.Resolution = resolution; } else { // subscribe to an equity in our provided resolution algorithm.AddEquity("AAPL", resolution); } // Default benchmark is SPY which is NY TimeZone, // Set timezone to UTC. algorithm.SetTimeZone(DateTimeZone.Utc); algorithm.PostInitialize(); // Verify if our log is there (Should only be there in Daily case) switch (resolution) { case Resolution.Daily: if (algorithm.LogMessages.TryPeek(out string result)) { Assert.IsTrue(result.Contains("Using a security benchmark of a different timezone", StringComparison.InvariantCulture)); } else { Assert.Fail("Warning was not posted"); } break; default: Assert.AreEqual(0, algorithm.LogMessages.Count); break; } }
public void DelistedSecuritiesInsightsTest(bool isDelisted, int expectedCount) { var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); algorithm.Transactions.SetOrderProcessor(new FakeOrderProcessor()); algorithm.SetStartDate(2007, 5, 16); algorithm.SetUniverseSelection(new ManualUniverseSelectionModel()); algorithm.SetFinishedWarmingUp(); var alpha = new FakeAlpha(); algorithm.SetAlpha(alpha); var construction = new FakePortfolioConstruction(); algorithm.SetPortfolioConstruction(construction); var actualInsights = new List <Insight>(); algorithm.InsightsGenerated += (s, e) => actualInsights.AddRange(e.Insights); var security = algorithm.AddEquity("SPY", Resolution.Daily); var tick = new Tick { Symbol = security.Symbol, Value = 1, Quantity = 2 }; security.SetMarketPrice(tick); security.IsDelisted = isDelisted; // Trigger Alpha to emit insight algorithm.OnFrameworkData(new Slice(new DateTime(2000, 01, 01), new List <BaseData>() { tick })); // Manually emit insight algorithm.EmitInsights(Insight.Price(Symbols.SPY, TimeSpan.FromDays(1), InsightDirection.Up, .5, .75)); // Should be zero because security is delisted Assert.AreEqual(expectedCount, actualInsights.Count); }
public void RegisterPythonCustomIndicatorProperly() { var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); var spy = algorithm.AddEquity("SPY").Symbol; using (Py.GIL()) { var module = PythonEngine.ModuleFromString( Guid.NewGuid().ToString(), @" from clr import AddReference AddReference('QuantConnect.Common') AddReference('QuantConnect.Indicators') from QuantConnect import * from QuantConnect.Indicators import * class GoodCustomIndicator(PythonIndicator): def __init__(self): self.Value = 0 def Update(self, input): self.Value = input.Value return True class BadCustomIndicator(PythonIndicator): def __init__(self): self.Valeu = 0 def Update(self, input): self.Value = input.Value return True" ); var goodIndicator = module.GetAttr("GoodCustomIndicator").Invoke(); Assert.DoesNotThrow(() => algorithm.RegisterIndicator(spy, goodIndicator, Resolution.Minute)); var actual = algorithm.SubscriptionManager.Subscriptions .FirstOrDefault(config => config.TickType == TickType.Trade) .Consolidators.Count; Assert.AreEqual(1, actual); var badIndicator = module.GetAttr("BadCustomIndicator").Invoke(); Assert.Throws <NotImplementedException>(() => algorithm.RegisterIndicator(spy, badIndicator, Resolution.Minute)); } }
public void OnSecuritiesChangeDoesNotThrow( Language language, MarketDataType marketDataType) { var time = new DateTime(2018, 8, 2, 16, 0, 0); Func <double, int, BaseData> func = (x, i) => { var price = Convert.ToDecimal(x); switch (marketDataType) { case MarketDataType.TradeBar: return(new TradeBar(time.AddMinutes(i), Symbols.AAPL, price, price, price, price, 100m)); case MarketDataType.QuoteBar: var bar = new Bar(price, price, price, price); return(new QuoteBar(time.AddMinutes(i), Symbols.AAPL, bar, 10m, bar, 10m)); default: throw new ArgumentException($"Invalid MarketDataType: {marketDataType}"); } }; var algorithm = new QCAlgorithm(); algorithm.SetPandasConverter(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); algorithm.SetDateTime(time.AddMinutes(5)); var security = algorithm.AddEquity(Symbols.AAPL.Value); security.SetMarketPrice(new TradeBar { Value = 250 }); algorithm.SetFinishedWarmingUp(); var model = GetExecutionModel(language); algorithm.SetExecution(model); var changes = new SecurityChanges(new[] { security }, Enumerable.Empty <Security>()); Assert.DoesNotThrow(() => model.OnSecuritiesChanged(algorithm, changes)); }