Lean  $LEAN_TAG$
KrakenFeeModel.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 
17 
18 using System.Collections.Generic;
19 using System.Linq;
21 using QuantConnect.Util;
22 
24 {
25  /// <summary>
26  /// Provides an implementation of <see cref="FeeModel"/> that models Kraken order fees
27  /// </summary>
28  public class KrakenFeeModel : FeeModel
29  {
30  /// <summary>
31  /// We don't use 30 day model, so using only tier1 fees.
32  /// https://www.kraken.com/features/fee-schedule#kraken-pro
33  /// </summary>
34  public const decimal MakerTier1CryptoFee = 0.0016m;
35 
36  /// <summary>
37  /// We don't use 30 day model, so using only tier1 fees.
38  /// https://www.kraken.com/features/fee-schedule#kraken-pro
39  /// </summary>
40  public const decimal TakerTier1CryptoFee = 0.0026m;
41 
42  /// <summary>
43  /// We don't use 30 day model, so using only tier1 fees.
44  /// https://www.kraken.com/features/fee-schedule#stablecoin-fx-pairs
45  /// </summary>
46  public const decimal Tier1FxFee = 0.002m;
47 
48  /// <summary>
49  /// Fiats and stablecoins list that have own fee.
50  /// </summary>
51  public List<string> FxStablecoinList { get; init; } = new() {"CAD", "EUR", "GBP", "JPY", "USD", "USDT", "DAI", "USDC"};
52 
53  /// <summary>
54  /// Get the fee for this order.
55  /// If sell - fees in base currency
56  /// If buy - fees in quote currency
57  /// It can be defined manually in <see cref="KrakenOrderProperties"/>
58  /// </summary>
59  /// <param name="parameters">A <see cref="OrderFeeParameters"/> object
60  /// containing the security and order</param>
61  /// <returns>The fee of the order</returns>
62  public override OrderFee GetOrderFee(OrderFeeParameters parameters)
63  {
64  var order = parameters.Order;
65  var security = parameters.Security;
66 
67  var isBuy = order.Direction == OrderDirection.Buy;
68  var unitPrice = isBuy ? security.AskPrice : security.BidPrice;
69 
70  if (order.Type == OrderType.Limit)
71  {
72  // limit order posted to the order book
73  unitPrice = ((LimitOrder)order).LimitPrice;
74  }
75 
76  unitPrice *= security.SymbolProperties.ContractMultiplier;
77 
78  var fee = TakerTier1CryptoFee;
79 
80  var props = order.Properties as KrakenOrderProperties;
81 
82  if (order.Type == OrderType.Limit &&
83  (props?.PostOnly == true || !order.IsMarketable))
84  {
85  // limit order posted to the order book
86  fee = MakerTier1CryptoFee;
87  }
88 
89  if (isBuy && props?.FeeInBase == true)
90  {
91  isBuy = false;
92  }
93 
94  if (!isBuy && props?.FeeInQuote == true)
95  {
96  isBuy = true;
97  }
98 
99  if (FxStablecoinList.Any(i => security.Symbol.Value.StartsWith(i)))
100  {
101  fee = Tier1FxFee;
102  }
103  string actualBaseCurrency;
104  string actualQuoteCurrency;
105 
106  CurrencyPairUtil.DecomposeCurrencyPair(security.Symbol, out actualBaseCurrency, out actualQuoteCurrency);
107 
108  return new OrderFee(new CashAmount(
109  isBuy ? unitPrice * order.AbsoluteQuantity * fee : 1 * order.AbsoluteQuantity * fee,
110  isBuy ? actualQuoteCurrency : actualBaseCurrency));
111  }
112  }
113 }