Skip to main content

nautilus_tardis/python/
config.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
16use nautilus_core::python::to_pyvalue_err;
17use nautilus_model::{data::BarSpecification, identifiers::InstrumentId};
18use pyo3::prelude::*;
19use ustr::Ustr;
20
21use crate::{
22    common::{enums::TardisExchange, parse::bar_spec_to_tardis_trade_bar_string},
23    config::TardisDataClientConfig,
24    machine::types::{
25        ReplayNormalizedRequestOptions, StreamNormalizedRequestOptions, TardisInstrumentMiniInfo,
26    },
27};
28
29#[pymethods]
30#[pyo3_stub_gen::derive::gen_stub_pymethods]
31impl TardisInstrumentMiniInfo {
32    /// Instrument definition information necessary for stream parsing.
33    #[new]
34    fn py_new(
35        instrument_id: InstrumentId,
36        raw_symbol: &str,
37        exchange: &str,
38        price_precision: u8,
39        size_precision: u8,
40    ) -> PyResult<Self> {
41        let exchange: TardisExchange = exchange.parse().map_err(to_pyvalue_err)?;
42        Ok(Self::new(
43            instrument_id,
44            Some(Ustr::from(raw_symbol)),
45            exchange,
46            price_precision,
47            size_precision,
48        ))
49    }
50
51    #[getter]
52    #[pyo3(name = "instrument_id")]
53    const fn py_instrument_id(&self) -> InstrumentId {
54        self.instrument_id
55    }
56
57    #[getter]
58    #[pyo3(name = "raw_symbol")]
59    fn py_raw_symbol(&self) -> String {
60        self.raw_symbol.to_string()
61    }
62
63    #[getter]
64    #[pyo3(name = "exchange")]
65    fn py_exchange(&self) -> String {
66        self.exchange.to_string()
67    }
68
69    #[getter]
70    #[pyo3(name = "price_precision")]
71    const fn py_price_precision(&self) -> u8 {
72        self.price_precision
73    }
74
75    #[getter]
76    #[pyo3(name = "size_precision")]
77    const fn py_size_precision(&self) -> u8 {
78        self.size_precision
79    }
80}
81
82/// Converts a Nautilus `BarSpecification` to the Tardis trade bar string convention.
83///
84/// # Errors
85///
86/// Returns an error if the bar aggregation kind is unsupported.
87#[pyfunction(name = "bar_spec_to_tardis_trade_bar_string")]
88#[pyo3_stub_gen::derive::gen_stub_pyfunction(module = "nautilus_trader.adapters.tardis")]
89pub fn py_bar_spec_to_tardis_trade_bar_string(bar_spec: &BarSpecification) -> PyResult<String> {
90    bar_spec_to_tardis_trade_bar_string(bar_spec).map_err(to_pyvalue_err)
91}
92
93#[pymethods]
94#[pyo3_stub_gen::derive::gen_stub_pymethods]
95impl TardisDataClientConfig {
96    /// Configuration for the Tardis data client.
97    #[new]
98    #[pyo3(signature = (
99        api_key = None,
100        tardis_ws_url = None,
101        proxy_url = None,
102        normalize_symbols = None,
103        options = None,
104        stream_options = None,
105        extract_bbo_as_quotes = None,
106    ))]
107    fn py_new(
108        api_key: Option<String>,
109        tardis_ws_url: Option<String>,
110        proxy_url: Option<String>,
111        normalize_symbols: Option<bool>,
112        options: Option<Vec<ReplayNormalizedRequestOptions>>,
113        stream_options: Option<Vec<StreamNormalizedRequestOptions>>,
114        extract_bbo_as_quotes: Option<bool>,
115    ) -> Self {
116        let defaults = Self::default();
117        Self {
118            api_key,
119            tardis_ws_url,
120            proxy_url,
121            normalize_symbols: normalize_symbols.unwrap_or(defaults.normalize_symbols),
122            book_snapshot_output: defaults.book_snapshot_output,
123            extract_bbo_as_quotes: extract_bbo_as_quotes.unwrap_or(defaults.extract_bbo_as_quotes),
124            options: options.unwrap_or_default(),
125            stream_options: stream_options.unwrap_or_default(),
126        }
127    }
128
129    #[getter]
130    const fn has_proxy_url(&self) -> bool {
131        self.proxy_url.is_some()
132    }
133
134    fn __repr__(&self) -> String {
135        stringify!(TardisDataClientConfig).to_string()
136    }
137}