1use nautilus_model::enums::{MarketStatusAction, OrderSide, OrderStatus, OrderType};
19use serde::{Deserialize, Serialize};
20use strum::{AsRefStr, Display, EnumString, FromRepr};
21
22#[derive(
24 Clone,
25 Copy,
26 Debug,
27 Default,
28 Display,
29 AsRefStr,
30 EnumString,
31 FromRepr,
32 PartialEq,
33 Eq,
34 Hash,
35 Serialize,
36 Deserialize,
37)]
38#[cfg_attr(
39 feature = "python",
40 pyo3::pyclass(
41 module = "nautilus_trader.core.nautilus_pyo3.kraken",
42 eq,
43 eq_int,
44 frozen,
45 hash,
46 from_py_object,
47 rename_all = "SCREAMING_SNAKE_CASE",
48 )
49)]
50#[cfg_attr(
51 feature = "python",
52 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
53)]
54#[serde(rename_all = "lowercase")]
55#[strum(ascii_case_insensitive, serialize_all = "lowercase")]
56pub enum KrakenEnvironment {
57 #[default]
58 Mainnet,
59 Demo,
60}
61
62#[derive(
64 Clone,
65 Copy,
66 Debug,
67 Default,
68 Display,
69 AsRefStr,
70 EnumString,
71 FromRepr,
72 PartialEq,
73 Eq,
74 Hash,
75 Serialize,
76 Deserialize,
77)]
78#[cfg_attr(
79 feature = "python",
80 pyo3::pyclass(
81 module = "nautilus_trader.core.nautilus_pyo3.kraken",
82 eq,
83 eq_int,
84 frozen,
85 hash,
86 from_py_object,
87 rename_all = "SCREAMING_SNAKE_CASE",
88 )
89)]
90#[cfg_attr(
91 feature = "python",
92 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
93)]
94#[serde(rename_all = "lowercase")]
95#[strum(ascii_case_insensitive, serialize_all = "lowercase")]
96pub enum KrakenProductType {
97 #[default]
98 Spot,
99 Futures,
100}
101
102#[derive(
104 Clone,
105 Copy,
106 Debug,
107 Display,
108 AsRefStr,
109 EnumString,
110 FromRepr,
111 PartialEq,
112 Eq,
113 Hash,
114 Serialize,
115 Deserialize,
116)]
117#[cfg_attr(
118 feature = "python",
119 pyo3::pyclass(
120 module = "nautilus_trader.core.nautilus_pyo3.kraken",
121 eq,
122 eq_int,
123 from_py_object
124 )
125)]
126#[cfg_attr(
127 feature = "python",
128 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
129)]
130#[serde(rename_all = "lowercase")]
131#[strum(ascii_case_insensitive, serialize_all = "lowercase")]
132pub enum KrakenOrderType {
133 Market,
134 Limit,
135 #[serde(rename = "stop-loss")]
136 #[strum(serialize = "stop-loss")]
137 StopLoss,
138 #[serde(rename = "take-profit")]
139 #[strum(serialize = "take-profit")]
140 TakeProfit,
141 #[serde(rename = "stop-loss-limit")]
142 #[strum(serialize = "stop-loss-limit")]
143 StopLossLimit,
144 #[serde(rename = "take-profit-limit")]
145 #[strum(serialize = "take-profit-limit")]
146 TakeProfitLimit,
147 #[serde(rename = "trailing-stop")]
148 #[strum(serialize = "trailing-stop")]
149 TrailingStop,
150 #[serde(rename = "trailing-stop-limit")]
151 #[strum(serialize = "trailing-stop-limit")]
152 TrailingStopLimit,
153 #[serde(rename = "settle-position")]
154 #[strum(serialize = "settle-position")]
155 SettlePosition,
156}
157
158#[derive(
160 Clone,
161 Copy,
162 Debug,
163 Display,
164 AsRefStr,
165 EnumString,
166 FromRepr,
167 PartialEq,
168 Eq,
169 Hash,
170 Serialize,
171 Deserialize,
172)]
173#[cfg_attr(
174 feature = "python",
175 pyo3::pyclass(
176 module = "nautilus_trader.core.nautilus_pyo3.kraken",
177 eq,
178 eq_int,
179 from_py_object
180 )
181)]
182#[cfg_attr(
183 feature = "python",
184 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
185)]
186#[serde(rename_all = "lowercase")]
187#[strum(ascii_case_insensitive, serialize_all = "lowercase")]
188pub enum KrakenOrderSide {
189 Buy,
190 Sell,
191}
192
193#[derive(
195 Clone,
196 Copy,
197 Debug,
198 Display,
199 AsRefStr,
200 EnumString,
201 FromRepr,
202 PartialEq,
203 Eq,
204 Hash,
205 Serialize,
206 Deserialize,
207)]
208#[cfg_attr(
209 feature = "python",
210 pyo3::pyclass(
211 module = "nautilus_trader.core.nautilus_pyo3.kraken",
212 eq,
213 eq_int,
214 from_py_object
215 )
216)]
217#[cfg_attr(
218 feature = "python",
219 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
220)]
221#[serde(rename_all = "UPPERCASE")]
222#[strum(ascii_case_insensitive, serialize_all = "UPPERCASE")]
223pub enum KrakenTimeInForce {
224 #[serde(rename = "GTC")]
225 #[strum(serialize = "GTC")]
226 GoodTilCancelled,
227 #[serde(rename = "IOC")]
228 #[strum(serialize = "IOC")]
229 ImmediateOrCancel,
230 #[serde(rename = "GTD")]
231 #[strum(serialize = "GTD")]
232 GoodTilDate,
233}
234
235#[derive(
237 Clone,
238 Copy,
239 Debug,
240 Display,
241 AsRefStr,
242 EnumString,
243 FromRepr,
244 PartialEq,
245 Eq,
246 Hash,
247 Serialize,
248 Deserialize,
249)]
250#[cfg_attr(
251 feature = "python",
252 pyo3::pyclass(
253 module = "nautilus_trader.core.nautilus_pyo3.kraken",
254 eq,
255 eq_int,
256 from_py_object
257 )
258)]
259#[cfg_attr(
260 feature = "python",
261 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
262)]
263#[serde(rename_all = "lowercase")]
264#[strum(ascii_case_insensitive, serialize_all = "lowercase")]
265pub enum KrakenOrderStatus {
266 Pending,
267 Open,
268 Closed,
269 Canceled,
270 Expired,
271}
272
273#[derive(
275 Clone,
276 Copy,
277 Debug,
278 Display,
279 AsRefStr,
280 EnumString,
281 FromRepr,
282 PartialEq,
283 Eq,
284 Hash,
285 Serialize,
286 Deserialize,
287)]
288#[cfg_attr(
289 feature = "python",
290 pyo3::pyclass(
291 module = "nautilus_trader.core.nautilus_pyo3.kraken",
292 eq,
293 eq_int,
294 from_py_object
295 )
296)]
297#[cfg_attr(
298 feature = "python",
299 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
300)]
301#[serde(rename_all = "lowercase")]
302#[strum(ascii_case_insensitive, serialize_all = "lowercase")]
303pub enum KrakenPositionSide {
304 Long,
305 Short,
306}
307
308#[derive(
310 Clone,
311 Copy,
312 Debug,
313 Display,
314 AsRefStr,
315 EnumString,
316 FromRepr,
317 PartialEq,
318 Eq,
319 Hash,
320 Serialize,
321 Deserialize,
322)]
323#[cfg_attr(
324 feature = "python",
325 pyo3::pyclass(
326 module = "nautilus_trader.core.nautilus_pyo3.kraken",
327 eq,
328 eq_int,
329 from_py_object
330 )
331)]
332#[cfg_attr(
333 feature = "python",
334 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
335)]
336#[serde(rename_all = "snake_case")]
337#[strum(ascii_case_insensitive, serialize_all = "snake_case")]
338pub enum KrakenPairStatus {
339 Online,
340 #[serde(rename = "cancel_only")]
341 #[strum(serialize = "cancel_only")]
342 CancelOnly,
343 #[serde(rename = "post_only")]
344 #[strum(serialize = "post_only")]
345 PostOnly,
346 #[serde(rename = "limit_only")]
347 #[strum(serialize = "limit_only")]
348 LimitOnly,
349 #[serde(rename = "reduce_only")]
350 #[strum(serialize = "reduce_only")]
351 ReduceOnly,
352}
353
354#[derive(
356 Clone,
357 Copy,
358 Debug,
359 Display,
360 AsRefStr,
361 EnumString,
362 FromRepr,
363 PartialEq,
364 Eq,
365 Hash,
366 Serialize,
367 Deserialize,
368)]
369#[cfg_attr(
370 feature = "python",
371 pyo3::pyclass(
372 module = "nautilus_trader.core.nautilus_pyo3.kraken",
373 eq,
374 eq_int,
375 from_py_object
376 )
377)]
378#[cfg_attr(
379 feature = "python",
380 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
381)]
382#[serde(rename_all = "lowercase")]
383#[strum(ascii_case_insensitive, serialize_all = "lowercase")]
384pub enum KrakenSystemStatus {
385 Online,
386 Maintenance,
387 #[serde(rename = "cancel_only")]
388 #[strum(serialize = "cancel_only")]
389 CancelOnly,
390 #[serde(rename = "post_only")]
391 #[strum(serialize = "post_only")]
392 PostOnly,
393}
394
395#[derive(
397 Clone,
398 Copy,
399 Debug,
400 Display,
401 AsRefStr,
402 EnumString,
403 FromRepr,
404 PartialEq,
405 Eq,
406 Hash,
407 Serialize,
408 Deserialize,
409)]
410#[cfg_attr(
411 feature = "python",
412 pyo3::pyclass(
413 module = "nautilus_trader.core.nautilus_pyo3.kraken",
414 eq,
415 eq_int,
416 from_py_object
417 )
418)]
419#[cfg_attr(
420 feature = "python",
421 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
422)]
423#[serde(rename_all = "lowercase")]
424#[strum(ascii_case_insensitive, serialize_all = "lowercase")]
425pub enum KrakenAssetClass {
426 Currency,
427 #[serde(rename = "tokenized_asset")]
428 #[strum(serialize = "tokenized_asset")]
429 TokenizedAsset,
430}
431
432#[derive(
434 Clone,
435 Copy,
436 Debug,
437 Display,
438 AsRefStr,
439 EnumString,
440 FromRepr,
441 PartialEq,
442 Eq,
443 Hash,
444 Serialize,
445 Deserialize,
446)]
447#[cfg_attr(
448 feature = "python",
449 pyo3::pyclass(
450 module = "nautilus_trader.core.nautilus_pyo3.kraken",
451 eq,
452 eq_int,
453 from_py_object
454 )
455)]
456#[cfg_attr(
457 feature = "python",
458 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
459)]
460#[serde(rename_all = "lowercase")]
461#[strum(ascii_case_insensitive, serialize_all = "lowercase")]
462pub enum KrakenFuturesOrderType {
463 #[serde(rename = "lmt", alias = "limit")]
464 #[strum(serialize = "lmt")]
465 Limit,
466 #[serde(rename = "ioc")]
467 #[strum(serialize = "ioc")]
468 Ioc,
469 #[serde(rename = "post")]
470 #[strum(serialize = "post")]
471 Post,
472 #[serde(rename = "mkt", alias = "market")]
473 #[strum(serialize = "mkt")]
474 Market,
475 #[serde(rename = "stp")]
476 #[strum(serialize = "stp")]
477 Stop,
478 #[serde(rename = "stop")]
479 #[strum(serialize = "stop")]
480 StopLower,
481 #[serde(rename = "take_profit")]
482 #[strum(serialize = "take_profit")]
483 TakeProfit,
484 #[serde(rename = "stop_loss")]
485 #[strum(serialize = "stop_loss")]
486 StopLoss,
487}
488
489#[derive(
491 Clone,
492 Copy,
493 Debug,
494 Display,
495 AsRefStr,
496 EnumString,
497 FromRepr,
498 PartialEq,
499 Eq,
500 Hash,
501 Serialize,
502 Deserialize,
503)]
504#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
505#[strum(ascii_case_insensitive, serialize_all = "SCREAMING_SNAKE_CASE")]
506pub enum KrakenFuturesOrderEventType {
507 Place,
509 Fill,
511 Execution,
513 Reject,
515 Cancel,
517 Edit,
519 #[serde(alias = "EXPIRED")]
521 #[strum(serialize = "EXPIRED")]
522 Expire,
523}
524
525#[derive(
527 Clone,
528 Copy,
529 Debug,
530 Display,
531 AsRefStr,
532 EnumString,
533 FromRepr,
534 PartialEq,
535 Eq,
536 Hash,
537 Serialize,
538 Deserialize,
539)]
540#[cfg_attr(
541 feature = "python",
542 pyo3::pyclass(
543 module = "nautilus_trader.core.nautilus_pyo3.kraken",
544 eq,
545 eq_int,
546 from_py_object
547 )
548)]
549#[cfg_attr(
550 feature = "python",
551 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
552)]
553#[serde(rename_all = "camelCase")]
554#[strum(ascii_case_insensitive, serialize_all = "camelCase")]
555pub enum KrakenFuturesOrderStatus {
556 Untouched,
557 PartiallyFilled,
558 Filled,
559 Cancelled,
560 Expired,
561}
562
563#[derive(
565 Clone,
566 Copy,
567 Debug,
568 Display,
569 AsRefStr,
570 EnumString,
571 FromRepr,
572 PartialEq,
573 Eq,
574 Hash,
575 Serialize,
576 Deserialize,
577)]
578#[cfg_attr(
579 feature = "python",
580 pyo3::pyclass(
581 module = "nautilus_trader.core.nautilus_pyo3.kraken",
582 eq,
583 eq_int,
584 from_py_object
585 )
586)]
587#[cfg_attr(
588 feature = "python",
589 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
590)]
591#[strum(ascii_case_insensitive, serialize_all = "lowercase")]
592pub enum KrakenTriggerSignal {
593 #[serde(rename = "last", alias = "last_price")]
594 Last,
595 #[serde(rename = "mark", alias = "mark_price")]
596 Mark,
597 #[serde(
598 rename = "spot",
599 alias = "spot_price",
600 alias = "index",
601 alias = "index_price"
602 )]
603 #[strum(
604 serialize = "spot",
605 serialize = "spot_price",
606 serialize = "index",
607 serialize = "index_price"
608 )]
609 Index,
610}
611
612#[derive(
614 Clone,
615 Copy,
616 Debug,
617 Display,
618 AsRefStr,
619 EnumString,
620 FromRepr,
621 PartialEq,
622 Eq,
623 Hash,
624 Serialize,
625 Deserialize,
626)]
627#[cfg_attr(
628 feature = "python",
629 pyo3::pyclass(
630 module = "nautilus_trader.core.nautilus_pyo3.kraken",
631 eq,
632 eq_int,
633 from_py_object
634 )
635)]
636#[cfg_attr(
637 feature = "python",
638 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
639)]
640#[serde(rename_all = "lowercase")]
641#[strum(ascii_case_insensitive, serialize_all = "lowercase")]
642pub enum KrakenSpotTrigger {
643 Last,
645 Index,
647}
648
649#[derive(
651 Clone,
652 Copy,
653 Debug,
654 Display,
655 AsRefStr,
656 EnumString,
657 FromRepr,
658 PartialEq,
659 Eq,
660 Hash,
661 Serialize,
662 Deserialize,
663)]
664#[cfg_attr(
665 feature = "python",
666 pyo3::pyclass(
667 module = "nautilus_trader.core.nautilus_pyo3.kraken",
668 eq,
669 eq_int,
670 from_py_object
671 )
672)]
673#[cfg_attr(
674 feature = "python",
675 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
676)]
677#[serde(rename_all = "lowercase")]
678#[strum(ascii_case_insensitive, serialize_all = "lowercase")]
679pub enum KrakenFillType {
680 Maker,
681 Taker,
682}
683
684#[derive(
686 Clone,
687 Copy,
688 Debug,
689 Display,
690 AsRefStr,
691 EnumString,
692 FromRepr,
693 PartialEq,
694 Eq,
695 Hash,
696 Serialize,
697 Deserialize,
698)]
699#[cfg_attr(
700 feature = "python",
701 pyo3::pyclass(
702 module = "nautilus_trader.core.nautilus_pyo3.kraken",
703 eq,
704 eq_int,
705 from_py_object
706 )
707)]
708#[cfg_attr(
709 feature = "python",
710 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
711)]
712#[serde(rename_all = "lowercase")]
713#[strum(ascii_case_insensitive, serialize_all = "lowercase")]
714pub enum KrakenApiResult {
715 Success,
716 Error,
717}
718
719#[derive(
721 Clone,
722 Copy,
723 Debug,
724 Display,
725 AsRefStr,
726 EnumString,
727 FromRepr,
728 PartialEq,
729 Eq,
730 Hash,
731 Serialize,
732 Deserialize,
733)]
734#[cfg_attr(
735 feature = "python",
736 pyo3::pyclass(
737 module = "nautilus_trader.core.nautilus_pyo3.kraken",
738 eq,
739 eq_int,
740 from_py_object
741 )
742)]
743#[cfg_attr(
744 feature = "python",
745 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
746)]
747#[serde(rename_all = "snake_case")]
748#[strum(ascii_case_insensitive, serialize_all = "snake_case")]
749pub enum KrakenInstrumentType {
750 FuturesInverse,
752 FlexibleFutures,
754}
755
756#[derive(
758 Clone,
759 Copy,
760 Debug,
761 Display,
762 AsRefStr,
763 EnumString,
764 FromRepr,
765 PartialEq,
766 Eq,
767 Hash,
768 Serialize,
769 Deserialize,
770)]
771#[cfg_attr(
772 feature = "python",
773 pyo3::pyclass(
774 module = "nautilus_trader.core.nautilus_pyo3.kraken",
775 eq,
776 eq_int,
777 from_py_object
778 )
779)]
780#[cfg_attr(
781 feature = "python",
782 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
783)]
784#[serde(rename_all = "camelCase")]
785#[strum(ascii_case_insensitive, serialize_all = "camelCase")]
786pub enum KrakenSendStatus {
787 Placed,
789 Cancelled,
791 Edited,
793 NotFound,
795 NoOrdersToCancel,
803 InsufficientAvailableFunds,
805 InvalidOrderType,
807 InvalidSize,
809 WouldCauseLiquidation,
811 PostWouldExecute,
813 ReduceOnlyWouldIncreasePosition,
815}
816
817#[derive(
819 Clone,
820 Copy,
821 Debug,
822 Display,
823 AsRefStr,
824 EnumString,
825 FromRepr,
826 PartialEq,
827 Eq,
828 Hash,
829 Serialize,
830 Deserialize,
831)]
832#[cfg_attr(
833 feature = "python",
834 pyo3::pyclass(
835 module = "nautilus_trader.core.nautilus_pyo3.kraken",
836 eq,
837 eq_int,
838 from_py_object
839 )
840)]
841#[cfg_attr(
842 feature = "python",
843 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.kraken")
844)]
845#[serde(rename_all = "snake_case")]
846#[strum(ascii_case_insensitive, serialize_all = "snake_case")]
847pub enum KrakenTriggerSide {
848 #[serde(rename = "trigger_above")]
850 #[strum(serialize = "trigger_above")]
851 TriggerAbove,
852 #[serde(rename = "trigger_below")]
854 #[strum(serialize = "trigger_below")]
855 TriggerBelow,
856}
857
858impl From<KrakenOrderSide> for OrderSide {
859 fn from(value: KrakenOrderSide) -> Self {
860 match value {
861 KrakenOrderSide::Buy => Self::Buy,
862 KrakenOrderSide::Sell => Self::Sell,
863 }
864 }
865}
866
867impl From<KrakenOrderType> for OrderType {
868 fn from(value: KrakenOrderType) -> Self {
874 match value {
875 KrakenOrderType::Market => Self::Market,
876 KrakenOrderType::Limit => Self::Limit,
877 KrakenOrderType::StopLoss => Self::StopMarket,
878 KrakenOrderType::TakeProfit => Self::MarketIfTouched,
879 KrakenOrderType::StopLossLimit => Self::StopLimit,
880 KrakenOrderType::TakeProfitLimit => Self::LimitIfTouched,
881 KrakenOrderType::TrailingStop => Self::StopMarket,
882 KrakenOrderType::TrailingStopLimit => Self::StopLimit,
883 KrakenOrderType::SettlePosition => Self::Market,
884 }
885 }
886}
887
888impl From<KrakenOrderStatus> for OrderStatus {
889 fn from(value: KrakenOrderStatus) -> Self {
890 match value {
891 KrakenOrderStatus::Pending => Self::Initialized,
892 KrakenOrderStatus::Open => Self::Accepted,
893 KrakenOrderStatus::Closed => Self::Filled,
894 KrakenOrderStatus::Canceled => Self::Canceled,
895 KrakenOrderStatus::Expired => Self::Expired,
896 }
897 }
898}
899
900impl From<KrakenFuturesOrderType> for OrderType {
901 fn from(value: KrakenFuturesOrderType) -> Self {
902 match value {
903 KrakenFuturesOrderType::Limit
904 | KrakenFuturesOrderType::Ioc
905 | KrakenFuturesOrderType::Post => Self::Limit,
906 KrakenFuturesOrderType::Market => Self::Market,
907 KrakenFuturesOrderType::Stop | KrakenFuturesOrderType::StopLower => Self::StopMarket,
908 KrakenFuturesOrderType::TakeProfit => Self::MarketIfTouched,
909 KrakenFuturesOrderType::StopLoss => Self::StopMarket,
910 }
911 }
912}
913
914impl TryFrom<OrderSide> for KrakenOrderSide {
915 type Error = &'static str;
916
917 fn try_from(value: OrderSide) -> Result<Self, Self::Error> {
918 match value {
919 OrderSide::Buy => Ok(Self::Buy),
920 OrderSide::Sell => Ok(Self::Sell),
921 OrderSide::NoOrderSide => Err("Cannot convert NoOrderSide to KrakenOrderSide"),
922 }
923 }
924}
925
926impl From<KrakenFuturesOrderStatus> for OrderStatus {
927 fn from(value: KrakenFuturesOrderStatus) -> Self {
928 match value {
929 KrakenFuturesOrderStatus::Untouched => Self::Accepted,
930 KrakenFuturesOrderStatus::PartiallyFilled => Self::PartiallyFilled,
931 KrakenFuturesOrderStatus::Filled => Self::Filled,
932 KrakenFuturesOrderStatus::Cancelled => Self::Canceled,
933 KrakenFuturesOrderStatus::Expired => Self::Expired,
934 }
935 }
936}
937
938impl From<KrakenPairStatus> for MarketStatusAction {
939 fn from(value: KrakenPairStatus) -> Self {
940 match value {
941 KrakenPairStatus::Online => Self::Trading,
942 KrakenPairStatus::CancelOnly => Self::Halt,
943 KrakenPairStatus::PostOnly => Self::Pause,
944 KrakenPairStatus::LimitOnly => Self::Pause,
945 KrakenPairStatus::ReduceOnly => Self::Pause,
946 }
947 }
948}
949
950#[must_use]
961pub fn product_type_from_symbol(symbol: &str) -> KrakenProductType {
962 if symbol.starts_with("PI_")
963 || symbol.starts_with("PF_")
964 || symbol.starts_with("PV_")
965 || symbol.starts_with("FI_")
966 || symbol.starts_with("FF_")
967 {
968 KrakenProductType::Futures
969 } else {
970 KrakenProductType::Spot
971 }
972}
973
974#[cfg(test)]
975mod tests {
976 use nautilus_model::enums::{MarketStatusAction, OrderType};
977 use rstest::rstest;
978
979 use super::*;
980
981 #[rstest]
982 #[case::online(KrakenPairStatus::Online, MarketStatusAction::Trading)]
983 #[case::cancel_only(KrakenPairStatus::CancelOnly, MarketStatusAction::Halt)]
984 #[case::post_only(KrakenPairStatus::PostOnly, MarketStatusAction::Pause)]
985 #[case::limit_only(KrakenPairStatus::LimitOnly, MarketStatusAction::Pause)]
986 #[case::reduce_only(KrakenPairStatus::ReduceOnly, MarketStatusAction::Pause)]
987 fn test_pair_status_to_market_status_action(
988 #[case] input: KrakenPairStatus,
989 #[case] expected: MarketStatusAction,
990 ) {
991 assert_eq!(MarketStatusAction::from(input), expected);
992 }
993
994 #[rstest]
995 #[case::trailing_stop(KrakenOrderType::TrailingStop, OrderType::StopMarket)]
996 #[case::trailing_stop_limit(KrakenOrderType::TrailingStopLimit, OrderType::StopLimit)]
997 fn test_trailing_stop_order_type_mapping(
998 #[case] input: KrakenOrderType,
999 #[case] expected: OrderType,
1000 ) {
1001 assert_eq!(OrderType::from(input), expected);
1002 }
1003
1004 #[rstest]
1005 #[case("\"placed\"", KrakenSendStatus::Placed)]
1006 #[case("\"cancelled\"", KrakenSendStatus::Cancelled)]
1007 #[case("\"edited\"", KrakenSendStatus::Edited)]
1008 #[case("\"notFound\"", KrakenSendStatus::NotFound)]
1009 #[case("\"noOrdersToCancel\"", KrakenSendStatus::NoOrdersToCancel)]
1010 #[case(
1011 "\"insufficientAvailableFunds\"",
1012 KrakenSendStatus::InsufficientAvailableFunds
1013 )]
1014 #[case("\"invalidOrderType\"", KrakenSendStatus::InvalidOrderType)]
1015 #[case("\"invalidSize\"", KrakenSendStatus::InvalidSize)]
1016 #[case("\"wouldCauseLiquidation\"", KrakenSendStatus::WouldCauseLiquidation)]
1017 #[case("\"postWouldExecute\"", KrakenSendStatus::PostWouldExecute)]
1018 #[case(
1019 "\"reduceOnlyWouldIncreasePosition\"",
1020 KrakenSendStatus::ReduceOnlyWouldIncreasePosition
1021 )]
1022 fn test_send_status_deserialization(#[case] raw: &str, #[case] expected: KrakenSendStatus) {
1023 let parsed: KrakenSendStatus = serde_json::from_str(raw).unwrap();
1024 assert_eq!(parsed, expected);
1025 }
1026
1027 #[rstest]
1028 #[case("\"last\"", KrakenTriggerSignal::Last)]
1029 #[case("\"last_price\"", KrakenTriggerSignal::Last)]
1030 #[case("\"mark\"", KrakenTriggerSignal::Mark)]
1031 #[case("\"mark_price\"", KrakenTriggerSignal::Mark)]
1032 #[case("\"spot\"", KrakenTriggerSignal::Index)]
1033 #[case("\"spot_price\"", KrakenTriggerSignal::Index)]
1034 #[case("\"index\"", KrakenTriggerSignal::Index)]
1035 #[case("\"index_price\"", KrakenTriggerSignal::Index)]
1036 fn test_trigger_signal_deserialization(
1037 #[case] raw: &str,
1038 #[case] expected: KrakenTriggerSignal,
1039 ) {
1040 let parsed: KrakenTriggerSignal = serde_json::from_str(raw).unwrap();
1041 assert_eq!(parsed, expected);
1042 }
1043
1044 #[rstest]
1045 #[case("\"PLACE\"", KrakenFuturesOrderEventType::Place)]
1046 #[case("\"FILL\"", KrakenFuturesOrderEventType::Fill)]
1047 #[case("\"EXECUTION\"", KrakenFuturesOrderEventType::Execution)]
1048 #[case("\"REJECT\"", KrakenFuturesOrderEventType::Reject)]
1049 #[case("\"CANCEL\"", KrakenFuturesOrderEventType::Cancel)]
1050 #[case("\"EDIT\"", KrakenFuturesOrderEventType::Edit)]
1051 #[case("\"EXPIRE\"", KrakenFuturesOrderEventType::Expire)]
1052 #[case("\"EXPIRED\"", KrakenFuturesOrderEventType::Expire)]
1053 fn test_futures_order_event_type_deserialization(
1054 #[case] raw: &str,
1055 #[case] expected: KrakenFuturesOrderEventType,
1056 ) {
1057 let parsed: KrakenFuturesOrderEventType = serde_json::from_str(raw).unwrap();
1058 assert_eq!(parsed, expected);
1059 }
1060}