/// <summary> /// Check if there is sufficient buying power to execute this order. /// </summary> /// <param name="parameters">An object containing the portfolio, the security and the order</param> /// <returns>Returns buying power information for an order</returns> public virtual HasSufficientBuyingPowerForOrderResult HasSufficientBuyingPowerForOrder(HasSufficientBuyingPowerForOrderParameters parameters) { // short circuit the div 0 case if (parameters.Order.Quantity == 0) { return(parameters.Sufficient()); } var ticket = parameters.Portfolio.Transactions.GetOrderTicket(parameters.Order.Id); if (ticket == null) { return(parameters.Insufficient( $"Null order ticket for id: {parameters.Order.Id}" )); } if (parameters.Order.Type == OrderType.OptionExercise) { // for option assignment and exercise orders we look into the requirements to process the underlying security transaction var option = (Option.Option)parameters.Security; var underlying = option.Underlying; if (option.IsAutoExercised(underlying.Close) && underlying.IsTradable) { var quantity = option.GetExerciseQuantity(parameters.Order.Quantity); var newOrder = new LimitOrder { Id = parameters.Order.Id, Time = parameters.Order.Time, LimitPrice = option.StrikePrice, Symbol = underlying.Symbol, Quantity = quantity }; // we continue with this call for underlying var parametersForUnderlying = parameters.ForUnderlying(newOrder); var freeMargin = underlying.BuyingPowerModel.GetBuyingPower(parametersForUnderlying.Portfolio, parametersForUnderlying.Security, parametersForUnderlying.Order.Direction); // we add the margin used by the option itself freeMargin += GetMaintenanceMargin(MaintenanceMarginParameters.ForQuantityAtCurrentPrice(option, -parameters.Order.Quantity)); var initialMarginRequired = underlying.BuyingPowerModel.GetInitialMarginRequiredForOrder( new InitialMarginRequiredForOrderParameters(parameters.Portfolio.CashBook, underlying, newOrder)); return(HasSufficientBuyingPowerForOrder(parametersForUnderlying, ticket, freeMargin, initialMarginRequired)); } return(parameters.Sufficient()); } return(HasSufficientBuyingPowerForOrder(parameters, ticket)); }
/// <summary> /// Gets the margin currently allocated to the specified holding /// </summary> /// <param name="parameters">An object containing the security and holdings quantity/cost/value</param> /// <returns>The maintenance margin required for the provided holdings quantity/cost/value</returns> public virtual MaintenanceMargin GetMaintenanceMargin(MaintenanceMarginParameters parameters) { return(parameters.AbsoluteHoldingsValue * _maintenanceMarginRequirement); }
/// <summary> /// Gets the margin currently allocated to the specified holding /// </summary> /// <param name="model">The buying power model</param> /// <param name="security">The security</param> /// <returns>The maintenance margin required for the provided holdings quantity/cost/value</returns> public static decimal GetMaintenanceMargin(this IBuyingPowerModel model, Security security) { return(model.GetMaintenanceMargin(MaintenanceMarginParameters.ForCurrentHoldings(security))); }