nautilus_model/ffi/orderbook/
book.rs1use std::{
17 ffi::c_char,
18 ops::{Deref, DerefMut},
19};
20
21use nautilus_core::ffi::{cvec::CVec, string::str_to_cstr};
22
23use super::level::BookLevel_API;
24use crate::{
25 data::{
26 BookOrder, OrderBookDelta, OrderBookDeltas_API, OrderBookDepth10, QuoteTick, TradeTick,
27 },
28 enums::{BookType, OrderSide},
29 identifiers::InstrumentId,
30 orderbook::{analysis::book_check_integrity, OrderBook},
31 types::{Price, Quantity},
32};
33
34#[repr(C)]
43#[allow(non_camel_case_types)]
44pub struct OrderBook_API(Box<OrderBook>);
45
46impl Deref for OrderBook_API {
47 type Target = OrderBook;
48
49 fn deref(&self) -> &Self::Target {
50 &self.0
51 }
52}
53
54impl DerefMut for OrderBook_API {
55 fn deref_mut(&mut self) -> &mut Self::Target {
56 &mut self.0
57 }
58}
59
60#[no_mangle]
61pub extern "C" fn orderbook_new(instrument_id: InstrumentId, book_type: BookType) -> OrderBook_API {
62 OrderBook_API(Box::new(OrderBook::new(instrument_id, book_type)))
63}
64
65#[no_mangle]
66pub extern "C" fn orderbook_drop(book: OrderBook_API) {
67 drop(book); }
69
70#[no_mangle]
71pub extern "C" fn orderbook_reset(book: &mut OrderBook_API) {
72 book.reset();
73}
74
75#[no_mangle]
76pub extern "C" fn orderbook_instrument_id(book: &OrderBook_API) -> InstrumentId {
77 book.instrument_id
78}
79
80#[no_mangle]
81pub extern "C" fn orderbook_book_type(book: &OrderBook_API) -> BookType {
82 book.book_type
83}
84
85#[no_mangle]
86pub extern "C" fn orderbook_sequence(book: &OrderBook_API) -> u64 {
87 book.sequence
88}
89
90#[no_mangle]
91pub extern "C" fn orderbook_ts_last(book: &OrderBook_API) -> u64 {
92 book.ts_last.into()
93}
94
95#[no_mangle]
96pub extern "C" fn orderbook_count(book: &OrderBook_API) -> u64 {
97 book.count
98}
99
100#[no_mangle]
101#[cfg_attr(feature = "high-precision", allow(improper_ctypes_definitions))]
102pub extern "C" fn orderbook_add(
103 book: &mut OrderBook_API,
104 order: BookOrder,
105 flags: u8,
106 sequence: u64,
107 ts_event: u64,
108) {
109 book.add(order, flags, sequence, ts_event.into());
110}
111
112#[no_mangle]
113#[cfg_attr(feature = "high-precision", allow(improper_ctypes_definitions))]
114pub extern "C" fn orderbook_update(
115 book: &mut OrderBook_API,
116 order: BookOrder,
117 flags: u8,
118 sequence: u64,
119 ts_event: u64,
120) {
121 book.update(order, flags, sequence, ts_event.into());
122}
123
124#[no_mangle]
125#[cfg_attr(feature = "high-precision", allow(improper_ctypes_definitions))]
126pub extern "C" fn orderbook_delete(
127 book: &mut OrderBook_API,
128 order: BookOrder,
129 flags: u8,
130 sequence: u64,
131 ts_event: u64,
132) {
133 book.delete(order, flags, sequence, ts_event.into());
134}
135
136#[no_mangle]
137pub extern "C" fn orderbook_clear(book: &mut OrderBook_API, sequence: u64, ts_event: u64) {
138 book.clear(sequence, ts_event.into());
139}
140
141#[no_mangle]
142pub extern "C" fn orderbook_clear_bids(book: &mut OrderBook_API, sequence: u64, ts_event: u64) {
143 book.clear_bids(sequence, ts_event.into());
144}
145
146#[no_mangle]
147pub extern "C" fn orderbook_clear_asks(book: &mut OrderBook_API, sequence: u64, ts_event: u64) {
148 book.clear_asks(sequence, ts_event.into());
149}
150
151#[no_mangle]
152pub extern "C" fn orderbook_apply_delta(book: &mut OrderBook_API, delta: &OrderBookDelta) {
153 book.apply_delta(delta);
154}
155
156#[no_mangle]
157pub extern "C" fn orderbook_apply_deltas(book: &mut OrderBook_API, deltas: &OrderBookDeltas_API) {
158 book.apply_deltas(deltas.deref());
160}
161
162#[no_mangle]
163pub extern "C" fn orderbook_apply_depth(book: &mut OrderBook_API, depth: &OrderBookDepth10) {
164 book.apply_depth(depth);
165}
166
167#[no_mangle]
168pub extern "C" fn orderbook_bids(book: &mut OrderBook_API) -> CVec {
169 book.bids
170 .levels
171 .values()
172 .map(|level| BookLevel_API::new(level.clone()))
173 .collect::<Vec<BookLevel_API>>()
174 .into()
175}
176
177#[no_mangle]
178pub extern "C" fn orderbook_asks(book: &mut OrderBook_API) -> CVec {
179 book.asks
180 .levels
181 .values()
182 .map(|level| BookLevel_API::new(level.clone()))
183 .collect::<Vec<BookLevel_API>>()
184 .into()
185}
186
187#[no_mangle]
188pub extern "C" fn orderbook_has_bid(book: &mut OrderBook_API) -> u8 {
189 u8::from(book.has_bid())
190}
191
192#[no_mangle]
193pub extern "C" fn orderbook_has_ask(book: &mut OrderBook_API) -> u8 {
194 u8::from(book.has_ask())
195}
196
197#[no_mangle]
198#[cfg_attr(feature = "high-precision", allow(improper_ctypes_definitions))]
199pub extern "C" fn orderbook_best_bid_price(book: &mut OrderBook_API) -> Price {
200 book.best_bid_price()
201 .expect("Error: No bid orders for best bid price")
202}
203
204#[no_mangle]
205#[cfg_attr(feature = "high-precision", allow(improper_ctypes_definitions))]
206pub extern "C" fn orderbook_best_ask_price(book: &mut OrderBook_API) -> Price {
207 book.best_ask_price()
208 .expect("Error: No ask orders for best ask price")
209}
210
211#[no_mangle]
212#[cfg_attr(feature = "high-precision", allow(improper_ctypes_definitions))]
213pub extern "C" fn orderbook_best_bid_size(book: &mut OrderBook_API) -> Quantity {
214 book.best_bid_size()
215 .expect("Error: No bid orders for best bid size")
216}
217
218#[no_mangle]
219#[cfg_attr(feature = "high-precision", allow(improper_ctypes_definitions))]
220pub extern "C" fn orderbook_best_ask_size(book: &mut OrderBook_API) -> Quantity {
221 book.best_ask_size()
222 .expect("Error: No ask orders for best ask size")
223}
224
225#[no_mangle]
226pub extern "C" fn orderbook_spread(book: &mut OrderBook_API) -> f64 {
227 book.spread()
228 .expect("Error: Unable to calculate `spread` (no bid or ask)")
229}
230
231#[no_mangle]
232pub extern "C" fn orderbook_midpoint(book: &mut OrderBook_API) -> f64 {
233 book.midpoint()
234 .expect("Error: Unable to calculate `midpoint` (no bid or ask)")
235}
236
237#[no_mangle]
238#[cfg_attr(feature = "high-precision", allow(improper_ctypes_definitions))]
239pub extern "C" fn orderbook_get_avg_px_for_quantity(
240 book: &mut OrderBook_API,
241 qty: Quantity,
242 order_side: OrderSide,
243) -> f64 {
244 book.get_avg_px_for_quantity(qty, order_side)
245}
246
247#[no_mangle]
248#[cfg_attr(feature = "high-precision", allow(improper_ctypes_definitions))]
249pub extern "C" fn orderbook_get_quantity_for_price(
250 book: &mut OrderBook_API,
251 price: Price,
252 order_side: OrderSide,
253) -> f64 {
254 book.get_quantity_for_price(price, order_side)
255}
256
257#[no_mangle]
264pub extern "C" fn orderbook_update_quote_tick(book: &mut OrderBook_API, quote: &QuoteTick) {
265 book.update_quote_tick(quote).unwrap();
266}
267
268#[no_mangle]
275pub extern "C" fn orderbook_update_trade_tick(book: &mut OrderBook_API, trade: &TradeTick) {
276 book.update_trade_tick(trade).unwrap();
277}
278
279#[no_mangle]
280#[cfg_attr(feature = "high-precision", allow(improper_ctypes_definitions))]
281pub extern "C" fn orderbook_simulate_fills(book: &OrderBook_API, order: BookOrder) -> CVec {
282 book.simulate_fills(&order).into()
283}
284
285#[no_mangle]
286pub extern "C" fn orderbook_check_integrity(book: &OrderBook_API) -> u8 {
287 u8::from(book_check_integrity(book).is_ok())
288}
289
290#[allow(clippy::drop_non_drop)]
293#[no_mangle]
294pub extern "C" fn vec_fills_drop(v: CVec) {
295 let CVec { ptr, len, cap } = v;
296 let data: Vec<(Price, Quantity)> =
297 unsafe { Vec::from_raw_parts(ptr.cast::<(Price, Quantity)>(), len, cap) };
298 drop(data); }
300
301#[no_mangle]
303pub extern "C" fn orderbook_pprint_to_cstr(
304 book: &OrderBook_API,
305 num_levels: usize,
306) -> *const c_char {
307 str_to_cstr(&book.pprint(num_levels))
308}