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