nautilus_common/cache/database.rs
1// -------------------------------------------------------------------------------------------------
2// Copyright (C) 2015-2026 Nautech Systems Pty Ltd. All rights reserved.
3// https://nautechsystems.io
4//
5// Licensed under the GNU Lesser General Public License Version 3.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 https://www.gnu.org/licenses/lgpl-3.0.en.html
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//! Provides a `Cache` database backing.
17
18// Under development
19#![allow(dead_code)]
20#![allow(unused_variables)]
21
22use ahash::AHashMap;
23use bytes::Bytes;
24use nautilus_core::UnixNanos;
25use nautilus_model::{
26 accounts::AccountAny,
27 data::{
28 Bar, CustomData, DataType, FundingRateUpdate, QuoteTick, TradeTick,
29 greeks::{GreeksData, YieldCurveData},
30 },
31 events::{OrderEventAny, OrderSnapshot, position::snapshot::PositionSnapshot},
32 identifiers::{
33 AccountId, ClientId, ClientOrderId, ComponentId, InstrumentId, PositionId, StrategyId,
34 VenueOrderId,
35 },
36 instruments::{InstrumentAny, SyntheticInstrument},
37 orderbook::OrderBook,
38 orders::OrderAny,
39 position::Position,
40 types::Currency,
41};
42use ustr::Ustr;
43
44use crate::signal::Signal;
45
46#[derive(Debug, Default)]
47pub struct CacheMap {
48 pub currencies: AHashMap<Ustr, Currency>,
49 pub instruments: AHashMap<InstrumentId, InstrumentAny>,
50 pub synthetics: AHashMap<InstrumentId, SyntheticInstrument>,
51 pub accounts: AHashMap<AccountId, AccountAny>,
52 pub orders: AHashMap<ClientOrderId, OrderAny>,
53 pub positions: AHashMap<PositionId, Position>,
54 pub greeks: AHashMap<InstrumentId, GreeksData>,
55 pub yield_curves: AHashMap<String, YieldCurveData>,
56}
57
58#[async_trait::async_trait]
59pub trait CacheDatabaseAdapter {
60 /// Closes the cache database connection.
61 ///
62 /// # Errors
63 ///
64 /// Returns an error if the database fails to close properly.
65 fn close(&mut self) -> anyhow::Result<()>;
66
67 /// Flushes any pending changes to the database.
68 ///
69 /// # Errors
70 ///
71 /// Returns an error if flushing changes fails.
72 fn flush(&mut self) -> anyhow::Result<()>;
73
74 /// Loads all cached data into memory.
75 ///
76 /// # Errors
77 ///
78 /// Returns an error if loading data from the database fails.
79 async fn load_all(&self) -> anyhow::Result<CacheMap>;
80
81 /// Loads raw key-value data from the database.
82 ///
83 /// # Errors
84 ///
85 /// Returns an error if the load operation fails.
86 fn load(&self) -> anyhow::Result<AHashMap<String, Bytes>>;
87
88 /// Loads all currencies from the cache.
89 ///
90 /// # Errors
91 ///
92 /// Returns an error if loading currencies fails.
93 async fn load_currencies(&self) -> anyhow::Result<AHashMap<Ustr, Currency>>;
94
95 /// Loads all instruments from the cache.
96 ///
97 /// # Errors
98 ///
99 /// Returns an error if loading instruments fails.
100 async fn load_instruments(&self) -> anyhow::Result<AHashMap<InstrumentId, InstrumentAny>>;
101
102 /// Loads all synthetic instruments from the cache.
103 ///
104 /// # Errors
105 ///
106 /// Returns an error if loading synthetic instruments fails.
107 async fn load_synthetics(&self) -> anyhow::Result<AHashMap<InstrumentId, SyntheticInstrument>>;
108
109 /// Loads all accounts from the cache.
110 ///
111 /// # Errors
112 ///
113 /// Returns an error if loading accounts fails.
114 async fn load_accounts(&self) -> anyhow::Result<AHashMap<AccountId, AccountAny>>;
115
116 /// Loads all orders from the cache.
117 ///
118 /// # Errors
119 ///
120 /// Returns an error if loading orders fails.
121 async fn load_orders(&self) -> anyhow::Result<AHashMap<ClientOrderId, OrderAny>>;
122
123 /// Loads all positions from the cache.
124 ///
125 /// # Errors
126 ///
127 /// Returns an error if loading positions fails.
128 async fn load_positions(&self) -> anyhow::Result<AHashMap<PositionId, Position>>;
129
130 /// Loads all [`GreeksData`] from the cache.
131 ///
132 /// # Errors
133 ///
134 /// Returns an error if loading greeks data fails.
135 async fn load_greeks(&self) -> anyhow::Result<AHashMap<InstrumentId, GreeksData>> {
136 Ok(AHashMap::new())
137 }
138
139 /// Loads all [`YieldCurveData`] from the cache.
140 ///
141 /// # Errors
142 ///
143 /// Returns an error if loading yield curve data fails.
144 async fn load_yield_curves(&self) -> anyhow::Result<AHashMap<String, YieldCurveData>> {
145 Ok(AHashMap::new())
146 }
147
148 /// Loads mapping from order IDs to position IDs.
149 ///
150 /// # Errors
151 ///
152 /// Returns an error if loading the index order-position mapping fails.
153 fn load_index_order_position(&self) -> anyhow::Result<AHashMap<ClientOrderId, Position>>;
154
155 /// Loads mapping from order IDs to client IDs.
156 ///
157 /// # Errors
158 ///
159 /// Returns an error if loading the index order-client mapping fails.
160 fn load_index_order_client(&self) -> anyhow::Result<AHashMap<ClientOrderId, ClientId>>;
161
162 /// Loads a single currency by code.
163 ///
164 /// # Errors
165 ///
166 /// Returns an error if loading a single currency fails.
167 async fn load_currency(&self, code: &Ustr) -> anyhow::Result<Option<Currency>>;
168
169 /// Loads a single instrument by ID.
170 ///
171 /// # Errors
172 ///
173 /// Returns an error if loading a single instrument fails.
174 async fn load_instrument(
175 &self,
176 instrument_id: &InstrumentId,
177 ) -> anyhow::Result<Option<InstrumentAny>>;
178
179 /// Loads a single synthetic instrument by ID.
180 ///
181 /// # Errors
182 ///
183 /// Returns an error if loading a single synthetic instrument fails.
184 async fn load_synthetic(
185 &self,
186 instrument_id: &InstrumentId,
187 ) -> anyhow::Result<Option<SyntheticInstrument>>;
188
189 /// Loads a single account by ID.
190 ///
191 /// # Errors
192 ///
193 /// Returns an error if loading a single account fails.
194 async fn load_account(&self, account_id: &AccountId) -> anyhow::Result<Option<AccountAny>>;
195
196 /// Loads a single order by client order ID.
197 ///
198 /// # Errors
199 ///
200 /// Returns an error if loading a single order fails.
201 async fn load_order(&self, client_order_id: &ClientOrderId)
202 -> anyhow::Result<Option<OrderAny>>;
203
204 /// Loads a single position by position ID.
205 ///
206 /// # Errors
207 ///
208 /// Returns an error if loading a single position fails.
209 async fn load_position(&self, position_id: &PositionId) -> anyhow::Result<Option<Position>>;
210
211 /// Loads actor state by component ID.
212 ///
213 /// # Errors
214 ///
215 /// Returns an error if loading actor state fails.
216 fn load_actor(&self, component_id: &ComponentId) -> anyhow::Result<AHashMap<String, Bytes>>;
217
218 /// Loads strategy state by strategy ID.
219 ///
220 /// # Errors
221 ///
222 /// Returns an error if loading strategy state fails.
223 fn load_strategy(&self, strategy_id: &StrategyId) -> anyhow::Result<AHashMap<String, Bytes>>;
224
225 /// Loads signals by name.
226 ///
227 /// # Errors
228 ///
229 /// Returns an error if loading signals fails.
230 fn load_signals(&self, name: &str) -> anyhow::Result<Vec<Signal>>;
231
232 /// Loads custom data by data type.
233 ///
234 /// # Errors
235 ///
236 /// Returns an error if loading custom data fails.
237 fn load_custom_data(&self, data_type: &DataType) -> anyhow::Result<Vec<CustomData>>;
238
239 /// Loads an order snapshot by client order ID.
240 ///
241 /// # Errors
242 ///
243 /// Returns an error if loading the order snapshot fails.
244 fn load_order_snapshot(
245 &self,
246 client_order_id: &ClientOrderId,
247 ) -> anyhow::Result<Option<OrderSnapshot>>;
248
249 /// Loads a position snapshot by position ID.
250 ///
251 /// # Errors
252 ///
253 /// Returns an error if loading the position snapshot fails.
254 fn load_position_snapshot(
255 &self,
256 position_id: &PositionId,
257 ) -> anyhow::Result<Option<PositionSnapshot>>;
258
259 /// Loads quote ticks by instrument ID.
260 ///
261 /// # Errors
262 ///
263 /// Returns an error if loading quotes fails.
264 fn load_quotes(&self, instrument_id: &InstrumentId) -> anyhow::Result<Vec<QuoteTick>>;
265
266 /// Loads trade ticks by instrument ID.
267 ///
268 /// # Errors
269 ///
270 /// Returns an error if loading trades fails.
271 fn load_trades(&self, instrument_id: &InstrumentId) -> anyhow::Result<Vec<TradeTick>>;
272
273 /// Loads funding rate updates by instrument ID.
274 ///
275 /// # Errors
276 ///
277 /// Returns an error if loading funding rates fails.
278 fn load_funding_rates(
279 &self,
280 instrument_id: &InstrumentId,
281 ) -> anyhow::Result<Vec<FundingRateUpdate>>;
282
283 /// Loads bars by instrument ID.
284 ///
285 /// # Errors
286 ///
287 /// Returns an error if loading bars fails.
288 fn load_bars(&self, instrument_id: &InstrumentId) -> anyhow::Result<Vec<Bar>>;
289
290 /// Adds a generic key-value pair to the cache.
291 ///
292 /// # Errors
293 ///
294 /// Returns an error if adding a generic key/value fails.
295 fn add(&self, key: String, value: Bytes) -> anyhow::Result<()>;
296
297 /// Adds a currency to the cache.
298 ///
299 /// # Errors
300 ///
301 /// Returns an error if adding a currency fails.
302 fn add_currency(&self, currency: &Currency) -> anyhow::Result<()>;
303
304 /// Adds an instrument to the cache.
305 ///
306 /// # Errors
307 ///
308 /// Returns an error if adding an instrument fails.
309 fn add_instrument(&self, instrument: &InstrumentAny) -> anyhow::Result<()>;
310
311 /// Adds a synthetic instrument to the cache.
312 ///
313 /// # Errors
314 ///
315 /// Returns an error if adding a synthetic instrument fails.
316 fn add_synthetic(&self, synthetic: &SyntheticInstrument) -> anyhow::Result<()>;
317
318 /// Adds an account to the cache.
319 ///
320 /// # Errors
321 ///
322 /// Returns an error if adding an account fails.
323 fn add_account(&self, account: &AccountAny) -> anyhow::Result<()>;
324
325 /// Adds an order to the cache.
326 ///
327 /// # Errors
328 ///
329 /// Returns an error if adding an order fails.
330 fn add_order(&self, order: &OrderAny, client_id: Option<ClientId>) -> anyhow::Result<()>;
331
332 /// Adds an order snapshot to the cache.
333 ///
334 /// # Errors
335 ///
336 /// Returns an error if adding an order snapshot fails.
337 fn add_order_snapshot(&self, snapshot: &OrderSnapshot) -> anyhow::Result<()>;
338
339 /// Adds a position to the cache.
340 ///
341 /// # Errors
342 ///
343 /// Returns an error if adding a position fails.
344 fn add_position(&self, position: &Position) -> anyhow::Result<()>;
345
346 /// Adds a position snapshot to the cache.
347 ///
348 /// # Errors
349 ///
350 /// Returns an error if adding a position snapshot fails.
351 fn add_position_snapshot(&self, snapshot: &PositionSnapshot) -> anyhow::Result<()>;
352
353 /// Adds an order book to the cache.
354 ///
355 /// # Errors
356 ///
357 /// Returns an error if adding an order book fails.
358 fn add_order_book(&self, order_book: &OrderBook) -> anyhow::Result<()>;
359
360 /// Adds a signal to the cache.
361 ///
362 /// # Errors
363 ///
364 /// Returns an error if adding a signal fails.
365 fn add_signal(&self, signal: &Signal) -> anyhow::Result<()>;
366
367 /// Adds custom data to the cache.
368 ///
369 /// # Errors
370 ///
371 /// Returns an error if adding custom data fails.
372 fn add_custom_data(&self, data: &CustomData) -> anyhow::Result<()>;
373
374 /// Adds a quote tick to the cache.
375 ///
376 /// # Errors
377 ///
378 /// Returns an error if adding a quote tick fails.
379 fn add_quote(&self, quote: &QuoteTick) -> anyhow::Result<()>;
380
381 /// Adds a trade tick to the cache.
382 ///
383 /// # Errors
384 ///
385 /// Returns an error if adding a trade tick fails.
386 fn add_trade(&self, trade: &TradeTick) -> anyhow::Result<()>;
387
388 /// Adds a funding rate update to the cache.
389 ///
390 /// # Errors
391 ///
392 /// Returns an error if adding a funding rate update fails.
393 fn add_funding_rate(&self, funding_rate: &FundingRateUpdate) -> anyhow::Result<()>;
394
395 /// Adds a bar to the cache.
396 ///
397 /// # Errors
398 ///
399 /// Returns an error if adding a bar fails.
400 fn add_bar(&self, bar: &Bar) -> anyhow::Result<()>;
401
402 /// Adds greeks data to the cache.
403 ///
404 /// # Errors
405 ///
406 /// Returns an error if adding greeks data fails.
407 fn add_greeks(&self, greeks: &GreeksData) -> anyhow::Result<()> {
408 Ok(())
409 }
410
411 /// Adds yield curve data to the cache.
412 ///
413 /// # Errors
414 ///
415 /// Returns an error if adding yield curve data fails.
416 fn add_yield_curve(&self, yield_curve: &YieldCurveData) -> anyhow::Result<()> {
417 Ok(())
418 }
419
420 /// Deletes actor state from the cache.
421 ///
422 /// # Errors
423 ///
424 /// Returns an error if deleting actor state fails.
425 fn delete_actor(&self, component_id: &ComponentId) -> anyhow::Result<()>;
426
427 /// Deletes strategy state from the cache.
428 ///
429 /// # Errors
430 ///
431 /// Returns an error if deleting strategy state fails.
432 fn delete_strategy(&self, component_id: &StrategyId) -> anyhow::Result<()>;
433
434 /// Deletes an order from the cache.
435 ///
436 /// # Errors
437 ///
438 /// Returns an error if deleting an order fails.
439 fn delete_order(&self, client_order_id: &ClientOrderId) -> anyhow::Result<()>;
440
441 /// Deletes a position from the cache.
442 ///
443 /// # Errors
444 ///
445 /// Returns an error if deleting a position fails.
446 fn delete_position(&self, position_id: &PositionId) -> anyhow::Result<()>;
447
448 /// Deletes an account event from the cache.
449 ///
450 /// # Errors
451 ///
452 /// Returns an error if deleting account events fails.
453 fn delete_account_event(&self, account_id: &AccountId, event_id: &str) -> anyhow::Result<()>;
454
455 /// Indexes a venue order ID with its client order ID.
456 ///
457 /// # Errors
458 ///
459 /// Returns an error if indexing venue order ID fails.
460 fn index_venue_order_id(
461 &self,
462 client_order_id: ClientOrderId,
463 venue_order_id: VenueOrderId,
464 ) -> anyhow::Result<()>;
465
466 /// Indexes an order-position mapping.
467 ///
468 /// # Errors
469 ///
470 /// Returns an error if indexing order-position mapping fails.
471 fn index_order_position(
472 &self,
473 client_order_id: ClientOrderId,
474 position_id: PositionId,
475 ) -> anyhow::Result<()>;
476
477 /// Updates actor state in the cache.
478 ///
479 /// # Errors
480 ///
481 /// Returns an error if updating actor state fails.
482 fn update_actor(&self) -> anyhow::Result<()>;
483
484 /// Updates strategy state in the cache.
485 ///
486 /// # Errors
487 ///
488 /// Returns an error if updating strategy state fails.
489 fn update_strategy(&self) -> anyhow::Result<()>;
490
491 /// Updates an account in the cache.
492 ///
493 /// # Errors
494 ///
495 /// Returns an error if updating an account fails.
496 fn update_account(&self, account: &AccountAny) -> anyhow::Result<()>;
497
498 /// Updates an order in the cache with an order event.
499 ///
500 /// # Errors
501 ///
502 /// Returns an error if updating an order fails.
503 fn update_order(&self, order_event: &OrderEventAny) -> anyhow::Result<()>;
504
505 /// Updates a position in the cache.
506 ///
507 /// # Errors
508 ///
509 /// Returns an error if updating a position fails.
510 fn update_position(&self, position: &Position) -> anyhow::Result<()>;
511
512 /// Creates a snapshot of order state.
513 ///
514 /// # Errors
515 ///
516 /// Returns an error if snapshotting order state fails.
517 fn snapshot_order_state(&self, order: &OrderAny) -> anyhow::Result<()>;
518
519 /// Creates a snapshot of position state.
520 ///
521 /// # Errors
522 ///
523 /// Returns an error if snapshotting position state fails.
524 fn snapshot_position_state(&self, position: &Position) -> anyhow::Result<()>;
525
526 /// Records a heartbeat timestamp.
527 ///
528 /// # Errors
529 ///
530 /// Returns an error if heartbeat recording fails.
531 fn heartbeat(&self, timestamp: UnixNanos) -> anyhow::Result<()>;
532}