Skip to main content

nautilus_betfair/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
16//! Python bindings for Betfair configuration.
17
18use nautilus_model::identifiers::{AccountId, TraderId};
19use pyo3::prelude::*;
20
21use crate::config::{BetfairDataConfig, BetfairExecConfig};
22
23fn stringify_ids(values: Option<Vec<u64>>) -> Option<Vec<String>> {
24    values.map(|values| values.into_iter().map(|value| value.to_string()).collect())
25}
26
27#[pymethods]
28#[pyo3_stub_gen::derive::gen_stub_pymethods]
29impl BetfairDataConfig {
30    /// Configuration for the Betfair live data client.
31    #[new]
32    #[pyo3(signature = (
33        account_currency = None,
34        username = None,
35        password = None,
36        app_key = None,
37        proxy_url = None,
38        request_rate_per_second = 5,
39        default_min_notional = None,
40        event_type_ids = None,
41        event_type_names = None,
42        event_ids = None,
43        country_codes = None,
44        market_types = None,
45        market_ids = None,
46        min_market_start_time = None,
47        max_market_start_time = None,
48        stream_host = None,
49        stream_port = None,
50        stream_heartbeat_ms = 5_000,
51        stream_idle_timeout_ms = 60_000,
52        stream_reconnect_delay_initial_ms = 2_000,
53        stream_reconnect_delay_max_ms = 30_000,
54        stream_use_tls = true,
55        stream_conflate_ms = None,
56        subscription_delay_secs = None,
57        subscribe_race_data = false,
58    ))]
59    #[expect(clippy::too_many_arguments)]
60    fn py_new(
61        account_currency: Option<String>,
62        username: Option<String>,
63        password: Option<String>,
64        app_key: Option<String>,
65        proxy_url: Option<String>,
66        request_rate_per_second: u32,
67        default_min_notional: Option<f64>,
68        event_type_ids: Option<Vec<u64>>,
69        event_type_names: Option<Vec<String>>,
70        event_ids: Option<Vec<u64>>,
71        country_codes: Option<Vec<String>>,
72        market_types: Option<Vec<String>>,
73        market_ids: Option<Vec<String>>,
74        min_market_start_time: Option<String>,
75        max_market_start_time: Option<String>,
76        stream_host: Option<String>,
77        stream_port: Option<u16>,
78        stream_heartbeat_ms: u64,
79        stream_idle_timeout_ms: u64,
80        stream_reconnect_delay_initial_ms: u64,
81        stream_reconnect_delay_max_ms: u64,
82        stream_use_tls: bool,
83        stream_conflate_ms: Option<u64>,
84        subscription_delay_secs: Option<u64>,
85        subscribe_race_data: bool,
86    ) -> Self {
87        Self {
88            account_currency: account_currency.unwrap_or_else(|| "GBP".to_string()),
89            username,
90            password,
91            app_key,
92            proxy_url,
93            request_rate_per_second,
94            default_min_notional,
95            event_type_ids: stringify_ids(event_type_ids),
96            event_type_names,
97            event_ids: stringify_ids(event_ids),
98            country_codes,
99            market_types,
100            market_ids,
101            min_market_start_time,
102            max_market_start_time,
103            stream_host,
104            stream_port,
105            stream_heartbeat_ms,
106            stream_idle_timeout_ms,
107            stream_reconnect_delay_initial_ms,
108            stream_reconnect_delay_max_ms,
109            stream_use_tls,
110            stream_conflate_ms,
111            subscription_delay_secs: subscription_delay_secs.unwrap_or(3),
112            subscribe_race_data,
113        }
114    }
115
116    fn __repr__(&self) -> String {
117        format!("{self:?}")
118    }
119}
120
121#[pymethods]
122#[pyo3_stub_gen::derive::gen_stub_pymethods]
123impl BetfairExecConfig {
124    /// Configuration for the Betfair live execution client.
125    #[new]
126    #[pyo3(signature = (
127        trader_id = None,
128        account_id = None,
129        account_currency = None,
130        username = None,
131        password = None,
132        app_key = None,
133        proxy_url = None,
134        request_rate_per_second = 5,
135        order_request_rate_per_second = 20,
136        stream_host = None,
137        stream_port = None,
138        stream_heartbeat_ms = 5_000,
139        stream_idle_timeout_ms = 60_000,
140        stream_reconnect_delay_initial_ms = 2_000,
141        stream_reconnect_delay_max_ms = 30_000,
142        stream_use_tls = true,
143        stream_market_ids_filter = None,
144        ignore_external_orders = false,
145        calculate_account_state = true,
146        request_account_state_secs = 300,
147        reconcile_market_ids_only = false,
148        reconcile_market_ids = None,
149        use_market_version = false,
150    ))]
151    #[expect(clippy::too_many_arguments)]
152    fn py_new(
153        trader_id: Option<TraderId>,
154        account_id: Option<AccountId>,
155        account_currency: Option<String>,
156        username: Option<String>,
157        password: Option<String>,
158        app_key: Option<String>,
159        proxy_url: Option<String>,
160        request_rate_per_second: u32,
161        order_request_rate_per_second: u32,
162        stream_host: Option<String>,
163        stream_port: Option<u16>,
164        stream_heartbeat_ms: u64,
165        stream_idle_timeout_ms: u64,
166        stream_reconnect_delay_initial_ms: u64,
167        stream_reconnect_delay_max_ms: u64,
168        stream_use_tls: bool,
169        stream_market_ids_filter: Option<Vec<String>>,
170        ignore_external_orders: bool,
171        calculate_account_state: bool,
172        request_account_state_secs: u64,
173        reconcile_market_ids_only: bool,
174        reconcile_market_ids: Option<Vec<String>>,
175        use_market_version: bool,
176    ) -> Self {
177        Self {
178            trader_id: trader_id.unwrap_or_else(|| TraderId::from("TRADER-001")),
179            account_id: account_id.unwrap_or_else(|| AccountId::from("BETFAIR-001")),
180            account_currency: account_currency.unwrap_or_else(|| "GBP".to_string()),
181            username,
182            password,
183            app_key,
184            proxy_url,
185            request_rate_per_second,
186            order_request_rate_per_second,
187            stream_host,
188            stream_port,
189            stream_heartbeat_ms,
190            stream_idle_timeout_ms,
191            stream_reconnect_delay_initial_ms,
192            stream_reconnect_delay_max_ms,
193            stream_use_tls,
194            stream_market_ids_filter,
195            ignore_external_orders,
196            calculate_account_state,
197            request_account_state_secs,
198            reconcile_market_ids_only,
199            reconcile_market_ids,
200            use_market_version,
201        }
202    }
203
204    fn __repr__(&self) -> String {
205        format!("{self:?}")
206    }
207}