diff --git a/src/api.rs b/src/api.rs index 3d03e84f..3357c926 100644 --- a/src/api.rs +++ b/src/api.rs @@ -78,6 +78,7 @@ pub enum Futures { AllOrders, UserTrades, Order, + AlgoOrder, PositionRisk, Balance, PositionSide, @@ -155,6 +156,7 @@ impl From for String { Futures::UserTrades => "/fapi/v1/userTrades", Futures::PositionSide => "/fapi/v1/positionSide/dual", Futures::Order => "/fapi/v1/order", + Futures::AlgoOrder => "/fapi/v1/algoOrder", Futures::PositionRisk => "/fapi/v2/positionRisk", Futures::Balance => "/fapi/v2/balance", Futures::OpenInterest => "/fapi/v1/openInterest", diff --git a/src/futures/account.rs b/src/futures/account.rs index 08462e12..a91c488e 100644 --- a/src/futures/account.rs +++ b/src/futures/account.rs @@ -1,6 +1,7 @@ use std::collections::BTreeMap; use std::fmt::Display; + use crate::util::{build_signed_request, uuid_futures}; use crate::errors::Result; use crate::client::Client; @@ -47,6 +48,11 @@ pub enum PositionSide { Short, } +#[derive(Debug, Clone)] +pub enum AlgoType { + Conditional, +} + impl Display for PositionSide { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -139,9 +145,15 @@ struct OrderRequest { pub price_protect: Option, pub new_client_order_id: Option, pub good_till_date: Option, + pub algo_type: Option, + pub client_algo_id: Option, } pub struct CustomOrderRequest { + // algoOrder params + pub algo_type: AlgoType, + pub client_algo_id: Option, + // pub symbol: String, pub side: OrderSide, /// Default `BOTH` for One-way Mode ; `LONG` or `SHORT` for Hedge Mode. \ @@ -254,8 +266,10 @@ impl FuturesAccount { price_protect: None, new_client_order_id: None, good_till_date: None, + algo_type: None, + client_algo_id: None, }; - let order = self.build_order(buy, None); + let order = self.build_order(buy, None, None); let request = build_signed_request(order, self.recv_window)?; self.client .post_signed(API::Futures(Futures::Order), request) @@ -282,8 +296,10 @@ impl FuturesAccount { price_protect: None, new_client_order_id: None, good_till_date: None, + algo_type: None, + client_algo_id: None, }; - let order = self.build_order(sell, None); + let order = self.build_order(sell, None, None); let request = build_signed_request(order, self.recv_window)?; self.client .post_signed(API::Futures(Futures::Order), request) @@ -312,8 +328,10 @@ impl FuturesAccount { price_protect: None, new_client_order_id: None, good_till_date: None, + algo_type: None, + client_algo_id: None, }; - let order = self.build_order(buy, None); + let order = self.build_order(buy, None, None); let request = build_signed_request(order, self.recv_window)?; self.client .post_signed(API::Futures(Futures::Order), request) @@ -342,8 +360,10 @@ impl FuturesAccount { price_protect: None, new_client_order_id: None, good_till_date: None, + algo_type: None, + client_algo_id: None, }; - let order = self.build_order(sell, None); + let order = self.build_order(sell, None, None); let request = build_signed_request(order, self.recv_window)?; self.client .post_signed(API::Futures(Futures::Order), request) @@ -400,11 +420,13 @@ impl FuturesAccount { price_protect: None, new_client_order_id: None, good_till_date: None, + algo_type: Some(AlgoType::Conditional), + client_algo_id: None, }; - let order = self.build_order(sell, None); + let order = self.build_order(sell, None, None); let request = build_signed_request(order, self.recv_window)?; self.client - .post_signed(API::Futures(Futures::Order), request) + .post_signed(API::Futures(Futures::AlgoOrder), request) } // Place a STOP_MARKET close - SELL @@ -430,11 +452,13 @@ impl FuturesAccount { price_protect: None, new_client_order_id: None, good_till_date: None, + algo_type: Some(AlgoType::Conditional), + client_algo_id: None, }; - let order = self.build_order(sell, None); + let order = self.build_order(sell, None, Some(API::Futures(Futures::AlgoOrder))); let request = build_signed_request(order, self.recv_window)?; self.client - .post_signed(API::Futures(Futures::Order), request) + .post_signed(API::Futures(Futures::AlgoOrder), request) } // Custom order for for professional traders @@ -463,11 +487,17 @@ impl FuturesAccount { price_protect: order_request.price_protect, new_client_order_id: order_request.new_client_order_id, good_till_date: order_request.good_till_date, + algo_type: Some(order_request.algo_type), + client_algo_id: order_request.client_algo_id, }; - let order = self.build_order(order, Some(request_params)); + let order = self.build_order( + order, + Some(request_params), + Some(API::Futures(Futures::AlgoOrder)), + ); let request = build_signed_request(order, self.recv_window)?; self.client - .post_signed(API::Futures(Futures::Order), request) + .post_signed(API::Futures(Futures::AlgoOrder), request) } // Custom order for for professional traders @@ -494,13 +524,19 @@ impl FuturesAccount { price_protect: order_request.price_protect, new_client_order_id: order_request.new_client_order_id, good_till_date: order_request.good_till_date, + algo_type: Some(order_request.algo_type), + client_algo_id: order_request.client_algo_id, }; - let _order = self.build_order(order, Some(request_params.clone())); + let _order = self.build_order( + order, + Some(request_params.clone()), + Some(API::Futures(Futures::AlgoOrder)), + ); // TODO : make a request string for batch orders api // let request = build_signed_request(order, self.recv_window)?; } self.client - .post_signed(API::Futures(Futures::Order), request) + .post_signed(API::Futures(Futures::AlgoOrder), request) } // Custom order for for professional traders @@ -567,12 +603,26 @@ impl FuturesAccount { } fn build_order( &self, order: OrderRequest, request_params: Option>, + api_type: Option, ) -> BTreeMap { let mut parameters = BTreeMap::new(); parameters.insert("symbol".into(), order.symbol); parameters.insert("side".into(), order.side.to_string()); parameters.insert("type".into(), order.order_type.to_string()); + if let Some(API::Futures(Futures::AlgoOrder)) = api_type { + parameters.insert("algoType".into(), "Conditional".into()); + parameters.insert("clientAlgoId".into(), "Conditional".into()); + + if let Some(client_algo_id) = order.client_algo_id { + parameters.insert("clientAlgoId".into(), client_algo_id.to_string()); + } + + if let Some(stop_price) = order.stop_price { + parameters.insert("triggerPrice".into(), stop_price.to_string()); + } + } + if let Some(position_side) = order.position_side { parameters.insert("positionSide".into(), position_side.to_string()); } diff --git a/tests/futures_account_tests.rs b/tests/futures_account_tests.rs index 4dc6ed0d..3ff32f84 100644 --- a/tests/futures_account_tests.rs +++ b/tests/futures_account_tests.rs @@ -231,6 +231,8 @@ mod tests { let account: FuturesAccount = Binance::new_with_config(None, None, &config); let _ = env_logger::try_init(); let custom_order = CustomOrderRequest { + algo_type: AlgoType::Conditional, + client_algo_id: Some("myAlgoId".into()), symbol: "SRMUSDT".into(), side: OrderSide::Sell, position_side: None, @@ -247,6 +249,7 @@ mod tests { price_protect: None, new_client_order_id: Some("myId".into()), good_till_date: None, + }; let transaction: Transaction = account.custom_order(custom_order).unwrap();