/// <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 void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes) { changes.FilterCustomSecurities = false; foreach (var security in changes.RemovedSecurities) { if (security.Type != SecurityType.Base) { _removedSymbols.Enqueue(security.Symbol); } else if (security.Symbol.IsCustomDataType <AlphaStreamsPortfolioState>()) { _rebalance = true; _targetsPerSymbolPerAlpha.Remove(security.Symbol); LastPortfolioPerAlpha.Remove(security.Symbol); } } foreach (var security in changes.AddedSecurities) { if (security.Symbol.IsCustomDataType <AlphaStreamsPortfolioState>()) { _rebalance = true; _targetsPerSymbolPerAlpha[security.Symbol] = new Dictionary <Symbol, PortfolioTarget>(); var lastState = security.Cache.GetData <AlphaStreamsPortfolioState>(); lastState ??= algorithm.GetLastKnownPrices(security).OfType <AlphaStreamsPortfolioState>().LastOrDefault(); if (lastState != null) { // keep the last state per alpha LastPortfolioPerAlpha[security.Symbol] = lastState; if (!algorithm.Portfolio.CashBook.ContainsKey(lastState.AccountCurrency)) { // ensure we have conversion rates if the alpha has another account currency algorithm.SetCash(lastState.AccountCurrency, 0); } } } } }