Skip to main content

nautilus_trading/python/
sessions.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 std::str::FromStr;
17
18use chrono::{DateTime, Utc};
19use nautilus_core::python::to_pyvalue_err;
20use nautilus_model::python::common::EnumIterator;
21use pyo3::{PyTypeInfo, prelude::*, types::PyType};
22
23use crate::sessions::{
24    ForexSession, fx_local_from_utc, fx_next_end, fx_next_start, fx_prev_end, fx_prev_start,
25};
26
27#[pymethods]
28#[pyo3_stub_gen::derive::gen_stub_pymethods]
29#[expect(
30    clippy::trivially_copy_pass_by_ref,
31    reason = "PyO3 enum methods must keep by-reference receivers for Python instance methods"
32)]
33impl ForexSession {
34    /// Represents a major Forex market session based on trading hours.
35    #[new]
36    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
37        let t = Self::type_object(py);
38        Self::py_from_str(&t, value)
39    }
40
41    const fn __hash__(&self) -> isize {
42        *self as isize
43    }
44
45    fn __repr__(&self) -> String {
46        format!(
47            "<{}.{}: '{}'>",
48            stringify!(PositionSide),
49            self.name(),
50            self.value(),
51        )
52    }
53
54    fn __str__(&self) -> String {
55        self.to_string()
56    }
57
58    #[getter]
59    #[must_use]
60    pub fn name(&self) -> String {
61        self.to_string()
62    }
63
64    #[getter]
65    #[must_use]
66    pub const fn value(&self) -> u8 {
67        *self as u8
68    }
69
70    #[classmethod]
71    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
72        EnumIterator::new::<Self>(py)
73    }
74
75    #[classmethod]
76    #[pyo3(name = "from_str")]
77    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
78        let data_str: &str = data.extract()?;
79        let tokenized = data_str.to_uppercase();
80        Self::from_str(&tokenized).map_err(to_pyvalue_err)
81    }
82}
83
84/// Converts a UTC timestamp to the local time for the given Forex session.
85#[pyfunction]
86#[pyo3_stub_gen::derive::gen_stub_pyfunction(module = "nautilus_trader.trading")]
87#[pyo3(name = "fx_local_from_utc")]
88pub fn py_fx_local_from_utc(session: ForexSession, time_now: DateTime<Utc>) -> PyResult<String> {
89    Ok(fx_local_from_utc(session, time_now).to_rfc3339())
90}
91
92/// Returns the next session start time in UTC.
93#[pyfunction]
94#[pyo3_stub_gen::derive::gen_stub_pyfunction(module = "nautilus_trader.trading")]
95#[pyo3(name = "fx_next_start")]
96pub fn py_fx_next_start(session: ForexSession, time_now: DateTime<Utc>) -> PyResult<DateTime<Utc>> {
97    Ok(fx_next_start(session, time_now))
98}
99
100/// Returns the next session end time in UTC.
101#[pyfunction]
102#[pyo3_stub_gen::derive::gen_stub_pyfunction(module = "nautilus_trader.trading")]
103#[pyo3(name = "fx_next_end")]
104pub fn py_fx_next_end(session: ForexSession, time_now: DateTime<Utc>) -> PyResult<DateTime<Utc>> {
105    Ok(fx_next_end(session, time_now))
106}
107
108/// Returns the previous session start time in UTC.
109#[pyfunction]
110#[pyo3_stub_gen::derive::gen_stub_pyfunction(module = "nautilus_trader.trading")]
111#[pyo3(name = "fx_prev_start")]
112pub fn py_fx_prev_start(session: ForexSession, time_now: DateTime<Utc>) -> PyResult<DateTime<Utc>> {
113    Ok(fx_prev_start(session, time_now))
114}
115
116/// Returns the previous session end time in UTC.
117#[pyfunction]
118#[pyo3_stub_gen::derive::gen_stub_pyfunction(module = "nautilus_trader.trading")]
119#[pyo3(name = "fx_prev_end")]
120pub fn py_fx_prev_end(session: ForexSession, time_now: DateTime<Utc>) -> PyResult<DateTime<Utc>> {
121    Ok(fx_prev_end(session, time_now))
122}