Skip to content

Commit

Permalink
Merge pull request #43 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 and data download requests
  • Loading branch information
jhonabreul authored Feb 27, 2024
2 parents 7016508 + d0c7db4 commit 82bb5a6
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 154 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ private static TestCaseData[] TestParameters
{
get
{
TestGlobals.Initialize();
return new[]
{
new TestCaseData(Symbol.Create("EURUSD", SecurityType.Crypto, Market.Kraken), Resolution.Tick, 10000, false),
Expand Down
174 changes: 76 additions & 98 deletions QuantConnect.KrakenBrokerage.Tests/KrakenHistoryProviderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,106 +20,65 @@
using QuantConnect.Brokerages.Kraken;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Lean.Engine.DataFeeds;
using QuantConnect.Lean.Engine.HistoricalData;
using QuantConnect.Logging;
using QuantConnect.Securities;

namespace QuantConnect.Tests.Brokerages.Kraken
{
public partial class KrakenBrokerageTests
{
[Test]
[TestCaseSource(nameof(ValidHistory))]
[TestCaseSource(nameof(InvalidHistory))]
public void GetsHistory(Symbol symbol, Resolution resolution, TimeSpan period, bool throwsException)
private static Symbol _ethusd;
private static Symbol ETHUSD
{
TestDelegate test = () =>
get
{
var brokerage = (KrakenBrokerage)Brokerage;

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

var now = DateTime.UtcNow;

var requests = new[]
if (_ethusd == null)
{
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);

foreach (var slice in history)
{
var bar = slice.Bars[symbol];

Log.Debug($"{bar.Time}: {bar}");
TestGlobals.Initialize();
_ethusd = Symbol.Create("ETHUSD", SecurityType.Crypto, Market.Kraken);
}

Log.Trace("Data points retrieved: " + historyProvider.DataPointCount);
};

if (throwsException)
{
Assert.Throws<ArgumentException>(test);
}
else
{
Assert.DoesNotThrow(test);
return _ethusd;
}
}

[Test]
[TestCaseSource(nameof(NoHistory))]
public void GetEmptyHistory(Symbol symbol, Resolution resolution, TimeSpan period)
[TestCaseSource(nameof(ValidHistory))]
[TestCaseSource(nameof(InvalidHistory))]
public void GetsHistory(Symbol symbol, Resolution resolution, TickType tickType, TimeSpan period, bool unsupported)
{
TestDelegate test = () =>
var brokerage = unsupported ? TestableKrakenBrokerage.Create() : (KrakenBrokerage)Brokerage;

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 brokerage = (KrakenBrokerage)Brokerage;

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

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)
};
Assert.IsNull(history);
return;
}

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

Log.Trace("Data points retrieved: " + historyProvider.DataPointCount);
Assert.AreEqual(0, historyProvider.DataPointCount);
Assert.IsEmpty(history);
};
foreach (var bar in history.Cast<TradeBar>())
{
Log.Debug($"{bar.Time}: {bar}");
}

Assert.DoesNotThrow(test);
Log.Trace("Data points retrieved: " + history.Count);
}

private static TestCaseData[] ValidHistory
Expand All @@ -129,40 +88,59 @@ private static TestCaseData[] ValidHistory
return new[]
{
// valid
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.Crypto, Market.Kraken), Resolution.Tick, Time.OneHour, false),
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.Crypto, Market.Kraken), Resolution.Minute, Time.OneDay, false),
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.Crypto, Market.Kraken), Resolution.Hour, TimeSpan.FromDays(30), false),
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.Crypto, Market.Kraken), Resolution.Daily, TimeSpan.FromDays(15), false),
new TestCaseData(ETHUSD, Resolution.Tick, TickType.Trade, Time.OneHour, false),
new TestCaseData(ETHUSD, Resolution.Minute, TickType.Trade, Time.OneDay, false),
new TestCaseData(ETHUSD, Resolution.Hour, TickType.Trade, TimeSpan.FromDays(30), false),
new TestCaseData(ETHUSD, Resolution.Daily, TickType.Trade, TimeSpan.FromDays(15), false),
};
}
}

private static TestCaseData[] NoHistory
private static TestCaseData[] InvalidHistory
{
get
{
TestGlobals.Initialize();
return new[]
{
new TestCaseData(Symbol.Create("ETHUSD", SecurityType.Crypto, Market.Kraken), Resolution.Second, Time.OneMinute),

// invalid security type, no error, empty result"
new TestCaseData(Symbols.AAPL, Resolution.Daily, TimeSpan.FromDays(15)),

// invalid period, no error, empty result
new TestCaseData(Symbols.EURUSD, Resolution.Daily, TimeSpan.FromDays(-15)),
// invalid symbol
new TestCaseData(Symbol.Create("XYZ", SecurityType.Crypto, Market.Kraken), Resolution.Daily, TickType.Trade, TimeSpan.FromDays(15), true),

// invalid security type
new TestCaseData(Symbols.AAPL, Resolution.Daily, TickType.Trade, TimeSpan.FromDays(15), true),

// invalid resolution
new TestCaseData(ETHUSD, Resolution.Second, TickType.Trade, TimeSpan.FromDays(15), true),

// invalid tick type
new TestCaseData(ETHUSD, Resolution.Daily, TickType.Quote, TimeSpan.FromDays(15), true),
new TestCaseData(ETHUSD, Resolution.Daily, TickType.OpenInterest, TimeSpan.FromDays(15), true),

// invalid period
new TestCaseData(ETHUSD, Resolution.Daily, TickType.Trade, TimeSpan.FromDays(-15), true),

};
}
}

private static TestCaseData[] InvalidHistory
private class TestableKrakenBrokerage : KrakenBrokerage
{
get
public TestableKrakenBrokerage()
{
return new[]
{
// invalid symbol, throws "System.ArgumentException : Unknown symbol: XYZ"
new TestCaseData(Symbol.Create("XYZ", SecurityType.Crypto, Market.Kraken), Resolution.Daily, TimeSpan.FromDays(15), true)
};
}

public override void Connect()
{
}

public static TestableKrakenBrokerage Create()
{
var brokerage = new TestableKrakenBrokerage();

var factory = new KrakenBrokerageFactory();
brokerage.SetJob(new Packets.LiveNodePacket() { BrokerageData = factory.BrokerageData });

return brokerage;
}
}
}
Expand Down
21 changes: 1 addition & 20 deletions QuantConnect.KrakenBrokerage.ToolBox/KrakenDataDownloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,6 @@ public IEnumerable<BaseData> Get(DataDownloaderGetParameters dataDownloaderGetPa
var resolution = dataDownloaderGetParameters.Resolution;
var startUtc = dataDownloaderGetParameters.StartUtc;
var endUtc = dataDownloaderGetParameters.EndUtc;
var tickType = dataDownloaderGetParameters.TickType;

if (tickType != TickType.Trade)
{
yield break;
}

if (endUtc < startUtc)
{
throw new ArgumentException("The end date must be greater or equal than the start date.");
}

if (!_symbolMapper.IsKnownLeanSymbol(symbol))
{
throw new ArgumentException($"The ticker {symbol.Value} is not available in Kraken. Use Lean symbols for downloader (i.e BTCUSD, not XXBTZUSD)");
}

var historyRequest = new HistoryRequest(
startUtc,
Expand All @@ -85,10 +69,7 @@ public IEnumerable<BaseData> Get(DataDownloaderGetParameters dataDownloaderGetPa
DataNormalizationMode.Adjusted,
TickType.Trade);

foreach (var baseData in _brokerage.GetHistory(historyRequest))
{
yield return baseData;
}
return _brokerage.GetHistory(historyRequest);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,13 @@ public static void KrakenDownloader(IList<string> tickers, string resolution, Da
// Download data
var pairObject = Symbol.Create(pair, SecurityType.Crypto, Market.Kraken);
var data = downloader.Get(new DataDownloaderGetParameters(pairObject, castResolution == Resolution.Second ? Resolution.Tick : castResolution, startDate, endDate));
if (data == null)
{
continue;
}

var bars = data.Cast<TradeBar>().ToList();

// Write data
var writer = new LeanDataWriter(castResolution, pairObject, dataDirectory);

Expand All @@ -71,7 +76,7 @@ public static void KrakenDownloader(IList<string> tickers, string resolution, Da
Log.Error(err);
}
}

/// <summary>
/// Endpoint for downloading exchange info
/// </summary>
Expand Down
Loading

0 comments on commit 82bb5a6

Please sign in to comment.