using CryptoExchange.Net.Objects; using System; namespace CryptoExchange.Net.SharedApis { /// /// Support for different quantity notations /// public record SharedQuantitySupport { /// /// Supported quantity notations for buy limit orders /// public SharedQuantityType BuyLimit { get; set; } /// /// Supported quantity notations for sell limit orders /// public SharedQuantityType SellLimit { get; set; } /// /// Supported quantity notations for buy market orders /// public SharedQuantityType BuyMarket { get; set; } /// /// Supported quantity notations for sell market orders /// public SharedQuantityType SellMarket { get; set; } /// /// ctor /// public SharedQuantitySupport(SharedQuantityType buyLimit, SharedQuantityType sellLimit, SharedQuantityType buyMarket, SharedQuantityType sellMarket) { BuyLimit = buyLimit; SellLimit = sellLimit; BuyMarket = buyMarket; SellMarket = sellMarket; } /// /// Get the supported quantity type for a specific order configuration /// /// Side of the order /// Type of the order /// The supported quantity type public SharedQuantityType GetSupportedQuantityType(SharedOrderSide side, SharedOrderType orderType) { if (side == SharedOrderSide.Buy && (orderType == SharedOrderType.Limit || orderType == SharedOrderType.LimitMaker)) return BuyLimit; if (side == SharedOrderSide.Buy && orderType == SharedOrderType.Market) return BuyMarket; if (side == SharedOrderSide.Sell && (orderType == SharedOrderType.Limit || orderType == SharedOrderType.LimitMaker)) return SellLimit; if (side == SharedOrderSide.Sell && orderType == SharedOrderType.Market) return SellMarket; throw new ArgumentException("Unknown side/type combination"); } /// /// Get whether the API supports a specific quantity type for an order configuration /// /// Side of the order /// Type of the order /// Type of quantity /// True if supported, false if not public bool IsSupported(SharedOrderSide side, SharedOrderType orderType, SharedQuantityType quantityType) { var supportedType = GetSupportedQuantityType(side, orderType); if (supportedType == quantityType) return true; if (supportedType == SharedQuantityType.BaseAndQuoteAssetAndContracts) return true; if (supportedType == SharedQuantityType.BaseAndQuoteAsset && (quantityType == SharedQuantityType.BaseAsset || quantityType == SharedQuantityType.QuoteAsset)) return true; return false; } /// /// Validate a request /// public Error? Validate(SharedOrderSide side, SharedOrderType type, SharedQuantity? quantity) { var supportedType = GetSupportedQuantityType(side, type); if (supportedType == SharedQuantityType.BaseAndQuoteAsset || supportedType == SharedQuantityType.BaseAndQuoteAssetAndContracts) return null; if (supportedType == SharedQuantityType.BaseAndQuoteAsset && quantity != null && quantity.QuantityInBaseAsset == null && quantity.QuantityInQuoteAsset == null) return ArgumentError.Invalid("Quantity", $"Quantity for {side}.{type} required in base or quote asset"); if (supportedType == SharedQuantityType.QuoteAsset && quantity != null && quantity.QuantityInQuoteAsset == null) return ArgumentError.Invalid("Quantity", $"Quantity for {side}.{type} required in quote asset"); if (supportedType == SharedQuantityType.BaseAsset && quantity != null && quantity.QuantityInBaseAsset == null && quantity.QuantityInContracts == null) return ArgumentError.Invalid("Quantity", $"Quantity for {side}.{type} required in base asset"); if (supportedType == SharedQuantityType.Contracts && quantity != null && quantity.QuantityInContracts == null) return ArgumentError.Invalid("Quantity", $"Quantity for {side}.{type} required in contracts"); return null; } /// public override string ToString() { return $"Limit buy: {BuyLimit}, limit sell: {SellLimit}, market buy: {BuyMarket}, market sell: {SellMarket}"; } } }