nautilus_model/instruments/
any.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::UnixNanos;
17use rust_decimal::Decimal;
18use serde::{Deserialize, Serialize};
19use ustr::Ustr;
20
21use super::{
22    Instrument, betting::BettingInstrument, binary_option::BinaryOption,
23    crypto_future::CryptoFuture, crypto_perpetual::CryptoPerpetual, currency_pair::CurrencyPair,
24    equity::Equity, futures_contract::FuturesContract, futures_spread::FuturesSpread,
25    option_contract::OptionContract, option_spread::OptionSpread,
26};
27use crate::{
28    enums::InstrumentClass,
29    identifiers::{InstrumentId, Symbol, Venue},
30    types::{Currency, Money, Price, Quantity},
31};
32
33#[derive(Clone, Debug, Serialize, Deserialize)]
34pub enum InstrumentAny {
35    Betting(BettingInstrument),
36    BinaryOption(BinaryOption),
37    CryptoFuture(CryptoFuture),
38    CryptoPerpetual(CryptoPerpetual),
39    CurrencyPair(CurrencyPair),
40    Equity(Equity),
41    FuturesContract(FuturesContract),
42    FuturesSpread(FuturesSpread),
43    OptionContract(OptionContract),
44    OptionSpread(OptionSpread),
45}
46
47impl InstrumentAny {
48    /// Consumes the `OrderAny` enum and returns the underlying order as a boxed trait.
49    #[must_use]
50    pub fn into_instrument(self) -> Box<dyn Instrument> {
51        match self {
52            Self::Betting(inst) => Box::new(inst),
53            Self::BinaryOption(inst) => Box::new(inst),
54            Self::CryptoFuture(inst) => Box::new(inst),
55            Self::CryptoPerpetual(inst) => Box::new(inst),
56            Self::CurrencyPair(inst) => Box::new(inst),
57            Self::Equity(inst) => Box::new(inst),
58            Self::FuturesContract(inst) => Box::new(inst),
59            Self::FuturesSpread(inst) => Box::new(inst),
60            Self::OptionContract(inst) => Box::new(inst),
61            Self::OptionSpread(inst) => Box::new(inst),
62        }
63    }
64
65    #[must_use]
66    pub fn instrument_class(&self) -> InstrumentClass {
67        match self {
68            Self::Betting(inst) => inst.instrument_class(),
69            Self::BinaryOption(inst) => inst.instrument_class(),
70            Self::CryptoFuture(inst) => inst.instrument_class(),
71            Self::CryptoPerpetual(inst) => inst.instrument_class(),
72            Self::CurrencyPair(inst) => inst.instrument_class(),
73            Self::Equity(inst) => inst.instrument_class(),
74            Self::FuturesContract(inst) => inst.instrument_class(),
75            Self::FuturesSpread(inst) => inst.instrument_class(),
76            Self::OptionContract(inst) => inst.instrument_class(),
77            Self::OptionSpread(inst) => inst.instrument_class(),
78        }
79    }
80
81    #[must_use]
82    pub fn id(&self) -> InstrumentId {
83        match self {
84            Self::Betting(inst) => inst.id,
85            Self::BinaryOption(inst) => inst.id,
86            Self::CryptoFuture(inst) => inst.id,
87            Self::CryptoPerpetual(inst) => inst.id,
88            Self::CurrencyPair(inst) => inst.id,
89            Self::Equity(inst) => inst.id,
90            Self::FuturesContract(inst) => inst.id,
91            Self::FuturesSpread(inst) => inst.id,
92            Self::OptionContract(inst) => inst.id,
93            Self::OptionSpread(inst) => inst.id,
94        }
95    }
96
97    #[must_use]
98    pub fn symbol(&self) -> Symbol {
99        match self {
100            Self::Betting(inst) => inst.id.symbol,
101            Self::BinaryOption(inst) => inst.id.symbol,
102            Self::CryptoFuture(inst) => inst.id.symbol,
103            Self::CryptoPerpetual(inst) => inst.id.symbol,
104            Self::CurrencyPair(inst) => inst.id.symbol,
105            Self::Equity(inst) => inst.id.symbol,
106            Self::FuturesContract(inst) => inst.id.symbol,
107            Self::FuturesSpread(inst) => inst.id.symbol,
108            Self::OptionContract(inst) => inst.id.symbol,
109            Self::OptionSpread(inst) => inst.id.symbol,
110        }
111    }
112
113    #[must_use]
114    pub fn venue(&self) -> Venue {
115        match self {
116            Self::Betting(inst) => inst.id.venue,
117            Self::BinaryOption(inst) => inst.id.venue,
118            Self::CryptoFuture(inst) => inst.id.venue,
119            Self::CryptoPerpetual(inst) => inst.id.venue,
120            Self::CurrencyPair(inst) => inst.id.venue,
121            Self::Equity(inst) => inst.id.venue,
122            Self::FuturesContract(inst) => inst.id.venue,
123            Self::FuturesSpread(inst) => inst.id.venue,
124            Self::OptionContract(inst) => inst.id.venue,
125            Self::OptionSpread(inst) => inst.id.venue,
126        }
127    }
128
129    #[must_use]
130    pub fn raw_symbol(&self) -> Symbol {
131        match self {
132            Self::Betting(inst) => inst.raw_symbol(),
133            Self::BinaryOption(inst) => inst.raw_symbol(),
134            Self::CryptoFuture(inst) => inst.raw_symbol(),
135            Self::CryptoPerpetual(inst) => inst.raw_symbol(),
136            Self::CurrencyPair(inst) => inst.raw_symbol(),
137            Self::Equity(inst) => inst.raw_symbol(),
138            Self::FuturesContract(inst) => inst.raw_symbol(),
139            Self::FuturesSpread(inst) => inst.raw_symbol(),
140            Self::OptionContract(inst) => inst.raw_symbol(),
141            Self::OptionSpread(inst) => inst.raw_symbol(),
142        }
143    }
144
145    #[must_use]
146    pub fn underlying(&self) -> Option<&Ustr> {
147        match self {
148            Self::Betting(_) => None,
149            Self::BinaryOption(_) => None,
150            Self::CryptoFuture(inst) => Some(&inst.underlying.code),
151            Self::CryptoPerpetual(_) => None,
152            Self::CurrencyPair(_) => None,
153            Self::Equity(_) => None,
154            Self::FuturesContract(inst) => Some(&inst.underlying),
155            Self::FuturesSpread(inst) => Some(&inst.underlying),
156            Self::OptionContract(inst) => Some(&inst.underlying),
157            Self::OptionSpread(inst) => Some(&inst.underlying),
158        }
159    }
160
161    #[must_use]
162    pub fn base_currency(&self) -> Option<Currency> {
163        match self {
164            Self::Betting(inst) => inst.base_currency(),
165            Self::BinaryOption(inst) => inst.base_currency(),
166            Self::CryptoFuture(inst) => inst.base_currency(),
167            Self::CryptoPerpetual(inst) => inst.base_currency(),
168            Self::CurrencyPair(inst) => inst.base_currency(),
169            Self::Equity(inst) => inst.base_currency(),
170            Self::FuturesContract(inst) => inst.base_currency(),
171            Self::FuturesSpread(inst) => inst.base_currency(),
172            Self::OptionContract(inst) => inst.base_currency(),
173            Self::OptionSpread(inst) => inst.base_currency(),
174        }
175    }
176
177    #[must_use]
178    pub fn quote_currency(&self) -> Currency {
179        match self {
180            Self::Betting(inst) => inst.quote_currency(),
181            Self::BinaryOption(inst) => inst.quote_currency(),
182            Self::CryptoFuture(inst) => inst.quote_currency(),
183            Self::CryptoPerpetual(inst) => inst.quote_currency(),
184            Self::CurrencyPair(inst) => inst.quote_currency(),
185            Self::Equity(inst) => inst.quote_currency(),
186            Self::FuturesContract(inst) => inst.quote_currency(),
187            Self::FuturesSpread(inst) => inst.quote_currency(),
188            Self::OptionContract(inst) => inst.quote_currency(),
189            Self::OptionSpread(inst) => inst.quote_currency(),
190        }
191    }
192
193    #[must_use]
194    pub fn settlement_currency(&self) -> Currency {
195        match self {
196            Self::Betting(inst) => inst.settlement_currency(),
197            Self::BinaryOption(inst) => inst.settlement_currency(),
198            Self::CryptoFuture(inst) => inst.settlement_currency(),
199            Self::CryptoPerpetual(inst) => inst.settlement_currency(),
200            Self::CurrencyPair(inst) => inst.settlement_currency(),
201            Self::Equity(inst) => inst.settlement_currency(),
202            Self::FuturesContract(inst) => inst.settlement_currency(),
203            Self::FuturesSpread(inst) => inst.settlement_currency(),
204            Self::OptionContract(inst) => inst.settlement_currency(),
205            Self::OptionSpread(inst) => inst.settlement_currency(),
206        }
207    }
208
209    #[must_use]
210    pub fn is_inverse(&self) -> bool {
211        match self {
212            Self::Betting(inst) => inst.is_inverse(),
213            Self::BinaryOption(inst) => inst.is_inverse(),
214            Self::CryptoFuture(inst) => inst.is_inverse(),
215            Self::CryptoPerpetual(inst) => inst.is_inverse(),
216            Self::CurrencyPair(inst) => inst.is_inverse(),
217            Self::Equity(inst) => inst.is_inverse(),
218            Self::FuturesContract(inst) => inst.is_inverse(),
219            Self::FuturesSpread(inst) => inst.is_inverse(),
220            Self::OptionContract(inst) => inst.is_inverse(),
221            Self::OptionSpread(inst) => inst.is_inverse(),
222        }
223    }
224
225    #[must_use]
226    pub fn price_precision(&self) -> u8 {
227        match self {
228            Self::Betting(inst) => inst.price_precision(),
229            Self::BinaryOption(inst) => inst.price_precision(),
230            Self::CryptoFuture(inst) => inst.price_precision(),
231            Self::CryptoPerpetual(inst) => inst.price_precision(),
232            Self::CurrencyPair(inst) => inst.price_precision(),
233            Self::Equity(inst) => inst.price_precision(),
234            Self::FuturesContract(inst) => inst.price_precision(),
235            Self::FuturesSpread(inst) => inst.price_precision(),
236            Self::OptionContract(inst) => inst.price_precision(),
237            Self::OptionSpread(inst) => inst.price_precision(),
238        }
239    }
240
241    #[must_use]
242    pub fn size_precision(&self) -> u8 {
243        match self {
244            Self::Betting(inst) => inst.size_precision(),
245            Self::BinaryOption(inst) => inst.size_precision(),
246            Self::CryptoFuture(inst) => inst.size_precision(),
247            Self::CryptoPerpetual(inst) => inst.size_precision(),
248            Self::CurrencyPair(inst) => inst.size_precision(),
249            Self::Equity(inst) => inst.size_precision(),
250            Self::FuturesContract(inst) => inst.size_precision(),
251            Self::FuturesSpread(inst) => inst.size_precision(),
252            Self::OptionContract(inst) => inst.size_precision(),
253            Self::OptionSpread(inst) => inst.size_precision(),
254        }
255    }
256
257    #[must_use]
258    pub fn price_increment(&self) -> Price {
259        match self {
260            Self::Betting(inst) => inst.price_increment(),
261            Self::BinaryOption(inst) => inst.price_increment(),
262            Self::CryptoFuture(inst) => inst.price_increment(),
263            Self::CryptoPerpetual(inst) => inst.price_increment(),
264            Self::CurrencyPair(inst) => inst.price_increment(),
265            Self::Equity(inst) => inst.price_increment(),
266            Self::FuturesContract(inst) => inst.price_increment(),
267            Self::FuturesSpread(inst) => inst.price_increment(),
268            Self::OptionContract(inst) => inst.price_increment(),
269            Self::OptionSpread(inst) => inst.price_increment(),
270        }
271    }
272
273    #[must_use]
274    pub fn size_increment(&self) -> Quantity {
275        match self {
276            Self::Betting(inst) => inst.size_increment(),
277            Self::BinaryOption(inst) => inst.size_increment(),
278            Self::CryptoFuture(inst) => inst.size_increment(),
279            Self::CryptoPerpetual(inst) => inst.size_increment(),
280            Self::CurrencyPair(inst) => inst.size_increment(),
281            Self::Equity(inst) => inst.size_increment(),
282            Self::FuturesContract(inst) => inst.size_increment(),
283            Self::FuturesSpread(inst) => inst.size_increment(),
284            Self::OptionContract(inst) => inst.size_increment(),
285            Self::OptionSpread(inst) => inst.size_increment(),
286        }
287    }
288
289    #[must_use]
290    pub fn multiplier(&self) -> Quantity {
291        match self {
292            Self::Betting(inst) => inst.multiplier(),
293            Self::BinaryOption(inst) => inst.multiplier(),
294            Self::CryptoFuture(inst) => inst.multiplier(),
295            Self::CryptoPerpetual(inst) => inst.multiplier(),
296            Self::CurrencyPair(inst) => inst.multiplier(),
297            Self::Equity(inst) => inst.multiplier(),
298            Self::FuturesContract(inst) => inst.multiplier(),
299            Self::FuturesSpread(inst) => inst.multiplier(),
300            Self::OptionContract(inst) => inst.multiplier(),
301            Self::OptionSpread(inst) => inst.multiplier(),
302        }
303    }
304
305    #[must_use]
306    pub fn activation_ns(&self) -> Option<UnixNanos> {
307        match self {
308            Self::Betting(inst) => inst.activation_ns(),
309            Self::BinaryOption(inst) => inst.activation_ns(),
310            Self::CryptoFuture(inst) => inst.activation_ns(),
311            Self::CryptoPerpetual(inst) => inst.activation_ns(),
312            Self::CurrencyPair(inst) => inst.activation_ns(),
313            Self::Equity(inst) => inst.activation_ns(),
314            Self::FuturesContract(inst) => inst.activation_ns(),
315            Self::FuturesSpread(inst) => inst.activation_ns(),
316            Self::OptionContract(inst) => inst.activation_ns(),
317            Self::OptionSpread(inst) => inst.activation_ns(),
318        }
319    }
320
321    #[must_use]
322    pub fn expiration_ns(&self) -> Option<UnixNanos> {
323        match self {
324            Self::Betting(inst) => inst.expiration_ns(),
325            Self::BinaryOption(inst) => inst.expiration_ns(),
326            Self::CryptoFuture(inst) => inst.expiration_ns(),
327            Self::CryptoPerpetual(inst) => inst.expiration_ns(),
328            Self::CurrencyPair(inst) => inst.expiration_ns(),
329            Self::Equity(inst) => inst.expiration_ns(),
330            Self::FuturesContract(inst) => inst.expiration_ns(),
331            Self::FuturesSpread(inst) => inst.expiration_ns(),
332            Self::OptionContract(inst) => inst.expiration_ns(),
333            Self::OptionSpread(inst) => inst.expiration_ns(),
334        }
335    }
336
337    pub fn max_quantity(&self) -> Option<Quantity> {
338        match self {
339            Self::Betting(inst) => inst.max_quantity(),
340            Self::BinaryOption(inst) => inst.max_quantity(),
341            Self::CryptoFuture(inst) => inst.max_quantity(),
342            Self::CryptoPerpetual(inst) => inst.max_quantity(),
343            Self::CurrencyPair(inst) => inst.max_quantity(),
344            Self::Equity(inst) => inst.max_quantity(),
345            Self::FuturesContract(inst) => inst.max_quantity(),
346            Self::FuturesSpread(inst) => inst.max_quantity(),
347            Self::OptionContract(inst) => inst.max_quantity(),
348            Self::OptionSpread(inst) => inst.max_quantity(),
349        }
350    }
351
352    pub fn min_quantity(&self) -> Option<Quantity> {
353        match self {
354            Self::Betting(inst) => inst.min_quantity(),
355            Self::BinaryOption(inst) => inst.min_quantity(),
356            Self::CryptoFuture(inst) => inst.min_quantity(),
357            Self::CryptoPerpetual(inst) => inst.min_quantity(),
358            Self::CurrencyPair(inst) => inst.min_quantity(),
359            Self::Equity(inst) => inst.min_quantity(),
360            Self::FuturesContract(inst) => inst.min_quantity(),
361            Self::FuturesSpread(inst) => inst.min_quantity(),
362            Self::OptionContract(inst) => inst.min_quantity(),
363            Self::OptionSpread(inst) => inst.min_quantity(),
364        }
365    }
366
367    pub fn max_notional(&self) -> Option<Money> {
368        match self {
369            Self::Betting(inst) => inst.max_notional(),
370            Self::BinaryOption(inst) => inst.max_notional(),
371            Self::CryptoFuture(inst) => inst.max_notional(),
372            Self::CryptoPerpetual(inst) => inst.max_notional(),
373            Self::CurrencyPair(inst) => inst.max_notional(),
374            Self::Equity(inst) => inst.max_notional(),
375            Self::FuturesContract(inst) => inst.max_notional(),
376            Self::FuturesSpread(inst) => inst.max_notional(),
377            Self::OptionContract(inst) => inst.max_notional(),
378            Self::OptionSpread(inst) => inst.max_notional(),
379        }
380    }
381
382    pub fn min_notional(&self) -> Option<Money> {
383        match self {
384            Self::Betting(inst) => inst.min_notional(),
385            Self::BinaryOption(inst) => inst.min_notional(),
386            Self::CryptoFuture(inst) => inst.min_notional(),
387            Self::CryptoPerpetual(inst) => inst.min_notional(),
388            Self::CurrencyPair(inst) => inst.min_notional(),
389            Self::Equity(inst) => inst.min_notional(),
390            Self::FuturesContract(inst) => inst.min_notional(),
391            Self::FuturesSpread(inst) => inst.min_notional(),
392            Self::OptionContract(inst) => inst.min_notional(),
393            Self::OptionSpread(inst) => inst.min_notional(),
394        }
395    }
396
397    pub fn ts_event(&self) -> UnixNanos {
398        match self {
399            Self::Betting(inst) => inst.ts_event,
400            Self::BinaryOption(inst) => inst.ts_event,
401            Self::CryptoFuture(inst) => inst.ts_event,
402            Self::CryptoPerpetual(inst) => inst.ts_event,
403            Self::CurrencyPair(inst) => inst.ts_event,
404            Self::Equity(inst) => inst.ts_event,
405            Self::FuturesContract(inst) => inst.ts_event,
406            Self::FuturesSpread(inst) => inst.ts_event,
407            Self::OptionContract(inst) => inst.ts_event,
408            Self::OptionSpread(inst) => inst.ts_event,
409        }
410    }
411
412    pub fn ts_init(&self) -> UnixNanos {
413        match self {
414            Self::Betting(inst) => inst.ts_init,
415            Self::BinaryOption(inst) => inst.ts_init,
416            Self::CryptoFuture(inst) => inst.ts_init,
417            Self::CryptoPerpetual(inst) => inst.ts_init,
418            Self::CurrencyPair(inst) => inst.ts_init,
419            Self::Equity(inst) => inst.ts_init,
420            Self::FuturesContract(inst) => inst.ts_init,
421            Self::FuturesSpread(inst) => inst.ts_init,
422            Self::OptionContract(inst) => inst.ts_init,
423            Self::OptionSpread(inst) => inst.ts_init,
424        }
425    }
426
427    pub fn make_price(&self, value: f64) -> Price {
428        match self {
429            Self::Betting(inst) => inst.make_price(value),
430            Self::BinaryOption(inst) => inst.make_price(value),
431            Self::CryptoFuture(inst) => inst.make_price(value),
432            Self::CryptoPerpetual(inst) => inst.make_price(value),
433            Self::CurrencyPair(inst) => inst.make_price(value),
434            Self::Equity(inst) => inst.make_price(value),
435            Self::FuturesContract(inst) => inst.make_price(value),
436            Self::FuturesSpread(inst) => inst.make_price(value),
437            Self::OptionContract(inst) => inst.make_price(value),
438            Self::OptionSpread(inst) => inst.make_price(value),
439        }
440    }
441
442    pub fn make_qty(&self, value: f64) -> Quantity {
443        match self {
444            Self::Betting(inst) => inst.make_qty(value),
445            Self::BinaryOption(inst) => inst.make_qty(value),
446            Self::CryptoFuture(inst) => inst.make_qty(value),
447            Self::CryptoPerpetual(inst) => inst.make_qty(value),
448            Self::CurrencyPair(inst) => inst.make_qty(value),
449            Self::Equity(inst) => inst.make_qty(value),
450            Self::FuturesContract(inst) => inst.make_qty(value),
451            Self::FuturesSpread(inst) => inst.make_qty(value),
452            Self::OptionContract(inst) => inst.make_qty(value),
453            Self::OptionSpread(inst) => inst.make_qty(value),
454        }
455    }
456
457    #[must_use]
458    pub fn calculate_notional_value(
459        &self,
460        quantity: Quantity,
461        price: Price,
462        use_quote_for_inverse: Option<bool>,
463    ) -> Money {
464        match self {
465            Self::Betting(inst) => {
466                inst.calculate_notional_value(quantity, price, use_quote_for_inverse)
467            }
468            Self::BinaryOption(inst) => {
469                inst.calculate_notional_value(quantity, price, use_quote_for_inverse)
470            }
471            Self::CryptoFuture(inst) => {
472                inst.calculate_notional_value(quantity, price, use_quote_for_inverse)
473            }
474            Self::CryptoPerpetual(inst) => {
475                inst.calculate_notional_value(quantity, price, use_quote_for_inverse)
476            }
477            Self::CurrencyPair(inst) => {
478                inst.calculate_notional_value(quantity, price, use_quote_for_inverse)
479            }
480            Self::Equity(inst) => {
481                inst.calculate_notional_value(quantity, price, use_quote_for_inverse)
482            }
483            Self::FuturesContract(inst) => {
484                inst.calculate_notional_value(quantity, price, use_quote_for_inverse)
485            }
486            Self::FuturesSpread(inst) => {
487                inst.calculate_notional_value(quantity, price, use_quote_for_inverse)
488            }
489            Self::OptionContract(inst) => {
490                inst.calculate_notional_value(quantity, price, use_quote_for_inverse)
491            }
492            Self::OptionSpread(inst) => {
493                inst.calculate_notional_value(quantity, price, use_quote_for_inverse)
494            }
495        }
496    }
497
498    // #[deprecated(since = "0.21.0", note = "Will be removed in a future version")]
499    #[must_use]
500    pub fn maker_fee(&self) -> Decimal {
501        match self {
502            Self::Betting(inst) => inst.maker_fee(),
503            Self::BinaryOption(inst) => inst.maker_fee(),
504            Self::CryptoFuture(inst) => inst.maker_fee(),
505            Self::CryptoPerpetual(inst) => inst.maker_fee(),
506            Self::CurrencyPair(inst) => inst.maker_fee(),
507            Self::Equity(inst) => inst.maker_fee(),
508            Self::FuturesContract(inst) => inst.maker_fee(),
509            Self::FuturesSpread(inst) => inst.maker_fee(),
510            Self::OptionContract(inst) => inst.maker_fee(),
511            Self::OptionSpread(inst) => inst.maker_fee(),
512        }
513    }
514
515    // #[deprecated(since = "0.21.0", note = "Will be removed in a future version")]
516    #[must_use]
517    pub fn taker_fee(&self) -> Decimal {
518        match self {
519            Self::Betting(inst) => inst.taker_fee(),
520            Self::BinaryOption(inst) => inst.taker_fee(),
521            Self::CryptoFuture(inst) => inst.taker_fee(),
522            Self::CryptoPerpetual(inst) => inst.taker_fee(),
523            Self::CurrencyPair(inst) => inst.taker_fee(),
524            Self::Equity(inst) => inst.taker_fee(),
525            Self::FuturesContract(inst) => inst.taker_fee(),
526            Self::FuturesSpread(inst) => inst.taker_fee(),
527            Self::OptionContract(inst) => inst.taker_fee(),
528            Self::OptionSpread(inst) => inst.taker_fee(),
529        }
530    }
531
532    pub fn get_base_quantity(&self, quantity: Quantity, last_px: Price) -> Quantity {
533        match self {
534            Self::Betting(inst) => inst.calculate_base_quantity(quantity, last_px),
535            Self::BinaryOption(inst) => inst.calculate_base_quantity(quantity, last_px),
536            Self::CryptoFuture(inst) => inst.calculate_base_quantity(quantity, last_px),
537            Self::CryptoPerpetual(inst) => inst.calculate_base_quantity(quantity, last_px),
538            Self::CurrencyPair(inst) => inst.calculate_base_quantity(quantity, last_px),
539            Self::Equity(inst) => inst.calculate_base_quantity(quantity, last_px),
540            Self::FuturesContract(inst) => inst.calculate_base_quantity(quantity, last_px),
541            Self::FuturesSpread(inst) => inst.calculate_base_quantity(quantity, last_px),
542            Self::OptionContract(inst) => inst.calculate_base_quantity(quantity, last_px),
543            Self::OptionSpread(inst) => inst.calculate_base_quantity(quantity, last_px),
544        }
545    }
546}
547
548impl PartialEq for InstrumentAny {
549    fn eq(&self, other: &Self) -> bool {
550        self.id() == other.id()
551    }
552}