public void SetHoldings_Short_RoundOff() { var algo = new QCAlgorithm(); algo.AddSecurity(SecurityType.Forex, "EURUSD"); algo.SetCash(100000); algo.SetBrokerageModel(BrokerageName.FxcmBrokerage); algo.Securities[Symbols.EURUSD].TransactionModel = new ConstantFeeTransactionModel(0); Security eurusd = algo.Securities[Symbols.EURUSD]; // Set Price to $26 Update(eurusd, 26); // So -100000/26 = -3846, After Rounding off becomes -3000 var actual = algo.CalculateOrderQuantity(Symbols.EURUSD, -1m); Assert.AreEqual(-3000m, actual); var btcusd = algo.AddCrypto("BTCUSD", market: Market.GDAX); btcusd.TransactionModel = new ConstantFeeTransactionModel(0); // Set Price to $26 Update(btcusd, 26); // So -100000/26 = 3846.153846153846, After Rounding off becomes -3846.15384615, since lot size is 0.00000001 actual = algo.CalculateOrderQuantity(Symbols.BTCUSD, -1m); Assert.AreEqual(-3846.15384615m, actual); }
public void SetBuyingPowerModelSuccess(bool isChild) { var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); algorithm.SetDateTime(new DateTime(2018, 8, 20, 15, 0, 0)); algorithm.Transactions.SetOrderProcessor(new FakeOrderProcessor()); var spy = algorithm.AddEquity("SPY", Resolution.Daily); spy.SetMarketPrice(new Tick(algorithm.Time, Symbols.SPY, 100m, 100m)); // Test two custom buying power models. // The first inherits from C# SecurityMarginModel and the other is 100% python var code = isChild ? CreateCustomBuyingPowerModelFromSecurityMarginModelCode() : CreateCustomBuyingPowerModelCode(); spy.SetBuyingPowerModel(CreateCustomBuyingPowerModel(code)); Assert.IsAssignableFrom <BuyingPowerModelPythonWrapper>(spy.MarginModel); Assert.AreEqual(1, spy.MarginModel.GetLeverage(spy)); spy.SetLeverage(2); Assert.AreEqual(2, spy.MarginModel.GetLeverage(spy)); var quantity = algorithm.CalculateOrderQuantity(spy.Symbol, 1m); Assert.AreEqual(isChild ? 100 : 200, quantity); }
public void HasSufficientBuyingPowerForOrderInvalidTargets(decimal target) { var algorithm = new QCAlgorithm(); algorithm.SetFinishedWarmingUp(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); var orderProcessor = new FakeOrderProcessor(); algorithm.Transactions.SetOrderProcessor(orderProcessor); var ticker = QuantConnect.Securities.Futures.Financials.EuroDollar; var futureSecurity = algorithm.AddFuture(ticker); // set closed market for simpler math futureSecurity.Exchange.SetLocalDateTimeFrontier(new DateTime(2020, 2, 1)); Update(futureSecurity, 100, algorithm); var model = GetModel(futureSecurity, out _futureMarginModel, algorithm.Portfolio); var quantity = algorithm.CalculateOrderQuantity(futureSecurity.Symbol, target); var request = GetOrderRequest(futureSecurity.Symbol, quantity); request.SetOrderId(0); orderProcessor.AddTicket(new OrderTicket(algorithm.Transactions, request)); var result = model.HasSufficientBuyingPowerForOrder(new HasSufficientBuyingPowerForOrderParameters( algorithm.Portfolio, futureSecurity, // we get the maximum target value 1/-1 and add a lot size it shouldn't be a valid order new MarketOrder(futureSecurity.Symbol, quantity + futureSecurity.SymbolProperties.LotSize * Math.Sign(quantity), DateTime.UtcNow))); Assert.IsFalse(result.IsSufficient); }
public void ClosingSoonIntradayClosedMarketMargins(decimal target) { var algorithm = new QCAlgorithm(); algorithm.SetFinishedWarmingUp(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); var orderProcessor = new FakeOrderProcessor(); algorithm.Transactions.SetOrderProcessor(orderProcessor); var ticker = QuantConnect.Securities.Futures.Financials.EuroDollar; var futureSecurity = algorithm.AddFuture(ticker); Update(futureSecurity, 100, algorithm); var localTime = new DateTime(2020, 2, 3); var utcTime = localTime.ConvertToUtc(futureSecurity.Exchange.TimeZone); var timeKeeper = new TimeKeeper(utcTime, futureSecurity.Exchange.TimeZone); var model = GetModel(futureSecurity, out _futureMarginModel, algorithm.Portfolio); // this is important _futureMarginModel.EnableIntradayMargins = true; // Open market futureSecurity.Exchange.SetLocalDateTimeFrontier(localTime); var quantity = algorithm.CalculateOrderQuantity(futureSecurity.Symbol, target); var request = GetOrderRequest(futureSecurity.Symbol, quantity); request.SetOrderId(0); orderProcessor.AddTicket(new OrderTicket(algorithm.Transactions, request)); Assert.IsTrue(model.HasSufficientBuyingPowerForOrder( new HasSufficientBuyingPowerForOrderParameters(algorithm.Portfolio, futureSecurity, new MarketOrder(futureSecurity.Symbol, quantity, DateTime.UtcNow))).IsSufficient); // Closing soon market futureSecurity.Exchange.SetLocalDateTimeFrontier(new DateTime(2020, 2, 3, 15, 50, 0)); Assert.IsFalse(model.HasSufficientBuyingPowerForOrder( new HasSufficientBuyingPowerForOrderParameters(algorithm.Portfolio, futureSecurity, new MarketOrder(futureSecurity.Symbol, quantity, DateTime.UtcNow))).IsSufficient); Assert.IsTrue(futureSecurity.Exchange.ExchangeOpen); Assert.IsTrue(futureSecurity.Exchange.ClosingSoon); // Close market futureSecurity.Exchange.SetLocalDateTimeFrontier(new DateTime(2020, 2, 1)); Assert.IsFalse(futureSecurity.Exchange.ExchangeOpen); Assert.IsFalse(model.HasSufficientBuyingPowerForOrder( new HasSufficientBuyingPowerForOrderParameters(algorithm.Portfolio, futureSecurity, new MarketOrder(futureSecurity.Symbol, quantity, DateTime.UtcNow))).IsSufficient); }
public void IntradayVersusOvernightMargins(decimal target) { var algorithm = new QCAlgorithm(); algorithm.SetFinishedWarmingUp(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); var orderProcessor = new FakeOrderProcessor(); algorithm.Transactions.SetOrderProcessor(orderProcessor); var ticker = QuantConnect.Securities.Futures.Financials.EuroDollar; var futureSecurity = algorithm.AddFuture(ticker); var lotSize = futureSecurity.SymbolProperties.LotSize; Update(futureSecurity, 100, algorithm); var model = GetModel(futureSecurity, out _futureMarginModel, algorithm.Portfolio); // Close market futureSecurity.Exchange.SetLocalDateTimeFrontier(new DateTime(2020, 2, 1)); var quantityClosedMarket = algorithm.CalculateOrderQuantity(futureSecurity.Symbol, target); Assert.AreEqual(quantityClosedMarket.DiscretelyRoundBy(lotSize), quantityClosedMarket, "Calculated order quantity was not whole number multiple of the lot size" ); var request = GetOrderRequest(futureSecurity.Symbol, quantityClosedMarket); request.SetOrderId(0); orderProcessor.AddTicket(new OrderTicket(algorithm.Transactions, request)); Assert.IsTrue(model.HasSufficientBuyingPowerForOrder( new HasSufficientBuyingPowerForOrderParameters(algorithm.Portfolio, futureSecurity, new MarketOrder(futureSecurity.Symbol, quantityClosedMarket, DateTime.UtcNow))).IsSufficient); var initialOvernight = _futureMarginModel.InitialOvernightMarginRequirement; var maintenanceOvernight = _futureMarginModel.MaintenanceOvernightMarginRequirement; // Open market futureSecurity.Exchange.SetLocalDateTimeFrontier(new DateTime(2020, 2, 3)); var fourtyPercentQuantity = (quantityClosedMarket * 0.4m).DiscretelyRoundBy(lotSize); futureSecurity.Holdings.SetHoldings(100, fourtyPercentQuantity); var halfQuantity = (quantityClosedMarket / 2).DiscretelyRoundBy(lotSize); Assert.IsTrue(model.HasSufficientBuyingPowerForOrder( new HasSufficientBuyingPowerForOrderParameters(algorithm.Portfolio, futureSecurity, new MarketOrder(futureSecurity.Symbol, halfQuantity, DateTime.UtcNow))).IsSufficient); Assert.Greater(initialOvernight, _futureMarginModel.InitialIntradayMarginRequirement); Assert.Greater(maintenanceOvernight, _futureMarginModel.MaintenanceIntradayMarginRequirement); }
public void DefaultValueOfSetHoldingsBufferWorksCorrectly() { var algo = new QCAlgorithm(); InitializeAndGetFakeOrderProcessor(algo); var actual = algo.CalculateOrderQuantity(Symbols.SPY, 1m); // 100000 / 20 - 1 due to fee - effect of the target being reduced because of FreePortfolioValuePercentage Assert.AreEqual(4986m, actual); }
public void SettingSetHoldingsBufferWorksCorrectly() { var algo = new QCAlgorithm(); algo.Settings.FreePortfolioValuePercentage = 0; InitializeAndGetFakeOrderProcessor(algo); var actual = algo.CalculateOrderQuantity(Symbols.SPY, 1m); // 100000 / 20 - 2 due to fee = Assert.AreEqual(4998m, actual); }
public void GetMaximumOrderQuantityForTargetBuyingPower_TwoStep(decimal target) { var algorithm = new QCAlgorithm(); algorithm.SetFinishedWarmingUp(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); var orderProcessor = new FakeOrderProcessor(); algorithm.Transactions.SetOrderProcessor(orderProcessor); var ticker = QuantConnect.Securities.Futures.Financials.EuroDollar; var futureSecurity = algorithm.AddFuture(ticker); futureSecurity.BuyingPowerModel = GetModel(futureSecurity, out _futureMarginModel, algorithm.Portfolio); // set closed market for simpler math futureSecurity.Exchange.SetLocalDateTimeFrontier(new DateTime(2020, 2, 1)); Update(futureSecurity, 100, algorithm); var expectedFinalQuantity = algorithm.CalculateOrderQuantity(futureSecurity.Symbol, target); var quantity = algorithm.CalculateOrderQuantity(futureSecurity.Symbol, target / 2); futureSecurity.Holdings.SetHoldings(100, quantity); algorithm.Portfolio.InvalidateTotalPortfolioValue(); var quantity2 = algorithm.CalculateOrderQuantity(futureSecurity.Symbol, target); var request = GetOrderRequest(futureSecurity.Symbol, quantity2); request.SetOrderId(0); orderProcessor.AddTicket(new OrderTicket(algorithm.Transactions, request)); Assert.IsTrue(futureSecurity.BuyingPowerModel.HasSufficientBuyingPowerForOrder( new HasSufficientBuyingPowerForOrderParameters(algorithm.Portfolio, futureSecurity, new MarketOrder(futureSecurity.Symbol, quantity2, DateTime.UtcNow))).IsSufficient); // two step operation is the same as 1 step Assert.AreEqual(expectedFinalQuantity, quantity + quantity2); }
public void SetHoldings_Long_ToZero_RoundOff() { var algo = new QCAlgorithm(); algo.AddSecurity(SecurityType.Forex, "EURUSD"); algo.SetCash(10000); algo.SetBrokerageModel(BrokerageName.FxcmBrokerage); algo.Securities[Symbols.EURUSD].TransactionModel = new ConstantFeeTransactionModel(0); Security eurusd = algo.Securities[Symbols.EURUSD]; // Set Price to $25 Update(eurusd, 25); // So 10000/25 = 400, After Rounding off becomes 0 var actual = algo.CalculateOrderQuantity(Symbols.EURUSD, 1m); Assert.AreEqual(0m, actual); }
public void SetHoldings_Short_RoundOff() { var algo = new QCAlgorithm(); algo.AddSecurity(SecurityType.Forex, "EURUSD"); algo.SetCash(100000); algo.SetBrokerageModel(BrokerageName.FxcmBrokerage); algo.Securities[Symbols.EURUSD].TransactionModel = new ConstantFeeTransactionModel(0); Security eurusd = algo.Securities[Symbols.EURUSD]; // Set Price to $26 Update(eurusd, 26); // So -100000/26 = -3846, After Rounding off becomes -3000 var actual = algo.CalculateOrderQuantity("EURUSD", -1m); Assert.AreEqual(-3000m, actual); }
public void IntradayVersusOvernightMargins(decimal target) { var algorithm = new QCAlgorithm(); algorithm.SetFinishedWarmingUp(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); var orderProcessor = new FakeOrderProcessor(); algorithm.Transactions.SetOrderProcessor(orderProcessor); var ticker = QuantConnect.Securities.Futures.Financials.EuroDollar; var futureSecurity = algorithm.AddFuture(ticker); Update(futureSecurity, 100, algorithm); var model = futureSecurity.BuyingPowerModel as FutureMarginModel; // Close market futureSecurity.Exchange.SetLocalDateTimeFrontier(new DateTime(2020, 2, 1)); var quantityClosedMarket = algorithm.CalculateOrderQuantity(futureSecurity.Symbol, target); var request = GetOrderRequest(futureSecurity.Symbol, quantityClosedMarket); request.SetOrderId(0); orderProcessor.AddTicket(new OrderTicket(algorithm.Transactions, request)); Assert.IsTrue(model.HasSufficientBuyingPowerForOrder( new HasSufficientBuyingPowerForOrderParameters(algorithm.Portfolio, futureSecurity, new MarketOrder(futureSecurity.Symbol, quantityClosedMarket, DateTime.UtcNow))).IsSufficient); var initialOvernight = model.InitialOvernightMarginRequirement; var maintenanceOvernight = model.MaintenanceOvernightMarginRequirement; // Open market futureSecurity.Exchange.SetLocalDateTimeFrontier(new DateTime(2020, 2, 3)); futureSecurity.Holdings.SetHoldings(100, quantityClosedMarket * 0.4m); Assert.IsTrue(model.HasSufficientBuyingPowerForOrder( new HasSufficientBuyingPowerForOrderParameters(algorithm.Portfolio, futureSecurity, new MarketOrder(futureSecurity.Symbol, quantityClosedMarket / 2, DateTime.UtcNow))).IsSufficient); Assert.Greater(initialOvernight, model.InitialIntradayMarginRequirement); Assert.Greater(maintenanceOvernight, model.MaintenanceIntradayMarginRequirement); }
public void GetMaximumOrderQuantityForTargetBuyingPower_WithHoldingsInverseDirection(decimal target) { var algorithm = new QCAlgorithm(); algorithm.SetFinishedWarmingUp(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); var orderProcessor = new FakeOrderProcessor(); algorithm.Transactions.SetOrderProcessor(orderProcessor); var ticker = QuantConnect.Securities.Futures.Financials.EuroDollar; var futureSecurity = algorithm.AddFuture(ticker); // set closed market for simpler math futureSecurity.Exchange.SetLocalDateTimeFrontier(new DateTime(2020, 2, 1)); futureSecurity.Holdings.SetHoldings(100, 10 * -1 * Math.Sign(target)); Update(futureSecurity, 100, algorithm); var model = GetModel(futureSecurity, out _futureMarginModel, algorithm.Portfolio); futureSecurity.BuyingPowerModel = _futureMarginModel; var quantity = algorithm.CalculateOrderQuantity(futureSecurity.Symbol, target); var expected = (algorithm.Portfolio.TotalPortfolioValue * Math.Abs(target) + Math.Abs(model.GetInitialMarginRequirement(futureSecurity, futureSecurity.Holdings.Quantity))) / _futureMarginModel.InitialOvernightMarginRequirement - 1 * Math.Abs(target); // -1 fees expected -= expected % futureSecurity.SymbolProperties.LotSize; Log.Trace($"Expected {expected}"); Assert.AreEqual(expected * Math.Sign(target), quantity); var request = GetOrderRequest(futureSecurity.Symbol, quantity); request.SetOrderId(0); orderProcessor.AddTicket(new OrderTicket(algorithm.Transactions, request)); Assert.IsTrue(model.HasSufficientBuyingPowerForOrder( new HasSufficientBuyingPowerForOrderParameters(algorithm.Portfolio, futureSecurity, new MarketOrder(futureSecurity.Symbol, expected * Math.Sign(target), DateTime.UtcNow))).IsSufficient); }
public void Run(Position initialPosition, Position finalPosition, FeeType feeType, PriceMovement priceMovement, int leverage) { //Console.WriteLine("----------"); //Console.WriteLine("PARAMETERS"); //Console.WriteLine("Initial position: " + initialPosition); //Console.WriteLine("Final position: " + finalPosition); //Console.WriteLine("Fee type: " + feeType); //Console.WriteLine("Price movement: " + priceMovement); //Console.WriteLine("Leverage: " + leverage); //Console.WriteLine("----------"); //Console.WriteLine(); var algorithm = new QCAlgorithm(); var security = algorithm.AddSecurity(_symbol.ID.SecurityType, _symbol.ID.Symbol); security.FeeModel = _feeModels[feeType]; security.SetLeverage(leverage); algorithm.SetCash(Cash); Update(security, BasePrice); decimal targetPercentage; OrderDirection orderDirection; MarketOrder order; decimal orderFee; OrderEvent fill; int orderQuantity; decimal freeMargin; decimal requiredMargin; if (initialPosition != Position.Zero) { targetPercentage = (decimal)initialPosition; orderDirection = initialPosition == Position.Long ? OrderDirection.Buy : OrderDirection.Sell; orderQuantity = algorithm.CalculateOrderQuantity(_symbol, targetPercentage); order = new MarketOrder(_symbol, orderQuantity, DateTime.UtcNow); freeMargin = algorithm.Portfolio.GetMarginRemaining(_symbol, orderDirection); requiredMargin = security.MarginModel.GetInitialMarginRequiredForOrder(security, order); //Console.WriteLine("Current price: " + security.Price); //Console.WriteLine("Target percentage: " + targetPercentage); //Console.WriteLine("Order direction: " + orderDirection); //Console.WriteLine("Order quantity: " + orderQuantity); //Console.WriteLine("Free margin: " + freeMargin); //Console.WriteLine("Required margin: " + requiredMargin); //Console.WriteLine(); Assert.That(Math.Abs(requiredMargin) <= freeMargin); orderFee = security.FeeModel.GetOrderFee(security, order); fill = new OrderEvent(order, DateTime.UtcNow, orderFee) { FillPrice = security.Price, FillQuantity = orderQuantity }; algorithm.Portfolio.ProcessFill(fill); //Console.WriteLine("Portfolio.Cash: " + algorithm.Portfolio.Cash); //Console.WriteLine("Portfolio.TotalPortfolioValue: " + algorithm.Portfolio.TotalPortfolioValue); //Console.WriteLine(); if (priceMovement == PriceMovement.RisingSmall) { Update(security, HighPrice); } else if (priceMovement == PriceMovement.FallingSmall) { Update(security, LowPrice); } else if (priceMovement == PriceMovement.RisingLarge) { Update(security, VeryHighPrice); } else if (priceMovement == PriceMovement.FallingLarge) { Update(security, VeryLowPrice); } } targetPercentage = (decimal)finalPosition; orderDirection = finalPosition == Position.Long || (finalPosition == Position.Zero && initialPosition == Position.Short) ? OrderDirection.Buy : OrderDirection.Sell; orderQuantity = algorithm.CalculateOrderQuantity(_symbol, targetPercentage); order = new MarketOrder(_symbol, orderQuantity, DateTime.UtcNow); freeMargin = algorithm.Portfolio.GetMarginRemaining(_symbol, orderDirection); requiredMargin = security.MarginModel.GetInitialMarginRequiredForOrder(security, order); //Console.WriteLine("Current price: " + security.Price); //Console.WriteLine("Target percentage: " + targetPercentage); //Console.WriteLine("Order direction: " + orderDirection); //Console.WriteLine("Order quantity: " + orderQuantity); //Console.WriteLine("Free margin: " + freeMargin); //Console.WriteLine("Required margin: " + requiredMargin); //Console.WriteLine(); Assert.That(Math.Abs(requiredMargin) <= freeMargin); orderFee = security.FeeModel.GetOrderFee(security, order); fill = new OrderEvent(order, DateTime.UtcNow, orderFee) { FillPrice = security.Price, FillQuantity = orderQuantity }; algorithm.Portfolio.ProcessFill(fill); //Console.WriteLine("Portfolio.Cash: " + algorithm.Portfolio.Cash); //Console.WriteLine("Portfolio.TotalPortfolioValue: " + algorithm.Portfolio.TotalPortfolioValue); //Console.WriteLine(); }
/// <summary> /// Calculate Alpha and Beta, the initial number of shares for each security needed to achieve a 50/50 weighting /// </summary> /// <param name="algorithm"></param> private void CalculateAlphaBeta(QCAlgorithm algorithm) { _alpha = algorithm.CalculateOrderQuantity(_longSymbol, 0.5); _beta = algorithm.CalculateOrderQuantity(_shortSymbol, 0.5); algorithm.Log($"{algorithm.Time} :: Alpha: {_alpha} Beta: {_beta}"); }
public void Run(object[] parameters) { Position initialPosition = (Position)parameters[0]; Position finalPosition = (Position)parameters[1]; FeeType feeType = (FeeType)parameters[2]; PriceMovement priceMovement = (PriceMovement)parameters[3]; int leverage = (int)parameters[4]; //Console.WriteLine("----------"); //Console.WriteLine("PARAMETERS"); //Console.WriteLine("Initial position: " + initialPosition); //Console.WriteLine("Final position: " + finalPosition); //Console.WriteLine("Fee type: " + feeType); //Console.WriteLine("Price movement: " + priceMovement); //Console.WriteLine("Leverage: " + leverage); //Console.WriteLine("----------"); //Console.WriteLine(); var algorithm = new QCAlgorithm(); algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(algorithm)); var security = algorithm.AddSecurity(_symbol.ID.SecurityType, _symbol.ID.Symbol); security.FeeModel = _feeModels[feeType]; security.SetLeverage(leverage); var buyingPowerModel = new TestSecurityMarginModel(leverage); security.BuyingPowerModel = buyingPowerModel; algorithm.SetCash(Cash); Update(security, BasePrice); decimal targetPercentage; OrderDirection orderDirection; MarketOrder order; OrderFee orderFee; OrderEvent fill; decimal orderQuantity; decimal freeMargin; decimal requiredMargin; if (initialPosition != Position.Zero) { targetPercentage = (decimal)initialPosition; orderDirection = initialPosition == Position.Long ? OrderDirection.Buy : OrderDirection.Sell; orderQuantity = algorithm.CalculateOrderQuantity(_symbol, targetPercentage); order = new MarketOrder(_symbol, orderQuantity, DateTime.UtcNow); freeMargin = buyingPowerModel.GetMarginRemaining(algorithm.Portfolio, security, orderDirection); requiredMargin = buyingPowerModel.GetInitialMarginRequiredForOrder( new InitialMarginRequiredForOrderParameters( new IdentityCurrencyConverter(algorithm.Portfolio.CashBook.AccountCurrency), security, order)); //Console.WriteLine("Current price: " + security.Price); //Console.WriteLine("Target percentage: " + targetPercentage); //Console.WriteLine("Order direction: " + orderDirection); //Console.WriteLine("Order quantity: " + orderQuantity); //Console.WriteLine("Free margin: " + freeMargin); //Console.WriteLine("Required margin: " + requiredMargin); //Console.WriteLine(); Assert.That(Math.Abs(requiredMargin) <= freeMargin); orderFee = security.FeeModel.GetOrderFee( new OrderFeeParameters(security, order)); fill = new OrderEvent(order, DateTime.UtcNow, orderFee) { FillPrice = security.Price, FillQuantity = orderQuantity }; algorithm.Portfolio.ProcessFill(fill); //Console.WriteLine("Portfolio.Cash: " + algorithm.Portfolio.Cash); //Console.WriteLine("Portfolio.TotalPortfolioValue: " + algorithm.Portfolio.TotalPortfolioValue); //Console.WriteLine(); if (priceMovement == PriceMovement.RisingSmall) { Update(security, HighPrice); } else if (priceMovement == PriceMovement.FallingSmall) { Update(security, LowPrice); } else if (priceMovement == PriceMovement.RisingLarge) { Update(security, VeryHighPrice); } else if (priceMovement == PriceMovement.FallingLarge) { Update(security, VeryLowPrice); } } targetPercentage = (decimal)finalPosition; orderDirection = finalPosition == Position.Long || (finalPosition == Position.Zero && initialPosition == Position.Short) ? OrderDirection.Buy : OrderDirection.Sell; orderQuantity = algorithm.CalculateOrderQuantity(_symbol, targetPercentage); order = new MarketOrder(_symbol, orderQuantity, DateTime.UtcNow); freeMargin = buyingPowerModel.GetMarginRemaining(algorithm.Portfolio, security, orderDirection); requiredMargin = buyingPowerModel.GetInitialMarginRequiredForOrder( new InitialMarginRequiredForOrderParameters( new IdentityCurrencyConverter(algorithm.Portfolio.CashBook.AccountCurrency), security, order)); //Console.WriteLine("Current price: " + security.Price); //Console.WriteLine("Target percentage: " + targetPercentage); //Console.WriteLine("Order direction: " + orderDirection); //Console.WriteLine("Order quantity: " + orderQuantity); //Console.WriteLine("Free margin: " + freeMargin); //Console.WriteLine("Required margin: " + requiredMargin); //Console.WriteLine(); Assert.That(Math.Abs(requiredMargin) <= freeMargin); orderFee = security.FeeModel.GetOrderFee( new OrderFeeParameters(security, order)); fill = new OrderEvent(order, DateTime.UtcNow, orderFee) { FillPrice = security.Price, FillQuantity = orderQuantity }; algorithm.Portfolio.ProcessFill(fill); //Console.WriteLine("Portfolio.Cash: " + algorithm.Portfolio.Cash); //Console.WriteLine("Portfolio.TotalPortfolioValue: " + algorithm.Portfolio.TotalPortfolioValue); //Console.WriteLine(); }