use serde::Serialize;
use crate::{
common::enums::{BinanceSelfTradePreventionMode, BinanceSide, BinanceTimeInForce},
spot::enums::{BinanceCancelReplaceMode, BinanceOrderResponseType, BinanceSpotOrderType},
};
#[derive(Debug, Clone, Serialize)]
pub struct DepthParams {
pub symbol: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
}
impl DepthParams {
#[must_use]
pub fn new(symbol: impl Into<String>) -> Self {
Self {
symbol: symbol.into(),
limit: None,
}
}
#[must_use]
pub fn with_limit(mut self, limit: u32) -> Self {
self.limit = Some(limit);
self
}
}
#[derive(Debug, Clone, Serialize)]
pub struct TradesParams {
pub symbol: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
}
impl TradesParams {
#[must_use]
pub fn new(symbol: impl Into<String>) -> Self {
Self {
symbol: symbol.into(),
limit: None,
}
}
#[must_use]
pub fn with_limit(mut self, limit: u32) -> Self {
self.limit = Some(limit);
self
}
}
#[derive(Debug, Clone, Serialize)]
pub struct NewOrderParams {
pub symbol: String,
pub side: BinanceSide,
#[serde(rename = "type")]
pub order_type: BinanceSpotOrderType,
#[serde(skip_serializing_if = "Option::is_none", rename = "timeInForce")]
pub time_in_force: Option<BinanceTimeInForce>,
#[serde(skip_serializing_if = "Option::is_none")]
pub quantity: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "quoteOrderQty")]
pub quote_order_qty: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub price: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "newClientOrderId")]
pub new_client_order_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "stopPrice")]
pub stop_price: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "trailingDelta")]
pub trailing_delta: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "icebergQty")]
pub iceberg_qty: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "newOrderRespType")]
pub new_order_resp_type: Option<BinanceOrderResponseType>,
#[serde(
skip_serializing_if = "Option::is_none",
rename = "selfTradePreventionMode"
)]
pub self_trade_prevention_mode: Option<BinanceSelfTradePreventionMode>,
#[serde(skip_serializing_if = "Option::is_none", rename = "strategyId")]
pub strategy_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "strategyType")]
pub strategy_type: Option<i64>,
}
impl NewOrderParams {
#[must_use]
pub fn limit(
symbol: impl Into<String>,
side: BinanceSide,
quantity: impl Into<String>,
price: impl Into<String>,
) -> Self {
Self {
symbol: symbol.into(),
side,
order_type: BinanceSpotOrderType::Limit,
time_in_force: Some(BinanceTimeInForce::Gtc),
quantity: Some(quantity.into()),
quote_order_qty: None,
price: Some(price.into()),
new_client_order_id: None,
stop_price: None,
trailing_delta: None,
iceberg_qty: None,
new_order_resp_type: Some(BinanceOrderResponseType::Full),
self_trade_prevention_mode: None,
strategy_id: None,
strategy_type: None,
}
}
#[must_use]
pub fn market(
symbol: impl Into<String>,
side: BinanceSide,
quantity: impl Into<String>,
) -> Self {
Self {
symbol: symbol.into(),
side,
order_type: BinanceSpotOrderType::Market,
time_in_force: None,
quantity: Some(quantity.into()),
quote_order_qty: None,
price: None,
new_client_order_id: None,
stop_price: None,
trailing_delta: None,
iceberg_qty: None,
new_order_resp_type: Some(BinanceOrderResponseType::Full),
self_trade_prevention_mode: None,
strategy_id: None,
strategy_type: None,
}
}
#[must_use]
pub fn with_client_order_id(mut self, id: impl Into<String>) -> Self {
self.new_client_order_id = Some(id.into());
self
}
#[must_use]
pub fn with_time_in_force(mut self, tif: BinanceTimeInForce) -> Self {
self.time_in_force = Some(tif);
self
}
#[must_use]
pub fn with_stop_price(mut self, price: impl Into<String>) -> Self {
self.stop_price = Some(price.into());
self
}
#[must_use]
pub fn with_stp_mode(mut self, mode: BinanceSelfTradePreventionMode) -> Self {
self.self_trade_prevention_mode = Some(mode);
self
}
}
#[derive(Debug, Clone, Serialize)]
pub struct CancelOrderParams {
pub symbol: String,
#[serde(skip_serializing_if = "Option::is_none", rename = "orderId")]
pub order_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "origClientOrderId")]
pub orig_client_order_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "newClientOrderId")]
pub new_client_order_id: Option<String>,
}
impl CancelOrderParams {
#[must_use]
pub fn by_order_id(symbol: impl Into<String>, order_id: i64) -> Self {
Self {
symbol: symbol.into(),
order_id: Some(order_id),
orig_client_order_id: None,
new_client_order_id: None,
}
}
#[must_use]
pub fn by_client_order_id(
symbol: impl Into<String>,
client_order_id: impl Into<String>,
) -> Self {
Self {
symbol: symbol.into(),
order_id: None,
orig_client_order_id: Some(client_order_id.into()),
new_client_order_id: None,
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct CancelOpenOrdersParams {
pub symbol: String,
}
impl CancelOpenOrdersParams {
#[must_use]
pub fn new(symbol: impl Into<String>) -> Self {
Self {
symbol: symbol.into(),
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct CancelReplaceOrderParams {
pub symbol: String,
pub side: BinanceSide,
#[serde(rename = "type")]
pub order_type: BinanceSpotOrderType,
#[serde(rename = "cancelReplaceMode")]
pub cancel_replace_mode: BinanceCancelReplaceMode,
#[serde(skip_serializing_if = "Option::is_none", rename = "timeInForce")]
pub time_in_force: Option<BinanceTimeInForce>,
#[serde(skip_serializing_if = "Option::is_none")]
pub quantity: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "quoteOrderQty")]
pub quote_order_qty: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub price: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "cancelOrderId")]
pub cancel_order_id: Option<i64>,
#[serde(
skip_serializing_if = "Option::is_none",
rename = "cancelOrigClientOrderId"
)]
pub cancel_orig_client_order_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "newClientOrderId")]
pub new_client_order_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "stopPrice")]
pub stop_price: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "trailingDelta")]
pub trailing_delta: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "icebergQty")]
pub iceberg_qty: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "newOrderRespType")]
pub new_order_resp_type: Option<BinanceOrderResponseType>,
#[serde(
skip_serializing_if = "Option::is_none",
rename = "selfTradePreventionMode"
)]
pub self_trade_prevention_mode: Option<BinanceSelfTradePreventionMode>,
}
#[derive(Debug, Clone, Serialize)]
pub struct QueryOrderParams {
pub symbol: String,
#[serde(skip_serializing_if = "Option::is_none", rename = "orderId")]
pub order_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "origClientOrderId")]
pub orig_client_order_id: Option<String>,
}
impl QueryOrderParams {
#[must_use]
pub fn by_order_id(symbol: impl Into<String>, order_id: i64) -> Self {
Self {
symbol: symbol.into(),
order_id: Some(order_id),
orig_client_order_id: None,
}
}
#[must_use]
pub fn by_client_order_id(
symbol: impl Into<String>,
client_order_id: impl Into<String>,
) -> Self {
Self {
symbol: symbol.into(),
order_id: None,
orig_client_order_id: Some(client_order_id.into()),
}
}
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct OpenOrdersParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbol: Option<String>,
}
impl OpenOrdersParams {
#[must_use]
pub fn all() -> Self {
Self { symbol: None }
}
#[must_use]
pub fn for_symbol(symbol: impl Into<String>) -> Self {
Self {
symbol: Some(symbol.into()),
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct AllOrdersParams {
pub symbol: String,
#[serde(skip_serializing_if = "Option::is_none", rename = "orderId")]
pub order_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "startTime")]
pub start_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "endTime")]
pub end_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
}
impl AllOrdersParams {
#[must_use]
pub fn new(symbol: impl Into<String>) -> Self {
Self {
symbol: symbol.into(),
order_id: None,
start_time: None,
end_time: None,
limit: None,
}
}
#[must_use]
pub fn with_limit(mut self, limit: u32) -> Self {
self.limit = Some(limit);
self
}
#[must_use]
pub fn with_time_range(mut self, start: i64, end: i64) -> Self {
self.start_time = Some(start);
self.end_time = Some(end);
self
}
}
#[derive(Debug, Clone, Serialize)]
pub struct NewOcoOrderParams {
pub symbol: String,
pub side: BinanceSide,
pub quantity: String,
pub price: String,
#[serde(rename = "stopPrice")]
pub stop_price: String,
#[serde(skip_serializing_if = "Option::is_none", rename = "stopLimitPrice")]
pub stop_limit_price: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "listClientOrderId")]
pub list_client_order_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "limitClientOrderId")]
pub limit_client_order_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "stopClientOrderId")]
pub stop_client_order_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "limitIcebergQty")]
pub limit_iceberg_qty: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "stopIcebergQty")]
pub stop_iceberg_qty: Option<String>,
#[serde(
skip_serializing_if = "Option::is_none",
rename = "stopLimitTimeInForce"
)]
pub stop_limit_time_in_force: Option<BinanceTimeInForce>,
#[serde(skip_serializing_if = "Option::is_none", rename = "newOrderRespType")]
pub new_order_resp_type: Option<BinanceOrderResponseType>,
#[serde(
skip_serializing_if = "Option::is_none",
rename = "selfTradePreventionMode"
)]
pub self_trade_prevention_mode: Option<BinanceSelfTradePreventionMode>,
}
impl NewOcoOrderParams {
#[must_use]
pub fn new(
symbol: impl Into<String>,
side: BinanceSide,
quantity: impl Into<String>,
price: impl Into<String>,
stop_price: impl Into<String>,
) -> Self {
Self {
symbol: symbol.into(),
side,
quantity: quantity.into(),
price: price.into(),
stop_price: stop_price.into(),
stop_limit_price: None,
list_client_order_id: None,
limit_client_order_id: None,
stop_client_order_id: None,
limit_iceberg_qty: None,
stop_iceberg_qty: None,
stop_limit_time_in_force: None,
new_order_resp_type: Some(BinanceOrderResponseType::Full),
self_trade_prevention_mode: None,
}
}
#[must_use]
pub fn with_stop_limit_price(mut self, price: impl Into<String>) -> Self {
self.stop_limit_price = Some(price.into());
self.stop_limit_time_in_force = Some(BinanceTimeInForce::Gtc);
self
}
}
#[derive(Debug, Clone, Serialize)]
pub struct CancelOrderListParams {
pub symbol: String,
#[serde(skip_serializing_if = "Option::is_none", rename = "orderListId")]
pub order_list_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "listClientOrderId")]
pub list_client_order_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "newClientOrderId")]
pub new_client_order_id: Option<String>,
}
impl CancelOrderListParams {
#[must_use]
pub fn by_order_list_id(symbol: impl Into<String>, order_list_id: i64) -> Self {
Self {
symbol: symbol.into(),
order_list_id: Some(order_list_id),
list_client_order_id: None,
new_client_order_id: None,
}
}
#[must_use]
pub fn by_list_client_order_id(
symbol: impl Into<String>,
list_client_order_id: impl Into<String>,
) -> Self {
Self {
symbol: symbol.into(),
order_list_id: None,
list_client_order_id: Some(list_client_order_id.into()),
new_client_order_id: None,
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct QueryOrderListParams {
#[serde(skip_serializing_if = "Option::is_none", rename = "orderListId")]
pub order_list_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "origClientOrderId")]
pub orig_client_order_id: Option<String>,
}
impl QueryOrderListParams {
#[must_use]
pub fn by_order_list_id(order_list_id: i64) -> Self {
Self {
order_list_id: Some(order_list_id),
orig_client_order_id: None,
}
}
#[must_use]
pub fn by_client_order_id(client_order_id: impl Into<String>) -> Self {
Self {
order_list_id: None,
orig_client_order_id: Some(client_order_id.into()),
}
}
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct AllOrderListsParams {
#[serde(skip_serializing_if = "Option::is_none", rename = "startTime")]
pub start_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "endTime")]
pub end_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct OpenOrderListsParams {}
#[derive(Debug, Clone, Default, Serialize)]
pub struct AccountInfoParams {
#[serde(skip_serializing_if = "Option::is_none", rename = "omitZeroBalances")]
pub omit_zero_balances: Option<bool>,
}
impl AccountInfoParams {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn omit_zero_balances(mut self) -> Self {
self.omit_zero_balances = Some(true);
self
}
}
#[derive(Debug, Clone, Serialize)]
pub struct AccountTradesParams {
pub symbol: String,
#[serde(skip_serializing_if = "Option::is_none", rename = "orderId")]
pub order_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "startTime")]
pub start_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "endTime")]
pub end_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "fromId")]
pub from_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
}
impl AccountTradesParams {
#[must_use]
pub fn new(symbol: impl Into<String>) -> Self {
Self {
symbol: symbol.into(),
order_id: None,
start_time: None,
end_time: None,
from_id: None,
limit: None,
}
}
#[must_use]
pub fn for_order(mut self, order_id: i64) -> Self {
self.order_id = Some(order_id);
self
}
#[must_use]
pub fn with_limit(mut self, limit: u32) -> Self {
self.limit = Some(limit);
self
}
#[must_use]
pub fn with_time_range(mut self, start: i64, end: i64) -> Self {
self.start_time = Some(start);
self.end_time = Some(end);
self
}
}
#[derive(Debug, Clone, Serialize)]
pub struct KlinesParams {
pub symbol: String,
pub interval: String,
#[serde(skip_serializing_if = "Option::is_none", rename = "startTime")]
pub start_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "endTime")]
pub end_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "timeZone")]
pub time_zone: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
}
#[derive(Debug, Clone, Serialize)]
pub struct ListenKeyParams {
#[serde(rename = "listenKey")]
pub listen_key: String,
}
impl ListenKeyParams {
#[must_use]
pub fn new(listen_key: impl Into<String>) -> Self {
Self {
listen_key: listen_key.into(),
}
}
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct TickerParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbol: Option<String>,
}
impl TickerParams {
#[must_use]
pub fn all() -> Self {
Self { symbol: None }
}
#[must_use]
pub fn for_symbol(symbol: impl Into<String>) -> Self {
Self {
symbol: Some(symbol.into()),
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct AvgPriceParams {
pub symbol: String,
}
impl AvgPriceParams {
#[must_use]
pub fn new(symbol: impl Into<String>) -> Self {
Self {
symbol: symbol.into(),
}
}
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct TradeFeeParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbol: Option<String>,
}
impl TradeFeeParams {
#[must_use]
pub fn all() -> Self {
Self { symbol: None }
}
#[must_use]
pub fn for_symbol(symbol: impl Into<String>) -> Self {
Self {
symbol: Some(symbol.into()),
}
}
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BatchOrderItem {
pub symbol: String,
pub side: String,
#[serde(rename = "type")]
pub order_type: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub time_in_force: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub quantity: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub price: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub new_client_order_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stop_price: Option<String>,
}
impl BatchOrderItem {
#[must_use]
pub fn from_params(params: &NewOrderParams) -> Self {
Self {
symbol: params.symbol.clone(),
side: format!("{:?}", params.side).to_uppercase(),
order_type: format!("{:?}", params.order_type).to_uppercase(),
time_in_force: params
.time_in_force
.map(|t| format!("{t:?}").to_uppercase()),
quantity: params.quantity.clone(),
price: params.price.clone(),
new_client_order_id: params.new_client_order_id.clone(),
stop_price: params.stop_price.clone(),
}
}
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BatchCancelItem {
pub symbol: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub order_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub orig_client_order_id: Option<String>,
}
impl BatchCancelItem {
#[must_use]
pub fn by_order_id(symbol: impl Into<String>, order_id: i64) -> Self {
Self {
symbol: symbol.into(),
order_id: Some(order_id),
orig_client_order_id: None,
}
}
#[must_use]
pub fn by_client_order_id(
symbol: impl Into<String>,
client_order_id: impl Into<String>,
) -> Self {
Self {
symbol: symbol.into(),
order_id: None,
orig_client_order_id: Some(client_order_id.into()),
}
}
}