Skip to content

Commit

Permalink
Merge pull request #29 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 b12171e + 291aeb9 commit d4b5566
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ private static TestCaseData[] TestParameters
{
get
{
var seasEquity = Symbol.Create("SEAS", SecurityType.Equity, Market.USA);
var seasOptionSymbol = Symbol.CreateOption(seasEquity, Market.USA, OptionStyle.American, OptionRight.Call, 50, new DateTime(2022, 8, 19));

return new[]
{
// valid parameters
Expand All @@ -55,17 +52,15 @@ private static TestCaseData[] TestParameters
new TestCaseData(Symbols.AAPL, Resolution.Hour, false, 7 * 2, TickType.Trade),
new TestCaseData(Symbols.AAPL, Resolution.Daily, false, 6, TickType.Trade),

// invalid data type, returns empty response
new TestCaseData(Symbols.AAPL, Resolution.Minute, false, 0, TickType.Quote),
new TestCaseData(Symbols.AAPL, Resolution.Minute, false, 0, TickType.OpenInterest),

new TestCaseData(seasOptionSymbol, Resolution.Daily, false, 0, TickType.Trade),
// invalid tick type, null result
new TestCaseData(Symbols.AAPL, Resolution.Minute, true, 0, TickType.Quote),
new TestCaseData(Symbols.AAPL, Resolution.Minute, true, 0, TickType.OpenInterest),

// invalid canonical symbo, throws "System.ArgumentException : Invalid symbol, cannot use canonical"
// canonical symbol, null result
new TestCaseData(Symbols.SPY_Option_Chain, Resolution.Daily, true, 0, TickType.Trade),

// invalid security type, throws "System.ArgumentException : Invalid security type: Forex"
new TestCaseData(Symbols.EURUSD, Resolution.Daily, true, 0, TickType.Trade),
// invalid security type, null result
new TestCaseData(Symbols.EURUSD, Resolution.Daily, true, 0, TickType.Trade)
};
}
}
Expand All @@ -90,7 +85,7 @@ public void TearDown()
}

[Test, TestCaseSource(nameof(TestParameters))]
public void GetsHistory(Symbol symbol, Resolution resolution, bool throwsException, int expectedCount, TickType tickType)
public void GetsHistory(Symbol symbol, Resolution resolution, bool unsupported, int expectedCount, TickType tickType)
{
if (_useSandbox && (resolution == Resolution.Tick || resolution == Resolution.Second))
{
Expand All @@ -104,9 +99,9 @@ public void GetsHistory(Symbol symbol, Resolution resolution, bool throwsExcepti
var request = new HistoryRequest(startUtc, endUtc, LeanData.GetDataType(resolution, tickType), symbol, resolution, mhdb.ExchangeHours,
mhdb.DataTimeZone, null, false, false, DataNormalizationMode.Adjusted, tickType);

if (throwsException)
if (unsupported)
{
Assert.Throws<ArgumentException>(() => GetHistoryHelper(request));
Assert.IsNull(_brokerage.GetHistory(request));
}
else
{
Expand Down Expand Up @@ -197,7 +192,11 @@ private int GetHistoryHelper(HistoryRequest request)
{
var count = 0;
BaseData previous = null;
foreach (var data in _brokerage.GetHistory(request))
var history = _brokerage.GetHistory(request);

Assert.IsNotNull(history);

foreach (var data in history)
{
Assert.AreEqual(request.Resolution.ToTimeSpan(), data.EndTime - data.Time);

Expand Down
38 changes: 21 additions & 17 deletions QuantConnect.TradierBrokerage/TradierBrokerage.HistoryProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ namespace QuantConnect.Brokerages.Tradier
public partial class TradierBrokerage
{
private bool _loggedTradierSupportsOnlyTradeBars;
private bool _loggedUnsupportedAssetForHistory;
private bool _loggedInvalidTimeRangeForHistory;

/// <summary>
/// Gets the history for the requested security
Expand All @@ -40,19 +42,26 @@ public partial class TradierBrokerage
/// <returns>An enumerable of bars covering the span specified in the request</returns>
public override IEnumerable<BaseData> GetHistory(HistoryRequest request)
{
if (request.Symbol.ID.SecurityType != SecurityType.Equity && request.Symbol.ID.SecurityType != SecurityType.Option)
if (!CanSubscribe(request.Symbol))
{
throw new ArgumentException($"Invalid security type: {request.Symbol.ID.SecurityType}");
if (!_loggedUnsupportedAssetForHistory)
{
_loggedUnsupportedAssetForHistory = true;
_algorithm?.Debug("Warning: Tradier does not support this asset for history requests.");
Log.Error("TradierBrokerage.GetHistory(): Unsupported asset: " + request.Symbol.Value);
}
return null;
}

if (request.StartTimeUtc >= request.EndTimeUtc)
{
throw new ArgumentException("Invalid date range specified start time can not be after end time");
}

if (request.Symbol.IsCanonical())
{
throw new ArgumentException("Invalid symbol, cannot use canonical symbols for history request");
if (!_loggedInvalidTimeRangeForHistory)
{
_loggedInvalidTimeRangeForHistory = true;
_algorithm?.Debug("Warning: The request start date must precede the end date, no history returned.");
Log.Error("TradierBrokerage.GetHistory(): Invalid date range.");
}
return null;
}

if (request.TickType != TickType.Trade)
Expand All @@ -63,13 +72,12 @@ public override IEnumerable<BaseData> GetHistory(HistoryRequest request)
_algorithm?.Debug("Warning: Tradier history provider only supports trade information, does not support quotes.");
Log.Error("TradierBrokerage.GetHistory(): Tradier only supports TradeBars");
}
yield break;
return null;
}

var start = request.StartTimeUtc.ConvertTo(DateTimeZone.Utc, TimeZones.NewYork);
var end = request.EndTimeUtc.ConvertTo(DateTimeZone.Utc, TimeZones.NewYork);


IEnumerable<BaseData> history;
switch (request.Resolution)
{
Expand Down Expand Up @@ -97,13 +105,9 @@ public override IEnumerable<BaseData> GetHistory(HistoryRequest request)
throw new ArgumentException("Invalid date range specified");
}

foreach (var bar in history.Where(bar => bar.Time >= request.StartTimeLocal && bar.EndTime <= request.EndTimeLocal))
{
if (request.ExchangeHours.IsOpen(bar.Time, bar.EndTime, request.IncludeExtendedMarketHours))
{
yield return bar;
}
}
return history.Where(bar => bar.Time >= request.StartTimeLocal &&
bar.EndTime <= request.EndTimeLocal &&
request.ExchangeHours.IsOpen(bar.Time, bar.EndTime, request.IncludeExtendedMarketHours));
}

private IEnumerable<BaseData> GetHistoryTick(HistoryRequest request, DateTime start, DateTime end)
Expand Down

0 comments on commit d4b5566

Please sign in to comment.