Skip to content

Commit

Permalink
Merge pull request #34 from jhonabreul/feature-null-history-for-unsup…
Browse files Browse the repository at this point in the history
…ported-securities

 Return null on unsupported history requests
  • Loading branch information
jhonabreul authored Feb 27, 2024
2 parents 8f4d06d + fa79be1 commit 2759a9a
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 262 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
* 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");
*
* 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.
Expand All @@ -18,6 +18,7 @@
using QuantConnect.Data.Market;
using QuantConnect.Interfaces;
using QuantConnect.Logging;
using QuantConnect.Tests;
using System;
using System.Threading;

Expand All @@ -30,6 +31,7 @@ private static TestCaseData[] TestParameters
{
get
{
TestGlobals.Initialize();
var FTM_USDT = Symbol.Create("FTMUSDT", SecurityType.Crypto, Market.Binance);

return new[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,11 @@
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Lean.Engine.DataFeeds;
using QuantConnect.Lean.Engine.HistoricalData;
using QuantConnect.Logging;
using QuantConnect.Securities;
using QuantConnect.Tests;
using System;
using System.Linq;
using QuantConnect.Lean.Engine.Storage;
using QuantConnect.Storage;

namespace QuantConnect.BinanceBrokerage.Tests
{
Expand All @@ -39,6 +36,7 @@ public class BinanceBrokerageHistoryProviderTests
[OneTimeSetUp]
public void Setup()
{
TestGlobals.Initialize();
_brokerage = CreateBrokerage();
}

Expand All @@ -52,109 +50,44 @@ public void TearDown()
[Test]
[TestCaseSource(nameof(ValidHistory))]
[TestCaseSource(nameof(InvalidHistory))]
public virtual void GetsHistory(Symbol symbol, Resolution resolution, TimeSpan period, bool throwsException)
public virtual void GetsHistory(Symbol symbol, Resolution resolution, TimeSpan period, TickType tickType, bool unsupported)
{
BaseHistoryTest(symbol, resolution, period, throwsException, _brokerage);
BaseHistoryTest(symbol, resolution, period, tickType, unsupported, _brokerage);
}

[Test]
[TestCaseSource(nameof(NoHistory))]
public virtual void GetEmptyHistory(Symbol symbol, Resolution resolution, TimeSpan period, TickType tickType)
public static void BaseHistoryTest(Symbol symbol, Resolution resolution, TimeSpan period, TickType tickType, bool unsupported, Brokerage brokerage)
{
BaseEmptyHistoryTest(symbol, resolution, period, tickType, _brokerage);
}

public static void BaseEmptyHistoryTest(Symbol symbol, Resolution resolution, TimeSpan period, TickType tickType, Brokerage brokerage)
{
TestDelegate test = () =>
var now = DateTime.UtcNow;
var request = new HistoryRequest(now.Add(-period),
now,
typeof(TradeBar),
symbol,
resolution,
SecurityExchangeHours.AlwaysOpen(TimeZones.Utc),
DateTimeZone.Utc,
Resolution.Minute,
false,
false,
DataNormalizationMode.Adjusted,
tickType);

var history = brokerage.GetHistory(request)?.ToList();

if (unsupported)
{
var historyProvider = new BrokerageHistoryProvider();
historyProvider.SetBrokerage(brokerage);
historyProvider.Initialize(new HistoryProviderInitializeParameters(null, null, null, null, null, null, null, false, new DataPermissionManager(), new LocalObjectStore()));

var now = DateTime.UtcNow;

var requests = new[]
{
new HistoryRequest(now.Add(-period),
now,
typeof(TradeBar),
symbol,
resolution,
SecurityExchangeHours.AlwaysOpen(TimeZones.Utc),
DateTimeZone.Utc,
Resolution.Minute,
false,
false,
DataNormalizationMode.Adjusted,
tickType)
};

var history = historyProvider.GetHistory(requests, TimeZones.Utc).ToList();

Log.Trace("Data points retrieved: " + historyProvider.DataPointCount);
Assert.AreEqual(0, historyProvider.DataPointCount);
};

Assert.DoesNotThrow(test);
}

public static void BaseHistoryTest(Symbol symbol, Resolution resolution, TimeSpan period, bool throwsException, Brokerage brokerage)
{
TestDelegate test = () =>
Assert.IsNull(history);
}
else
{
var historyProvider = new BrokerageHistoryProvider();
historyProvider.SetBrokerage(brokerage);
historyProvider.Initialize(new HistoryProviderInitializeParameters(null, null, null, null, null, null, null, false, new DataPermissionManager(), new LocalObjectStore()));

var now = DateTime.UtcNow;

var requests = new[]
{
new HistoryRequest(now.Add(-period),
now,
typeof(TradeBar),
symbol,
resolution,
SecurityExchangeHours.AlwaysOpen(TimeZones.Utc),
DateTimeZone.Utc,
Resolution.Minute,
false,
false,
DataNormalizationMode.Adjusted,
TickType.Trade)
};

var history = historyProvider.GetHistory(requests, TimeZones.Utc);
Assert.IsNotNull(history);

foreach (var slice in history)
foreach (var bar in history.Cast<TradeBar>())
{
if (resolution == Resolution.Tick)
{
foreach (var tick in slice.Ticks[symbol])
{
Log.Trace("{0}: {1} - {2} / {3}", tick.Time.ToStringInvariant("yyyy-MM-dd HH:mm:ss.fff"), tick.Symbol, tick.BidPrice, tick.AskPrice);
}
}
else
{
var bar = slice.Bars[symbol];

Log.Trace("{0}: {1} - O={2}, H={3}, L={4}, C={5}", bar.Time, bar.Symbol, bar.Open, bar.High, bar.Low, bar.Close);
}
Log.Trace("{0}: {1} - O={2}, H={3}, L={4}, C={5}", bar.Time, bar.Symbol, bar.Open, bar.High, bar.Low, bar.Close);
}

Assert.Greater(historyProvider.DataPointCount, 0);
Log.Debug("Data points retrieved: " + historyProvider.DataPointCount);
};

if (throwsException)
{
Assert.Throws<ArgumentException>(test);
}
else
{
Assert.DoesNotThrow(test);
Assert.Greater(history.Count, 0);
Log.Debug("Data points retrieved: " + history.Count);
}
}

Expand All @@ -164,23 +97,9 @@ private static TestCaseData[] ValidHistory
{
return new[]
{
// valid
new TestCaseData(Symbol.Create("ETHUSDT", SecurityType.Crypto, Market.Binance), Resolution.Minute, Time.OneHour, false),
new TestCaseData(Symbol.Create("ETHUSDT", SecurityType.Crypto, Market.Binance), Resolution.Hour, Time.OneDay, false),
new TestCaseData(Symbol.Create("ETHUSDT", SecurityType.Crypto, Market.Binance), Resolution.Daily, TimeSpan.FromDays(15), false),
};
}
}

private static TestCaseData[] NoHistory
{
get
{
return new[]
{
new TestCaseData(Symbol.Create("ETHUSDT", SecurityType.Crypto, Market.Binance), Resolution.Tick, TimeSpan.FromSeconds(15), TickType.Trade),
new TestCaseData(Symbol.Create("ETHUSDT", SecurityType.Crypto, Market.Binance), Resolution.Second, Time.OneMinute, TickType.Trade),
new TestCaseData(Symbol.Create("ETHUSDT", SecurityType.Crypto, Market.Binance), Resolution.Minute, Time.OneHour, TickType.Quote),
new TestCaseData(Symbol.Create("ETHUSDT", SecurityType.Crypto, Market.Binance), Resolution.Minute, Time.OneHour, TickType.Trade, false),
new TestCaseData(Symbol.Create("ETHUSDT", SecurityType.Crypto, Market.Binance), Resolution.Hour, Time.OneDay, TickType.Trade, false),
new TestCaseData(Symbol.Create("ETHUSDT", SecurityType.Crypto, Market.Binance), Resolution.Daily, TimeSpan.FromDays(15), TickType.Trade, false),
};
}
}
Expand All @@ -191,14 +110,21 @@ private static TestCaseData[] InvalidHistory
{
return new[]
{
// invalid period, no error, empty result
new TestCaseData(Symbols.EURUSD, Resolution.Daily, TimeSpan.FromDays(-15), false),

// invalid symbol, throws "System.ArgumentException : Unknown symbol: XYZ"
new TestCaseData(Symbol.Create("XYZ", SecurityType.Crypto, Market.Binance), Resolution.Daily, TimeSpan.FromDays(15), true),

// invalid security type, throws "System.ArgumentException : Invalid security type: Equity"
new TestCaseData(Symbols.AAPL, Resolution.Daily, TimeSpan.FromDays(15), false),
// invalid period
new TestCaseData(Symbol.Create("ETHUSDT", SecurityType.Crypto, Market.Binance), Resolution.Daily, TimeSpan.FromDays(-15), TickType.Trade, true),
// invalid symbol
new TestCaseData(Symbol.Create("XYZ", SecurityType.Crypto, Market.Binance), Resolution.Daily, TimeSpan.FromDays(15), TickType.Trade, true),
// invalid security type
new TestCaseData(Symbols.AAPL, Resolution.Daily, TimeSpan.FromDays(15), TickType.Trade, true),
new TestCaseData(Symbols.USDJPY, Resolution.Daily, TimeSpan.FromDays(15), TickType.Trade, true),
// invalid market
new TestCaseData(Symbol.Create("ETHUSDT", SecurityType.Crypto, Market.BinanceUS), Resolution.Daily, TimeSpan.FromDays(15), TickType.Trade, true),
// invalid resolution
new TestCaseData(Symbol.Create("ETHUSDT", SecurityType.Crypto, Market.Binance), Resolution.Tick, TimeSpan.FromSeconds(15), TickType.Trade, true),
new TestCaseData(Symbol.Create("ETHUSDT", SecurityType.Crypto, Market.Binance), Resolution.Second, Time.OneMinute, TickType.Trade, true),
// Invalid tick type
new TestCaseData(Symbol.Create("ETHUSDT", SecurityType.Crypto, Market.Binance), Resolution.Minute, Time.OneHour, TickType.Quote, true),
new TestCaseData(Symbol.Create("ETHUSDT", SecurityType.Crypto, Market.Binance), Resolution.Minute, Time.OneHour, TickType.OpenInterest, true),
};
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,9 @@ public void TearDown()
[Test]
[TestCaseSource(nameof(ValidHistory))]
[TestCaseSource(nameof(InvalidHistory))]
public virtual void GetsHistory(Symbol symbol, Resolution resolution, TimeSpan period, bool throwsException)
public virtual void GetsHistory(Symbol symbol, Resolution resolution, TimeSpan period, TickType tickType, bool unsupported)
{
BinanceBrokerageHistoryProviderTests.BaseHistoryTest(symbol, resolution, period, throwsException, _brokerage);
}

[Test]
[TestCaseSource(nameof(NoHistory))]
public virtual void GetEmptyHistory(Symbol symbol, Resolution resolution, TimeSpan period, TickType tickType)
{
BinanceBrokerageHistoryProviderTests.BaseEmptyHistoryTest(symbol, resolution, period, tickType, _brokerage);
BinanceBrokerageHistoryProviderTests.BaseHistoryTest(symbol, resolution, period, tickType, unsupported, _brokerage);
}

private static TestCaseData[] ValidHistory
Expand All @@ -62,22 +55,9 @@ private static TestCaseData[] ValidHistory
return new[]
{
// valid
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.CryptoFuture, Market.Binance), Resolution.Minute, Time.OneHour, false),
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.CryptoFuture, Market.Binance), Resolution.Hour, Time.OneDay, false),
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.CryptoFuture, Market.Binance), Resolution.Daily, TimeSpan.FromDays(15), false),
};
}
}

private static TestCaseData[] NoHistory
{
get
{
return new[]
{
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.CryptoFuture, Market.Binance), Resolution.Tick, TimeSpan.FromSeconds(15), TickType.Trade),
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.CryptoFuture, Market.Binance), Resolution.Second, Time.OneMinute, TickType.Trade),
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.CryptoFuture, Market.Binance), Resolution.Minute, Time.OneHour, TickType.Quote),
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.CryptoFuture, Market.Binance), Resolution.Minute, Time.OneHour, TickType.Trade, false),
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.CryptoFuture, Market.Binance), Resolution.Hour, Time.OneDay, TickType.Trade, false),
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.CryptoFuture, Market.Binance), Resolution.Daily, TimeSpan.FromDays(15), TickType.Trade, false),
};
}
}
Expand All @@ -88,14 +68,20 @@ private static TestCaseData[] InvalidHistory
{
return new[]
{
// invalid period, no error, empty result
new TestCaseData(Symbols.EURUSD, Resolution.Daily, TimeSpan.FromDays(-15), false),

// invalid symbol, throws "System.ArgumentException : Unknown symbol: XYZ"
new TestCaseData(Symbol.Create("XYZ", SecurityType.CryptoFuture, Market.Binance), Resolution.Daily, TimeSpan.FromDays(15), true),

// invalid security type, throws "System.ArgumentException : Invalid security type: Equity"
new TestCaseData(Symbols.AAPL, Resolution.Daily, TimeSpan.FromDays(15), false),
// invalid period
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.CryptoFuture, Market.Binance), Resolution.Minute, TimeSpan.FromDays(-15), TickType.Trade, true),
// Invalid type of future
new TestCaseData(Symbol.Create("ETHUSDT", SecurityType.CryptoFuture, Market.Binance), Resolution.Minute, TimeSpan.FromSeconds(15), TickType.Trade, true),
// invalid resolution
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.CryptoFuture, Market.Binance), Resolution.Tick, TimeSpan.FromSeconds(15), TickType.Trade, true),
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.CryptoFuture, Market.Binance), Resolution.Second, Time.OneMinute, TickType.Trade, true),
// invalid tick type
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.CryptoFuture, Market.Binance), Resolution.Minute, Time.OneHour, TickType.Quote, true),
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.CryptoFuture, Market.Binance), Resolution.Minute, Time.OneHour, TickType.OpenInterest, true),
// invalid symbol
new TestCaseData(Symbol.Create("XYZ", SecurityType.CryptoFuture, Market.Binance), Resolution.Daily, TimeSpan.FromDays(15), TickType.Trade, true),
// invalid security type
new TestCaseData(Symbols.AAPL, Resolution.Daily, TimeSpan.FromDays(15), TickType.Trade, true),
};
}
}
Expand Down
Loading

0 comments on commit 2759a9a

Please sign in to comment.