Skip to content

Commit 66c177c

Browse files
authored
Enhancements and Bug Fixes (#2)
* refactor: validation that user can subscribe on real time update * fix: config for Rest Url to run client externally * feat: handle WS's error response * feat: add explicit attribute for test classes * remove: not used configs * feat: ReSubscription process when internet was disconnected * fix:workflow: name of test dll * refactor: OptionChainProvider list refactor: GetOptionContracts in DataDownloader * fix: QuoteBars with Resolution greater then Tick feat: QuoteBar tests revert: data-folder path in config * refactor: name of variable
1 parent bfb96fa commit 66c177c

17 files changed

Lines changed: 243 additions & 76 deletions

.github/workflows/gh-actions.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,4 @@ jobs:
4646
run: dotnet build ./QuantConnect.ThetaData.Tests/QuantConnect.DataSource.ThetaData.Tests.csproj /p:Configuration=Release /v:quiet /p:WarningLevel=1
4747

4848
- name: Run QuantConnect.ThetaData.Tests
49-
run: dotnet test ./QuantConnect.ThetaData.Tests/bin/Release/QuantConnect.Lean.DataSource.ThetaData.dll
49+
run: dotnet test ./QuantConnect.ThetaData.Tests/bin/Release/QuantConnect.Lean.DataSource.ThetaData.Tests.dll

QuantConnect.ThetaData.Tests/TestHelpers.cs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,11 @@ public static void ValidateHistoricalBaseData(IEnumerable<BaseData> history, Res
5353
case TickType.Trade:
5454
AssertTradeTickBars(history.Select(x => x as Tick), requestedSymbol);
5555
break;
56+
case TickType.Quote when resolution == Resolution.Tick:
57+
AssertQuoteTickBars(history.Select(x => x as Tick), requestedSymbol);
58+
break;
5659
case TickType.Quote:
57-
AssertTickQuoteBars(history.Select(t => t as Tick), requestedSymbol);
60+
AssertQuoteBars(history.Select(t => t as QuoteBar), requestedSymbol, resolution.ToTimeSpan());
5861
break;
5962
}
6063
}
@@ -74,7 +77,7 @@ public static void AssertTradeTickBars(IEnumerable<Tick> ticks, Symbol symbol =
7477
}
7578
}
7679

77-
public static void AssertTickQuoteBars(IEnumerable<Tick> ticks, Symbol symbol = null)
80+
public static void AssertQuoteTickBars(IEnumerable<Tick> ticks, Symbol symbol = null)
7881
{
7982
foreach (var tick in ticks)
8083
{
@@ -94,6 +97,41 @@ public static void AssertTickQuoteBars(IEnumerable<Tick> ticks, Symbol symbol =
9497
}
9598
}
9699

100+
public static void AssertQuoteBars(IEnumerable<QuoteBar> ticks, Symbol symbol, TimeSpan resolutionInTimeSpan)
101+
{
102+
foreach (var tick in ticks)
103+
{
104+
if (symbol != null)
105+
{
106+
Assert.That(tick.Symbol, Is.EqualTo(symbol));
107+
}
108+
109+
Assert.That(tick.Ask.Open, Is.GreaterThan(0));
110+
Assert.That(tick.Ask.High, Is.GreaterThan(0));
111+
Assert.That(tick.Ask.Low, Is.GreaterThan(0));
112+
Assert.That(tick.Ask.Close, Is.GreaterThan(0));
113+
114+
Assert.That(tick.Bid.Open, Is.GreaterThan(0));
115+
Assert.That(tick.Bid.High, Is.GreaterThan(0));
116+
Assert.That(tick.Bid.Low, Is.GreaterThan(0));
117+
Assert.That(tick.Bid.Close, Is.GreaterThan(0));
118+
119+
Assert.That(tick.Close, Is.GreaterThan(0));
120+
Assert.That(tick.High, Is.GreaterThan(0));
121+
Assert.That(tick.Low, Is.GreaterThan(0));
122+
Assert.That(tick.Open, Is.GreaterThan(0));
123+
Assert.That(tick.Price, Is.GreaterThan(0));
124+
Assert.That(tick.Value, Is.GreaterThan(0));
125+
Assert.That(tick.DataType, Is.EqualTo(MarketDataType.QuoteBar));
126+
Assert.That(tick.EndTime, Is.GreaterThan(default(DateTime)));
127+
Assert.That(tick.Time, Is.GreaterThan(default(DateTime)));
128+
129+
Assert.That(tick.LastAskSize, Is.GreaterThan(0));
130+
Assert.That(tick.LastBidSize, Is.GreaterThan(0));
131+
Assert.That(tick.Period, Is.EqualTo(resolutionInTimeSpan));
132+
}
133+
}
134+
97135
public static void AssertTradeBars(IEnumerable<TradeBar> tradeBars, Symbol symbol, TimeSpan period)
98136
{
99137
foreach (var tradeBar in tradeBars)

QuantConnect.ThetaData.Tests/ThetaDataDownloaderTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ namespace QuantConnect.Lean.DataSource.ThetaData.Tests
2323
{
2424

2525
[TestFixture]
26+
[Explicit("This test requires the ThetaData terminal to be running in order to execute properly.")]
2627
public class ThetaDataDownloaderTests
2728
{
2829
private ThetaDataDownloader _dataDownloader;

QuantConnect.ThetaData.Tests/ThetaDataHistoryProviderTests..cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
namespace QuantConnect.Lean.DataSource.ThetaData.Tests
2121
{
2222
[TestFixture]
23+
[Explicit("This test requires the ThetaData terminal to be running in order to execute properly.")]
2324
public class ThetaDataHistoryProviderTests
2425
{
2526
ThetaDataProvider _thetaDataProvider = new();

QuantConnect.ThetaData.Tests/ThetaDataOptionChainProviderTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
namespace QuantConnect.Lean.DataSource.ThetaData.Tests
2626
{
2727
[TestFixture]
28+
[Explicit("This test requires the ThetaData terminal to be running in order to execute properly.")]
2829
public class ThetaDataOptionChainProviderTests
2930
{
3031
private ThetaDataOptionChainProvider _thetaDataOptionChainProvider;

QuantConnect.ThetaData.Tests/ThetaDataProviderTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
namespace QuantConnect.Lean.DataSource.ThetaData.Tests
3030
{
3131
[TestFixture]
32+
[Explicit("This test requires the ThetaData terminal to be running in order to execute properly.")]
3233
public class ThetaDataProviderTests
3334
{
3435
private ThetaDataProvider _thetaDataProvider;

QuantConnect.ThetaData.Tests/ThetaDataQueueUniverseProviderTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
namespace QuantConnect.Lean.DataSource.ThetaData.Tests
2222
{
2323
[TestFixture]
24+
[Explicit("This test requires the ThetaData terminal to be running in order to execute properly.")]
2425
public class ThetaDataQueueUniverseProviderTests
2526
{
2627
private TestableThetaDataProvider _thetaDataProvider;
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
{
22
"data-folder": "../../../../Lean/Data/",
3-
"data-directory": "../../../../Lean/Data/",
4-
5-
"thetadata-subscription-plan": "Free"
3+
"thetadata-subscription-plan": "Pro"
64
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3+
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using Newtonsoft.Json;
17+
using Newtonsoft.Json.Linq;
18+
using QuantConnect.Lean.DataSource.ThetaData.Models.Rest;
19+
20+
namespace QuantConnect.Lean.DataSource.ThetaData.Converters;
21+
22+
/// <summary>
23+
/// JSON converter to convert ThetaData Quote
24+
/// </summary>
25+
public class ThetaDataQuoteListContractConverter : JsonConverter<QuoteListContract>
26+
{
27+
/// <summary>
28+
/// Gets a value indicating whether this <see cref="JsonConverter"/> can write JSON.
29+
/// </summary>
30+
/// <value><c>true</c> if this <see cref="JsonConverter"/> can write JSON; otherwise, <c>false</c>.</value>
31+
public override bool CanWrite => false;
32+
33+
/// <summary>
34+
/// Gets a value indicating whether this <see cref="JsonConverter"/> can read JSON.
35+
/// </summary>
36+
/// <value><c>true</c> if this <see cref="JsonConverter"/> can read JSON; otherwise, <c>false</c>.</value>
37+
public override bool CanRead => true;
38+
39+
/// <summary>
40+
/// Writes the JSON representation of the object.
41+
/// </summary>
42+
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
43+
/// <param name="value">The value.</param>
44+
/// <param name="serializer">The calling serializer.</param>
45+
public override void WriteJson(JsonWriter writer, QuoteListContract value, JsonSerializer serializer)
46+
{
47+
throw new NotSupportedException();
48+
}
49+
50+
/// <summary>
51+
/// Reads the JSON representation of the object.
52+
/// </summary>
53+
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
54+
/// <param name="objectType">Type of the object.</param>
55+
/// <param name="existingValue">The existing value of object being read.</param>
56+
/// <param name="hasExistingValue">The existing value has a value.</param>
57+
/// <param name="serializer">The calling serializer.</param>
58+
/// <returns>The object value.</returns>
59+
public override QuoteListContract ReadJson(JsonReader reader, Type objectType, QuoteListContract existingValue, bool hasExistingValue, JsonSerializer serializer)
60+
{
61+
var token = JToken.Load(reader);
62+
if (token.Type != JTokenType.Array || token.Count() != 4) throw new Exception($"{nameof(ThetaDataQuoteConverter)}.{nameof(ReadJson)}: Invalid token type or count. Expected a JSON array with exactly four elements.");
63+
64+
return new(
65+
token[0]!.Value<string>()!,
66+
token[1]!.Value<string>()!.ConvertFromThetaDataDateFormat(),
67+
token[2]!.Value<decimal>(),
68+
token[3]!.Value<string>()!
69+
);
70+
}
71+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3+
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using Newtonsoft.Json;
17+
using QuantConnect.Lean.DataSource.ThetaData.Converters;
18+
19+
namespace QuantConnect.Lean.DataSource.ThetaData.Models.Rest;
20+
21+
[JsonConverter(typeof(ThetaDataQuoteListContractConverter))]
22+
public readonly struct QuoteListContract
23+
{
24+
public string Ticker { get; }
25+
26+
public DateTime Expiry { get; }
27+
28+
public decimal Strike { get; }
29+
30+
public string Right { get; }
31+
32+
public QuoteListContract(string ticker, DateTime expiry, decimal strike, string right)
33+
{
34+
Ticker = ticker;
35+
Expiry = expiry;
36+
Strike = strike;
37+
Right = right;
38+
}
39+
}

0 commit comments

Comments
 (0)