1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
use serde::{Deserialize, Serialize};
use strum_macros::{Display, EnumString};

/// Market type.
///
/// * In spot market, cryptocurrencies are traded for immediate delivery, see https://en.wikipedia.org/wiki/Spot_market.
/// * In futures market, delivery is set at a specified time in the future, see https://en.wikipedia.org/wiki/Futures_exchange.
/// * Swap market is a variant of futures market with no expiry date.
///
/// ## Margin
///
/// A market can have margin enabled or disabled.
///
/// * All contract markets are margin enabled, including future, swap and option.
/// * Most spot markets don't have margin enabled, only a few exchanges have spot market with margin enabled.
///
/// ## Linear VS. Inverse
///
/// A market can be inverse or linear.

/// * Linear means USDT-margined, i.e., you can use USDT as collateral
/// * Inverse means coin-margined, i.e., you can use BTC as collateral.
/// * Spot market is always linear.
///
/// **Margin and Inverse are orthogonal.**
#[repr(C)]
#[derive(Copy, Clone, Serialize, Deserialize, Display, Debug, EnumString, PartialEq, Hash, Eq)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum MarketType {
    Unknown,
    Spot,
    LinearFuture,
    InverseFuture,
    LinearSwap,
    InverseSwap,

    AmericanOption,
    EuropeanOption,

    QuantoFuture,
    QuantoSwap,

    Move,
    #[serde(rename = "bvol")]
    #[allow(clippy::upper_case_acronyms)]
    BVOL,
}

/// Get market types of a cryptocurrency exchange.
pub fn get_market_types(exchange: &str) -> Vec<MarketType> {
    match exchange {
        "binance" => vec![
            MarketType::Spot,
            MarketType::LinearFuture,
            MarketType::InverseFuture,
            MarketType::LinearSwap,
            MarketType::InverseSwap,
            MarketType::EuropeanOption,
        ],
        "bitfinex" => vec![MarketType::Spot, MarketType::LinearSwap],
        "bitget" => vec![
            MarketType::Spot,
            MarketType::InverseSwap,
            MarketType::LinearSwap,
        ],
        "bithumb" => vec![MarketType::Spot],
        // BitMEX only handles Bitcoin. All profit and loss is in Bitcoin
        "bitmex" => vec![
            MarketType::LinearSwap,
            MarketType::InverseSwap,
            MarketType::QuantoSwap,
            MarketType::LinearFuture,
            MarketType::InverseFuture,
            MarketType::QuantoFuture,
        ],
        "bitstamp" => vec![MarketType::Spot],
        "bitz" => vec![
            MarketType::Spot,
            MarketType::InverseSwap,
            MarketType::LinearSwap,
        ],
        "bybit" => vec![
            MarketType::InverseSwap,
            MarketType::LinearSwap,
            MarketType::InverseFuture,
        ],
        "coinbase_pro" => vec![MarketType::Spot],
        // Deribit only accepts Bitcoin as funds to deposit.
        "deribit" => vec![
            MarketType::InverseFuture,
            MarketType::InverseSwap,
            MarketType::EuropeanOption, // inverse
        ],
        "dydx" => vec![MarketType::LinearSwap],
        "ftx" => vec![
            MarketType::Spot,
            MarketType::LinearFuture,
            MarketType::LinearSwap,
            MarketType::Move,
            MarketType::BVOL,
        ],
        "gate" => vec![
            MarketType::Spot,
            MarketType::InverseFuture,
            MarketType::LinearFuture,
            MarketType::InverseSwap,
            MarketType::LinearSwap,
        ],
        "huobi" => vec![
            MarketType::Spot,
            MarketType::InverseFuture,
            MarketType::LinearSwap,
            MarketType::InverseSwap,
            // MarketType::EuropeanOption,
        ],
        "kraken" => vec![
            MarketType::Spot,
            MarketType::InverseFuture,
            MarketType::InverseSwap,
        ],
        "kucoin" => vec![
            MarketType::Spot,
            MarketType::LinearSwap,
            MarketType::InverseSwap,
            MarketType::InverseFuture,
        ],
        "mxc" | "mexc" => vec![
            MarketType::Spot,
            MarketType::LinearSwap,
            MarketType::InverseSwap,
        ],
        "okex" | "okx" => vec![
            MarketType::Spot,
            MarketType::LinearFuture,
            MarketType::InverseFuture,
            MarketType::LinearSwap,
            MarketType::InverseSwap,
            MarketType::EuropeanOption,
        ],
        "zbg" => vec![
            MarketType::Spot,
            MarketType::InverseSwap,
            MarketType::LinearSwap,
        ],
        _ => panic!("Unknown exchange {}", exchange),
    }
}