diff --git a/connector/src/binancefutures/mod.rs b/connector/src/binancefutures/mod.rs index 3b3c63f..72a1e38 100644 --- a/connector/src/binancefutures/mod.rs +++ b/connector/src/binancefutures/mod.rs @@ -202,6 +202,8 @@ impl Connector for BinanceFutures { id: u64, ev_tx: UnboundedSender, ) { + // Binance futures symbols must be lowercase to subscribe to the WebSocket stream. + let symbol = symbol.to_lowercase(); let mut instruments = self.instruments.lock().unwrap(); if instruments.contains_key(&symbol) { let order_manager = self.order_manager.lock().unwrap(); diff --git a/connector/src/binancefutures/msg/rest.rs b/connector/src/binancefutures/msg/rest.rs index d3a8a63..12d6de1 100644 --- a/connector/src/binancefutures/msg/rest.rs +++ b/connector/src/binancefutures/msg/rest.rs @@ -2,7 +2,7 @@ use hftbacktest::types::{OrdType, Side, Status, TimeInForce}; use serde::Deserialize; use super::{from_str_to_side, from_str_to_status, from_str_to_tif, from_str_to_type}; -use crate::utils::{from_str_to_f64, from_str_to_f64_opt, to_uppercase}; +use crate::utils::{from_str_to_f64, from_str_to_f64_opt, to_lowercase}; #[derive(Deserialize, Debug)] #[serde(untagged)] @@ -56,7 +56,7 @@ pub struct OrderResponse { pub stop_price: f64, #[serde(rename = "closePosition")] pub close_position: bool, - #[serde(deserialize_with = "to_uppercase")] + #[serde(deserialize_with = "to_lowercase")] pub symbol: String, // for Coin-M futures // pub pair: String, @@ -132,7 +132,7 @@ pub struct PositionInformationV2 { pub notional: f64, #[serde(rename = "isolatedWallet")] pub isolated_wallet: String, - #[serde(deserialize_with = "to_uppercase")] + #[serde(deserialize_with = "to_lowercase")] pub symbol: String, #[serde(rename = "unRealizedProfit")] pub unrealized_pnl: String, diff --git a/connector/src/binancefutures/msg/stream.rs b/connector/src/binancefutures/msg/stream.rs index 7f6e62e..113865c 100644 --- a/connector/src/binancefutures/msg/stream.rs +++ b/connector/src/binancefutures/msg/stream.rs @@ -2,7 +2,7 @@ use hftbacktest::types::{OrdType, Side, Status, TimeInForce}; use serde::Deserialize; use super::{from_str_to_side, from_str_to_status, from_str_to_tif, from_str_to_type}; -use crate::utils::{from_str_to_f64, to_uppercase}; +use crate::utils::{from_str_to_f64, to_lowercase}; #[derive(Deserialize, Debug)] #[serde(tag = "e")] @@ -26,7 +26,7 @@ pub struct Depth { #[serde(rename = "E")] pub event_time: i64, #[serde(rename = "s")] - #[serde(deserialize_with = "to_uppercase")] + #[serde(deserialize_with = "to_lowercase")] pub symbol: String, // for Coin-M futures // #[serde(rename = "ps")] @@ -50,7 +50,7 @@ pub struct Trade { #[serde(rename = "E")] pub event_time: i64, #[serde(rename = "s")] - #[serde(deserialize_with = "to_uppercase")] + #[serde(deserialize_with = "to_lowercase")] pub symbol: String, #[serde(rename = "t")] pub id: i64, @@ -102,7 +102,7 @@ pub struct Balance { #[derive(Deserialize, Debug)] pub struct Position { #[serde(rename = "s")] - #[serde(deserialize_with = "to_uppercase")] + #[serde(deserialize_with = "to_lowercase")] pub symbol: String, #[serde(rename = "pa")] #[serde(deserialize_with = "from_str_to_f64")] @@ -139,7 +139,7 @@ pub struct OrderTradeUpdate { #[derive(Deserialize, Debug)] pub struct Order { #[serde(rename = "s")] - #[serde(deserialize_with = "to_uppercase")] + #[serde(deserialize_with = "to_lowercase")] pub symbol: String, #[serde(rename = "c")] pub client_order_id: String, diff --git a/connector/src/utils.rs b/connector/src/utils.rs index 13ca143..5484868 100644 --- a/connector/src/utils.rs +++ b/connector/src/utils.rs @@ -117,6 +117,14 @@ where Ok(s.to_uppercase()) } +pub fn to_lowercase<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let s: &str = Deserialize::deserialize(deserializer)?; + Ok(s.to_lowercase()) +} + pub fn sign_hmac_sha256(secret: &str, s: &str) -> String { let mut mac = Hmac::::new_from_slice(secret.as_bytes()).unwrap(); mac.update(s.as_bytes());