1use jiff::{Timestamp, civil::Date, tz::Offset};
17use nautilus_core::UnixNanos;
18use rstest::fixture;
19use rust_decimal::Decimal;
20use rust_decimal_macros::dec;
21use ustr::Ustr;
22
23use super::{
24 CryptoOption, betting::BettingInstrument, binary_option::BinaryOption, cfd::Cfd,
25 commodity::Commodity, futures_spread::FuturesSpread, index_instrument::IndexInstrument,
26 option_spread::OptionSpread, perpetual_contract::PerpetualContract,
27 synthetic::SyntheticInstrument, tokenized_asset::TokenizedAsset,
28};
29use crate::{
30 enums::{AssetClass, OptionKind},
31 identifiers::{InstrumentId, Symbol, Venue},
32 instruments::{
33 CryptoFuture, CryptoFuturesSpread, CryptoOptionSpread, CryptoPerpetual, CurrencyPair,
34 Equity, FuturesContract, OptionContract,
35 },
36 types::{Currency, Money, Price, Quantity},
37};
38
39fn timestamp(year: i16, month: i8, day: i8, hour: i8, minute: i8, second: i8) -> Timestamp {
40 let datetime = Date::new(year, month, day)
41 .expect("valid date")
42 .at(hour, minute, second, 0);
43 Offset::UTC.to_timestamp(datetime).expect("valid timestamp")
44}
45
46impl Default for SyntheticInstrument {
47 fn default() -> Self {
49 let btc_binance = InstrumentId::from("BTC.BINANCE");
50 let ltc_binance = InstrumentId::from("LTC.BINANCE");
51 let formula = "(BTC.BINANCE + LTC.BINANCE) / 2.0";
52 Self::builder()
53 .symbol(Symbol::new("BTC-LTC"))
54 .price_precision(2)
55 .components(vec![btc_binance, ltc_binance])
56 .formula(formula)
57 .ts_event(0.into())
58 .ts_init(0.into())
59 .build()
60 .unwrap()
61 }
62}
63
64#[fixture]
65pub fn crypto_future_btcusdt(
66 #[default(2)] price_precision: u8,
67 #[default(6)] size_precision: u8,
68 #[default(Price::from("0.01"))] price_increment: Price,
69 #[default(Quantity::from("0.000001"))] size_increment: Quantity,
70) -> CryptoFuture {
71 let activation = timestamp(2014, 4, 8, 0, 0, 0);
72 let expiration = timestamp(2014, 7, 8, 0, 0, 0);
73 CryptoFuture::builder()
74 .instrument_id(InstrumentId::from("ETHUSDT-123.BINANCE"))
75 .raw_symbol(Symbol::from("BTCUSDT"))
76 .underlying(Currency::from("BTC"))
77 .quote_currency(Currency::from("USDT"))
78 .settlement_currency(Currency::from("USDT"))
79 .is_inverse(false)
80 .activation_ns(UnixNanos::from(activation))
81 .expiration_ns(UnixNanos::from(expiration))
82 .price_precision(price_precision)
83 .size_precision(size_precision)
84 .price_increment(price_increment)
85 .size_increment(size_increment)
86 .max_quantity(Quantity::from("9000.0"))
87 .min_quantity(Quantity::from("0.000001"))
88 .min_notional(Money::new(10.00, Currency::from("USDT")))
89 .max_price(Price::from("1000000.00"))
90 .min_price(Price::from("0.01"))
91 .ts_event(0.into())
92 .ts_init(0.into())
93 .build()
94 .unwrap()
95}
96
97#[fixture]
98pub fn ethbtc_quanto(
99 #[default(5)] price_precision: u8,
100 #[default(3)] size_precision: u8,
101 #[default(Price::from("0.00001"))] price_increment: Price,
102 #[default(Quantity::from("0.001"))] size_increment: Quantity,
103) -> CryptoFuture {
104 let activation = timestamp(2014, 4, 8, 0, 0, 0);
105 let expiration = timestamp(2014, 7, 8, 0, 0, 0);
106 CryptoFuture::builder()
107 .instrument_id(InstrumentId::from("ETHBTC-123.BINANCE"))
108 .raw_symbol(Symbol::from("ETHBTC"))
109 .underlying(Currency::from("ETH"))
110 .quote_currency(Currency::from("BTC"))
111 .settlement_currency(Currency::from("USDT"))
112 .is_inverse(false)
113 .activation_ns(UnixNanos::from(activation))
114 .expiration_ns(UnixNanos::from(expiration))
115 .price_precision(price_precision)
116 .size_precision(size_precision)
117 .price_increment(price_increment)
118 .size_increment(size_increment)
119 .max_quantity(Quantity::from("9000.0"))
120 .min_quantity(Quantity::from("0.001"))
121 .min_notional(Money::new(1.0, Currency::from("USDT")))
122 .max_price(Price::from("1.0"))
123 .min_price(Price::from("0.00001"))
124 .ts_event(0.into())
125 .ts_init(0.into())
126 .build()
127 .unwrap()
128}
129
130#[fixture]
131pub fn xbtusd_inverse_perp(
132 #[default(1)] price_precision: u8,
134 #[default(0)] size_precision: u8,
135 #[default(Price::from("0.5"))] price_increment: Price,
136 #[default(Quantity::from("1"))] size_increment: Quantity,
137) -> CryptoPerpetual {
138 CryptoPerpetual::builder()
139 .instrument_id(InstrumentId::from("XBTUSD-PERP.BITMEX"))
141 .raw_symbol(Symbol::from("XBTUSD"))
142 .base_currency(Currency::BTC())
144 .quote_currency(Currency::USD())
146 .settlement_currency(Currency::BTC())
148 .is_inverse(true)
149 .price_precision(price_precision)
150 .size_precision(size_precision)
151 .price_increment(price_increment)
152 .size_increment(size_increment)
153 .lot_size(Quantity::from("1"))
154 .max_notional(Money::from("10000000 USD"))
155 .min_notional(Money::from("1 USD"))
156 .max_price(Price::from("10000000"))
157 .min_price(Price::from("0.01"))
158 .margin_init(dec!(0.01))
159 .margin_maint(dec!(0.0035))
160 .maker_fee(dec!(-0.00025))
162 .taker_fee(dec!(0.00075))
163 .ts_event(UnixNanos::default())
164 .ts_init(UnixNanos::default())
165 .build()
166 .unwrap()
167}
168
169#[fixture]
170pub fn crypto_option_btc_deribit(
171 #[default(3)] price_precision: u8,
172 #[default(1)] size_precision: u8,
173 #[default(Price::from("0.001"))] price_increment: Price,
174 #[default(Quantity::from("0.1"))] size_increment: Quantity,
175) -> CryptoOption {
176 let activation = UnixNanos::from(1_671_696_002_000_000_000);
177 let expiration = UnixNanos::from(1_673_596_800_000_000_000);
178 CryptoOption::builder()
179 .instrument_id(InstrumentId::from("BTC-13JAN23-16000-P.DERIBIT"))
180 .raw_symbol(Symbol::from("BTC-13JAN23-16000-P"))
181 .underlying(Currency::from("BTC"))
182 .quote_currency(Currency::from("USD"))
183 .settlement_currency(Currency::from("BTC"))
184 .is_inverse(false)
185 .option_kind(OptionKind::Put)
186 .strike_price(Price::from("16000.000"))
187 .activation_ns(activation)
188 .expiration_ns(expiration)
189 .price_precision(price_precision)
190 .size_precision(size_precision)
191 .price_increment(price_increment)
192 .size_increment(size_increment)
193 .multiplier(Quantity::from(1))
194 .lot_size(Quantity::from(1))
195 .max_quantity(Quantity::from("9000.0"))
196 .min_quantity(Quantity::from("0.1"))
197 .min_notional(Money::new(10.00, Currency::from("USD")))
198 .maker_fee(dec!(0.0003))
199 .taker_fee(dec!(0.0003))
200 .ts_event(0.into())
201 .ts_init(0.into())
202 .build()
203 .unwrap()
204}
205
206#[fixture]
207pub fn crypto_perpetual_ethusdt() -> CryptoPerpetual {
208 CryptoPerpetual::builder()
209 .instrument_id(InstrumentId::from("ETHUSDT-PERP.BINANCE"))
210 .raw_symbol(Symbol::from("ETHUSDT"))
211 .base_currency(Currency::from("ETH"))
212 .quote_currency(Currency::from("USDT"))
213 .settlement_currency(Currency::from("USDT"))
214 .is_inverse(false)
215 .price_precision(2)
216 .size_precision(3)
217 .price_increment(Price::from("0.01"))
218 .size_increment(Quantity::from("0.001"))
219 .max_quantity(Quantity::from("10000.0"))
220 .min_quantity(Quantity::from("0.001"))
221 .min_notional(Money::new(10.00, Currency::from("USDT")))
222 .max_price(Price::from("15000.00"))
223 .min_price(Price::from("1.0"))
224 .margin_init(dec!(1.0))
225 .margin_maint(dec!(0.35))
226 .maker_fee(dec!(0.0002))
227 .taker_fee(dec!(0.0004))
228 .ts_event(UnixNanos::default())
229 .ts_init(UnixNanos::default())
230 .build()
231 .unwrap()
232}
233
234#[fixture]
235pub fn xbtusd_bitmex() -> CryptoPerpetual {
236 CryptoPerpetual::builder()
237 .instrument_id(InstrumentId::from("BTCUSDT.BITMEX"))
238 .raw_symbol(Symbol::from("XBTUSD"))
239 .base_currency(Currency::BTC())
240 .quote_currency(Currency::USD())
241 .settlement_currency(Currency::BTC())
242 .is_inverse(true)
243 .price_precision(1)
244 .size_precision(0)
245 .price_increment(Price::from("0.5"))
246 .size_increment(Quantity::from("1"))
247 .max_notional(Money::from("10000000 USD"))
248 .min_notional(Money::from("1 USD"))
249 .max_price(Price::from("10000000"))
250 .min_price(Price::from("0.01"))
251 .margin_init(dec!(0.01))
252 .margin_maint(dec!(0.0035))
253 .maker_fee(dec!(-0.00025))
254 .taker_fee(dec!(0.00075))
255 .ts_event(UnixNanos::default())
256 .ts_init(UnixNanos::default())
257 .build()
258 .unwrap()
259}
260
261#[fixture]
262pub fn ethusdt_bitmex() -> CryptoPerpetual {
263 CryptoPerpetual::builder()
264 .instrument_id(InstrumentId::from("ETHUSD.BITMEX"))
265 .raw_symbol(Symbol::from("ETHUSD"))
266 .base_currency(Currency::ETH())
267 .quote_currency(Currency::USD())
268 .settlement_currency(Currency::ETH())
269 .is_inverse(true)
270 .price_precision(2)
271 .size_precision(0)
272 .price_increment(Price::from("0.05"))
273 .size_increment(Quantity::from("1"))
274 .max_price(Price::from("10000000"))
275 .min_price(Price::from("0.01"))
276 .margin_init(dec!(0.01))
277 .margin_maint(dec!(0.0035))
278 .maker_fee(dec!(-0.00025))
279 .taker_fee(dec!(0.00075))
280 .ts_event(UnixNanos::default())
281 .ts_init(UnixNanos::default())
282 .build()
283 .unwrap()
284}
285
286#[fixture]
287pub fn currency_pair_btcusdt() -> CurrencyPair {
288 CurrencyPair::builder()
289 .instrument_id(InstrumentId::from("BTCUSDT.BINANCE"))
290 .raw_symbol(Symbol::from("BTCUSDT"))
291 .base_currency(Currency::from("BTC"))
292 .quote_currency(Currency::from("USDT"))
293 .price_precision(2)
294 .size_precision(6)
295 .price_increment(Price::from("0.01"))
296 .size_increment(Quantity::from("0.000001"))
297 .max_quantity(Quantity::from("9000"))
298 .min_quantity(Quantity::from("0.000001"))
299 .max_price(Price::from("1000000"))
300 .min_price(Price::from("0.01"))
301 .margin_init(dec!(0.001))
302 .margin_maint(dec!(0.001))
303 .maker_fee(dec!(0.001))
304 .taker_fee(dec!(0.001))
305 .ts_event(UnixNanos::default())
306 .ts_init(UnixNanos::default())
307 .build()
308 .unwrap()
309}
310
311#[fixture]
312pub fn currency_pair_ethusdt() -> CurrencyPair {
313 CurrencyPair::builder()
314 .instrument_id(InstrumentId::from("ETHUSDT.BINANCE"))
315 .raw_symbol(Symbol::from("ETHUSDT"))
316 .base_currency(Currency::from("ETH"))
317 .quote_currency(Currency::from("USDT"))
318 .price_precision(2)
319 .size_precision(5)
320 .price_increment(Price::from("0.01"))
321 .size_increment(Quantity::from("0.00001"))
322 .max_quantity(Quantity::from("9000"))
323 .min_quantity(Quantity::from("0.00001"))
324 .max_price(Price::from("1000000"))
325 .min_price(Price::from("0.01"))
326 .margin_init(dec!(0.01))
327 .margin_maint(dec!(0.0035))
328 .maker_fee(dec!(0.0001))
329 .taker_fee(dec!(0.0001))
330 .ts_event(UnixNanos::default())
331 .ts_init(UnixNanos::default())
332 .build()
333 .unwrap()
334}
335
336#[must_use]
340pub fn default_fx_ccy(symbol: Symbol, venue: Option<Venue>) -> CurrencyPair {
341 let target_venue = venue.unwrap_or(Venue::from("SIM"));
342 let instrument_id = InstrumentId::new(symbol, target_venue);
343 let base_currency = symbol.as_str().split('/').next().unwrap();
344 let quote_currency = symbol.as_str().split('/').next_back().unwrap();
345 let price_precision = if quote_currency == "JPY" { 3 } else { 5 };
346 let tick_scheme = if quote_currency == "JPY" {
347 "FOREX_3DECIMAL"
348 } else {
349 "FOREX_5DECIMAL"
350 };
351 let price_increment = Price::new(
352 1.0 / 10.0f64.powi(i32::from(price_precision)),
353 price_precision,
354 );
355 CurrencyPair::builder()
356 .instrument_id(instrument_id)
357 .raw_symbol(symbol)
358 .base_currency(Currency::from(base_currency))
359 .quote_currency(Currency::from(quote_currency))
360 .price_precision(price_precision)
361 .size_precision(0)
362 .price_increment(price_increment)
363 .size_increment(Quantity::from("1"))
364 .lot_size(Quantity::from("1000"))
365 .max_quantity(Quantity::from("1000000"))
366 .min_quantity(Quantity::from("100"))
367 .margin_init(dec!(0.03))
368 .margin_maint(dec!(0.03))
369 .maker_fee(dec!(0.00002))
370 .taker_fee(dec!(0.00002))
371 .tick_scheme(Ustr::from(tick_scheme))
372 .ts_event(UnixNanos::default())
373 .ts_init(UnixNanos::default())
374 .build()
375 .unwrap()
376}
377
378#[fixture]
379pub fn audusd_sim() -> CurrencyPair {
380 default_fx_ccy(Symbol::from("AUD/USD"), Some(Venue::from("SIM")))
381}
382
383#[fixture]
384pub fn gbpusd_sim() -> CurrencyPair {
385 default_fx_ccy(Symbol::from("GBP/USD"), Some(Venue::from("SIM")))
386}
387
388#[fixture]
389pub fn usdjpy_idealpro() -> CurrencyPair {
390 default_fx_ccy(Symbol::from("USD/JPY"), Some(Venue::from("IDEALPRO")))
391}
392
393#[fixture]
394pub fn equity_aapl() -> Equity {
395 Equity::builder()
396 .instrument_id(InstrumentId::from("AAPL.XNAS"))
397 .raw_symbol(Symbol::from("AAPL"))
398 .isin(Ustr::from("US0378331005"))
399 .currency(Currency::from("USD"))
400 .price_precision(2)
401 .price_increment(Price::from("0.01"))
402 .ts_event(UnixNanos::default())
403 .ts_init(UnixNanos::default())
404 .build()
405 .unwrap()
406}
407
408#[must_use]
414pub fn equity_aapl_itch() -> Equity {
415 Equity::builder()
416 .instrument_id(InstrumentId::from("AAPL.XNAS"))
417 .raw_symbol(Symbol::from("AAPL"))
418 .isin(Ustr::from("US0378331005"))
419 .currency(Currency::from("USD"))
420 .price_precision(4)
421 .price_increment(Price::from("0.0001"))
422 .ts_event(UnixNanos::default())
423 .ts_init(UnixNanos::default())
424 .build()
425 .unwrap()
426}
427
428#[must_use]
433pub fn futures_contract_es(
434 activation: Option<UnixNanos>,
435 expiration: Option<UnixNanos>,
436) -> FuturesContract {
437 let activation = activation.unwrap_or(UnixNanos::from(timestamp(2021, 9, 10, 0, 0, 0)));
438 let expiration = expiration.unwrap_or(UnixNanos::from(timestamp(2021, 12, 17, 0, 0, 0)));
439 FuturesContract::builder()
440 .instrument_id(InstrumentId::from("ESZ21.GLBX"))
441 .raw_symbol(Symbol::from("ESZ21"))
442 .asset_class(AssetClass::Index)
443 .exchange(Ustr::from("XCME"))
444 .underlying(Ustr::from("ES"))
445 .activation_ns(activation)
446 .expiration_ns(expiration)
447 .currency(Currency::USD())
448 .price_precision(2)
449 .price_increment(Price::from("0.01"))
450 .multiplier(Quantity::from(1))
451 .lot_size(Quantity::from(1))
452 .ts_event(UnixNanos::default())
453 .ts_init(UnixNanos::default())
454 .build()
455 .unwrap()
456}
457
458#[fixture]
459pub fn futures_spread_es() -> FuturesSpread {
460 let activation = timestamp(2022, 6, 21, 13, 30, 0);
461 let expiration = timestamp(2024, 6, 21, 13, 30, 0);
462 FuturesSpread::builder()
463 .instrument_id(InstrumentId::from("ESM4-ESU4.GLBX"))
464 .raw_symbol(Symbol::from("ESM4-ESU4"))
465 .asset_class(AssetClass::Index)
466 .exchange(Ustr::from("XCME"))
467 .underlying(Ustr::from("ES"))
468 .strategy_type(Ustr::from("EQ"))
469 .activation_ns(UnixNanos::from(activation))
470 .expiration_ns(UnixNanos::from(expiration))
471 .currency(Currency::USD())
472 .price_precision(2)
473 .price_increment(Price::from("0.01"))
474 .multiplier(Quantity::from(1))
475 .lot_size(Quantity::from(1))
476 .ts_event(UnixNanos::default())
477 .ts_init(UnixNanos::default())
478 .build()
479 .unwrap()
480}
481
482#[fixture]
483pub fn option_contract_appl() -> OptionContract {
484 let activation = timestamp(2021, 9, 17, 0, 0, 0);
485 let expiration = timestamp(2021, 12, 17, 0, 0, 0);
486 OptionContract::builder()
487 .instrument_id(InstrumentId::from("AAPL211217C00150000.OPRA"))
488 .raw_symbol(Symbol::from("AAPL211217C00150000"))
489 .asset_class(AssetClass::Equity)
490 .exchange(Ustr::from("GMNI"))
491 .underlying(Ustr::from("AAPL"))
492 .option_kind(OptionKind::Call)
493 .strike_price(Price::from("149.0"))
494 .currency(Currency::USD())
495 .activation_ns(UnixNanos::from(activation))
496 .expiration_ns(UnixNanos::from(expiration))
497 .price_precision(2)
498 .price_increment(Price::from("0.01"))
499 .multiplier(Quantity::from(1))
500 .lot_size(Quantity::from(1))
501 .ts_event(UnixNanos::default())
502 .ts_init(UnixNanos::default())
503 .build()
504 .unwrap()
505}
506
507#[fixture]
508pub fn option_spread() -> OptionSpread {
509 let activation = timestamp(2023, 11, 6, 20, 54, 7);
510 let expiration = timestamp(2024, 2, 23, 22, 59, 0);
511 OptionSpread::builder()
512 .instrument_id(InstrumentId::from("UD:U$: GN 2534559.GLBX"))
513 .raw_symbol(Symbol::from("UD:U$: GN 2534559"))
514 .asset_class(AssetClass::FX)
515 .exchange(Ustr::from("XCME"))
516 .underlying(Ustr::from("SR3"))
517 .strategy_type(Ustr::from("GN"))
518 .activation_ns(UnixNanos::from(activation))
519 .expiration_ns(UnixNanos::from(expiration))
520 .currency(Currency::USD())
521 .price_precision(2)
522 .price_increment(Price::from("0.01"))
523 .multiplier(Quantity::from(1))
524 .lot_size(Quantity::from(1))
525 .ts_event(UnixNanos::default())
526 .ts_init(UnixNanos::default())
527 .build()
528 .unwrap()
529}
530
531#[fixture]
532pub fn crypto_futures_spread_btc_deribit() -> CryptoFuturesSpread {
533 let activation = timestamp(2026, 5, 12, 0, 0, 0);
534 let expiration = timestamp(2026, 5, 19, 8, 0, 0);
535 CryptoFuturesSpread::builder()
536 .instrument_id(InstrumentId::from("BTC-FS-19MAY26_PERP.DERIBIT"))
537 .raw_symbol(Symbol::from("BTC-FS-19MAY26_PERP"))
538 .underlying(Currency::BTC())
539 .quote_currency(Currency::USD())
540 .settlement_currency(Currency::BTC())
541 .is_inverse(false)
542 .strategy_type(Ustr::from("FS"))
543 .activation_ns(UnixNanos::from(activation))
544 .expiration_ns(UnixNanos::from(expiration))
545 .price_precision(1)
546 .size_precision(0)
547 .price_increment(Price::from("0.5"))
548 .size_increment(Quantity::from("1"))
549 .multiplier(Quantity::from("10"))
550 .min_quantity(Quantity::from("1"))
551 .maker_fee(dec!(0.0003))
552 .taker_fee(dec!(0.0003))
553 .ts_event(0.into())
554 .ts_init(0.into())
555 .build()
556 .unwrap()
557}
558
559#[fixture]
560pub fn crypto_option_spread_btc_deribit() -> CryptoOptionSpread {
561 let activation = timestamp(2026, 5, 12, 0, 0, 0);
562 let expiration = timestamp(2026, 5, 19, 8, 0, 0);
563 CryptoOptionSpread::builder()
564 .instrument_id(InstrumentId::from("BTC-CS-19MAY26-70000_75000.DERIBIT"))
565 .raw_symbol(Symbol::from("BTC-CS-19MAY26-70000_75000"))
566 .underlying(Currency::BTC())
567 .quote_currency(Currency::USD())
568 .settlement_currency(Currency::BTC())
569 .is_inverse(false)
570 .strategy_type(Ustr::from("CS"))
571 .activation_ns(UnixNanos::from(activation))
572 .expiration_ns(UnixNanos::from(expiration))
573 .price_precision(4)
574 .size_precision(1)
575 .price_increment(Price::from("0.0001"))
576 .size_increment(Quantity::from("0.1"))
577 .multiplier(Quantity::from(1))
578 .min_quantity(Quantity::from("0.1"))
579 .maker_fee(dec!(0.0003))
580 .taker_fee(dec!(0.0003))
581 .ts_event(0.into())
582 .ts_init(0.into())
583 .build()
584 .unwrap()
585}
586
587#[fixture]
588pub fn betting() -> BettingInstrument {
589 let raw_symbol = Symbol::new("1-123456789");
590 let id = InstrumentId::from(format!("{raw_symbol}.BETFAIR"));
591 let event_type_id = 6423;
592 let event_type_name = Ustr::from("American Football");
593 let competition_id = 12_282_733;
594 let competition_name = Ustr::from("NFL");
595 let event_id = 29_678_534;
596 let event_name = Ustr::from("NFL");
597 let event_country_code = Ustr::from("GB");
598 let event_open_date = UnixNanos::from(timestamp(2022, 2, 7, 23, 30, 0));
599 let betting_type = Ustr::from("ODDS");
600 let market_id = Ustr::from("1-123456789");
601 let market_name = Ustr::from("AFC Conference Winner");
602 let market_type = Ustr::from("SPECIAL");
603 let market_start_time = UnixNanos::from(timestamp(2022, 2, 7, 23, 30, 0));
604 let selection_id = 50214;
605 let selection_name = Ustr::from("Kansas City Chiefs");
606 let selection_handicap = 0.0;
607 let currency = Currency::GBP();
608 let price_increment = Price::from("0.01");
609 let size_increment = Quantity::from("0.01");
610 let max_quantity = Some(Quantity::from("1000"));
611 let min_quantity = Some(Quantity::from("1"));
612 let max_notional = Some(Money::from("10000 GBP"));
613 let min_notional = Some(Money::from("10 GBP"));
614 let max_price = Some(Price::from("100.00"));
615 let min_price = Some(Price::from("1.00"));
616 let margin_init = Some(Decimal::from(1));
617 let margin_maint = Some(Decimal::from(1));
618 let maker_fee = Some(Decimal::from(0));
619 let taker_fee = Some(Decimal::from(0));
620 let ts_event = UnixNanos::default();
621 let ts_init = UnixNanos::default();
622
623 BettingInstrument::builder()
624 .instrument_id(id)
625 .raw_symbol(raw_symbol)
626 .event_type_id(event_type_id)
627 .event_type_name(event_type_name)
628 .competition_id(competition_id)
629 .competition_name(competition_name)
630 .event_id(event_id)
631 .event_name(event_name)
632 .event_country_code(event_country_code)
633 .event_open_date(event_open_date)
634 .betting_type(betting_type)
635 .market_id(market_id)
636 .market_name(market_name)
637 .market_type(market_type)
638 .market_start_time(market_start_time)
639 .selection_id(selection_id)
640 .selection_name(selection_name)
641 .selection_handicap(selection_handicap)
642 .currency(currency)
643 .price_precision(price_increment.precision)
644 .size_precision(size_increment.precision)
645 .price_increment(price_increment)
646 .size_increment(size_increment)
647 .maybe_max_quantity(max_quantity)
648 .maybe_min_quantity(min_quantity)
649 .maybe_max_notional(max_notional)
650 .maybe_min_notional(min_notional)
651 .maybe_max_price(max_price)
652 .maybe_min_price(min_price)
653 .maybe_margin_init(margin_init)
654 .maybe_margin_maint(margin_maint)
655 .maybe_maker_fee(maker_fee)
656 .maybe_taker_fee(taker_fee)
657 .ts_event(ts_event)
658 .ts_init(ts_init)
659 .build()
660 .unwrap()
661}
662
663#[fixture]
664pub fn commodity_gold() -> Commodity {
665 Commodity::builder()
666 .instrument_id(InstrumentId::from("GOLD.COMEX"))
667 .raw_symbol(Symbol::from("GOLD"))
668 .asset_class(AssetClass::Commodity)
669 .quote_currency(Currency::from("USD"))
670 .price_precision(2)
671 .size_precision(0)
672 .price_increment(Price::from("0.01"))
673 .size_increment(Quantity::from("1"))
674 .lot_size(Quantity::from("1"))
675 .ts_event(UnixNanos::default())
676 .ts_init(UnixNanos::default())
677 .build()
678 .unwrap()
679}
680
681#[fixture]
682pub fn index_instrument_spx() -> IndexInstrument {
683 IndexInstrument::builder()
684 .instrument_id(InstrumentId::from("SPX.INDEX"))
685 .raw_symbol(Symbol::from("SPX"))
686 .currency(Currency::from("USD"))
687 .price_precision(2)
688 .size_precision(0)
689 .price_increment(Price::from("0.01"))
690 .size_increment(Quantity::from("1"))
691 .ts_event(UnixNanos::default())
692 .ts_init(UnixNanos::default())
693 .build()
694 .unwrap()
695}
696
697#[fixture]
698pub fn cfd_gold() -> Cfd {
699 Cfd::builder()
700 .instrument_id(InstrumentId::from("GOLD-CFD.SIM"))
701 .raw_symbol(Symbol::from("GOLD-CFD"))
702 .asset_class(AssetClass::Commodity)
703 .quote_currency(Currency::from("USD"))
704 .price_precision(2)
705 .size_precision(0)
706 .price_increment(Price::from("0.01"))
707 .size_increment(Quantity::from("1"))
708 .lot_size(Quantity::from("1"))
709 .ts_event(UnixNanos::default())
710 .ts_init(UnixNanos::default())
711 .build()
712 .unwrap()
713}
714
715#[fixture]
716pub fn perpetual_contract_eurusd() -> PerpetualContract {
717 PerpetualContract::builder()
718 .instrument_id(InstrumentId::from("EURUSD-PERP.AX"))
719 .raw_symbol(Symbol::from("EURUSD-PERP"))
720 .underlying(Ustr::from("EURUSD"))
721 .asset_class(AssetClass::FX)
722 .base_currency(Currency::from("EUR"))
723 .quote_currency(Currency::from("USD"))
724 .settlement_currency(Currency::from("USD"))
725 .is_inverse(false)
726 .price_precision(5)
727 .size_precision(0)
728 .price_increment(Price::from("0.00001"))
729 .size_increment(Quantity::from("1"))
730 .margin_init(dec!(0.03))
731 .margin_maint(dec!(0.03))
732 .maker_fee(dec!(0.00002))
733 .taker_fee(dec!(0.00002))
734 .ts_event(UnixNanos::default())
735 .ts_init(UnixNanos::default())
736 .build()
737 .unwrap()
738}
739
740#[fixture]
741pub fn binary_option() -> BinaryOption {
742 let raw_symbol = Symbol::new(
743 "0x12a0cb60174abc437bf1178367c72d11f069e1a3add20b148fb0ab4279b772b2-92544998123698303655208967887569360731013655782348975589292031774495159624905",
744 );
745 let activation = timestamp(2023, 11, 6, 20, 54, 7);
746 let expiration = timestamp(2024, 2, 23, 22, 59, 0);
747 let price_increment = Price::from("0.001");
748 let size_increment = Quantity::from("0.01");
749 BinaryOption::builder()
750 .instrument_id(InstrumentId::from("{raw_symbol}.POLYMARKET"))
751 .raw_symbol(raw_symbol)
752 .asset_class(AssetClass::Alternative)
753 .currency(Currency::USDC())
754 .activation_ns(UnixNanos::from(activation))
755 .expiration_ns(UnixNanos::from(expiration))
756 .price_precision(price_increment.precision)
757 .size_precision(size_increment.precision)
758 .price_increment(price_increment)
759 .size_increment(size_increment)
760 .ts_event(UnixNanos::default())
761 .ts_init(UnixNanos::default())
762 .build()
763 .unwrap()
764}
765
766#[fixture]
767pub fn tokenized_asset_aaplx() -> TokenizedAsset {
768 TokenizedAsset::builder()
769 .instrument_id(InstrumentId::from("AAPLx/USD.KRAKEN"))
770 .raw_symbol(Symbol::from("AAPLxUSD"))
771 .asset_class(AssetClass::Equity)
772 .base_currency(Currency::get_or_create_crypto("AAPLx"))
773 .quote_currency(Currency::from("USD"))
774 .price_precision(2)
775 .size_precision(4)
776 .price_increment(Price::from("0.01"))
777 .size_increment(Quantity::from("0.0001"))
778 .min_quantity(Quantity::from("0.0001"))
779 .maker_fee(dec!(-0.0002))
780 .taker_fee(dec!(0.001))
781 .ts_event(UnixNanos::default())
782 .ts_init(UnixNanos::default())
783 .build()
784 .unwrap()
785}