/// <summary> /// Create portfolio targets from the specified insights /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="insights">The insights to create portoflio targets from</param> /// <returns>An enumerable of portoflio targets to be sent to the execution model</returns> public virtual IEnumerable <IPortfolioTarget> CreateTargets(QCAlgorithmFramework algorithm, Insight[] insights) { var targets = new List <IPortfolioTarget>(); if (_removedSymbols != null) { // zero out securities removes from the universe targets.AddRange(_removedSymbols.Select(s => new PortfolioTarget(s, 0))); _removedSymbols = null; } if (_securities.Count == 0) { return(Enumerable.Empty <IPortfolioTarget>()); } // give equal weighting to each security var percent = 1m / _securities.Count; foreach (var insight in insights) { targets.Add(PortfolioTarget.Percent(algorithm, insight.Symbol, (int)insight.Direction * percent)); } return(targets); }
/// <summary> /// Create portfolio targets from the specified insights /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="insights">The insights to create portoflio targets from</param> /// <returns>An enumerable of portoflio targets to be sent to the execution model</returns> public override IEnumerable <IPortfolioTarget> CreateTargets(QCAlgorithmFramework algorithm, Insight[] insights) { var targets = new List <IPortfolioTarget>(); if (algorithm.UtcTime <= _nextExpiryTime && algorithm.UtcTime <= _rebalancingTime && insights.Length == 0 && _removedSymbols == null) { return(targets); } _insightCollection.AddRange(insights); // Create flatten target for each security that was removed from the universe if (_removedSymbols != null) { var universeDeselectionTargets = _removedSymbols.Select(symbol => new PortfolioTarget(symbol, 0)); targets.AddRange(universeDeselectionTargets); _removedSymbols = null; } // Get insight that haven't expired of each symbol that is still in the universe var activeInsights = _insightCollection.GetActiveInsights(algorithm.UtcTime); // Get the last generated active insight for each symbol var lastActiveInsights = from insight in activeInsights group insight by insight.Symbol into g select g.OrderBy(x => x.GeneratedTimeUtc).Last(); // give equal weighting to each security var count = lastActiveInsights.Count(x => x.Direction != InsightDirection.Flat); var percent = count == 0 ? 0 : 1m / count; foreach (var insight in lastActiveInsights) { targets.Add(PortfolioTarget.Percent(algorithm, insight.Symbol, (int)insight.Direction * percent)); } // Get expired insights and create flatten targets for each symbol var expiredInsights = _insightCollection.RemoveExpiredInsights(algorithm.UtcTime); var expiredTargets = from insight in expiredInsights group insight.Symbol by insight.Symbol into g where !_insightCollection.HasActiveInsights(g.Key, algorithm.UtcTime) select new PortfolioTarget(g.Key, 0); targets.AddRange(expiredTargets); _nextExpiryTime = _insightCollection.GetNextExpiryTime(); _rebalancingTime = algorithm.UtcTime.Add(_rebalancingPeriod); return(targets); }
/// <summary> /// Create portfolio targets from the specified alphas /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="alphas">The alphas to create portoflio targets from</param> /// <returns>An enumerable of portoflio targets to be sent to the execution model</returns> public IEnumerable <IPortfolioTarget> CreateTargets(QCAlgorithmFramework algorithm, List <Alpha> alphas) { if (_securities.Count == 0) { return(Enumerable.Empty <IPortfolioTarget>()); } // give equal weighting to each security var percent = 1m / _securities.Count; return(alphas.Select(alpha => PortfolioTarget.Percent(algorithm, alpha.Symbol, (int)alpha.Direction * percent) )); }
/// <summary> /// Create portfolio targets from the specified insights /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="insights">The insights to create portoflio targets from</param> /// <returns>An enumerable of portoflio targets to be sent to the execution model</returns> public override IEnumerable <IPortfolioTarget> CreateTargets(QCAlgorithmFramework algorithm, Insight[] insights) { _insightCollection.AddRange(insights); var targets = new List <IPortfolioTarget>(); if (_removedSymbols != null) { // zero out securities removes from the universe targets.AddRange(_removedSymbols.Select(s => new PortfolioTarget(s, 0))); _removedSymbols = null; } if (insights.Length == 0) { return(targets); } // Get last insight that haven't expired of each symbol that is still in the universe var activeInsights = (from insight in _insightCollection // Remove expired insights where insight.CloseTimeUtc > algorithm.UtcTime // Force one group per symbol group insight by insight.Symbol into g // For direction, we'll trust the most recent insight select g.OrderBy(x => x.GeneratedTimeUtc).LastOrDefault()) .ToList(); if (activeInsights.Count == 0) { return(targets); } // give equal weighting to each security var count = activeInsights.Count(x => x.Direction != InsightDirection.Flat); var percent = count == 0 ? 0 : 1m / count; foreach (var insight in activeInsights) { targets.Add(PortfolioTarget.Percent(algorithm, insight.Symbol, (int)insight.Direction * percent)); } // add targets to remove invested securities targets.AddRange(from kvp in algorithm.Portfolio where kvp.Value.Invested where targets.All(x => kvp.Key != x.Symbol) select new PortfolioTarget(kvp.Key, 0)); return(targets); }
/// <summary> /// Create portfolio targets from the specified insights /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="insights">The insights to create portoflio targets from</param> /// <returns>An enumerable of portoflio targets to be sent to the execution model</returns> public override IEnumerable <IPortfolioTarget> CreateTargets(QCAlgorithmFramework algorithm, Insight[] insights) { _insightCollection.AddRange(insights); var targets = new List <IPortfolioTarget>(); if (_removedSymbols != null) { // zero out securities removes from the universe targets.AddRange(_removedSymbols.Select(s => new PortfolioTarget(s, 0))); _removedSymbols = null; } if (insights.Length == 0) { return(targets); } // Get symbols that have emit insights, are still in the universe, and insigths haven't expired var symbols = _insightCollection .Where(x => x.CloseTimeUtc > algorithm.UtcTime) .Select(x => x.Symbol).Distinct().ToList(); if (symbols.Count == 0) { return(targets); } // give equal weighting to each security var percent = 1m / symbols.Count; foreach (var symbol in symbols) { List <Insight> activeInsights; if (_insightCollection.TryGetValue(symbol, out activeInsights)) { var direction = activeInsights.Last().Direction; targets.Add(PortfolioTarget.Percent(algorithm, symbol, (int)direction * percent)); } } return(targets); }
private bool ProcessPortfolioState(AlphaStreamsPortfolioState portfolioState, QCAlgorithm algorithm) { var alphaId = portfolioState.Symbol; if (!_targetsPerSymbolPerAlpha.TryGetValue(alphaId, out var ourExistingTargets)) { _targetsPerSymbolPerAlpha[alphaId] = ourExistingTargets = new Dictionary <Symbol, PortfolioTarget>(); } var totalUsablePortfolioValue = algorithm.Portfolio.TotalPortfolioValue - algorithm.Settings.FreePortfolioValue; var alphaWeightFactor = GetAlphaWeight(portfolioState, totalUsablePortfolioValue, algorithm.Portfolio.CashBook); // first we create all the new aggregated targets for the provided portfolio state var newTargets = new Dictionary <Symbol, PortfolioTarget>(); foreach (var positionGroup in portfolioState.PositionGroups ?? Enumerable.Empty <PositionGroupState>()) { foreach (var position in positionGroup.Positions) { // let's keep the unit quantity so we can round by it _unitQuantity[position.Symbol] = position.UnitQuantity; newTargets.TryGetValue(position.Symbol, out var existingAggregatedTarget); var quantity = position.Quantity * alphaWeightFactor + (existingAggregatedTarget?.Quantity ?? 0); newTargets[position.Symbol] = new PortfolioTarget(position.Symbol, quantity.DiscretelyRoundBy(position.UnitQuantity, MidpointRounding.ToZero)); } } var updatedTargets = false; // We adjust the new targets based on what we already have: // - We add any existing targets if any -> other alphas // - But we deduct our own existing target from it if any (previous state) foreach (var ourNewTarget in newTargets.Values) { var symbol = ourNewTarget.Symbol; var newAggregatedTarget = ourNewTarget; if (_targetsPerSymbol.TryGetValue(symbol, out var existingAggregatedTarget)) { ourExistingTargets.TryGetValue(symbol, out var ourExistingTarget); var quantity = existingAggregatedTarget.Quantity + ourNewTarget.Quantity - (ourExistingTarget?.Quantity ?? 0); newAggregatedTarget = new PortfolioTarget(symbol, quantity.DiscretelyRoundBy(_unitQuantity[symbol], MidpointRounding.ToZero)); } ourExistingTargets[symbol] = ourNewTarget; if (existingAggregatedTarget == null || existingAggregatedTarget.Quantity != newAggregatedTarget.Quantity) { updatedTargets = true; _targetsPerSymbol[symbol] = newAggregatedTarget; } } List <Symbol> symbolsToRemove = null; // We adjust existing targets for symbols that got removed from this alpha foreach (var removedTarget in ourExistingTargets.Values.Where(target => !newTargets.ContainsKey(target.Symbol))) { var symbol = removedTarget.Symbol; var newAggregatedTarget = removedTarget; if (_targetsPerSymbol.TryGetValue(symbol, out var existingAggregatedTarget)) { var quantity = existingAggregatedTarget.Quantity - removedTarget.Quantity; newAggregatedTarget = new PortfolioTarget(symbol, quantity.DiscretelyRoundBy(_unitQuantity[symbol], MidpointRounding.ToZero)); } symbolsToRemove ??= new List <Symbol>(); symbolsToRemove.Add(symbol); if (existingAggregatedTarget == null || existingAggregatedTarget.Quantity != newAggregatedTarget.Quantity) { updatedTargets = true; _targetsPerSymbol[symbol] = newAggregatedTarget; } } if (symbolsToRemove != null) { for (var i = 0; i < symbolsToRemove.Count; i++) { // we can't remove from dictionary while iterating through it ourExistingTargets.Remove(symbolsToRemove[i]); } } return(updatedTargets); }
/// <summary> /// Create portfolio targets from the specified insights /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="insights">The insights to create portoflio targets from</param> /// <returns>An enumerable of portoflio targets to be sent to the execution model</returns> public override IEnumerable <IPortfolioTarget> CreateTargets(QCAlgorithmFramework algorithm, Insight[] insights) { var targets = new List <IPortfolioTarget>(); // remove pending foreach (var symbol in _pendingRemoval) { targets.Add(new PortfolioTarget(symbol, 0)); } _pendingRemoval.Clear(); var symbols = insights.Select(x => x.Symbol).Distinct(); if (symbols.Count() == 0 || insights.All(x => x.Magnitude == 0)) { return(targets); } // Get symbols' returns var returns = _symbolDataDict.FormReturnsMatrix(symbols); // Calculate equilibrium returns double[] Π; double[,] Σ; GetEquilibriumReturns(returns, out Π, out Σ); // Calculate implied equilibrium returns double[,] P; double[] Q; if (TryGetViews(insights, out P, out Q)) { // Create the diagonal covariance matrix of error terms from the expressed views var Ω = P.Dot(Σ).DotWithTransposed(P).Multiply(_tau); double[,] matrix = Matrix.Diagonal(P.Dot(Σ).DotWithTransposed(P).Multiply(_tau).Diagonal()); if (Ω.Determinant() != 0) { var invCov = Σ.Multiply(_tau).Inverse(); var PTomega = P.TransposeAndDot(Ω.Inverse()); var A = invCov.Add(PTomega.Dot(P)); var B = invCov.Dot(Π).Add(PTomega.Dot(Q)); Π = A.Inverse().Dot(B); } } // The optimization method processes the data frame var W = _optimizer.Optimize(returns, expectedReturns: Π); // Create portfolio targets from the specified insights if (W.Length > 0) { int sidx = 0; foreach (var symbol in symbols) { var weight = (decimal)W[sidx]; targets.Add(PortfolioTarget.Percent(algorithm, symbol, weight)); sidx++; } } return(targets); }
/// <summary> /// Create portfolio targets from the specified insights /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="insights">The insights to create portfolio targets from</param> /// <returns>An enumerable of portfolio targets to be sent to the execution model</returns> public override IEnumerable <IPortfolioTarget> CreateTargets(QCAlgorithm algorithm, Insight[] insights) { var targets = new List <IPortfolioTarget>(); // remove pending foreach (var symbol in _pendingRemoval) { targets.Add(new PortfolioTarget(symbol, 0)); } _pendingRemoval.Clear(); insights = FilterInvalidInsightMagnitude(algorithm, insights); var symbols = insights.Select(x => x.Symbol).Distinct(); if (symbols.Count() == 0 || insights.All(x => x.Magnitude == 0)) { return(targets); } foreach (var insight in insights) { ReturnsSymbolData data; if (_symbolDataDict.TryGetValue(insight.Symbol, out data)) { if (!insight.Magnitude.HasValue) { algorithm.SetRunTimeError( new ArgumentNullException( insight.Symbol.Value, "MeanVarianceOptimizationPortfolioConstructionModel does not accept 'null' as Insight.Magnitude. " + "Please checkout the selected Alpha Model specifications: " + insight.SourceModel)); continue; } data.Add(algorithm.Time, insight.Magnitude.Value.SafeDecimalCast()); } } // Get symbols' returns var returns = _symbolDataDict.FormReturnsMatrix(symbols); // Calculate rate of returns var rreturns = returns.Apply(e => Math.Pow(1.0 + e, 252.0) - 1.0); // Calculate geometric mean of rate of returns var gmean = Enumerable.Range(0, rreturns.GetLength(1)) .Select(i => rreturns.GetColumn(i)) .Select(c => Math.Pow(Elementwise.Add(c, 1.0).Product(), 1.0 / c.Length) - 1.0) .ToArray(); // The optimization method processes the data frame var W = _optimizer.Optimize(rreturns); //, gmean); // process results if (W.Length > 0) { int sidx = 0; foreach (var symbol in symbols) { var weight = W[sidx].SafeDecimalCast(); var target = PortfolioTarget.Percent(algorithm, symbol, weight); if (target != null) { targets.Add(target); } sidx++; } } return(targets); }
/// <summary> /// Create portfolio targets from the specified insights /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="insights">The insights to create portfolio targets from</param> /// <returns>An enumerable of portfolio targets to be sent to the execution model</returns> public override IEnumerable <IPortfolioTarget> CreateTargets(QCAlgorithm algorithm, Insight[] insights) { // always add new insights if (insights.Length > 0) { // Validate we should create a target for this insight InsightCollection.AddRange(insights.Where(ShouldCreateTargetForInsight)); } if (!IsRebalanceDue(insights, algorithm.UtcTime)) { return(Enumerable.Empty <IPortfolioTarget>()); } var targets = new List <IPortfolioTarget>(); // Create flatten target for each security that was removed from the universe if (_removedSymbols != null) { var universeDeselectionTargets = _removedSymbols.Select(symbol => new PortfolioTarget(symbol, 0)); targets.AddRange(universeDeselectionTargets); _removedSymbols = null; } // Get insight that haven't expired of each symbol that is still in the universe var activeInsights = InsightCollection.GetActiveInsights(algorithm.UtcTime); // Get the last generated active insight for each symbol var lastActiveInsights = (from insight in activeInsights group insight by insight.Symbol into g select g.OrderBy(x => x.GeneratedTimeUtc).Last()).ToList(); var errorSymbols = new HashSet <Symbol>(); // Determine target percent for the given insights var percents = DetermineTargetPercent(lastActiveInsights); foreach (var insight in lastActiveInsights) { var target = PortfolioTarget.Percent(algorithm, insight.Symbol, percents[insight]); if (target != null) { targets.Add(target); } else { errorSymbols.Add(insight.Symbol); } } // Get expired insights and create flatten targets for each symbol var expiredInsights = InsightCollection.RemoveExpiredInsights(algorithm.UtcTime); var expiredTargets = from insight in expiredInsights group insight.Symbol by insight.Symbol into g where !InsightCollection.HasActiveInsights(g.Key, algorithm.UtcTime) && !errorSymbols.Contains(g.Key) select new PortfolioTarget(g.Key, 0); targets.AddRange(expiredTargets); return(targets); }
/// <summary> /// Create portfolio targets from the specified insights /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="insights">The insights to create portfolio targets from</param> /// <returns>An enumerable of portfolio targets to be sent to the execution model</returns> public virtual IEnumerable <IPortfolioTarget> CreateTargets(QCAlgorithm algorithm, Insight[] insights) { Algorithm = algorithm; // always add new insights if (insights.Length > 0) { // Validate we should create a target for this insight InsightCollection.AddRange(insights .Where(insight => PythonWrapper?.ShouldCreateTargetForInsight(insight) ?? ShouldCreateTargetForInsight(insight))); } if (!(PythonWrapper?.IsRebalanceDue(insights, algorithm.UtcTime) ?? IsRebalanceDue(insights, algorithm.UtcTime))) { return(Enumerable.Empty <IPortfolioTarget>()); } var targets = new List <IPortfolioTarget>(); // Create flatten target for each security that was removed from the universe if (_removedSymbols != null) { var universeDeselectionTargets = _removedSymbols.Select(symbol => new PortfolioTarget(symbol, 0)); targets.AddRange(universeDeselectionTargets); _removedSymbols = null; } var lastActiveInsights = PythonWrapper?.GetTargetInsights() ?? GetTargetInsights(); var errorSymbols = new HashSet <Symbol>(); // Determine target percent for the given insights var percents = PythonWrapper?.DetermineTargetPercent(lastActiveInsights) ?? DetermineTargetPercent(lastActiveInsights); foreach (var insight in lastActiveInsights) { double percent; if (!percents.TryGetValue(insight, out percent)) { continue; } var target = PortfolioTarget.Percent(algorithm, insight.Symbol, percent); if (target != null) { targets.Add(target); } else { errorSymbols.Add(insight.Symbol); } } // Get expired insights and create flatten targets for each symbol var expiredInsights = InsightCollection.RemoveExpiredInsights(algorithm.UtcTime); var expiredTargets = from insight in expiredInsights group insight.Symbol by insight.Symbol into g where !InsightCollection.HasActiveInsights(g.Key, algorithm.UtcTime) && !errorSymbols.Contains(g.Key) select new PortfolioTarget(g.Key, 0); targets.AddRange(expiredTargets); return(targets); }
/// <summary> /// Create portfolio targets from the specified insights /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="insights">The insights to create portfolio targets from</param> /// <returns>An enumerable of portfolio targets to be sent to the execution model</returns> public override IEnumerable <IPortfolioTarget> CreateTargets(QCAlgorithm algorithm, Insight[] insights) { var targets = new List <IPortfolioTarget>(); if (algorithm.UtcTime <= _nextExpiryTime && algorithm.UtcTime <= _rebalancingTime && insights.Length == 0 && _removedSymbols == null) { return(targets); } insights = FilterInvalidInsightMagnitude(algorithm, insights); _insightCollection.AddRange(insights); // Create flatten target for each security that was removed from the universe if (_removedSymbols != null) { var universeDeselectionTargets = _removedSymbols.Select(symbol => new PortfolioTarget(symbol, 0)); targets.AddRange(universeDeselectionTargets); _removedSymbols = null; } // Get insight that haven't expired of each symbol that is still in the universe var activeInsights = _insightCollection.GetActiveInsights(algorithm.UtcTime); // Get the last generated active insight for each symbol var lastActiveInsights = (from insight in activeInsights group insight by new { insight.Symbol, insight.SourceModel } into g select g.OrderBy(x => x.GeneratedTimeUtc).Last()) .OrderBy(x => x.Symbol).ToArray(); double[,] P; double[] Q; if (TryGetViews(lastActiveInsights, out P, out Q)) { // Updates the ReturnsSymbolData with insights foreach (var insight in lastActiveInsights) { ReturnsSymbolData symbolData; if (_symbolDataDict.TryGetValue(insight.Symbol, out symbolData)) { if (insight.Magnitude == null) { algorithm.SetRunTimeError(new ArgumentNullException("BlackLittermanOptimizationPortfolioConstructionModel does not accept \'null\' as Insight.Magnitude. Please make sure your Alpha Model is generating Insights with the Magnitude property set.")); } symbolData.Add(algorithm.Time, insight.Magnitude.Value.SafeDecimalCast()); } } // Get symbols' returns var symbols = lastActiveInsights.Select(x => x.Symbol).Distinct().ToList(); var returns = _symbolDataDict.FormReturnsMatrix(symbols); // Calculate posterior estimate of the mean and uncertainty in the mean double[,] Σ; var Π = GetEquilibriumReturns(returns, out Σ); ApplyBlackLittermanMasterFormula(ref Π, ref Σ, P, Q); // Create portfolio targets from the specified insights var W = _optimizer.Optimize(returns, Π, Σ); var sidx = 0; foreach (var symbol in symbols) { var weight = W[sidx].SafeDecimalCast(); var target = PortfolioTarget.Percent(algorithm, symbol, weight); if (target != null) { targets.Add(target); } sidx++; } } // Get expired insights and create flatten targets for each symbol var expiredInsights = _insightCollection.RemoveExpiredInsights(algorithm.UtcTime); var expiredTargets = from insight in expiredInsights group insight.Symbol by insight.Symbol into g where !_insightCollection.HasActiveInsights(g.Key, algorithm.UtcTime) select new PortfolioTarget(g.Key, 0); targets.AddRange(expiredTargets); _nextExpiryTime = _insightCollection.GetNextExpiryTime(); _rebalancingTime = algorithm.UtcTime.Add(_rebalancingPeriod); return(targets); }
/// <summary> /// Create portfolio targets from the specified insights /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="insights">The insights to create portfolio targets from</param> /// <returns>An enumerable of portfolio targets to be sent to the execution model</returns> public override IEnumerable <IPortfolioTarget> CreateTargets(QCAlgorithm algorithm, Insight[] insights) { if (algorithm.UtcTime <= _nextExpiryTime && insights.Length == 0 && _removedSymbols == null) { yield break; } // Validate we should create a target for this insight _insightCollection.AddRange(insights.Where(ShouldCreateTargetForInsight)); // Create flatten target for each security that was removed from the universe foreach (var target in _removedSymbols.Select(symbol => new PortfolioTarget(symbol, 0))) { yield return(target); } // Get insight that haven't expired of each symbol that is still in the universe var activeInsights = _insightCollection.GetActiveInsights(algorithm.UtcTime); // Get the last generated active insight for each symbol var lastActiveInsights = (from insight in activeInsights group insight by insight.Symbol into g select g.OrderBy(x => x.GeneratedTimeUtc).Last()).ToList(); var errorSymbols = new HashSet <Symbol>(); // Determine target percent for the given insights var percents = DetermineTargetPercent(lastActiveInsights); foreach (var insight in percents.Keys) { var target = PortfolioTarget.Percent(algorithm, insight.Symbol, percents[insight]); if (target != null) { yield return(target); } else { errorSymbols.Add(insight.Symbol); } } // Get expired insights and create flatten targets for each symbol var expiredInsights = _insightCollection.RemoveExpiredInsights(algorithm.UtcTime); percents = UpdateExpiredInsights(expiredInsights); foreach (var insight in percents.Keys) { var target = PortfolioTarget.Percent(algorithm, insight.Symbol, percents[insight]); if (target != null) { yield return(target); } else { errorSymbols.Add(insight.Symbol); } } _nextExpiryTime = _insightCollection.GetNextExpiryTime(); }