From 8a5b4b1ec21bb9ce1f4bf964e3396408a5833224 Mon Sep 17 00:00:00 2001 From: DevWonder01 Date: Wed, 18 Mar 2026 10:11:12 +0100 Subject: [PATCH 1/4] Use Algo Order API for stop losses (/fapi/v1/algoOrder) As of December 2025, Binance requires conditional orders (STOP_MARKET, STOP, TAKE_PROFIT, etc.) to be placed via /fapi/v1/algoOrder endpoint. Add AlgoOrder variant to Futures enum and update related methods in FuturesAccount --- src/api.rs | 2 ++ src/futures/account.rs | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) 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..7d6c6cab 100644 --- a/src/futures/account.rs +++ b/src/futures/account.rs @@ -377,6 +377,7 @@ impl FuturesAccount { .delete_signed(API::Futures(Futures::Order), Some(request)) } + // Place a STOP_MARKET close - BUY pub fn stop_market_close_buy(&self, symbol: S, stop_price: F) -> Result where @@ -404,7 +405,7 @@ impl FuturesAccount { let order = self.build_order(sell, 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 @@ -434,7 +435,7 @@ impl FuturesAccount { let order = self.build_order(sell, 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) } // Custom order for for professional traders @@ -467,7 +468,7 @@ impl FuturesAccount { let order = self.build_order(order, Some(request_params)); 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 @@ -500,7 +501,7 @@ impl FuturesAccount { // 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 From d6385af7d326f46250e83a531a45ebeef4797c7a Mon Sep 17 00:00:00 2001 From: DevWonder01 Date: Wed, 18 Mar 2026 10:38:19 +0100 Subject: [PATCH 2/4] Add AlgoType enum and integrate into OrderRequest and CustomOrderRequest --- src/futures/account.rs | 19 ++++++++++++++++++- tests/futures_account_tests.rs | 3 +++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/futures/account.rs b/src/futures/account.rs index 7d6c6cab..18d7a209 100644 --- a/src/futures/account.rs +++ b/src/futures/account.rs @@ -47,6 +47,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 +144,14 @@ struct OrderRequest { pub price_protect: Option, pub new_client_order_id: Option, pub good_till_date: Option, + pub algo_type: 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,6 +264,7 @@ impl FuturesAccount { price_protect: None, new_client_order_id: None, good_till_date: None, + algo_type: None, }; let order = self.build_order(buy, None); let request = build_signed_request(order, self.recv_window)?; @@ -282,6 +293,7 @@ impl FuturesAccount { price_protect: None, new_client_order_id: None, good_till_date: None, + algo_type: None, }; let order = self.build_order(sell, None); let request = build_signed_request(order, self.recv_window)?; @@ -312,6 +324,7 @@ impl FuturesAccount { price_protect: None, new_client_order_id: None, good_till_date: None, + algo_type: None, }; let order = self.build_order(buy, None); let request = build_signed_request(order, self.recv_window)?; @@ -342,6 +355,7 @@ impl FuturesAccount { price_protect: None, new_client_order_id: None, good_till_date: None, + algo_type: None, }; let order = self.build_order(sell, None); let request = build_signed_request(order, self.recv_window)?; @@ -377,7 +391,6 @@ impl FuturesAccount { .delete_signed(API::Futures(Futures::Order), Some(request)) } - // Place a STOP_MARKET close - BUY pub fn stop_market_close_buy(&self, symbol: S, stop_price: F) -> Result where @@ -401,6 +414,7 @@ impl FuturesAccount { price_protect: None, new_client_order_id: None, good_till_date: None, + algo_type: None, }; let order = self.build_order(sell, None); let request = build_signed_request(order, self.recv_window)?; @@ -431,6 +445,7 @@ impl FuturesAccount { price_protect: None, new_client_order_id: None, good_till_date: None, + algo_type: None, }; let order = self.build_order(sell, None); let request = build_signed_request(order, self.recv_window)?; @@ -464,6 +479,7 @@ 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), }; let order = self.build_order(order, Some(request_params)); let request = build_signed_request(order, self.recv_window)?; @@ -495,6 +511,7 @@ 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), }; let _order = self.build_order(order, Some(request_params.clone())); // TODO : make a request string for batch orders api 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(); From aa0084930148002593a0aa21f59239de0d5ec1b2 Mon Sep 17 00:00:00 2001 From: DevWonder01 Date: Wed, 18 Mar 2026 10:54:42 +0100 Subject: [PATCH 3/4] Integrate AlgoType into order building for FuturesAccount and update build_order method to support algorithmic orders --- src/futures/account.rs | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/futures/account.rs b/src/futures/account.rs index 18d7a209..f1dacee4 100644 --- a/src/futures/account.rs +++ b/src/futures/account.rs @@ -266,7 +266,7 @@ impl FuturesAccount { good_till_date: None, algo_type: 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) @@ -295,7 +295,7 @@ impl FuturesAccount { good_till_date: None, algo_type: 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) @@ -326,7 +326,7 @@ impl FuturesAccount { good_till_date: None, algo_type: 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) @@ -357,7 +357,7 @@ impl FuturesAccount { good_till_date: None, algo_type: 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) @@ -414,9 +414,9 @@ impl FuturesAccount { price_protect: None, new_client_order_id: None, good_till_date: None, - algo_type: None, + algo_type: Some(AlgoType::Conditional), }; - 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::AlgoOrder), request) @@ -445,9 +445,9 @@ impl FuturesAccount { price_protect: None, new_client_order_id: None, good_till_date: None, - algo_type: None, + algo_type: Some(AlgoType::Conditional), }; - 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::AlgoOrder), request) @@ -481,7 +481,11 @@ impl FuturesAccount { good_till_date: order_request.good_till_date, algo_type: Some(order_request.algo_type), }; - 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::AlgoOrder), request) @@ -513,7 +517,11 @@ impl FuturesAccount { good_till_date: order_request.good_till_date, algo_type: Some(order_request.algo_type), }; - 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)?; } @@ -585,12 +593,17 @@ 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()); + } + if let Some(position_side) = order.position_side { parameters.insert("positionSide".into(), position_side.to_string()); } From 316ebe2e24e982439764375aacf88b2fcb87aa5b Mon Sep 17 00:00:00 2001 From: DevWonder01 Date: Wed, 18 Mar 2026 11:22:12 +0100 Subject: [PATCH 4/4] Add client_algo_id to OrderRequest and update request handling for algorithmic orders --- src/futures/account.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/futures/account.rs b/src/futures/account.rs index f1dacee4..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; @@ -145,6 +146,7 @@ struct OrderRequest { pub new_client_order_id: Option, pub good_till_date: Option, pub algo_type: Option, + pub client_algo_id: Option, } pub struct CustomOrderRequest { @@ -265,6 +267,7 @@ impl FuturesAccount { new_client_order_id: None, good_till_date: None, algo_type: None, + client_algo_id: None, }; let order = self.build_order(buy, None, None); let request = build_signed_request(order, self.recv_window)?; @@ -294,6 +297,7 @@ impl FuturesAccount { new_client_order_id: None, good_till_date: None, algo_type: None, + client_algo_id: None, }; let order = self.build_order(sell, None, None); let request = build_signed_request(order, self.recv_window)?; @@ -325,6 +329,7 @@ impl FuturesAccount { new_client_order_id: None, good_till_date: None, algo_type: None, + client_algo_id: None, }; let order = self.build_order(buy, None, None); let request = build_signed_request(order, self.recv_window)?; @@ -356,6 +361,7 @@ impl FuturesAccount { new_client_order_id: None, good_till_date: None, algo_type: None, + client_algo_id: None, }; let order = self.build_order(sell, None, None); let request = build_signed_request(order, self.recv_window)?; @@ -415,6 +421,7 @@ impl FuturesAccount { 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, None); let request = build_signed_request(order, self.recv_window)?; @@ -446,6 +453,7 @@ impl FuturesAccount { 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, Some(API::Futures(Futures::AlgoOrder))); let request = build_signed_request(order, self.recv_window)?; @@ -480,6 +488,7 @@ impl FuturesAccount { 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, @@ -516,6 +525,7 @@ impl FuturesAccount { 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, @@ -602,6 +612,15 @@ impl FuturesAccount { 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 {