/// <summary> /// Validate order price and quantity for a symbol. /// Price is ignored unless order is <see cref="LimitOrder"/>. /// </summary> /// <param name="symbol"></param> /// <param name="order"></param> public static void ValidatePriceQuantity(this Symbol symbol, ClientOrder order) { Throw.IfNull(symbol, nameof(symbol)); Throw.IfNull(order, nameof(order)); symbol.BaseAsset.ValidateAmount(order.Quantity, nameof(order.Quantity)); symbol.Quantity.Validate(order.Quantity, nameof(order.Quantity)); if (!(order is LimitOrder limitOrder)) { return; } symbol.QuoteAsset.ValidateAmount(limitOrder.Price, nameof(limitOrder.Price)); symbol.Price.Validate(limitOrder.Price, nameof(limitOrder.Price)); var notionalValue = limitOrder.Price * order.Quantity; if (notionalValue < symbol.NotionalMinimumValue) { throw new ArgumentOutOfRangeException(nameof(notionalValue), $"The price * quantity ({notionalValue}) must be greater than or equal to minimum notional value ({symbol.NotionalMinimumValue})."); } }
/// <summary> /// Determine if a symbol supports a client order type. /// </summary> /// <param name="symbol"></param> /// <param name="order"></param> /// <returns></returns> public static bool IsOrderTypeSupported(this Symbol symbol, ClientOrder order) { Throw.IfNull(order, nameof(order)); return(IsSupported(symbol, order.Type)); }
/// <summary> /// Determine if the client order has NOT been placed. /// /// NOTE: After successful order placement the 'Time' will be set, /// however if order placement fails or the state is UNKNOWN then /// the time remains the default value. /// </summary> /// <param name="clientOrder"></param> /// <returns></returns> public static bool IsNotPlaced(this ClientOrder clientOrder) { Throw.IfNull(clientOrder, nameof(clientOrder)); return(clientOrder.Time == default); }