Skip to main content

nautilus_interactive_brokers/
data_types.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//! Interactive Brokers subscription diagnostics delivered as custom data.
17
18use nautilus_core::UnixNanos;
19use nautilus_model::{
20    custom_data,
21    identifiers::{ClientId, InstrumentId},
22};
23
24/// A subscription receives no market data within its configured interval.
25///
26/// This is an inactivity signal, not evidence that the connection or market is closed.
27#[custom_data(pyo3, stub_module = "nautilus_trader.adapters.interactive_brokers")]
28pub struct InteractiveBrokersSubscriptionIdle {
29    /// The Nautilus data client identifier.
30    pub client_id: ClientId,
31    /// The subscribed instrument identifier.
32    pub instrument_id: InstrumentId,
33    /// The subscription kind, including the complete bar type for bar subscriptions.
34    pub subscription: String,
35    /// The configured interval without market data.
36    pub idle_timeout_secs: u64,
37    /// The last local receipt time, or `None` when no market data has arrived.
38    #[custom_data_field(serde)]
39    pub last_data_received_ns: Option<u64>,
40    /// The UNIX timestamp (nanoseconds) when inactivity is detected.
41    pub ts_event: UnixNanos,
42    /// The UNIX timestamp (nanoseconds) when the event is created.
43    pub ts_init: UnixNanos,
44}
45
46pub(crate) fn register_ib_custom_data() {
47    let _ = nautilus_model::data::ensure_custom_data_json_registered::<
48        InteractiveBrokersSubscriptionIdle,
49    >();
50}
51
52#[cfg(test)]
53mod tests {
54    use rstest::rstest;
55
56    use super::*;
57
58    #[rstest]
59    fn subscription_idle_round_trip_preserves_every_field() {
60        let event = InteractiveBrokersSubscriptionIdle {
61            client_id: ClientId::from("IB-DATA-17"),
62            instrument_id: InstrumentId::from("AAPL=STK.SMART"),
63            subscription: "trades".to_string(),
64            idle_timeout_secs: 17,
65            last_data_received_ns: Some(123),
66            ts_event: UnixNanos::from(456_u64),
67            ts_init: UnixNanos::from(789_u64),
68        };
69
70        let json = serde_json::to_string(&event).unwrap();
71        let restored: InteractiveBrokersSubscriptionIdle = serde_json::from_str(&json).unwrap();
72        assert_eq!(restored, event);
73    }
74}