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}