Skip to content

Commit

Permalink
Return null on unsupported history and data download requests
Browse files Browse the repository at this point in the history
  • Loading branch information
jhonabreul committed Feb 26, 2024
1 parent ed78c45 commit 552c56a
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,74 +27,73 @@ namespace QuantConnect.Tests.Brokerages.Zerodha
[TestFixture, Ignore("This test requires a configured and active Zerodha account")]
public class ZerodhaBrokerageHistoryProviderTests
{
private static TestCaseData[] TestParameters
private static TestCaseData[] TestParameters
{
get
{
get
return new[]
{
return new[]
{
// valid parameters
new TestCaseData(Symbols.SBIN, Resolution.Tick, Time.OneMinute, false),
new TestCaseData(Symbols.SBIN, Resolution.Second, Time.OneMinute, false),
new TestCaseData(Symbols.SBIN, Resolution.Minute, Time.OneHour, false),
new TestCaseData(Symbols.SBIN, Resolution.Hour, Time.OneDay, false),
new TestCaseData(Symbols.SBIN, Resolution.Daily, TimeSpan.FromDays(15), false),
new TestCaseData(Symbols.SBIN, Resolution.Minute, Time.OneHour, typeof(TradeBar), false),
new TestCaseData(Symbols.SBIN, Resolution.Hour, Time.OneDay, typeof(TradeBar), false),
new TestCaseData(Symbols.SBIN, Resolution.Daily, TimeSpan.FromDays(15), typeof(TradeBar), false),

// invalid period, throws "System.ArgumentException : Invalid date range specified"
new TestCaseData(Symbols.SBIN, Resolution.Daily, TimeSpan.FromDays(-15), true),
// invalid period
new TestCaseData(Symbols.SBIN, Resolution.Daily, TimeSpan.FromDays(-15), typeof(TradeBar), true),

// invalid security type, throws "System.ArgumentException : Invalid security type: Forex"
new TestCaseData(Symbols.EURUSD, Resolution.Daily, TimeSpan.FromDays(15), true)
// invalid security type
new TestCaseData(Symbols.EURUSD, Resolution.Daily, TimeSpan.FromDays(15), typeof(TradeBar), true),

// invalid resolution
new TestCaseData(Symbols.SBIN, Resolution.Tick, Time.OneMinute, typeof(TradeBar), true),
new TestCaseData(Symbols.SBIN, Resolution.Second, Time.OneMinute, typeof(TradeBar), true),

// invalid data type
new TestCaseData(Symbols.SBIN, Resolution.Minute, Time.OneHour, typeof(QuoteBar), true),
};
}
}
}

[Test, TestCaseSource(nameof(TestParameters))]
public void GetsHistory(Symbol symbol, Resolution resolution, TimeSpan period, bool throwsException)
{
TestDelegate test = () =>
{
var accessToken = Config.Get("zerodha-access-token");
var apiKey = Config.Get("zerodha-api-key");
var tradingSegment = Config.Get("zerodha-trading-segment");
var productType = Config.Get("zerodha-product-type");
var brokerage = new ZerodhaBrokerage(tradingSegment, productType, apiKey, accessToken, null,null,null);
[Test, TestCaseSource(nameof(TestParameters))]
public void GetsHistory(Symbol symbol, Resolution resolution, TimeSpan period, Type dataType, bool unsupported)
{
var accessToken = Config.Get("zerodha-access-token");
var apiKey = Config.Get("zerodha-api-key");
var tradingSegment = Config.Get("zerodha-trading-segment");
var productType = Config.Get("zerodha-product-type");
var brokerage = new ZerodhaBrokerage(tradingSegment, productType, apiKey, accessToken, null, null, null);

var now = DateTime.UtcNow;
var now = DateTime.UtcNow;

var request = new HistoryRequest(now.Add(-period),
now,
typeof(QuoteBar),
symbol,
resolution,
SecurityExchangeHours.AlwaysOpen(TimeZones.Kolkata),
TimeZones.Kolkata,
Resolution.Minute,
false,
false,
DataNormalizationMode.Adjusted,
TickType.Quote)
{ };
var request = new HistoryRequest(now.Add(-period),
now,
dataType,
symbol,
resolution,
SecurityExchangeHours.AlwaysOpen(TimeZones.Kolkata),
TimeZones.Kolkata,
Resolution.Minute,
false,
false,
DataNormalizationMode.Adjusted,
TickType.Trade);

var history = brokerage.GetHistory(request);

var history = brokerage.GetHistory(request);
if (unsupported)
{
Assert.IsNull(history);
return;
}

foreach (var slice in history)
{
Log.Trace("{0}: {1} - {2} / {3}", slice.Time, slice.Symbol, slice.Price, slice.IsFillForward);
}
Assert.IsNotNull(history);

Log.Trace("Base currency: " + brokerage.AccountBaseCurrency);
};

if (throwsException)
{
Assert.Throws<ArgumentException>(test);
}
else
{
Assert.DoesNotThrow(test);
}
}
foreach (var slice in history)
{
Log.Trace("{0}: {1} - {2} / {3}", slice.Time, slice.Symbol, slice.Price, slice.IsFillForward);
}

Log.Trace("Base currency: " + brokerage.AccountBaseCurrency);
}
}
}
65 changes: 36 additions & 29 deletions QuantConnect.ZerodhaBrokerage/ZerodhaBrokerage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ public partial class ZerodhaBrokerage : Brokerage, IDataQueueHandler
private DateTime _lastTradeTickTime;
private bool _historyDataTypeErrorFlag;
private bool _isInitialized;
private bool _historySecurityTypeErrorFlag;
private bool _historyResolutionErrorFlag;
private bool _historyDateRangeErrorFlag;

#endregion Declarations

Expand Down Expand Up @@ -859,43 +862,50 @@ public override List<CashAmount> GetCashBalance()
/// <returns>An enumerable of bars covering the span specified in the request</returns>
public override IEnumerable<BaseData> GetHistory(HistoryRequest request)
{
if (request.DataType != typeof(TradeBar) && !_historyDataTypeErrorFlag)
if (request.DataType != typeof(TradeBar))
{
OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, "InvalidBarType",
$"{request.DataType} type not supported, no history returned"));
_historyDataTypeErrorFlag = true;
yield break;
if (!_historyDataTypeErrorFlag)
{
OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, "InvalidBarType",
$"{request.DataType} type not supported, no history returned"));
_historyDataTypeErrorFlag = true;
}
return null;
}

if (request.Symbol.SecurityType != SecurityType.Equity && request.Symbol.SecurityType != SecurityType.Future && request.Symbol.SecurityType != SecurityType.Option)
if (request.Symbol.SecurityType != SecurityType.Equity &&
request.Symbol.SecurityType != SecurityType.Future &&
request.Symbol.SecurityType != SecurityType.Option)
{
OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, "InvalidSecurityType",
$"{request.Symbol.SecurityType} security type not supported, no history returned"));
yield break;
if (!_historySecurityTypeErrorFlag)
{
OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, "InvalidSecurityType",
$"{request.Symbol.SecurityType} security type not supported, no history returned"));
_historySecurityTypeErrorFlag = true;
}
return null;
}

if (request.Resolution == Resolution.Tick || request.Resolution == Resolution.Second)
{
OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, "InvalidResolution",
$"{request.Resolution} resolution not supported, no history returned"));
yield break;
}

if (request.StartTimeUtc >= request.EndTimeUtc)
{
OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, "InvalidDateRange",
"The history request start date must precede the end date, no history returned"));
yield break;
}

if (request.Symbol.ID.SecurityType != SecurityType.Equity && request.Symbol.ID.SecurityType != SecurityType.Future && request.Symbol.ID.SecurityType != SecurityType.Option)
{
throw new ArgumentException("Zerodha does not support this security type: " + request.Symbol.ID.SecurityType);
if (!_historyResolutionErrorFlag)
{
OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, "InvalidResolution",
$"{request.Resolution} resolution not supported, no history returned"));
_historyResolutionErrorFlag = true;
}
return null;
}

if (request.StartTimeUtc >= request.EndTimeUtc)
{
throw new ArgumentException("Invalid date range specified");
if (!_historyDateRangeErrorFlag)
{
OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, "InvalidDateRange",
"The history request start date must precede the end date, no history returned"));
_historyDateRangeErrorFlag = true;
}
return null;
}

var history = Enumerable.Empty<BaseData>();
Expand Down Expand Up @@ -924,10 +934,7 @@ public override IEnumerable<BaseData> GetHistory(HistoryRequest request)
}
}

foreach (var baseData in history)
{
yield return baseData;
}
return history;
}

private void Initialize(string tradingSegment, string zerodhaProductType, string apiKey, string apiSecret,
Expand Down

0 comments on commit 552c56a

Please sign in to comment.