@@ -19,15 +19,11 @@ use std::{
19
19
} ;
20
20
21
21
use databento:: {
22
- dbn,
23
- dbn:: { PitSymbolMap , Record , SymbolIndex , VersionUpgradePolicy } ,
22
+ dbn:: { self , PitSymbolMap , Publisher , Record , SymbolIndex , VersionUpgradePolicy } ,
24
23
live:: Subscription ,
25
24
} ;
26
25
use indexmap:: IndexMap ;
27
- use nautilus_core:: {
28
- python:: to_pyruntime_err,
29
- time:: { get_atomic_clock_realtime, AtomicTime } ,
30
- } ;
26
+ use nautilus_core:: { nanos:: UnixNanos , python:: to_pyruntime_err, time:: get_atomic_clock_realtime} ;
31
27
use nautilus_model:: {
32
28
data:: {
33
29
delta:: OrderBookDelta ,
@@ -209,6 +205,8 @@ impl DatabentoFeedHandler {
209
205
}
210
206
} ;
211
207
208
+ let ts_init = clock. get_time_ns ( ) ;
209
+
212
210
// Decode record
213
211
if let Some ( msg) = record. get :: < dbn:: ErrorMsg > ( ) {
214
212
handle_error_msg ( msg) ;
@@ -219,14 +217,25 @@ impl DatabentoFeedHandler {
219
217
instrument_id_map. remove ( & msg. hd . instrument_id ) ;
220
218
handle_symbol_mapping_msg ( msg, & mut symbol_map, & mut instrument_id_map) ;
221
219
} else if let Some ( msg) = record. get :: < dbn:: InstrumentDefMsg > ( ) {
220
+ // TODO: Make this configurable so that exchange can be used as venue
221
+ let use_exchange_as_venue = false ;
222
+ if use_exchange_as_venue && msg. publisher ( ) ? == Publisher :: GlbxMdp3Glbx {
223
+ update_instrument_id_map_with_exchange (
224
+ & symbol_map,
225
+ & self . symbol_venue_map ,
226
+ & mut instrument_id_map,
227
+ msg. hd . instrument_id ,
228
+ msg. exchange ( ) ?,
229
+ ) ;
230
+ } ;
222
231
let data = handle_instrument_def_msg (
223
232
msg,
224
233
& record,
225
234
& symbol_map,
226
235
& self . publisher_venue_map ,
227
236
& self . symbol_venue_map . read ( ) . unwrap ( ) ,
228
237
& mut instrument_id_map,
229
- clock ,
238
+ ts_init ,
230
239
) ?;
231
240
self . send_msg ( LiveMessage :: Instrument ( data) ) . await ;
232
241
} else if let Some ( msg) = record. get :: < dbn:: StatusMsg > ( ) {
@@ -237,7 +246,7 @@ impl DatabentoFeedHandler {
237
246
& self . publisher_venue_map ,
238
247
& self . symbol_venue_map . read ( ) . unwrap ( ) ,
239
248
& mut instrument_id_map,
240
- clock ,
249
+ ts_init ,
241
250
) ?;
242
251
self . send_msg ( LiveMessage :: Status ( data) ) . await ;
243
252
} else if let Some ( msg) = record. get :: < dbn:: ImbalanceMsg > ( ) {
@@ -248,7 +257,7 @@ impl DatabentoFeedHandler {
248
257
& self . publisher_venue_map ,
249
258
& self . symbol_venue_map . read ( ) . unwrap ( ) ,
250
259
& mut instrument_id_map,
251
- clock ,
260
+ ts_init ,
252
261
) ?;
253
262
self . send_msg ( LiveMessage :: Imbalance ( data) ) . await ;
254
263
} else if let Some ( msg) = record. get :: < dbn:: StatMsg > ( ) {
@@ -259,17 +268,17 @@ impl DatabentoFeedHandler {
259
268
& self . publisher_venue_map ,
260
269
& self . symbol_venue_map . read ( ) . unwrap ( ) ,
261
270
& mut instrument_id_map,
262
- clock ,
271
+ ts_init ,
263
272
) ?;
264
273
self . send_msg ( LiveMessage :: Statistics ( data) ) . await ;
265
274
} else {
266
275
let ( mut data1, data2) = match handle_record (
267
276
record,
268
277
& symbol_map,
269
278
& self . publisher_venue_map ,
270
- & self . symbol_venue_map . read ( ) . unwrap ( ) , // TODO: Optimize this bottleneck
279
+ & self . symbol_venue_map . read ( ) . unwrap ( ) ,
271
280
& mut instrument_id_map,
272
- clock ,
281
+ ts_init ,
273
282
) {
274
283
Ok ( decoded) => decoded,
275
284
Err ( e) => {
@@ -363,6 +372,24 @@ fn handle_symbol_mapping_msg(
363
372
instrument_id_map. remove ( & msg. header ( ) . instrument_id ) ;
364
373
}
365
374
375
+ fn update_instrument_id_map_with_exchange (
376
+ symbol_map : & PitSymbolMap ,
377
+ symbol_venue_map : & RwLock < HashMap < Symbol , Venue > > ,
378
+ instrument_id_map : & mut HashMap < u32 , InstrumentId > ,
379
+ raw_instrument_id : u32 ,
380
+ exchange : & str ,
381
+ ) -> InstrumentId {
382
+ let raw_symbol = symbol_map
383
+ . get ( raw_instrument_id)
384
+ . expect ( "Cannot resolve `raw_symbol` from `symbol_map`" ) ;
385
+ let symbol = Symbol :: from ( raw_symbol. as_str ( ) ) ;
386
+ let venue = Venue :: from ( exchange) ;
387
+ let instrument_id = InstrumentId :: new ( symbol, venue) ;
388
+ symbol_venue_map. write ( ) . unwrap ( ) . insert ( symbol, venue) ;
389
+ instrument_id_map. insert ( raw_instrument_id, instrument_id) ;
390
+ instrument_id
391
+ }
392
+
366
393
fn update_instrument_id_map (
367
394
record : & dbn:: RecordRef ,
368
395
symbol_map : & PitSymbolMap ,
@@ -403,7 +430,7 @@ fn handle_instrument_def_msg(
403
430
publisher_venue_map : & IndexMap < PublisherId , Venue > ,
404
431
symbol_venue_map : & HashMap < Symbol , Venue > ,
405
432
instrument_id_map : & mut HashMap < u32 , InstrumentId > ,
406
- clock : & AtomicTime ,
433
+ ts_init : UnixNanos ,
407
434
) -> anyhow:: Result < InstrumentAny > {
408
435
let instrument_id = update_instrument_id_map (
409
436
record,
@@ -412,7 +439,6 @@ fn handle_instrument_def_msg(
412
439
symbol_venue_map,
413
440
instrument_id_map,
414
441
) ;
415
- let ts_init = clock. get_time_ns ( ) ;
416
442
417
443
decode_instrument_def_msg ( msg, instrument_id, ts_init)
418
444
}
@@ -424,7 +450,7 @@ fn handle_status_msg(
424
450
publisher_venue_map : & IndexMap < PublisherId , Venue > ,
425
451
symbol_venue_map : & HashMap < Symbol , Venue > ,
426
452
instrument_id_map : & mut HashMap < u32 , InstrumentId > ,
427
- clock : & AtomicTime ,
453
+ ts_init : UnixNanos ,
428
454
) -> anyhow:: Result < InstrumentStatus > {
429
455
let instrument_id = update_instrument_id_map (
430
456
record,
@@ -433,7 +459,6 @@ fn handle_status_msg(
433
459
symbol_venue_map,
434
460
instrument_id_map,
435
461
) ;
436
- let ts_init = clock. get_time_ns ( ) ;
437
462
438
463
decode_status_msg ( msg, instrument_id, ts_init)
439
464
}
@@ -445,7 +470,7 @@ fn handle_imbalance_msg(
445
470
publisher_venue_map : & IndexMap < PublisherId , Venue > ,
446
471
symbol_venue_map : & HashMap < Symbol , Venue > ,
447
472
instrument_id_map : & mut HashMap < u32 , InstrumentId > ,
448
- clock : & AtomicTime ,
473
+ ts_init : UnixNanos ,
449
474
) -> anyhow:: Result < DatabentoImbalance > {
450
475
let instrument_id = update_instrument_id_map (
451
476
record,
@@ -456,7 +481,6 @@ fn handle_imbalance_msg(
456
481
) ;
457
482
458
483
let price_precision = 2 ; // Hard-coded for now
459
- let ts_init = clock. get_time_ns ( ) ;
460
484
461
485
decode_imbalance_msg ( msg, instrument_id, price_precision, ts_init)
462
486
}
@@ -468,7 +492,7 @@ fn handle_statistics_msg(
468
492
publisher_venue_map : & IndexMap < PublisherId , Venue > ,
469
493
symbol_venue_map : & HashMap < Symbol , Venue > ,
470
494
instrument_id_map : & mut HashMap < u32 , InstrumentId > ,
471
- clock : & AtomicTime ,
495
+ ts_init : UnixNanos ,
472
496
) -> anyhow:: Result < DatabentoStatistics > {
473
497
let instrument_id = update_instrument_id_map (
474
498
record,
@@ -479,7 +503,6 @@ fn handle_statistics_msg(
479
503
) ;
480
504
481
505
let price_precision = 2 ; // Hard-coded for now
482
- let ts_init = clock. get_time_ns ( ) ;
483
506
484
507
decode_statistics_msg ( msg, instrument_id, price_precision, ts_init)
485
508
}
@@ -490,7 +513,7 @@ fn handle_record(
490
513
publisher_venue_map : & IndexMap < PublisherId , Venue > ,
491
514
symbol_venue_map : & HashMap < Symbol , Venue > ,
492
515
instrument_id_map : & mut HashMap < u32 , InstrumentId > ,
493
- clock : & AtomicTime ,
516
+ ts_init : UnixNanos ,
494
517
) -> anyhow:: Result < ( Option < Data > , Option < Data > ) > {
495
518
let instrument_id = update_instrument_id_map (
496
519
& record,
@@ -501,7 +524,6 @@ fn handle_record(
501
524
) ;
502
525
503
526
let price_precision = 2 ; // Hard-coded for now
504
- let ts_init = clock. get_time_ns ( ) ;
505
527
506
528
decode_record (
507
529
& record,
0 commit comments