nautilus_execution/python/
fill.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2025 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::serialization::from_dict_pyo3, UUID4};
17use nautilus_model::{
18    enums::{LiquiditySide, OrderSide},
19    identifiers::{AccountId, ClientOrderId, InstrumentId, PositionId, TradeId, VenueOrderId},
20    types::{Money, Price, Quantity},
21};
22use pyo3::{basic::CompareOp, prelude::*, types::PyDict};
23
24use crate::reports::fill::FillReport;
25
26#[pymethods]
27impl FillReport {
28    #[new]
29    #[allow(clippy::too_many_arguments)]
30    #[pyo3(signature = (
31        account_id,
32        instrument_id,
33        venue_order_id,
34        trade_id,
35        order_side,
36        last_qty,
37        last_px,
38        commission,
39        liquidity_side,
40        ts_event,
41        ts_init,
42        client_order_id=None,
43        venue_position_id=None,
44        report_id=None,
45    ))]
46    fn py_new(
47        account_id: AccountId,
48        instrument_id: InstrumentId,
49        venue_order_id: VenueOrderId,
50        trade_id: TradeId,
51        order_side: OrderSide,
52        last_qty: Quantity,
53        last_px: Price,
54        commission: Money,
55        liquidity_side: LiquiditySide,
56        ts_event: u64,
57        ts_init: u64,
58        client_order_id: Option<ClientOrderId>,
59        venue_position_id: Option<PositionId>,
60        report_id: Option<UUID4>,
61    ) -> PyResult<Self> {
62        Ok(Self::new(
63            account_id,
64            instrument_id,
65            venue_order_id,
66            trade_id,
67            order_side,
68            last_qty,
69            last_px,
70            commission,
71            liquidity_side,
72            client_order_id,
73            venue_position_id,
74            ts_event.into(),
75            ts_init.into(),
76            report_id,
77        ))
78    }
79
80    fn __richcmp__(&self, other: &Self, op: CompareOp, py: Python<'_>) -> Py<PyAny> {
81        match op {
82            CompareOp::Eq => self.eq(other).into_py(py),
83            CompareOp::Ne => self.ne(other).into_py(py),
84            _ => py.NotImplemented(),
85        }
86    }
87
88    fn __repr__(&self) -> String {
89        self.to_string()
90    }
91
92    fn __str__(&self) -> String {
93        self.to_string()
94    }
95
96    #[getter]
97    #[pyo3(name = "account_id")]
98    const fn py_account_id(&self) -> AccountId {
99        self.account_id
100    }
101
102    #[getter]
103    #[pyo3(name = "instrument_id")]
104    const fn py_instrument_id(&self) -> InstrumentId {
105        self.instrument_id
106    }
107
108    #[getter]
109    #[pyo3(name = "venue_order_id")]
110    const fn py_venue_order_id(&self) -> VenueOrderId {
111        self.venue_order_id
112    }
113
114    #[getter]
115    #[pyo3(name = "trade_id")]
116    const fn py_trade_id(&self) -> TradeId {
117        self.trade_id
118    }
119
120    #[getter]
121    #[pyo3(name = "order_side")]
122    const fn py_order_side(&self) -> OrderSide {
123        self.order_side
124    }
125
126    #[getter]
127    #[pyo3(name = "last_qty")]
128    const fn py_last_qty(&self) -> Quantity {
129        self.last_qty
130    }
131
132    #[getter]
133    #[pyo3(name = "last_px")]
134    const fn py_last_px(&self) -> Price {
135        self.last_px
136    }
137
138    #[getter]
139    #[pyo3(name = "commission")]
140    const fn py_commission(&self) -> Money {
141        self.commission
142    }
143
144    #[getter]
145    #[pyo3(name = "liquidity_side")]
146    const fn py_liquidity_side(&self) -> LiquiditySide {
147        self.liquidity_side
148    }
149
150    #[getter]
151    #[pyo3(name = "report_id")]
152    const fn py_report_id(&self) -> UUID4 {
153        self.report_id
154    }
155
156    #[getter]
157    #[pyo3(name = "ts_event")]
158    const fn py_ts_event(&self) -> u64 {
159        self.ts_event.as_u64()
160    }
161
162    #[getter]
163    #[pyo3(name = "ts_init")]
164    const fn py_ts_init(&self) -> u64 {
165        self.ts_init.as_u64()
166    }
167
168    #[getter]
169    #[pyo3(name = "client_order_id")]
170    const fn py_client_order_id(&self) -> Option<ClientOrderId> {
171        self.client_order_id
172    }
173
174    #[getter]
175    #[pyo3(name = "venue_position_id")]
176    const fn py_venue_position_id(&self) -> Option<PositionId> {
177        self.venue_position_id
178    }
179
180    #[staticmethod]
181    #[pyo3(name = "from_dict")]
182    pub fn py_from_dict(py: Python<'_>, values: Py<PyDict>) -> PyResult<Self> {
183        from_dict_pyo3(py, values)
184    }
185
186    #[pyo3(name = "to_dict")]
187    pub fn py_to_dict(&self, py: Python<'_>) -> PyResult<PyObject> {
188        let dict = PyDict::new(py);
189        dict.set_item("type", stringify!(FillReport))?;
190        dict.set_item("account_id", self.account_id.to_string())?;
191        dict.set_item("instrument_id", self.instrument_id.to_string())?;
192        dict.set_item("venue_order_id", self.venue_order_id.to_string())?;
193        dict.set_item("trade_id", self.trade_id.to_string())?;
194        dict.set_item("order_side", self.order_side.to_string())?;
195        dict.set_item("last_qty", self.last_qty.to_string())?;
196        dict.set_item("last_px", self.last_px.to_string())?;
197        dict.set_item("commission", self.commission.to_string())?;
198        dict.set_item("liquidity_side", self.liquidity_side.to_string())?;
199        dict.set_item("report_id", self.report_id.to_string())?;
200        dict.set_item("ts_event", self.ts_event.as_u64())?;
201        dict.set_item("ts_init", self.ts_init.as_u64())?;
202
203        match &self.client_order_id {
204            Some(id) => dict.set_item("client_order_id", id.to_string())?,
205            None => dict.set_item("client_order_id", py.None())?,
206        }
207        match &self.venue_position_id {
208            Some(id) => dict.set_item("venue_position_id", id.to_string())?,
209            None => dict.set_item("venue_position_id", py.None())?,
210        }
211
212        Ok(dict.into())
213    }
214}