nautilus_common/actor/indicators.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// Under development
17#![allow(dead_code)]
18#![allow(unused_variables)]
19#![allow(unused_imports)]
20
21use std::{collections::HashMap, sync::Arc};
22
23use nautilus_indicators::indicator::Indicator;
24use nautilus_model::{data::BarType, identifiers::InstrumentId};
25
26/// Contains all indicator-related references.
27#[derive(Default)]
28pub(crate) struct Indicators {
29 pub indicators: Vec<Arc<dyn Indicator>>,
30 pub indicators_for_quotes: HashMap<InstrumentId, Vec<Arc<dyn Indicator>>>,
31 pub indicators_for_trades: HashMap<InstrumentId, Vec<Arc<dyn Indicator>>>,
32 pub indicators_for_bars: HashMap<BarType, Vec<Arc<dyn Indicator>>>,
33}
34
35impl Indicators {
36 /// Checks if all registered indicators are initialized.
37 pub fn is_initialized(&self) -> bool {
38 if self.indicators.is_empty() {
39 return false;
40 }
41
42 self.indicators
43 .iter()
44 .all(|indicator| indicator.initialized())
45 }
46
47 /// Register an indicator to receive quote ticks for the given instrument ID.
48 pub fn register_indicator_for_quotes(
49 &mut self,
50 instrument_id: InstrumentId,
51 indicator: Arc<dyn Indicator>,
52 ) {
53 // Add to overall indicators if not already present
54 if !self.indicators.iter().any(|i| Arc::ptr_eq(i, &indicator)) {
55 self.indicators.push(indicator.clone());
56 }
57
58 // Add to instrument-specific quotes indicators
59 let indicators = self.indicators_for_quotes.entry(instrument_id).or_default();
60
61 if !indicators.iter().any(|i| Arc::ptr_eq(i, &indicator)) {
62 indicators.push(indicator);
63 // TODO: Log registration
64 } else {
65 // TODO: Log error - already registered
66 }
67 }
68
69 /// Register an indicator to receive trade ticks for the given instrument ID.
70 pub fn register_indicator_for_trades(
71 &mut self,
72 instrument_id: InstrumentId,
73 indicator: Arc<dyn Indicator>,
74 ) {
75 // Add to overall indicators if not already present
76 if !self.indicators.iter().any(|i| Arc::ptr_eq(i, &indicator)) {
77 self.indicators.push(indicator.clone());
78 }
79
80 // Add to instrument-specific trades indicators
81 let indicators = self.indicators_for_trades.entry(instrument_id).or_default();
82
83 if !indicators.iter().any(|i| Arc::ptr_eq(i, &indicator)) {
84 indicators.push(indicator);
85 // TODO: Log registration
86 } else {
87 // TODO: Log error - already registered
88 }
89 }
90
91 /// Register an indicator to receive bar data for the given bar type.
92 pub fn register_indicator_for_bars(
93 &mut self,
94 bar_type: BarType,
95 indicator: Arc<dyn Indicator>,
96 ) {
97 // Add to overall indicators if not already present
98 if !self.indicators.iter().any(|i| Arc::ptr_eq(i, &indicator)) {
99 self.indicators.push(indicator.clone());
100 }
101
102 // Get standard bar type
103 let standard_bar_type = bar_type.standard();
104
105 // Add to bar type-specific indicators
106 let indicators = self
107 .indicators_for_bars
108 .entry(standard_bar_type)
109 .or_default();
110
111 if !indicators.iter().any(|i| Arc::ptr_eq(i, &indicator)) {
112 indicators.push(indicator);
113 // TODO: Log registration
114 } else {
115 // TODO: Log error - already registered
116 }
117 }
118}