Lean  $LEAN_TAG$
BinanceFeeModel.cs
1 /*
2 * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3 * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 
16 using QuantConnect.Util;
18 
20 {
21  /// <summary>
22  /// Provides an implementation of <see cref="FeeModel"/> that models Binance order fees
23  /// </summary>
24  public class BinanceFeeModel : FeeModel
25  {
26  /// <summary>
27  /// Tier 1 maker fees
28  /// https://www.binance.com/en/fee/schedule
29  /// </summary>
30  public const decimal MakerTier1Fee = 0.001m;
31 
32  /// <summary>
33  /// Tier 1 taker fees
34  /// https://www.binance.com/en/fee/schedule
35  /// </summary>
36  public const decimal TakerTier1Fee = 0.001m;
37 
38  private readonly decimal _makerFee;
39  private readonly decimal _takerFee;
40 
41  /// <summary>
42  /// Creates Binance fee model setting fees values
43  /// </summary>
44  /// <param name="mFee">Maker fee value</param>
45  /// <param name="tFee">Taker fee value</param>
46  public BinanceFeeModel(decimal mFee = MakerTier1Fee, decimal tFee = TakerTier1Fee)
47  {
48  _makerFee = mFee;
49  _takerFee = tFee;
50  }
51 
52  /// <summary>
53  /// Get the fee for this order in quote currency
54  /// </summary>
55  /// <param name="parameters">A <see cref="OrderFeeParameters"/> object containing the security and order</param>
56  /// <returns>The cost of the order in quote currency</returns>
57  public override OrderFee GetOrderFee(OrderFeeParameters parameters)
58  {
59  var security = parameters.Security;
60  var order = parameters.Order;
61 
62  var fee = GetFee(order);
63 
64  if(security.Symbol.ID.SecurityType == SecurityType.CryptoFuture)
65  {
66  var positionValue = security.Holdings.GetQuantityValue(order.AbsoluteQuantity, security.Price);
67  return new OrderFee(new CashAmount(positionValue.Amount * fee, positionValue.Cash.Symbol));
68  }
69 
70  if (order.Direction == OrderDirection.Buy)
71  {
72  // fees taken in the received currency
73  CurrencyPairUtil.DecomposeCurrencyPair(order.Symbol, out var baseCurrency, out _);
74  return new OrderFee(new CashAmount(order.AbsoluteQuantity * fee, baseCurrency));
75  }
76 
77  // get order value in quote currency
78  var unitPrice = order.Direction == OrderDirection.Buy ? security.AskPrice : security.BidPrice;
79  if (order.Type == OrderType.Limit)
80  {
81  // limit order posted to the order book
82  unitPrice = ((LimitOrder)order).LimitPrice;
83  }
84 
85  unitPrice *= security.SymbolProperties.ContractMultiplier;
86 
87  return new OrderFee(new CashAmount(
88  unitPrice * order.AbsoluteQuantity * fee,
89  security.QuoteCurrency.Symbol));
90  }
91 
92  /// <summary>
93  /// Gets the fee factor for the given order
94  /// </summary>
95  /// <param name="order">The order to get the fee factor for</param>
96  /// <returns>The fee factor for the given order</returns>
97  protected virtual decimal GetFee(Order order)
98  {
99  return GetFee(order, _makerFee, _takerFee);
100  }
101 
102  protected static decimal GetFee(Order order, decimal makerFee, decimal takerFee)
103  {
104  // apply fee factor, currently we do not model 30-day volume, so we use the first tier
105  var fee = takerFee;
106  var props = order.Properties as BinanceOrderProperties;
107 
108  if (order.Type == OrderType.Limit && ((props != null && props.PostOnly) || !order.IsMarketable))
109  {
110  // limit order posted to the order book
111  fee = makerFee;
112  }
113 
114  return fee;
115  }
116  }
117 }