Skip to main content

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}