public override void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes) { foreach (var security in changes.RemovedSecurities) { if (_symbolDataBySymbol.ContainsKey(security.Symbol)) { _symbolDataBySymbol.Remove(security.Symbol); } } // Retrieve price history for all securities in the security universe // and update the indicators in the SymbolData object var symbols = changes.AddedSecurities.Select(x => x.Symbol); var history = algorithm.History(symbols, 1, _resolution); if (symbols.Count() > 0 && history.Count() == 0) { algorithm.Debug($"No data on {algorithm.Time}"); } history.PushThrough(bar => { SymbolData symbolData; if (!_symbolDataBySymbol.TryGetValue(bar.Symbol, out symbolData)) { symbolData = new SymbolData(bar.Symbol, _predictionInterval); } symbolData.Update(bar.EndTime, bar.Price); _symbolDataBySymbol[bar.Symbol] = symbolData; }); }
/// <summary> /// Event fired each time the we add/remove securities from the data feed /// </summary> /// <param name="algorithm">The algorithm instance that experienced the change in securities</param> /// <param name="changes">The security additions and removals from the algorithm</param> public override void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes) { // Get removed symbol and invalidate them in the insight collection _removedSymbols = changes.RemovedSecurities.Select(x => x.Symbol).ToList(); _insightCollection.Clear(_removedSymbols.ToArray()); foreach (var symbol in _removedSymbols) { if (_symbolDataDict.ContainsKey(symbol)) { _symbolDataDict[symbol].Reset(); _symbolDataDict.Remove(symbol); } } // initialize data for added securities var addedSymbols = changes.AddedSecurities.Select(x => x.Symbol).ToList(); algorithm.History(addedSymbols, _lookback * _period, _resolution) .PushThrough(bar => { ReturnsSymbolData symbolData; if (!_symbolDataDict.TryGetValue(bar.Symbol, out symbolData)) { symbolData = new ReturnsSymbolData(bar.Symbol, _lookback, _period); _symbolDataDict.Add(bar.Symbol, symbolData); } symbolData.Update(bar.EndTime, bar.Value); }); }
public override void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes) { // Clean up data for removed securities foreach (var removed in changes.RemovedSecurities) { SymbolData symbolData; if (_symbolDataBySymbol.TryGetValue(removed.Symbol, out symbolData)) { symbolData.RemoveConsolidators(algorithm); _symbolDataBySymbol.Remove(removed.Symbol); } } // Initialize data for added securities var symbols = changes.AddedSecurities.Select(x => x.Symbol); var history = algorithm.History(symbols, _lookback, _resolution); if (symbols.Count() == 0 && history.Count() == 0) { return; } history.PushThrough(bar => { SymbolData symbolData; if (!_symbolDataBySymbol.TryGetValue(bar.Symbol, out symbolData)) { symbolData = new SymbolData(algorithm, bar.Symbol, _lookback, _resolution); _symbolDataBySymbol[bar.Symbol] = symbolData; } symbolData.WarmUpIndicators(bar); }); }
/// <summary> /// Event fired each time the we add/remove securities from the data feed /// </summary> /// <param name="algorithm">The algorithm instance that experienced the change in securities</param> /// <param name="changes">The security additions and removals from the algorithm</param> public override void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes) { NotifiedSecurityChanges.UpdateCollection(Securities, changes); var symbols = Securities.Select(x => x.Symbol).ToArray(); var history = algorithm.History(symbols, _lookback, _resolution); var vectors = GetPriceVectors(history); if (vectors.LongLength == 0) { algorithm.Debug($"PearsonCorrelationPairsTradingAlphaModel.OnSecuritiesChanged(): The requested historical data does not have series of prices with the same date/time. Please consider increasing the looback period. Current lookback: {_lookback}"); } else { var pearsonMatrix = Correlation.PearsonMatrix(vectors).UpperTriangle(); var maxValue = pearsonMatrix.Enumerate().Where(x => Math.Abs(x) < 1).Max(); if (maxValue >= _minimumCorrelation) { var maxTuple = pearsonMatrix.Find(x => x == maxValue); _bestPair = Tuple.Create(symbols[maxTuple.Item1], symbols[maxTuple.Item2]); } } base.OnSecuritiesChanged(algorithm, changes); }
private void WarmUpIndicators(QCAlgorithmFramework algorithm) { // Make a history call and update the indicators algorithm.History(new[] { _mortgageRate }, _indicatorPeriod, _resolution).PushThrough(bar => { _mortgageRateSma.Update(bar.EndTime, bar.Value); _mortgageRateStd.Update(bar.EndTime, bar.Value); }); }
/// <summary> /// Cleans out old security data and initializes the RSI for any newly added securities. /// This functional also seeds any new indicators using a history request. /// </summary> /// <param name="algorithm">The algorithm instance that experienced the change in securities</param> /// <param name="changes">The security additions and removals from the algorithm</param> public void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes) { // clean up data for removed securities if (changes.RemovedSecurities.Count > 0) { var removed = changes.RemovedSecurities.ToHashSet(x => x.Symbol); foreach (var subscription in algorithm.SubscriptionManager.Subscriptions) { if (removed.Contains(subscription.Symbol)) { _symbolDataBySymbol.Remove(subscription.Symbol); subscription.Consolidators.Clear(); } } } // initialize data for added securities if (changes.AddedSecurities.Count > 0) { var newSymbolData = new List <SymbolData>(); foreach (var added in changes.AddedSecurities) { if (!_symbolDataBySymbol.ContainsKey(added.Symbol)) { var rsi = algorithm.RSI(added.Symbol, _parameters.RsiPeriod, MovingAverageType.Wilders, _parameters.Resolution); var symbolData = new SymbolData(added.Symbol, rsi); _symbolDataBySymbol[added.Symbol] = symbolData; newSymbolData.Add(symbolData); if (_parameters.Plot) { algorithm.PlotIndicator("RSI Alpha Model", true, rsi); } } } // seed new indicators using history request var history = algorithm.History(newSymbolData.Select(x => x.Symbol), _parameters.RsiPeriod); foreach (var slice in history) { foreach (var symbol in slice.Keys) { var value = slice[symbol]; var list = value as IList; var data = (BaseData)(list != null ? list[list.Count - 1] : value); SymbolData symbolData; if (_symbolDataBySymbol.TryGetValue(symbol, out symbolData)) { symbolData.RSI.Update(data.EndTime, data.Value); } } } } }
public override void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes) { foreach (var removed in changes.RemovedSecurities) { if (_symbolDataBySymbol.ContainsKey(removed.Symbol)) { _symbolDataBySymbol[removed.Symbol].RemoveConsolidators(algorithm); _symbolDataBySymbol.Remove(removed.Symbol); } } // Initialize data for added securities var symbols = changes.AddedSecurities.Select(x => x.Symbol); var dailyHistory = algorithm.History(symbols, _historyDays + 1, Resolution.Daily); if (symbols.Count() > 0 && dailyHistory.Count() == 0) { algorithm.Debug($"{algorithm.Time} :: No daily data"); } dailyHistory.PushThrough(bar => { SymbolData symbolData; if (!_symbolDataBySymbol.TryGetValue(bar.Symbol, out symbolData)) { symbolData = new SymbolData(algorithm, bar.Symbol, _historyDays, _lookback, _resolution); _symbolDataBySymbol.Add(bar.Symbol, symbolData); } // Update daily rate of change indicator symbolData.UpdateDailyRateOfChange(bar); }); algorithm.History(symbols, _lookback, _resolution).PushThrough(bar => { // Update rate of change indicator with given resolution if (_symbolDataBySymbol.ContainsKey(bar.Symbol)) { _symbolDataBySymbol[bar.Symbol].UpdateRateOfChange(bar); } }); }
/// <summary> /// Cleans out old security data and initializes the RSI for any newly added securities. /// This functional also seeds any new indicators using a history request. /// </summary> /// <param name="algorithm">The algorithm instance that experienced the change in securities</param> /// <param name="changes">The security additions and removals from the algorithm</param> public override void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes) { // clean up data for removed securities if (changes.RemovedSecurities.Count > 0) { var removed = changes.RemovedSecurities.ToHashSet(x => x.Symbol); foreach (var subscription in algorithm.SubscriptionManager.Subscriptions) { if (removed.Contains(subscription.Symbol)) { _symbolDataBySymbol.Remove(subscription.Symbol); subscription.Consolidators.Clear(); } } } // initialize data for added securities var addedSymbols = new List <Symbol>(); foreach (var added in changes.AddedSecurities) { if (!_symbolDataBySymbol.ContainsKey(added.Symbol)) { if (!added.Symbol.HasUnderlying) //ignore derivatives { var symbolData = new SymbolData(algorithm, added.Symbol, _period, this.IsPercent); _symbolDataBySymbol[added.Symbol] = symbolData; addedSymbols.Add(symbolData.Symbol); var chart = new Chart(added.Symbol.Value + " - " + typeof(T).Name); chart.AddSeries(symbolData.IndicatorSeries); chart.AddSeries(symbolData.IndicatorSeriesSTD); algorithm.AddChart(chart); } } } if (addedSymbols.Count > 0) { // warmup our indicators by pushing history through the consolidators algorithm.History(addedSymbols, _resolution.Multiply(_period)) .PushThrough(data => { SymbolData symbolData; if (_symbolDataBySymbol.TryGetValue(data.Symbol, out symbolData)) { symbolData.Update((TradeBar)data); } }); } }
/// <summary> /// Scan to see if the returns are greater than 1% at 2.15pm to emit an insight. /// </summary> public override IEnumerable <Insight> Update(QCAlgorithmFramework algorithm, Slice data) { // Initialize: var insights = new List <Insight>(); var magnitude = 0.0005; // Paper suggests leveraged ETF's rebalance from 2.15pm - to close // giving an insight period of 105 minutes. var period = TimeSpan.FromMinutes(105); if (algorithm.Time.Date != _date) { _date = algorithm.Time.Date; // Save yesterday's price and reset the signal. foreach (var group in _etfGroups) { var history = algorithm.History(group.Underlying, 1, Resolution.Daily); group.YesterdayClose = history.Select(x => x.Close).FirstOrDefault(); } } // Check if the returns are > 1% at 14.15 if (algorithm.Time.Hour == 14 && algorithm.Time.Minute == 15) { foreach (var group in _etfGroups) { if (group.YesterdayClose == 0) { continue; } var returns = (algorithm.Portfolio[group.Underlying].Price - group.YesterdayClose) / group.YesterdayClose; if (returns > 0.01m) { insights.Add(Insight.Price(group.UltraLong, period, InsightDirection.Up, magnitude)); } else if (returns < -0.01m) { insights.Add(Insight.Price(group.UltraShort, period, InsightDirection.Down, magnitude)); } } } return(insights); }
/// <summary> /// Cleans out old security data and initializes the RSI for any newly added securities. /// This functional also seeds any new indicators using a history request. /// </summary> /// <param name="algorithm">The algorithm instance that experienced the change in securities</param> /// <param name="changes">The security additions and removals from the algorithm</param> public void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes) { // clean up data for removed securities if (changes.RemovedSecurities.Count > 0) { var removed = changes.RemovedSecurities.ToHashSet(x => x.Symbol); foreach (var subscription in algorithm.SubscriptionManager.Subscriptions) { if (removed.Contains(subscription.Symbol)) { _symbolDataBySymbol.Remove(subscription.Symbol); subscription.Consolidators.Clear(); } } } // initialize data for added securities var addedSymbols = new List <Symbol>(); foreach (var added in changes.AddedSecurities) { if (!_symbolDataBySymbol.ContainsKey(added.Symbol)) { var rsi = algorithm.RSI(added.Symbol, _period, MovingAverageType.Wilders, _resolution); var symbolData = new SymbolData(added.Symbol, rsi); _symbolDataBySymbol[added.Symbol] = symbolData; addedSymbols.Add(symbolData.Symbol); } } if (addedSymbols.Count > 0) { // warmup our indicators by pushing history through the consolidators algorithm.History(addedSymbols, _period, _resolution) .PushThrough(data => { SymbolData symbolData; if (_symbolDataBySymbol.TryGetValue(data.Symbol, out symbolData)) { symbolData.RSI.Update(data.EndTime, data.Value); } }); } }
/// <summary> /// Event fired each time the we add/remove securities from the data feed /// </summary> /// <param name="algorithm">The algorithm instance that experienced the change in securities</param> /// <param name="changes">The security additions and removals from the algorithm</param> public override void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes) { // clean up data for removed securities foreach (var removed in changes.RemovedSecurities) { _pendingRemoval.Add(removed.Symbol); ReturnsSymbolData data; if (_symbolDataDict.TryGetValue(removed.Symbol, out data)) { _symbolDataDict.Remove(removed.Symbol); data.Reset(); } } // initialize data for added securities var addedSymbols = new List <Symbol>(); foreach (var added in changes.AddedSecurities) { if (!_symbolDataDict.ContainsKey(added.Symbol)) { var symbolData = new ReturnsSymbolData(added.Symbol, _lookback, _period); _symbolDataDict[added.Symbol] = symbolData; addedSymbols.Add(added.Symbol); } } if (addedSymbols.Count == 0) { return; } // warmup our indicators by pushing history through the consolidators algorithm.History(addedSymbols, _lookback * _period, _resolution) .PushThrough(bar => { ReturnsSymbolData symbolData; if (_symbolDataDict.TryGetValue(bar.Symbol, out symbolData)) { symbolData.Update(bar.EndTime, bar.Value); } }); }
/// <summary> /// Event fired each time the we add/remove securities from the data feed /// </summary> /// <param name="algorithm">The algorithm instance that experienced the change in securities</param> /// <param name="changes">The security additions and removals from the algorithm</param> public override void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes) { var addedSymbols = new List <Symbol>(); foreach (var added in changes.AddedSecurities) { // initialize new securities if (!_symbolData.ContainsKey(added.Symbol)) { var symbolData = new SymbolData(algorithm, added, _period, _resolution); addedSymbols.Add(added.Symbol); _symbolData[added.Symbol] = symbolData; } } if (addedSymbols.Count > 0) { // warmup our indicators by pushing history through the consolidators algorithm.History(addedSymbols, _period, _resolution) .PushThroughConsolidators(symbol => { SymbolData data; return(_symbolData.TryGetValue(symbol, out data) ? data.Consolidator : null); }); } foreach (var removed in changes.RemovedSecurities) { // clean up data from removed securities SymbolData data; if (_symbolData.TryGetValue(removed.Symbol, out data)) { if (IsSafeToRemove(algorithm, removed.Symbol)) { _symbolData.Remove(removed.Symbol); algorithm.SubscriptionManager.RemoveConsolidator(removed.Symbol, data.Consolidator); } } } }
/// <summary> /// Event fired each time the we add/remove securities from the data feed /// </summary> /// <param name="algorithm">The algorithm instance that experienced the change in securities</param> /// <param name="changes">The security additions and removals from the algorithm</param> public override void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes) { // clean up data for removed securities foreach (var removed in changes.RemovedSecurities) { SymbolData data; if (_symbolDataBySymbol.TryGetValue(removed.Symbol, out data)) { _symbolDataBySymbol.Remove(removed.Symbol); algorithm.SubscriptionManager.RemoveConsolidator(removed.Symbol, data.Consolidator); } } // initialize data for added securities var addedSymbols = new List <Symbol>(); foreach (var added in changes.AddedSecurities) { if (!_symbolDataBySymbol.ContainsKey(added.Symbol)) { var symbolData = new SymbolData(algorithm, added, _lookback, _resolution); _symbolDataBySymbol[added.Symbol] = symbolData; addedSymbols.Add(symbolData.Security.Symbol); } } if (addedSymbols.Count > 0) { // warmup our indicators by pushing history through the consolidators algorithm.History(addedSymbols, _lookback, _resolution) .PushThrough(bar => { SymbolData symbolData; if (_symbolDataBySymbol.TryGetValue(bar.Symbol, out symbolData)) { symbolData.ROC.Update(bar.EndTime, bar.Value); } }); } }
public void OrdersAreSubmittedWhenRequiredForTargetsToExecute( Language language, double[] historicalPrices, decimal lastVolume, int expectedOrdersSubmitted, decimal expectedTotalQuantity) { var actualOrdersSubmitted = new List <SubmitOrderRequest>(); var time = new DateTime(2018, 8, 2, 16, 0, 0); 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> { new TradeBar { Time = time.AddMinutes(i), Symbol = Symbols.AAPL, Open = Convert.ToDecimal(x), High = Convert.ToDecimal(x), Low = Convert.ToDecimal(x), Close = Convert.ToDecimal(x), Volume = 100m } }))); var algorithm = new QCAlgorithmFramework(); algorithm.SubscriptionManager.SetDataManager(new DataManager()); algorithm.SetPandasConverter(); algorithm.SetHistoryProvider(historyProvider.Object); algorithm.SetDateTime(time.AddMinutes(5)); var security = algorithm.AddEquity(Symbols.AAPL.Value); security.SetMarketPrice(new TradeBar { Value = 250, Volume = lastVolume }); algorithm.SetFinishedWarmingUp(); 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>()); 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); algorithm.History(new List <Symbol> { security.Symbol }, historicalPrices.Length, Resolution.Minute) .PushThroughConsolidators(symbol => algorithm.Securities[symbol].Subscriptions.First().Consolidators.First()); var targets = new IPortfolioTarget[] { new PortfolioTarget(security.Symbol, 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); } }