Пример #1
0
 /// <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(QCAlgorithm algorithm, SecurityChanges changes)
 {
     base.OnSecuritiesChanged(algorithm, changes);
     // Get removed symbol and invalidate them in the insight collection
     _removedSymbols = changes.RemovedSecurities.Select(x => x.Symbol).ToList();
     InsightCollection.Clear(_removedSymbols.ToArray());
 }
        /// <summary>
        /// Determines the target percent for each insight
        /// </summary>
        /// <param name="activeInsights">The active insights to generate a target for</param>
        /// <returns>A target percent for each insight</returns>
        protected override Dictionary <Insight, double> DetermineTargetPercent(ICollection <Insight> activeInsights)
        {
            var percentPerSymbol = new Dictionary <Symbol, double>();

            foreach (var insight in InsightCollection.GetActiveInsights(_currentUtcTime)
                     .OrderBy(insight => insight.GeneratedTimeUtc))
            {
                double targetPercent;
                if (percentPerSymbol.TryGetValue(insight.Symbol, out targetPercent))
                {
                    if (insight.Direction == InsightDirection.Flat)
                    {
                        // We received a Flat
                        // if adding or subtracting will push past 0, then make it 0
                        if (Math.Abs(targetPercent) < _percent)
                        {
                            targetPercent = 0;
                        }
                        else
                        {
                            // otherwise, we flatten by percent
                            targetPercent += (targetPercent > 0 ? -_percent : _percent);
                        }
                    }
                }
                targetPercent += _percent * (int)insight.Direction;

                percentPerSymbol[insight.Symbol] = targetPercent;
            }

            return(activeInsights
                   .ToDictionary(insight => insight, insight => percentPerSymbol[insight.Symbol]));
        }
Пример #3
0
 /// <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 virtual void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
 {
     _securityChanges = changes != SecurityChanges.None;
     // Get removed symbol and invalidate them in the insight collection
     _removedSymbols = changes.RemovedSecurities.Select(x => x.Symbol).ToList();
     InsightCollection.Clear(_removedSymbols.ToArray());
 }
Пример #4
0
        /// <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(QCAlgorithm algorithm, SecurityChanges changes)
        {
            base.OnSecuritiesChanged(algorithm, 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);
            });
        }
Пример #5
0
        /// <summary>
        /// Gets the target insights to calculate a portfolio target percent for
        /// </summary>
        /// <returns>An enumerable of the target insights</returns>
        protected virtual List <Insight> GetTargetInsights()
        {
            // 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
            return((from insight in activeInsights
                    group insight by insight.Symbol into g
                    select g.OrderBy(x => x.GeneratedTimeUtc).Last()).ToList());
        }
Пример #6
0
        public static void InsightCollectionShouldBeAbleToBeConvertedToListWithoutStackOverflow()
        {
            var aapl = Symbol.Create("AAPL", SecurityType.Equity, "usa");
            var insightCollection = new InsightCollection();

            insightCollection.Add(new Insight(aapl, new TimeSpan(1, 0, 0, 0), InsightType.Price, InsightDirection.Up)
            {
                CloseTimeUtc = new DateTime(2019, 1, 1),
            });
            insightCollection.Add(new Insight(aapl, new TimeSpan(1, 0, 0, 0), InsightType.Volatility, InsightDirection.Up)
            {
                CloseTimeUtc = new DateTime(2019, 1, 2),
            });

            Assert.DoesNotThrow(() => insightCollection.OrderBy(x => x.CloseTimeUtc).ToList());
        }
Пример #7
0
        /// <summary>
        /// Determines if the portfolio should be rebalanced base on the provided rebalancing func,
        /// if any security change have been taken place or if an insight has expired or a new insight arrived
        /// If the rebalancing function has not been provided will return true.
        /// </summary>
        /// <param name="insights">The insights to create portfolio targets from</param>
        /// <param name="algorithmUtc">The current algorithm UTC time</param>
        /// <returns>True if should rebalance</returns>
        protected virtual bool IsRebalanceDue(Insight[] insights, DateTime algorithmUtc)
        {
            // if there is no rebalance func set, just return true but refresh state
            // just in case the rebalance func is going to be set.
            if (_rebalancingFunc == null)
            {
                RefreshRebalance(algorithmUtc);
                return(true);
            }

            // we always get the next expiry time
            // we don't know if a new insight was added or removed
            var nextInsightExpiryTime = InsightCollection.GetNextExpiryTime();

            if (_rebalancingTime == null)
            {
                _rebalancingTime = _rebalancingFunc(algorithmUtc);

                if (_rebalancingTime != null && _rebalancingTime <= algorithmUtc)
                {
                    // if the rebalancing time stopped being null and is current time
                    // we will ask for the next rebalance time in the next loop.
                    // we don't want to call the '_rebalancingFunc' twice in the same loop,
                    // since its internal state machine will probably be in the same state.
                    _rebalancingTime = null;
                    _securityChanges = false;
                    return(true);
                }
            }

            if (_rebalancingTime != null && _rebalancingTime <= algorithmUtc ||
                RebalanceOnSecurityChanges && _securityChanges ||
                RebalanceOnInsightChanges &&
                (insights.Length != 0 ||
                 nextInsightExpiryTime != null && nextInsightExpiryTime < algorithmUtc))
            {
                RefreshRebalance(algorithmUtc);
                return(true);
            }

            return(false);
        }
Пример #8
0
        /// <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 unless RebalanceOnSecurityChanges is False
            if (_removedSymbols != null)
            {
Пример #9
0
 public void SetNextExpiration(DateTime nextExpiration)
 {
     InsightCollection.Add(
         new Insight(Symbols.SPY, time => nextExpiration, InsightType.Price, InsightDirection.Down));
 }
Пример #10
0
        /// <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);
        }
Пример #11
0
 /// <summary>
 /// Initialize a new instance of <see cref="PortfolioConstructionModel"/>
 /// </summary>
 /// <param name="rebalancingFunc">For a given algorithm UTC DateTime returns the next expected rebalance time
 /// or null if unknown, in which case the function will be called again in the next loop. Returning current time
 /// will trigger rebalance. If null will be ignored</param>
 public PortfolioConstructionModel(Func <DateTime, DateTime?> rebalancingFunc)
 {
     _rebalancingFunc  = rebalancingFunc;
     InsightCollection = new InsightCollection();
 }
Пример #12
0
        /// <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);
        }
Пример #13
0
        /// <summary>
        /// Steps the manager forward in time, accepting new state information and potentialy newly generated insights
        /// </summary>
        /// <param name="frontierTimeUtc">The frontier time of the insight analysis</param>
        /// <param name="securityValuesCollection">Snap shot of the securities at the frontier time</param>
        /// <param name="generatedInsights">Any insight generated by the algorithm at the frontier time</param>
        public void Step(DateTime frontierTimeUtc, ReadOnlySecurityValuesCollection securityValuesCollection, InsightCollection generatedInsights)
        {
            if (generatedInsights != null && generatedInsights.Insights.Count > 0)
            {
                foreach (var insight in generatedInsights.Insights)
                {
                    // save initial security values and deterine analysis period
                    var initialValues  = securityValuesCollection[insight.Symbol];
                    var analysisPeriod = insight.Period + TimeSpan.FromTicks((long)(_extraAnalysisPeriodRatio * insight.Period.Ticks));

                    // set this as an open analysis context
                    var context = new InsightAnalysisContext(insight, initialValues, analysisPeriod);
                    _openInsightContexts.Add(context);

                    // let everyone know we've received an insight
                    _extensions.ForEach(e => e.OnInsightGenerated(context));
                }
            }

            UpdateScores(securityValuesCollection);

            foreach (var extension in _extensions)
            {
                extension.Step(frontierTimeUtc);
            }
        }
 /// <summary>
 /// Gets the target insights to calculate a portfolio target percent for
 /// </summary>
 /// <returns>An enumerable of the target insights</returns>
 protected override List <Insight> GetTargetInsights()
 {
     return(InsightCollection.GetActiveInsights(Algorithm.UtcTime)
            .OrderBy(insight => insight.GeneratedTimeUtc)
            .ToList());
 }
Пример #15
0
        /// <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)
            {
                insights = FilterInvalidInsightMagnitude(algorithm, insights);
                InsightCollection.AddRange(insights);
            }

            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 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);

            return(targets);
        }
Пример #16
0
 public InsightQueueItem(DateTime frontierTimeUtc, ReadOnlySecurityValuesCollection securityValues, InsightCollection generatedInsights = null)
 {
     FrontierTimeUtc   = frontierTimeUtc;
     SecurityValues    = securityValues;
     GeneratedInsights = generatedInsights ?? new InsightCollection(frontierTimeUtc, Enumerable.Empty <Insight>());
 }
Пример #17
0
        public static void InsightCollectionCopyTo()
        {
            var aapl = Symbol.Create("AAPL", SecurityType.Equity, "usa");
            var insightCollection = new InsightCollection();

            insightCollection.Add(new Insight(aapl, new TimeSpan(1, 0, 0, 0), InsightType.Price, InsightDirection.Up)
            {
                GeneratedTimeUtc = new DateTime(2019, 1, 1),
                CloseTimeUtc     = new DateTime(2019, 1, 1),
            });
            insightCollection.Add(new Insight(aapl, new TimeSpan(1, 0, 0, 0), InsightType.Volatility, InsightDirection.Up)
            {
                GeneratedTimeUtc = new DateTime(2019, 1, 2),
                CloseTimeUtc     = new DateTime(2019, 1, 2),
            });

            var insights = new Insight[7] {
                new Insight(aapl, new TimeSpan(1, 0, 0, 0), InsightType.Price, InsightDirection.Up)
                {
                    GeneratedTimeUtc = new DateTime(2019, 1, 5),
                    CloseTimeUtc     = new DateTime(2019, 1, 5),
                },
                new Insight(aapl, new TimeSpan(1, 0, 0, 0), InsightType.Price, InsightDirection.Flat)
                {
                    GeneratedTimeUtc = new DateTime(2019, 1, 6),
                    CloseTimeUtc     = new DateTime(2019, 1, 6),
                },
                new Insight(aapl, new TimeSpan(1, 0, 0, 0), InsightType.Price, InsightDirection.Down)
                {
                    GeneratedTimeUtc = new DateTime(2019, 1, 7),
                    CloseTimeUtc     = new DateTime(2019, 1, 7),
                },
                new Insight(aapl, new TimeSpan(1, 0, 0, 0), InsightType.Volatility, InsightDirection.Up)
                {
                    GeneratedTimeUtc = new DateTime(2019, 1, 8),
                    CloseTimeUtc     = new DateTime(2019, 1, 8),
                },
                new Insight(aapl, new TimeSpan(1, 0, 0, 0), InsightType.Volatility, InsightDirection.Down)
                {
                    GeneratedTimeUtc = new DateTime(2019, 1, 9),
                    CloseTimeUtc     = new DateTime(2019, 1, 9),
                },
                null,
                null
            };

            insightCollection.CopyTo(insights, 5);

            var orderedInsights   = insights.OrderBy(x => x.CloseTimeUtc).ToList();
            var orderedInsightsDe = JsonConvert.DeserializeObject <InsightCollection>(_expectedResultCopyTo);

            var equals = orderedInsights.Zip(orderedInsightsDe, (i, de) =>
            {
                return(i.CloseTimeUtc == de.CloseTimeUtc &&
                       i.GeneratedTimeUtc == de.GeneratedTimeUtc &&
                       i.Symbol.Value == de.Symbol.Value &&
                       i.Type == de.Type &&
                       i.ReferenceValue == de.ReferenceValue &&
                       i.Direction == de.Direction &&
                       i.Period == de.Period);
            });

            Assert.IsTrue(equals.All((x) => x));
        }