public void ReducesPositionWhenMarginAboveTargetBasedOnSetting(decimal holdings, decimal minimumOrderMarginPortfolioPercentage) { var algorithm = GetAlgorithm(); var security = InitAndGetSecurity(algorithm, 0); var model = new SecurityMarginModel(); security.Holdings.SetHoldings(security.Price, holdings); var currentSignedUsedMargin = model.GetInitialMarginRequirement(security, security.Holdings.Quantity); var totalPortfolioValue = algorithm.Portfolio.TotalPortfolioValue; var sign = Math.Sign(security.Holdings.Quantity) == 0 ? 1 : Math.Sign(security.Holdings.Quantity); // we inverse the sign here so that new target is less than current, we expect a reduction var newTarget = currentSignedUsedMargin / (totalPortfolioValue) + 0.00001m * sign * -1; var result = model.GetMaximumOrderQuantityForTargetBuyingPower(algorithm.Portfolio, security, newTarget, minimumOrderMarginPortfolioPercentage); if (minimumOrderMarginPortfolioPercentage == 0) { // Reproduces GH issue #5763 a small Reduction in the target should reduce the position Assert.AreEqual(1m * sign * -1, result.Quantity); Assert.IsFalse(result.IsError); } else { Assert.AreEqual(0, result.Quantity); Assert.IsFalse(result.IsError); } }
public void ReducesPositionWhenMarginAboveTargetWhenNegativeFreeMargin(decimal holdings) { var algorithm = GetAlgorithm(); var security = InitAndGetSecurity(algorithm, 0); var model = new SecurityMarginModel(); security.Holdings.SetHoldings(security.Price, holdings); var security2 = InitAndGetSecurity(algorithm, 0, symbol: "AAPL"); // eat up all our TPV security2.Holdings.SetHoldings(security.Price, (algorithm.Portfolio.TotalPortfolioValue / security.Price) * 2); var currentSignedUsedMargin = model.GetInitialMarginRequirement(security, security.Holdings.Quantity); var totalPortfolioValue = algorithm.Portfolio.TotalPortfolioValue; var sign = Math.Sign(security.Holdings.Quantity) == 0 ? 1 : Math.Sign(security.Holdings.Quantity); // we inverse the sign here so that new target is less than current, we expect a reduction var newTarget = currentSignedUsedMargin / (totalPortfolioValue) + 0.00001m * sign * -1; Assert.IsTrue(0 > algorithm.Portfolio.MarginRemaining); var result = model.GetMaximumOrderQuantityForTargetBuyingPower(algorithm.Portfolio, security, newTarget, 0); // Reproduces GH issue #5763 a small Reduction in the target should reduce the position Assert.AreEqual(1m * sign * -1, result.Quantity); Assert.IsFalse(result.IsError); }
public void ReturnsMinimumOrderValueReason() { var algorithm = GetAlgorithm(); var security = InitAndGetSecurity(algorithm, 0); var model = new SecurityMarginModel(); var result = model.GetMaximumOrderQuantityForTargetBuyingPower(algorithm.Portfolio, security, 0.00000001m); Assert.AreEqual(0m, result.Quantity); Assert.IsFalse(result.IsError); Assert.IsTrue(result.Reason.Contains("is less than the minimum")); }
public void ZeroTargetWithZeroHoldingsIsNotAnError() { var algorithm = GetAlgorithm(); var security = InitAndGetSecurity(algorithm, 0); var model = new SecurityMarginModel(); var result = model.GetMaximumOrderQuantityForTargetBuyingPower(algorithm.Portfolio, security, 0, 0); Assert.AreEqual(0, result.Quantity); Assert.IsTrue(result.Reason.IsNullOrEmpty()); Assert.IsFalse(result.IsError); }
public void ZeroTargetWithNonZeroHoldingsReturnsNegativeOfQuantity() { var algorithm = GetAlgorithm(); var security = InitAndGetSecurity(algorithm, 0); security.Holdings.SetHoldings(200, 10); var model = new SecurityMarginModel(); var result = model.GetMaximumOrderQuantityForTargetBuyingPower(algorithm.Portfolio, security, 0, 0); Assert.AreEqual(-10, result.Quantity); Assert.IsTrue(result.Reason.IsNullOrEmpty()); Assert.IsFalse(result.IsError); }
public void ReturnsMinimumOrderValueReason(decimal holdings) { var algorithm = GetAlgorithm(); var security = InitAndGetSecurity(algorithm, 0); var model = new SecurityMarginModel(); security.Holdings.SetHoldings(security.Price, holdings); var currentSignedUsedMargin = model.GetInitialMarginRequirement(security, security.Holdings.Quantity); var totalPortfolioValue = algorithm.Portfolio.TotalPortfolioValue; var sign = Math.Sign(security.Holdings.Quantity) == 0 ? 1 : Math.Sign(security.Holdings.Quantity); // we increase it slightly, should not trigger a new order because it's increasing final margin usage, rounds down var newTarget = currentSignedUsedMargin / (totalPortfolioValue) + 0.00001m * sign; var result = model.GetMaximumOrderQuantityForTargetBuyingPower(algorithm.Portfolio, security, newTarget, 0); Assert.AreEqual(0m, result.Quantity); Assert.IsFalse(result.IsError); Assert.IsTrue(result.Reason.Contains("The order quantity is less than the lot size of", StringComparison.InvariantCultureIgnoreCase)); }