Skip to content

Commit 8208365

Browse files
Got rid of my data type to use QuantConnects TradeBar and QuoteBar and Tick. Subscribe and Unsubscribe are now sync and return bools for success. GetHistory is the default implementation, no override. Fixed the wrong gateway url.
1 parent c60968d commit 8208365

4 files changed

Lines changed: 199 additions & 338 deletions

File tree

QuantConnect.DataBento/DataBentoDataDownloader.cs

Lines changed: 93 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
using System.Globalization;
2222
using System.Collections.Generic;
2323
using CsvHelper;
24+
using CsvHelper.Configuration.Attributes;
2425
using QuantConnect.Data;
2526
using QuantConnect.Data.Market;
2627
using QuantConnect.Util;
@@ -41,6 +42,7 @@ public class DataBentoDataDownloader : IDataProvider
4142

4243
/// <inheritdoc cref="MarketHoursDatabase" />
4344
private readonly MarketHoursDatabase _marketHoursDatabase;
45+
private const decimal PriceScaleFactor = 1e-9m;
4446

4547
/// <summary>
4648
/// Initializes a new instance of the <see cref="DataBentoDataDownloader"/>
@@ -104,32 +106,68 @@ public IEnumerable<BaseData> Get(DataDownloaderGetParameters parameters)
104106
using var reader = new StreamReader(stream);
105107
using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
106108

107-
// base data conversion
108-
foreach (var record in csv.GetRecords<DatabentoTrade>())
109+
if (tickType == TickType.Trade)
109110
{
110-
if (resolution == Resolution.Tick)
111+
foreach (var record in csv.GetRecords<DatabentoBar>())
111112
{
112-
yield return new Tick
113+
if (resolution == Resolution.Tick)
114+
{
115+
yield return new Tick
116+
{
117+
Time = record.Timestamp,
118+
Symbol = symbol,
119+
Value = record.Price,
120+
Quantity = record.Size
121+
};
122+
}
123+
else
113124
{
114-
Time = record.Timestamp,
115-
Symbol = symbol,
116-
Value = record.Price,
117-
Quantity = record.Size
118-
};
125+
yield return new TradeBar
126+
{
127+
Symbol = symbol,
128+
Time = record.Timestamp,
129+
Open = record.Open,
130+
High = record.High,
131+
Low = record.Low,
132+
Close = record.Close,
133+
Volume = record.Volume
134+
};
135+
}
119136
}
120-
else
137+
}
138+
else if (tickType == TickType.Quote)
139+
{
140+
foreach (var record in csv.GetRecords<DatabentoQuote>())
121141
{
122-
yield return new DataBentoDataType
142+
var bidPrice = record.BidPrice * PriceScaleFactor;
143+
var askPrice = record.AskPrice * PriceScaleFactor;
144+
145+
if (resolution == Resolution.Tick)
146+
{
147+
yield return new Tick
148+
{
149+
Time = record.Timestamp,
150+
Symbol = symbol,
151+
AskPrice = askPrice,
152+
BidPrice = bidPrice,
153+
AskSize = record.AskSize,
154+
BidSize = record.BidSize,
155+
TickType = TickType.Quote
156+
};
157+
}
158+
else
123159
{
124-
Symbol = symbol,
125-
Time = record.Timestamp,
126-
Open = record.Open,
127-
High = record.High,
128-
Low = record.Low,
129-
Close = record.Close,
130-
Volume = record.Volume,
131-
Value = record.Close
132-
};
160+
var bidBar = new Bar(bidPrice, bidPrice, bidPrice, bidPrice);
161+
var askBar = new Bar(askPrice, askPrice, askPrice, askPrice);
162+
yield return new QuoteBar(
163+
record.Timestamp,
164+
symbol,
165+
bidBar,
166+
record.BidSize,
167+
askBar,
168+
record.AskSize
169+
);
170+
}
133171
}
134172
}
135173
}
@@ -147,31 +185,33 @@ public void Dispose()
147185
/// </summary>
148186
private string GetSchema(Resolution resolution, TickType tickType)
149187
{
150-
if (resolution == Resolution.Tick && tickType == TickType.Trade)
151-
return "trades";
152-
153-
if (resolution == Resolution.Tick && tickType == TickType.Quote)
154-
return "mbp-1"; // top of book
155-
156-
if (resolution == Resolution.Second)
157-
return "ohlcv-1s";
158-
159-
if (resolution == Resolution.Minute)
160-
return "ohlcv-1m";
161-
162-
if (resolution == Resolution.Hour)
163-
return "ohlcv-1h";
164-
165-
if (resolution == Resolution.Daily)
166-
return "ohlcv-1d";
188+
if (tickType == TickType.Trade)
189+
{
190+
if (resolution == Resolution.Tick)
191+
return "trades";
192+
if (resolution == Resolution.Second)
193+
return "ohlcv-1s";
194+
if (resolution == Resolution.Minute)
195+
return "ohlcv-1m";
196+
if (resolution == Resolution.Hour)
197+
return "ohlcv-1h";
198+
if (resolution == Resolution.Daily)
199+
return "ohlcv-1d";
200+
}
201+
else if (tickType == TickType.Quote)
202+
{
203+
// top of book
204+
if (resolution == Resolution.Tick || resolution == Resolution.Second || resolution == Resolution.Minute || resolution == Resolution.Hour || resolution == Resolution.Daily)
205+
return "mbp-1";
206+
}
167207

168208
throw new NotSupportedException($"Unsupported resolution {resolution} / {tickType}");
169209
}
170210

171211
/// <summary>
172212
/// Map Lean Symbol to Databento symbol string for continous
173213
/// </summary>
174-
private string MapSymbol(Symbol symbol)
214+
private static string MapSymbol(Symbol symbol)
175215
{
176216
if (symbol.SecurityType == SecurityType.Future)
177217
{
@@ -183,7 +223,7 @@ private string MapSymbol(Symbol symbol)
183223

184224

185225
/// Class for parsing trade data from Databento
186-
private class DatabentoTrade
226+
private class DatabentoBar
187227
{
188228
public DateTime Timestamp { get; set; }
189229
public decimal Price { get; set; }
@@ -194,6 +234,19 @@ private class DatabentoTrade
194234
public decimal Close { get; set; }
195235
public decimal Volume { get; set; }
196236
}
237+
238+
private class DatabentoQuote
239+
{
240+
[Name("ts_event")]
241+
public DateTime Timestamp { get; set; }
242+
[Name("bid_px_00")]
243+
public long BidPrice { get; set; }
244+
[Name("bid_sz_00")]
245+
public int BidSize { get; set; }
246+
[Name("ask_px_00")]
247+
public long AskPrice { get; set; }
248+
[Name("ask_sz_00")]
249+
public int AskSize { get; set; }
250+
}
197251
}
198252
}
199-

QuantConnect.DataBento/DataBentoDataProvider.cs

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -117,36 +117,6 @@ private void Initialize()
117117
});
118118
}
119119

120-
/// <inheritdoc cref="HistoryProviderBase.GetHistory(IEnumerable{HistoryRequest}, DateTimeZone)"/>
121-
public override IEnumerable<Slice> GetHistory(IEnumerable<HistoryRequest> requests, DateTimeZone sliceTimeZone)
122-
{
123-
// Create subscription objects from the configs
124-
var subscriptions = new List<Subscription>();
125-
foreach (var request in requests)
126-
{
127-
// Retrieve the history for the current request
128-
var history = GetHistory(request);
129-
130-
if (history == null)
131-
{
132-
// If history is null, it indicates that the request contains wrong parameters
133-
// Handle the case where the request parameters are incorrect
134-
continue;
135-
}
136-
137-
var subscription = CreateSubscription(request, history);
138-
subscriptions.Add(subscription);
139-
}
140-
141-
// Validate that at least one subscription is valid; otherwise, return null
142-
if (subscriptions.Count == 0)
143-
{
144-
return null;
145-
}
146-
147-
return CreateSliceEnumerableFromSubscriptions(subscriptions, sliceTimeZone);
148-
}
149-
150120
/// <summary>
151121
/// Subscribe to the specified configuration
152122
/// </summary>
@@ -166,9 +136,9 @@ public IEnumerator<BaseData> Subscribe(SubscriptionDataConfig dataConfig, EventH
166136
// Subscribe to live data if client is connected
167137
if (_client?.IsConnected == true)
168138
{
169-
Task.Run(async () =>
139+
Task.Run(() =>
170140
{
171-
var success = await _client.Subscribe(dataConfig.Symbol, dataConfig.Resolution);
141+
var success = _client.Subscribe(dataConfig.Symbol, dataConfig.Resolution);
172142
if (!success)
173143
{
174144
Log.Error($"DataBentoProvider.Subscribe(): Failed to subscribe to live data for {dataConfig.Symbol}");
@@ -191,9 +161,9 @@ public void Unsubscribe(SubscriptionDataConfig dataConfig)
191161
// Unsubscribe from live data if client is connected
192162
if (_client?.IsConnected == true)
193163
{
194-
Task.Run(async () =>
164+
Task.Run(() =>
195165
{
196-
await _client.Unsubscribe(dataConfig.Symbol);
166+
_client.Unsubscribe(dataConfig.Symbol);
197167
});
198168
}
199169
}
@@ -369,11 +339,11 @@ private void OnConnectionStatusChanged(object sender, bool isConnected)
369339
if (isConnected)
370340
{
371341
// Resubscribe to all active subscriptions
372-
Task.Run(async () =>
342+
Task.Run(() =>
373343
{
374344
foreach (var config in _subscriptionManager.Subscriptions)
375345
{
376-
await _client.Subscribe(config.Symbol, config.Resolution, config.TickType);
346+
_client.Subscribe(config.Symbol, config.Resolution);
377347
}
378348
});
379349
}

0 commit comments

Comments
 (0)