Files
2026-07-13 13:02:50 +08:00

229 lines
8.3 KiB
C#

/*
* 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 NUnit.Framework;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Orders;
using QuantConnect.Orders.Fees;
using QuantConnect.Securities;
using QuantConnect.Securities.Crypto;
using System;
namespace QuantConnect.Tests.Common.Orders.Fees
{
[TestFixture]
public class FTXFeeTests
{
private Crypto _xrpusdt;
private Crypto _ethusd;
private IFeeModel _feeModel;
protected decimal TakerFee { get; set; }
protected decimal MakerFee { get; set; }
[SetUp]
public void Initialize()
{
_feeModel = GetFeeModel();
SetBrokerageFees();
var spdb = SymbolPropertiesDatabase.FromDataFolder();
var tz = TimeZones.Utc;
_xrpusdt = new Crypto(
SecurityExchangeHours.AlwaysOpen(tz),
new Cash("USDT", 0, 1),
new Cash("XRP", 0, 0),
new SubscriptionDataConfig(typeof(TradeBar), Symbol.Create("XRPUSDT", SecurityType.Crypto, Market.FTX), Resolution.Minute, tz, tz, true, false, false),
spdb.GetSymbolProperties(Market.FTX, Symbol.Create("XRPUSDT", SecurityType.Crypto, Market.FTX), SecurityType.Crypto, "USDT"),
ErrorCurrencyConverter.Instance,
RegisteredSecurityDataTypesProvider.Null
);
_xrpusdt.SetMarketPrice(new Tick(DateTime.UtcNow, _xrpusdt.Symbol, 100, 100));
_ethusd = new Crypto(
SecurityExchangeHours.AlwaysOpen(tz),
new Cash(Currencies.USD, 0, 10),
new Cash("ETH", 0, 0),
new SubscriptionDataConfig(typeof(TradeBar), Symbol.Create("ETHUSD", SecurityType.Crypto, Market.FTX), Resolution.Minute, tz, tz, true, false, false),
spdb.GetSymbolProperties(Market.FTX, Symbol.Create("ETHUSD", SecurityType.Crypto, Market.FTX), SecurityType.Crypto, Currencies.USD),
ErrorCurrencyConverter.Instance,
RegisteredSecurityDataTypesProvider.Null
);
_ethusd.SetMarketPrice(new Tick(DateTime.UtcNow, _ethusd.Symbol, 100, 100));
}
protected virtual void SetBrokerageFees()
{
MakerFee = 0.02m;
TakerFee = 0.07m;
}
[TestCase(-1)]
[TestCase(1)]
public void ReturnsTakerFeeInQuoteCurrency(decimal quantity)
{
//{
// "channel": "fills",
// "type": "update",
// "data": {
// "id": 4199228419,
// "market": "XRP/USDT",
// "future": null,
// "baseCurrency": "XRP",
// "quoteCurrency": "USDT",
// "type": "order",
// "side": "sell",
// "price": 1.07225,
// "size": 10,
// "orderId": 85922585621,
// "time": "2021-10-07T19:25:45.411201+00:00",
// "tradeId": 2084391649,
// "feeRate": 0.0007,
// "fee": 0.00750575,
// "feeCurrency": "USDT",
// "liquidity": "taker"
// }
//}
//{
// "channel": "fills",
// "type": "update",
// "data": {
// "id": 4199574804,
// "market": "XRP/USDT",
// "future": null,
// "baseCurrency": "XRP",
// "quoteCurrency": "USDT",
// "type": "order",
// "side": "buy",
// "price": 1.075725,
// "size": 1,
// "orderId": 85928918834,
// "time": "2021-10-07T20:02:07.116972+00:00",
// "tradeId": 2084563562,
// "feeRate": 0.0007,
// "fee": 0.0007530075,
// "feeCurrency": "USDT",
// "liquidity": "taker"
// }
//}
var fee = _feeModel.GetOrderFee(
new OrderFeeParameters(
_ethusd,
new MarketOrder(_ethusd.Symbol, quantity, DateTime.UtcNow)
)
);
Assert.AreEqual(_ethusd.QuoteCurrency.Symbol, fee.Value.Currency);
// 100 (price) * 0.0007 (taker fee, in quote currency)
Assert.AreEqual(TakerFee, fee.Value.Amount);
}
[Test]
public void ReturnsMakerFeeInQuoteCurrency()
{
//{
// "channel": "fills",
// "type": "update",
// "data": {
// "id": 4199162157,
// "market": "XRP/USDT",
// "future": null,
// "baseCurrency": "XRP",
// "quoteCurrency": "USDT",
// "type": "order",
// "side": "sell",
// "price": 1.074,
// "size": 1,
// "orderId": 85920785762,
// "time": "2021-10-07T19:19:27.092534+00:00",
// "tradeId": 2084358777,
// "feeRate": 0.0002,
// "fee": 0.0002148,
// "feeCurrency": "USDT",
// "liquidity": "maker"
// }
//}
var fee = _feeModel.GetOrderFee(
new OrderFeeParameters(
_ethusd,
new LimitOrder(_ethusd.Symbol, -1, 100, DateTime.UtcNow)
)
);
Assert.AreEqual(_ethusd.QuoteCurrency.Symbol, fee.Value.Currency);
// 0.0002 (maker fee, in quote currency)
Assert.AreEqual(MakerFee, fee.Value.Amount);
}
[Test]
public void ReturnsMakerFeeInBaseCurrency()
{
//{
// "channel": "fills",
// "type": "update",
// "data": {
// "id": 4199609111,
// "market": "XRP/USDT",
// "future": null,
// "baseCurrency": "XRP",
// "quoteCurrency": "USDT",
// "type": "order",
// "side": "buy",
// "price": 1.077,
// "size": 1,
// "orderId": 85929414038,
// "time": "2021-10-07T20:05:40.241875+00:00",
// "tradeId": 2084580551,
// "feeRate": 0.0002,
// "fee": 0.0002,
// "feeCurrency": "XRP",
// "liquidity": "maker"
// }
//}
var fee = _feeModel.GetOrderFee(
new OrderFeeParameters(
_ethusd,
new LimitOrder(_ethusd.Symbol, 1, 100, DateTime.UtcNow)
)
);
Assert.AreEqual(_ethusd.BaseCurrency.Symbol, fee.Value.Currency);
// 0.0002 (maker fee, in base currency)
Assert.AreEqual(MakerFee / 100, fee.Value.Amount);
}
[Test]
public void ReturnsFeeInQuoteCurrencyInNonAccountCurrency()
{
var fee = _feeModel.GetOrderFee(
new OrderFeeParameters(
_xrpusdt,
new MarketOrder(_xrpusdt.Symbol, 1, DateTime.UtcNow)
)
);
Assert.AreEqual("USDT", fee.Value.Currency);
// 100 (price) * 0.0007 (taker fee)
Assert.AreEqual(TakerFee, fee.Value.Amount);
}
protected virtual FTXFeeModel GetFeeModel() => new();
}
}