ccxt_exchanges/okx/
margin_impl.rs1use async_trait::async_trait;
7use ccxt_core::{
8 Result,
9 capability::ExchangeCapabilities,
10 traits::{Margin, PublicExchange},
11 types::{
12 FundingRate, FundingRateHistory, Position, Timeframe,
13 params::{LeverageParams, MarginMode},
14 },
15};
16
17use super::Okx;
18
19impl PublicExchange for Okx {
24 fn id(&self) -> &'static str {
25 "okx"
26 }
27
28 fn name(&self) -> &'static str {
29 "OKX"
30 }
31
32 fn version(&self) -> &'static str {
33 "v5"
34 }
35
36 fn certified(&self) -> bool {
37 false
38 }
39
40 fn capabilities(&self) -> ExchangeCapabilities {
41 use ccxt_core::exchange::Capability;
42
43 ExchangeCapabilities::builder()
44 .market_data()
46 .without_capability(Capability::FetchCurrencies)
47 .without_capability(Capability::FetchStatus)
48 .without_capability(Capability::FetchTime)
49 .trading()
51 .without_capability(Capability::CancelAllOrders)
52 .without_capability(Capability::EditOrder)
53 .without_capability(Capability::FetchOrders)
54 .without_capability(Capability::FetchCanceledOrders)
55 .capability(Capability::FetchBalance)
57 .capability(Capability::FetchMyTrades)
58 .capability(Capability::FetchPositions)
60 .capability(Capability::SetLeverage)
61 .capability(Capability::SetMarginMode)
62 .capability(Capability::FetchFundingRate)
63 .capability(Capability::FetchFundingRates)
64 .capability(Capability::Websocket)
66 .capability(Capability::WatchTicker)
67 .capability(Capability::WatchOrderBook)
68 .capability(Capability::WatchTrades)
69 .capability(Capability::WatchBalance)
70 .capability(Capability::WatchOrders)
71 .capability(Capability::WatchMyTrades)
72 .build()
73 }
74
75 fn timeframes(&self) -> Vec<Timeframe> {
76 vec![
77 Timeframe::M1,
78 Timeframe::M3,
79 Timeframe::M5,
80 Timeframe::M15,
81 Timeframe::M30,
82 Timeframe::H1,
83 Timeframe::H2,
84 Timeframe::H4,
85 Timeframe::H6,
86 Timeframe::H12,
87 Timeframe::D1,
88 Timeframe::W1,
89 Timeframe::Mon1,
90 ]
91 }
92
93 fn rate_limit(&self) -> u32 {
94 20
95 }
96
97 fn has_websocket(&self) -> bool {
98 true
99 }
100}
101
102#[async_trait]
107impl Margin for Okx {
108 async fn fetch_positions_for(&self, symbols: &[&str]) -> Result<Vec<Position>> {
109 self.fetch_positions_impl(symbols).await
110 }
111
112 async fn fetch_position(&self, symbol: &str) -> Result<Position> {
113 self.fetch_position_impl(symbol).await
114 }
115
116 async fn set_leverage_with_params(&self, params: LeverageParams) -> Result<()> {
117 let margin_mode = params.margin_mode.map(|m| match m {
118 MarginMode::Isolated => "isolated",
119 MarginMode::Cross => "cross",
120 });
121 self.set_leverage_impl(¶ms.symbol, params.leverage, margin_mode)
122 .await
123 }
124
125 async fn get_leverage(&self, symbol: &str) -> Result<u32> {
126 self.get_leverage_impl(symbol).await
127 }
128
129 async fn set_margin_mode(&self, symbol: &str, mode: MarginMode) -> Result<()> {
130 let mode_str = match mode {
131 MarginMode::Isolated => "isolated",
132 MarginMode::Cross => "cross",
133 };
134 self.set_margin_mode_impl(symbol, mode_str).await
135 }
136
137 async fn fetch_funding_rate(&self, symbol: &str) -> Result<FundingRate> {
138 self.fetch_funding_rate_impl(symbol).await
139 }
140
141 async fn fetch_funding_rates(&self, symbols: &[&str]) -> Result<Vec<FundingRate>> {
142 self.fetch_funding_rates_impl(symbols).await
143 }
144
145 async fn fetch_funding_rate_history(
146 &self,
147 symbol: &str,
148 since: Option<i64>,
149 limit: Option<u32>,
150 ) -> Result<Vec<FundingRateHistory>> {
151 self.fetch_funding_rate_history_impl(symbol, since, limit)
152 .await
153 }
154}
155
156#[cfg(test)]
157mod tests {
158 use super::*;
159 use ccxt_core::ExchangeConfig;
160
161 #[test]
162 fn test_okx_public_exchange_impl() {
163 let okx = Okx::new(ExchangeConfig::default()).unwrap();
164 let pe: &dyn PublicExchange = &okx;
165
166 assert_eq!(pe.id(), "okx");
167 assert_eq!(pe.name(), "OKX");
168 assert_eq!(pe.version(), "v5");
169 assert!(!pe.certified());
170 assert!(pe.has_websocket());
171 assert_eq!(pe.rate_limit(), 20);
172 }
173
174 #[test]
175 fn test_okx_capabilities_include_margin() {
176 let okx = Okx::new(ExchangeConfig::default()).unwrap();
177 let caps = PublicExchange::capabilities(&okx);
178
179 assert!(caps.has("fetchPositions"));
180 assert!(caps.has("setLeverage"));
181 assert!(caps.has("setMarginMode"));
182 assert!(caps.has("fetchFundingRate"));
183 assert!(caps.has("fetchFundingRates"));
184 }
185
186 #[test]
187 fn test_okx_margin_trait_object_safety() {
188 let okx = Okx::new(ExchangeConfig::default()).unwrap();
189 let _margin: Box<dyn Margin> = Box::new(okx);
191 }
192}