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