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