public void FlatUndoesAccumulation(Language language, InsightDirection direction) { SetPortfolioConstruction(language, _algorithm); // First emit long term insight var insights = new[] { GetInsight(Symbols.SPY, direction, _algorithm.UtcTime) }; var targets = _algorithm.PortfolioConstruction.CreateTargets(_algorithm, insights).ToList(); var expectedTargets = new List <IPortfolioTarget> { PortfolioTarget.Percent(_algorithm, Symbols.SPY, (int)direction * 1m * (decimal)DefaultPercent) }; AssertTargets(expectedTargets, targets); // One minute later, emits insight to add to portfolio SetUtcTime(_algorithm.UtcTime.AddMinutes(1)); insights = new[] { GetInsight(Symbols.SPY, direction, _algorithm.UtcTime) }; targets = _algorithm.PortfolioConstruction.CreateTargets(_algorithm, insights).ToList(); expectedTargets = new List <IPortfolioTarget> { PortfolioTarget.Percent(_algorithm, Symbols.SPY, (int)direction * 1m * 2 * (decimal)DefaultPercent) }; AssertTargets(expectedTargets, targets); // One minute later, emits flat insight SetUtcTime(_algorithm.UtcTime.AddMinutes(1)); insights = new[] { GetInsight(Symbols.SPY, InsightDirection.Flat, _algorithm.UtcTime) }; targets = _algorithm.PortfolioConstruction.CreateTargets(_algorithm, insights).ToList(); expectedTargets = new List <IPortfolioTarget> { PortfolioTarget.Percent(_algorithm, Symbols.SPY, (int)direction * 1m * (decimal)DefaultPercent) }; AssertTargets(expectedTargets, targets); }
public void PercentReturnsNullIfBuyingPowerModelError() { const decimal holdings = 50; const decimal targetPercent = 1m; var algorithm = PerformanceBenchmarkAlgorithms.SingleSecurity_Second; algorithm.Initialize(); algorithm.PostInitialize(); var security = algorithm.Securities.Single().Value; security.SetMarketPrice(new Tick { Value = 1m }); security.Holdings.SetHoldings(1m, holdings); var buyingPowerMock = new Mock <IBuyingPowerModel>(); buyingPowerMock.Setup(bpm => bpm.GetMaximumOrderQuantityForTargetValue(It.IsAny <GetMaximumOrderQuantityForTargetValueParameters>())) .Returns(new GetMaximumOrderQuantityForTargetValueResult(0, "The portfolio does not have enough margin available.")); security.BuyingPowerModel = buyingPowerMock.Object; var target = PortfolioTarget.Percent(algorithm, security.Symbol, targetPercent); Assert.IsNull(target); }
public void LongTermInsightPreservesPosition(Language language) { SetPortfolioConstruction(language, _algorithm); // First emit long term insight var insights = new[] { GetInsight(Symbols.SPY, InsightDirection.Down, _algorithm.UtcTime) }; var targets = _algorithm.PortfolioConstruction.CreateTargets(_algorithm, insights).ToList(); Assert.AreEqual(1, targets.Count); // One minute later, emits short term insight SetUtcTime(_algorithm.UtcTime.AddMinutes(1)); insights = new[] { GetInsight(Symbols.SPY, InsightDirection.Up, _algorithm.UtcTime, Time.OneMinute) }; targets = _algorithm.PortfolioConstruction.CreateTargets(_algorithm, insights).ToList(); Assert.AreEqual(1, targets.Count); // One minute later, emit empty insights array SetUtcTime(_algorithm.UtcTime.AddMinutes(1.1)); var expectedTargets = new List <IPortfolioTarget> { PortfolioTarget.Percent(_algorithm, Symbols.SPY, -1m * (decimal)Weight) }; // Create target from an empty insights array var actualTargets = _algorithm.PortfolioConstruction.CreateTargets(_algorithm, new Insight[0]); AssertTargets(expectedTargets, actualTargets); }
public void TwoViewsTest(Language language) { SetPortfolioConstruction(language); // Results from http://www.blacklitterman.org/code/hl_py.html (View 1+2) var expectedTargets = new[] { PortfolioTarget.Percent(_algorithm, GetSymbol("AUS"), 0.0152381), PortfolioTarget.Percent(_algorithm, GetSymbol("CAN"), 0.41863571), PortfolioTarget.Percent(_algorithm, GetSymbol("FRA"), -0.03409321), PortfolioTarget.Percent(_algorithm, GetSymbol("GER"), 0.33582847), PortfolioTarget.Percent(_algorithm, GetSymbol("JAP"), 0.11047619), PortfolioTarget.Percent(_algorithm, GetSymbol("UK"), -0.08173526), PortfolioTarget.Percent(_algorithm, GetSymbol("USA"), 0.18803095) }; var insights = _view1Insights.Concat(_view2Insights); var actualTargets = _algorithm.PortfolioConstruction.CreateTargets(_algorithm, insights.ToArray()); Assert.AreEqual(expectedTargets.Count(), actualTargets.Count()); foreach (var expected in expectedTargets) { var actual = actualTargets.FirstOrDefault(x => x.Symbol == expected.Symbol); Assert.IsNotNull(actual); Assert.AreEqual(expected.Quantity, actual.Quantity); } }
public void InsightExpirationUndoesAccumulation(Language language, InsightDirection direction) { SetPortfolioConstruction(language, _algorithm); // First emit long term insight SetUtcTime(_algorithm.Time); var insights = new[] { GetInsight(Symbols.SPY, direction, _algorithm.UtcTime, TimeSpan.FromMinutes(10)), GetInsight(Symbols.SPY, direction, _algorithm.UtcTime, TimeSpan.FromMinutes(10)) }; var targets = _algorithm.PortfolioConstruction.CreateTargets(_algorithm, insights).ToList(); var expectedTargets = new List <IPortfolioTarget> { PortfolioTarget.Percent(_algorithm, Symbols.SPY, (int)direction * 1m * 2 * (decimal)DefaultPercent) }; AssertTargets(expectedTargets, targets); // both insights should expire SetUtcTime(_algorithm.Time.AddMinutes(11)); targets = _algorithm.PortfolioConstruction.CreateTargets(_algorithm, new Insight[0]).ToList(); expectedTargets = new List <IPortfolioTarget> { PortfolioTarget.Percent(_algorithm, Symbols.SPY, 0) }; AssertTargets(expectedTargets, targets); // we expect no target targets = _algorithm.PortfolioConstruction.CreateTargets(_algorithm, new Insight[0]).ToList(); AssertTargets(new List <IPortfolioTarget>(), targets); }
public void PercentInvokesBuyingPowerModelAndAddsInExistingHoldings() { const decimal bpmQuantity = 100; const decimal holdings = 50; const decimal targetPercent = 0.5m; var algorithm = PerformanceBenchmarkAlgorithms.SingleSecurity_Second; algorithm.Initialize(); algorithm.PostInitialize(); var security = algorithm.Securities.Single().Value; security.SetMarketPrice(new Tick { Value = 1m }); security.Holdings.SetHoldings(1m, holdings); var buyingPowerMock = new Mock <IBuyingPowerModel>(); buyingPowerMock.Setup(bpm => bpm.GetMaximumOrderQuantityForTargetValue(algorithm.Portfolio, security, targetPercent)) .Returns(new GetMaximumOrderQuantityForTargetValueResult(bpmQuantity, null, false)); security.BuyingPowerModel = buyingPowerMock.Object; var target = PortfolioTarget.Percent(algorithm, security.Symbol, targetPercent); Assert.AreEqual(security.Symbol, target.Symbol); Assert.AreEqual(bpmQuantity + holdings, target.Quantity); }
public void OneViewTest(Language language) { SetPortfolioConstruction(language); // Results from http://www.blacklitterman.org/code/hl_py.html (View 1) var expectedTargets = new[] { PortfolioTarget.Percent(_algorithm, GetSymbol("AUS"), 0.0152381), PortfolioTarget.Percent(_algorithm, GetSymbol("CAN"), 0.02095238), PortfolioTarget.Percent(_algorithm, GetSymbol("FRA"), -0.03948465), PortfolioTarget.Percent(_algorithm, GetSymbol("GER"), 0.35410454), PortfolioTarget.Percent(_algorithm, GetSymbol("JAP"), 0.11047619), PortfolioTarget.Percent(_algorithm, GetSymbol("UK"), -0.09461989), PortfolioTarget.Percent(_algorithm, GetSymbol("USA"), 0.58571429) }; var actualTargets = _algorithm.PortfolioConstruction.CreateTargets(_algorithm, _view1Insights); Assert.AreEqual(expectedTargets.Count(), actualTargets.Count()); foreach (var expected in expectedTargets) { var actual = actualTargets.FirstOrDefault(x => x.Symbol == expected.Symbol); Assert.IsNotNull(actual); Assert.AreEqual(expected.Quantity, actual.Quantity); } }
public void PercentIgnoresExtremeValuesBasedOnSettings(double value, bool shouldBeNull) { var algorithm = PerformanceBenchmarkAlgorithms.SingleSecurity_Second; algorithm.Settings.MaxAbsolutePortfolioTargetPercentage = 2; algorithm.Settings.MinAbsolutePortfolioTargetPercentage = 0.1m; algorithm.Initialize(); algorithm.PostInitialize(); var security = algorithm.Securities.Single().Value; security.SetMarketPrice(new Tick { Value = 1m }); var buyingPowerMock = new Mock <IBuyingPowerModel>(); buyingPowerMock.Setup(bpm => bpm.GetMaximumOrderQuantityForTargetValue(It.IsAny <GetMaximumOrderQuantityForTargetValueParameters>())) .Returns(new GetMaximumOrderQuantityForTargetValueResult(1, null, false)); security.BuyingPowerModel = buyingPowerMock.Object; var target = PortfolioTarget.Percent(algorithm, security.Symbol, value); if (shouldBeNull) { Assert.IsNull(target); } else { Assert.IsNotNull(target); } }
public void LongTermInsightCanceledByNew(Language language) { SetPortfolioConstruction(language, _algorithm); // First emit long term insight var insights = new[] { GetInsight(Symbols.SPY, InsightDirection.Down, _algorithm.UtcTime) }; var targets = _algorithm.PortfolioConstruction.CreateTargets(_algorithm, insights).ToList(); var expectedTargets = new List <IPortfolioTarget> { PortfolioTarget.Percent(_algorithm, Symbols.SPY, -1m * (decimal)DefaultPercent) }; AssertTargets(expectedTargets, targets); // One minute later, emits short term insight to cancel long SetUtcTime(_algorithm.UtcTime.AddMinutes(1)); insights = new[] { GetInsight(Symbols.SPY, InsightDirection.Up, _algorithm.UtcTime, Time.OneMinute) }; targets = _algorithm.PortfolioConstruction.CreateTargets(_algorithm, insights).ToList(); expectedTargets = new List <IPortfolioTarget> { PortfolioTarget.Percent(_algorithm, Symbols.SPY, 0) }; AssertTargets(expectedTargets, targets); // One minute later, emit empty insights array, should stay 0 after the long expires SetUtcTime(_algorithm.UtcTime.AddMinutes(1.1)); expectedTargets = new List <IPortfolioTarget> { PortfolioTarget.Percent(_algorithm, Symbols.SPY, 0) }; // Create target from an empty insights array var actualTargets = _algorithm.PortfolioConstruction.CreateTargets(_algorithm, new Insight[0]); AssertTargets(expectedTargets, actualTargets); }
public void OrderByMarginImpactDoesNotReturnTargetsForWhichUnorderedQuantityIsZeroBecauseOpenOrder() { var algorithm = new FakeAlgorithm(); var orderProcessor = new FakeOrderProcessor(); algorithm.Transactions.SetOrderProcessor(orderProcessor); var symbol = new Symbol(SecurityIdentifier.GenerateEquity(_symbol, Market.USA), _symbol); var equity = algorithm.AddEquity(symbol); equity.Cache.AddData(new TradeBar(DateTime.UtcNow, symbol, 1, 1, 1, 1, 1)); var collection = new PortfolioTargetCollection(); var target = new PortfolioTarget(symbol, 1); collection.Add(target); var openOrderRequest = new SubmitOrderRequest(OrderType.Market, symbol.SecurityType, symbol, 1, 0, 0, DateTime.UtcNow, ""); openOrderRequest.SetOrderId(1); var openOrderTicket = new OrderTicket(algorithm.Transactions, openOrderRequest); orderProcessor.AddOrder(new MarketOrder(symbol, 1, DateTime.UtcNow)); orderProcessor.AddTicket(openOrderTicket); var targets = collection.OrderByMarginImpact(algorithm); Assert.AreEqual(collection.Count, 1); Assert.IsTrue(targets.IsNullOrEmpty()); }
/// <summary> /// Calculate the order quantity to achieve target-percent holdings. /// </summary> /// <param name="symbol">Security object we're asking for</param> /// <param name="target">Target percentage holdings, this is an unlevered value, so /// if you have 2x leverage and request 100% holdings, it will utilize half of the /// available margin</param> /// <returns>Order quantity to achieve this percentage</returns> public decimal CalculateOrderQuantity(Symbol symbol, decimal target) { var percent = PortfolioTarget.Percent(this, symbol, target, true); if (percent == null) { return 0; } return percent.Quantity; }
public void AddContainsAndRemoveWork() { var symbol = new Symbol(SecurityIdentifier.GenerateBase(_symbol, Market.USA), _symbol); var collection = new PortfolioTargetCollection(); var target = new PortfolioTarget(symbol, 1); collection.Add(target); Assert.AreEqual(collection.Count, 1); Assert.IsTrue(collection.Contains(target)); Assert.IsTrue(collection.Remove(target)); Assert.AreEqual(collection.Count, 0); }
public void RespectsRebalancingPeriod(Language language, InsightDirection direction) { PortfolioConstructionModel model = new AccumulativeInsightPortfolioConstructionModel(Resolution.Daily); if (language == Language.Python) { using (Py.GIL()) { var name = nameof(AccumulativeInsightPortfolioConstructionModel); dynamic instance = Py.Import(name).GetAttr(name); model = new PortfolioConstructionModelPythonWrapper(instance(Resolution.Daily)); } } model.RebalanceOnSecurityChanges = false; model.RebalanceOnInsightChanges = false; SetUtcTime(new DateTime(2018, 7, 31)); // First emit long term insight var insights = new[] { GetInsight(Symbols.SPY, direction, _algorithm.UtcTime, TimeSpan.FromDays(10)) }; AssertTargets(new List <IPortfolioTarget>(), model.CreateTargets(_algorithm, insights).ToList()); // One minute later, emits insight to add to portfolio SetUtcTime(_algorithm.Time.AddMinutes(1)); insights = new[] { GetInsight(Symbols.SPY, direction, _algorithm.UtcTime, TimeSpan.FromMinutes(10)) }; AssertTargets(new List <IPortfolioTarget>(), model.CreateTargets(_algorithm, insights)); // the second insight should expire SetUtcTime(_algorithm.Time.AddMinutes(1)); AssertTargets(new List <IPortfolioTarget>(), model.CreateTargets(_algorithm, insights)); // the rebalancing period is due and the first insight is still valid SetUtcTime(_algorithm.Time.AddDays(1)); var targets = model.CreateTargets(_algorithm, new Insight[0]); var expectedTargets = new List <IPortfolioTarget> { PortfolioTarget.Percent(_algorithm, Symbols.SPY, (int)direction * 1m * (decimal)DefaultPercent) }; AssertTargets(expectedTargets, targets); // the rebalancing period is due and no insight is valid SetUtcTime(_algorithm.Time.AddDays(10)); AssertTargets( new List <IPortfolioTarget> { PortfolioTarget.Percent(_algorithm, Symbols.SPY, 0) }, model.CreateTargets(_algorithm, new Insight[0])); AssertTargets(new List <IPortfolioTarget>(), model.CreateTargets(_algorithm, new Insight[0])); }
public override void Execute(QCAlgorithm algorithm, IPortfolioTarget[] targets) { var adjustedTargets = targets.ToList(); adjustedTargets.RemoveAll(x => algorithm.Portfolio.ContainsKey(x.Symbol) && algorithm.Portfolio[x.Symbol].Invested); adjustedTargets.AddRange(algorithm.ActiveSecurities .Where(x => algorithm.Portfolio.ContainsKey(x.Key) && algorithm.Portfolio[x.Key].Invested && !targets.Any(y => y.Symbol.Equals(x.Key))) .Select(x => PortfolioTarget.Percent(algorithm, x.Key, 0))); base.Execute(algorithm, adjustedTargets.ToArray()); }
public void ClearRemovesUnreachedTarget() { var algorithm = new FakeAlgorithm(); var symbol = new Symbol(SecurityIdentifier.GenerateEquity(_symbol, Market.USA), _symbol); var equity = algorithm.AddEquity(symbol); var dummySecurityHolding = new FakeSecurityHolding(equity); equity.Holdings = dummySecurityHolding; var collection = new PortfolioTargetCollection(); var target = new PortfolioTarget(symbol, -1); collection.Add(target); collection.Clear(); Assert.AreEqual(collection.Count, 0); }
public void OrderByMarginImpactDoesNotReturnTargetsWithNoData() { var algorithm = new FakeAlgorithm(); var symbol = new Symbol(SecurityIdentifier.GenerateEquity(_symbol, Market.USA), _symbol); algorithm.AddEquity(symbol); var collection = new PortfolioTargetCollection(); var target = new PortfolioTarget(symbol, -1); collection.Add(target); var targets = collection.OrderByMarginImpact(algorithm); Assert.AreEqual(collection.Count, 1); Assert.IsTrue(targets.IsNullOrEmpty()); }
public void ClearFulfilledRemovesPositiveTarget() { var algorithm = new FakeAlgorithm(); algorithm.SetFinishedWarmingUp(); var symbol = new Symbol(SecurityIdentifier.GenerateEquity(_symbol, Market.USA), _symbol); var equity = algorithm.AddEquity(symbol); var dummySecurityHolding = new FakeSecurityHolding(equity); equity.Holdings = dummySecurityHolding; var collection = new PortfolioTargetCollection(); var target = new PortfolioTarget(symbol, 1); collection.Add(target); dummySecurityHolding.SetQuantity(1); collection.ClearFulfilled(algorithm); Assert.AreEqual(collection.Count, 0); }
public void OrderByMarginImpactDoesNotReturnTargetsForWhichUnorderdQuantityIsZeroBecauseTargetIsZero() { var algorithm = new FakeAlgorithm(); algorithm.Transactions.SetOrderProcessor(new FakeOrderProcessor()); var symbol = new Symbol(SecurityIdentifier.GenerateEquity(_symbol, Market.USA), _symbol); var equity = algorithm.AddEquity(symbol); equity.Cache.AddData(new TradeBar(DateTime.UtcNow, symbol, 1, 1, 1, 1, 1)); var collection = new PortfolioTargetCollection(); var target = new PortfolioTarget(symbol, 0); collection.Add(target); var targets = collection.OrderByMarginImpact(algorithm); Assert.AreEqual(collection.Count, 1); Assert.IsTrue(targets.IsNullOrEmpty()); }
public void OrderByMarginImpactReturnsExpectedTargets() { var algorithm = new FakeAlgorithm(); algorithm.Transactions.SetOrderProcessor(new FakeOrderProcessor()); var symbol = new Symbol(SecurityIdentifier.GenerateEquity(_symbol, Market.USA), _symbol); var equity = algorithm.AddEquity(symbol); equity.Cache.AddData(new TradeBar(DateTime.UtcNow, symbol, 1, 1, 1, 1, 1)); var collection = new PortfolioTargetCollection(); var target = new PortfolioTarget(symbol, -1); collection.Add(target); var targets = collection.OrderByMarginImpact(algorithm); Assert.AreEqual(collection.Count, 1); Assert.AreEqual(targets.Count(), 1); Assert.AreEqual(targets.First(), target); }
public void PercentReturnsNullIfPriceIsZero() { const decimal holdings = 50; const decimal targetPercent = 1m; var algorithm = PerformanceBenchmarkAlgorithms.SingleSecurity_Second; algorithm.Initialize(); algorithm.PostInitialize(); var security = algorithm.Securities.Single().Value; security.SetMarketPrice(new Tick { Value = 0m }); security.Holdings.SetHoldings(1m, holdings); var target = PortfolioTarget.Percent(algorithm, security.Symbol, targetPercent); Assert.IsNull(target); }
private void Rebalance(Insight[] insights) { var shortCount = insights.Count(x => x.Direction == InsightDirection.Down); var longTargets = insights .Where(x => x.Direction == InsightDirection.Up) .Select(x => PortfolioTarget.Percent(this, x.Symbol, 1.0m / (_targetLongCount + shortCount))); var shortTargets = insights .Where(x => x.Direction == InsightDirection.Down) .Select(x => PortfolioTarget.Percent(this, x.Symbol, -1.0m / (NumLong + NumShort))); var targets = longTargets.Union(shortTargets); Plot("targetCounts", "longs", longTargets.Count()); Plot("targetCounts", "shorts", shortTargets.Count()); Plot("targetCounts", "active", ActiveSecurities.Count()); new SmartImmediateExecutionModel().Execute(this, targets.ToArray()); var targetsStr = targets.Any() ? string.Join(",", targets.Select(x => x.Symbol.Value).OrderBy(x => x)) : "nothing"; Log(targetsStr); SendEmailNotification($"We have positions in: {targetsStr}"); }
public override List <IPortfolioTarget> GetTargetsForSPY() { return(new List <IPortfolioTarget> { PortfolioTarget.Percent(Algorithm, Symbols.SPY, -_weight) }); }
public virtual List <IPortfolioTarget> GetTargetsForSPY() { return(new List <IPortfolioTarget> { PortfolioTarget.Percent(Algorithm, Symbols.SPY, -1m) }); }
public override IEnumerable <IPortfolioTarget> CreateTargets(QCAlgorithmFramework algorithm, Insight[] insights) { Insights = insights; return(insights.Select(insight => PortfolioTarget.Percent(algorithm, insight.Symbol, 0.01m))); }