/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using QuantConnect.Securities; namespace QuantConnect.Orders.Fees { /// /// Represents a fee model specific to Webull. /// /// /// /// Equity and standard options trades are commission-free on Webull. /// Index options carry a flat $0.50 Webull contract fee plus a variable exchange proprietary fee /// that depends on the underlying index symbol and the option's market price. /// public class WebullFeeModel : FeeModel { /// /// Webull contract fee applied to every index option contract, regardless of underlying. /// private const decimal _webullIndexOptionContractFee = 0.50m; /// /// Exchange proprietary fee for SPX options priced below $1.00. /// private const decimal _spxExchangeFeeBelow1 = 0.57m; /// /// Exchange proprietary fee for SPX options priced at or above $1.00. /// private const decimal _spxExchangeFeeAbove1 = 0.66m; /// /// Exchange proprietary fee for SPXW options priced below $1.00. /// private const decimal _spxwExchangeFeeBelow1 = 0.50m; /// /// Exchange proprietary fee for SPXW options priced at or above $1.00. /// private const decimal _spxwExchangeFeeAbove1 = 0.59m; /// /// VIX/VIXW exchange fee tier 1: option price at or below $0.10. /// private const decimal _vixExchangeFeeTier1 = 0.10m; /// /// VIX/VIXW exchange fee tier 2: option price between $0.11 and $0.99. /// private const decimal _vixExchangeFeeTier2 = 0.25m; /// /// VIX/VIXW exchange fee tier 3: option price between $1.00 and $1.99. /// private const decimal _vixExchangeFeeTier3 = 0.40m; /// /// VIX/VIXW exchange fee tier 4: option price at or above $2.00. /// private const decimal _vixExchangeFeeTier4 = 0.45m; /// /// XSP exchange fee for orders with fewer than 10 contracts. /// private const decimal _xspExchangeFeeSmall = 0.00m; /// /// XSP exchange fee for orders with 10 or more contracts. /// private const decimal _xspExchangeFeeLarge = 0.07m; /// /// DJX flat exchange proprietary fee per contract. /// private const decimal _djxExchangeFee = 0.18m; /// /// NDX/NDXP exchange fee for single-leg orders with premium below $25. /// private const decimal _ndxSingleLegFeeBelow25 = 0.50m; /// /// NDX/NDXP exchange fee for single-leg orders with premium at or above $25. /// private const decimal _ndxSingleLegFeeAbove25 = 0.75m; /// /// NDX/NDXP exchange fee for multi-leg orders with premium below $25. /// private const decimal _ndxMultiLegFeeBelow25 = 0.65m; /// /// NDX/NDXP exchange fee for multi-leg orders with premium at or above $25. /// private const decimal _ndxMultiLegFeeAbove25 = 0.90m; /// /// Gets the order fee for a given security and order. /// /// The parameters including the security and order details. /// /// for equity and standard options; /// a per-contract fee for index options. /// public override OrderFee GetOrderFee(OrderFeeParameters parameters) { switch (parameters.Security.Type) { case SecurityType.IndexOption: return new OrderFee(new CashAmount(GetIndexOptionFee(parameters), Currencies.USD)); default: // Equity and Option are commission-free on Webull. return OrderFee.Zero; } } /// /// Calculates the total per-contract fee for an index option order. /// The total fee = (exchange proprietary fee + Webull contract fee) × quantity. /// /// Order fee parameters containing the security and order. /// Total fee amount in USD. private static decimal GetIndexOptionFee(OrderFeeParameters parameters) { var order = parameters.Order; var security = parameters.Security; var quantity = order.AbsoluteQuantity; var price = security.Price; var underlying = security.Symbol.Underlying?.Value?.ToUpperInvariant() ?? string.Empty; var isMultiLeg = order.Type == OrderType.ComboMarket || order.Type == OrderType.ComboLimit || order.Type == OrderType.ComboLegLimit; var exchangeFee = GetIndexOptionExchangeFee(underlying, price, quantity, isMultiLeg); return quantity * (exchangeFee + _webullIndexOptionContractFee); } /// /// Returns the exchange proprietary fee per contract for an index option, based on /// the underlying ticker, the option's current price, order quantity, and leg type. /// /// Uppercase underlying ticker (e.g. "SPX", "VIX"). /// Current market price of the option. /// Absolute number of contracts in the order. /// True when the order is a combo/multi-leg order. /// Exchange fee per contract in USD. private static decimal GetIndexOptionExchangeFee(string underlying, decimal price, decimal quantity, bool isMultiLeg) { switch (underlying) { case "SPX": return price < 1m ? _spxExchangeFeeBelow1 : _spxExchangeFeeAbove1; case "SPXW": return price < 1m ? _spxwExchangeFeeBelow1 : _spxwExchangeFeeAbove1; case "VIX": case "VIXW": return GetVixExchangeFee(price); case "XSP": return quantity < 10m ? _xspExchangeFeeSmall : _xspExchangeFeeLarge; case "DJX": return _djxExchangeFee; case "NDX": case "NDXP": return GetNdxExchangeFee(price, isMultiLeg); default: return 0m; } } /// /// Returns the VIX/VIXW exchange fee for a simple order based on the option price tier. /// private static decimal GetVixExchangeFee(decimal price) { if (price <= 0.10m) { return _vixExchangeFeeTier1; } if (price <= 0.99m) { return _vixExchangeFeeTier2; } if (price <= 1.99m) { return _vixExchangeFeeTier3; } return _vixExchangeFeeTier4; } /// /// Returns the NDX/NDXP exchange fee per contract based on premium tier and order leg type. /// private static decimal GetNdxExchangeFee(decimal price, bool isMultiLeg) { if (isMultiLeg) { return price < 25m ? _ndxMultiLegFeeBelow25 : _ndxMultiLegFeeAbove25; } return price < 25m ? _ndxSingleLegFeeBelow25 : _ndxSingleLegFeeAbove25; } } }