/*
* Binance Margin Trading REST API
*
* OpenAPI Specification for the Binance Margin Trading REST API
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#![allow(unused_imports)]
use async_trait::async_trait;
use derive_builder::Builder;
use reqwest;
use rust_decimal::prelude::*;
use serde::{Deserialize, Serialize};
use serde_json::{Value, json};
use std::collections::BTreeMap;
use crate::common::{
config::ConfigurationRestApi,
models::{ParamBuildError, RestApiResponse},
utils::send_request,
};
use crate::margin_trading::rest_api::models;
const HAS_TIME_UNIT: bool = false;
#[async_trait]
pub trait TradeApi: Send + Sync {
async fn create_special_key(
&self,
params: CreateSpecialKeyParams,
) -> anyhow::Result<RestApiResponse<models::CreateSpecialKeyResponse>>;
async fn delete_special_key(
&self,
params: DeleteSpecialKeyParams,
) -> anyhow::Result<RestApiResponse<Value>>;
async fn edit_ip_for_special_key(
&self,
params: EditIpForSpecialKeyParams,
) -> anyhow::Result<RestApiResponse<Value>>;
async fn get_force_liquidation_record(
&self,
params: GetForceLiquidationRecordParams,
) -> anyhow::Result<RestApiResponse<models::GetForceLiquidationRecordResponse>>;
async fn get_small_liability_exchange_coin_list(
&self,
params: GetSmallLiabilityExchangeCoinListParams,
) -> anyhow::Result<RestApiResponse<Vec<models::GetSmallLiabilityExchangeCoinListResponseInner>>>;
async fn get_small_liability_exchange_history(
&self,
params: GetSmallLiabilityExchangeHistoryParams,
) -> anyhow::Result<RestApiResponse<models::GetSmallLiabilityExchangeHistoryResponse>>;
async fn margin_account_cancel_all_open_orders_on_a_symbol(
&self,
params: MarginAccountCancelAllOpenOrdersOnASymbolParams,
) -> anyhow::Result<
RestApiResponse<Vec<models::MarginAccountCancelAllOpenOrdersOnASymbolResponseInner>>,
>;
async fn margin_account_cancel_oco(
&self,
params: MarginAccountCancelOcoParams,
) -> anyhow::Result<RestApiResponse<models::MarginAccountCancelOcoResponse>>;
async fn margin_account_cancel_order(
&self,
params: MarginAccountCancelOrderParams,
) -> anyhow::Result<RestApiResponse<models::MarginAccountCancelOrderResponse>>;
async fn margin_account_new_oco(
&self,
params: MarginAccountNewOcoParams,
) -> anyhow::Result<RestApiResponse<models::MarginAccountNewOcoResponse>>;
async fn margin_account_new_order(
&self,
params: MarginAccountNewOrderParams,
) -> anyhow::Result<RestApiResponse<models::MarginAccountNewOrderResponse>>;
async fn margin_account_new_oto(
&self,
params: MarginAccountNewOtoParams,
) -> anyhow::Result<RestApiResponse<models::MarginAccountNewOtoResponse>>;
async fn margin_account_new_otoco(
&self,
params: MarginAccountNewOtocoParams,
) -> anyhow::Result<RestApiResponse<models::MarginAccountNewOtocoResponse>>;
async fn margin_manual_liquidation(
&self,
params: MarginManualLiquidationParams,
) -> anyhow::Result<RestApiResponse<models::MarginManualLiquidationResponse>>;
async fn query_current_margin_order_count_usage(
&self,
params: QueryCurrentMarginOrderCountUsageParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryCurrentMarginOrderCountUsageResponseInner>>>;
async fn query_margin_accounts_all_oco(
&self,
params: QueryMarginAccountsAllOcoParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryMarginAccountsAllOcoResponseInner>>>;
async fn query_margin_accounts_all_orders(
&self,
params: QueryMarginAccountsAllOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryMarginAccountsAllOrdersResponseInner>>>;
async fn query_margin_accounts_oco(
&self,
params: QueryMarginAccountsOcoParams,
) -> anyhow::Result<RestApiResponse<models::QueryMarginAccountsOcoResponse>>;
async fn query_margin_accounts_open_oco(
&self,
params: QueryMarginAccountsOpenOcoParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryMarginAccountsOpenOcoResponseInner>>>;
async fn query_margin_accounts_open_orders(
&self,
params: QueryMarginAccountsOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryMarginAccountsOpenOrdersResponseInner>>>;
async fn query_margin_accounts_order(
&self,
params: QueryMarginAccountsOrderParams,
) -> anyhow::Result<RestApiResponse<models::QueryMarginAccountsOrderResponse>>;
async fn query_margin_accounts_trade_list(
&self,
params: QueryMarginAccountsTradeListParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryMarginAccountsTradeListResponseInner>>>;
async fn query_prevented_matches(
&self,
params: QueryPreventedMatchesParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryPreventedMatchesResponseInner>>>;
async fn query_special_key(
&self,
params: QuerySpecialKeyParams,
) -> anyhow::Result<RestApiResponse<models::QuerySpecialKeyResponse>>;
async fn query_special_key_list(
&self,
params: QuerySpecialKeyListParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QuerySpecialKeyListResponseInner>>>;
async fn small_liability_exchange(
&self,
params: SmallLiabilityExchangeParams,
) -> anyhow::Result<RestApiResponse<Value>>;
}
#[derive(Debug, Clone)]
pub struct TradeApiClient {
configuration: ConfigurationRestApi,
}
impl TradeApiClient {
pub fn new(configuration: ConfigurationRestApi) -> Self {
Self { configuration }
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum MarginAccountNewOcoSideEnum {
#[serde(rename = "BUY")]
Buy,
#[serde(rename = "SELL")]
Sell,
}
impl MarginAccountNewOcoSideEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Buy => "BUY",
Self::Sell => "SELL",
}
}
}
impl std::str::FromStr for MarginAccountNewOcoSideEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"BUY" => Ok(Self::Buy),
"SELL" => Ok(Self::Sell),
other => Err(format!("invalid MarginAccountNewOcoSideEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum MarginAccountNewOcoNewOrderRespTypeEnum {
#[serde(rename = "ACK")]
Ack,
#[serde(rename = "RESULT")]
Result,
#[serde(rename = "FULL")]
Full,
}
impl MarginAccountNewOcoNewOrderRespTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Ack => "ACK",
Self::Result => "RESULT",
Self::Full => "FULL",
}
}
}
impl std::str::FromStr for MarginAccountNewOcoNewOrderRespTypeEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"ACK" => Ok(Self::Ack),
"RESULT" => Ok(Self::Result),
"FULL" => Ok(Self::Full),
other => {
Err(format!("invalid MarginAccountNewOcoNewOrderRespTypeEnum: {}", other).into())
}
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum MarginAccountNewOrderSideEnum {
#[serde(rename = "BUY")]
Buy,
#[serde(rename = "SELL")]
Sell,
}
impl MarginAccountNewOrderSideEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Buy => "BUY",
Self::Sell => "SELL",
}
}
}
impl std::str::FromStr for MarginAccountNewOrderSideEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"BUY" => Ok(Self::Buy),
"SELL" => Ok(Self::Sell),
other => Err(format!("invalid MarginAccountNewOrderSideEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum MarginAccountNewOrderNewOrderRespTypeEnum {
#[serde(rename = "ACK")]
Ack,
#[serde(rename = "RESULT")]
Result,
#[serde(rename = "FULL")]
Full,
}
impl MarginAccountNewOrderNewOrderRespTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Ack => "ACK",
Self::Result => "RESULT",
Self::Full => "FULL",
}
}
}
impl std::str::FromStr for MarginAccountNewOrderNewOrderRespTypeEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"ACK" => Ok(Self::Ack),
"RESULT" => Ok(Self::Result),
"FULL" => Ok(Self::Full),
other => Err(format!(
"invalid MarginAccountNewOrderNewOrderRespTypeEnum: {}",
other
)
.into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum MarginAccountNewOrderTimeInForceEnum {
#[serde(rename = "GTC")]
Gtc,
#[serde(rename = "IOC")]
Ioc,
#[serde(rename = "FOK")]
Fok,
}
impl MarginAccountNewOrderTimeInForceEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Gtc => "GTC",
Self::Ioc => "IOC",
Self::Fok => "FOK",
}
}
}
impl std::str::FromStr for MarginAccountNewOrderTimeInForceEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"GTC" => Ok(Self::Gtc),
"IOC" => Ok(Self::Ioc),
"FOK" => Ok(Self::Fok),
other => Err(format!("invalid MarginAccountNewOrderTimeInForceEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum MarginAccountNewOtoNewOrderRespTypeEnum {
#[serde(rename = "ACK")]
Ack,
#[serde(rename = "RESULT")]
Result,
#[serde(rename = "FULL")]
Full,
}
impl MarginAccountNewOtoNewOrderRespTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Ack => "ACK",
Self::Result => "RESULT",
Self::Full => "FULL",
}
}
}
impl std::str::FromStr for MarginAccountNewOtoNewOrderRespTypeEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"ACK" => Ok(Self::Ack),
"RESULT" => Ok(Self::Result),
"FULL" => Ok(Self::Full),
other => {
Err(format!("invalid MarginAccountNewOtoNewOrderRespTypeEnum: {}", other).into())
}
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum MarginAccountNewOtocoNewOrderRespTypeEnum {
#[serde(rename = "ACK")]
Ack,
#[serde(rename = "RESULT")]
Result,
#[serde(rename = "FULL")]
Full,
}
impl MarginAccountNewOtocoNewOrderRespTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Ack => "ACK",
Self::Result => "RESULT",
Self::Full => "FULL",
}
}
}
impl std::str::FromStr for MarginAccountNewOtocoNewOrderRespTypeEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"ACK" => Ok(Self::Ack),
"RESULT" => Ok(Self::Result),
"FULL" => Ok(Self::Full),
other => Err(format!(
"invalid MarginAccountNewOtocoNewOrderRespTypeEnum: {}",
other
)
.into()),
}
}
}
/// Request parameters for the [`create_special_key`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`create_special_key`](#method.create_special_key).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct CreateSpecialKeyParams {
///
/// The `api_name` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub api_name: String,
/// isolated margin pair
///
/// This field is **optional.
#[builder(setter(into), default)]
pub symbol: Option<String>,
/// Can be added in batches, separated by commas. Max 30 for an API key
///
/// This field is **optional.
#[builder(setter(into), default)]
pub ip: Option<String>,
/// 1. If publicKey is inputted it will create an RSA or Ed25519 key. <br />2. Need to be encoded to URL-encoded format
///
/// This field is **optional.
#[builder(setter(into), default)]
pub public_key: Option<String>,
/// This parameter is only for the Ed25519 API key, and does not effact for other encryption methods. The value can be TRADE (TRADE for all permissions) or READ (READ for `USER_DATA`, `FIX_API_READ_ONLY`). The default value is TRADE.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub permission_mode: Option<String>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl CreateSpecialKeyParams {
/// Create a builder for [`create_special_key`].
///
/// Required parameters:
///
/// * `api_name` — String
///
#[must_use]
pub fn builder(api_name: String) -> CreateSpecialKeyParamsBuilder {
CreateSpecialKeyParamsBuilder::default().api_name(api_name)
}
}
/// Request parameters for the [`delete_special_key`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`delete_special_key`](#method.delete_special_key).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct DeleteSpecialKeyParams {
///
/// The `api_name` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub api_name: Option<String>,
/// isolated margin pair
///
/// This field is **optional.
#[builder(setter(into), default)]
pub symbol: Option<String>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl DeleteSpecialKeyParams {
/// Create a builder for [`delete_special_key`].
///
#[must_use]
pub fn builder() -> DeleteSpecialKeyParamsBuilder {
DeleteSpecialKeyParamsBuilder::default()
}
}
/// Request parameters for the [`edit_ip_for_special_key`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`edit_ip_for_special_key`](#method.edit_ip_for_special_key).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct EditIpForSpecialKeyParams {
/// Can be added in batches, separated by commas. Max 30 for an API key
///
/// This field is **required.
#[builder(setter(into))]
pub ip: String,
/// isolated margin pair
///
/// This field is **optional.
#[builder(setter(into), default)]
pub symbol: Option<String>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl EditIpForSpecialKeyParams {
/// Create a builder for [`edit_ip_for_special_key`].
///
/// Required parameters:
///
/// * `ip` — Can be added in batches, separated by commas. Max 30 for an API key
///
#[must_use]
pub fn builder(ip: String) -> EditIpForSpecialKeyParamsBuilder {
EditIpForSpecialKeyParamsBuilder::default().ip(ip)
}
}
/// Request parameters for the [`get_force_liquidation_record`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_force_liquidation_record`](#method.get_force_liquidation_record).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetForceLiquidationRecordParams {
/// Only supports querying data from the past 90 days.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub start_time: Option<i64>,
///
/// The `end_time` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub end_time: Option<i64>,
/// isolated symbol
///
/// This field is **optional.
#[builder(setter(into), default)]
pub isolated_symbol: Option<String>,
/// Currently querying page. Start from 1. Default:1
///
/// This field is **optional.
#[builder(setter(into), default)]
pub current: Option<i64>,
/// Default:10 Max:100
///
/// This field is **optional.
#[builder(setter(into), default)]
pub size: Option<i64>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl GetForceLiquidationRecordParams {
/// Create a builder for [`get_force_liquidation_record`].
///
#[must_use]
pub fn builder() -> GetForceLiquidationRecordParamsBuilder {
GetForceLiquidationRecordParamsBuilder::default()
}
}
/// Request parameters for the [`get_small_liability_exchange_coin_list`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_small_liability_exchange_coin_list`](#method.get_small_liability_exchange_coin_list).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetSmallLiabilityExchangeCoinListParams {
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl GetSmallLiabilityExchangeCoinListParams {
/// Create a builder for [`get_small_liability_exchange_coin_list`].
///
#[must_use]
pub fn builder() -> GetSmallLiabilityExchangeCoinListParamsBuilder {
GetSmallLiabilityExchangeCoinListParamsBuilder::default()
}
}
/// Request parameters for the [`get_small_liability_exchange_history`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_small_liability_exchange_history`](#method.get_small_liability_exchange_history).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetSmallLiabilityExchangeHistoryParams {
/// Currently querying page. Start from 1. Default:1
///
/// This field is **required.
#[builder(setter(into))]
pub current: i64,
/// Default:10, Max:100
///
/// This field is **required.
#[builder(setter(into))]
pub size: i64,
/// Only supports querying data from the past 90 days.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub start_time: Option<i64>,
///
/// The `end_time` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub end_time: Option<i64>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl GetSmallLiabilityExchangeHistoryParams {
/// Create a builder for [`get_small_liability_exchange_history`].
///
/// Required parameters:
///
/// * `current` — Currently querying page. Start from 1. Default:1
/// * `size` — Default:10, Max:100
///
#[must_use]
pub fn builder(current: i64, size: i64) -> GetSmallLiabilityExchangeHistoryParamsBuilder {
GetSmallLiabilityExchangeHistoryParamsBuilder::default()
.current(current)
.size(size)
}
}
/// Request parameters for the [`margin_account_cancel_all_open_orders_on_a_symbol`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`margin_account_cancel_all_open_orders_on_a_symbol`](#method.margin_account_cancel_all_open_orders_on_a_symbol).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct MarginAccountCancelAllOpenOrdersOnASymbolParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
/// For isolated margin or not, "TRUE", "FALSE", default "FALSE"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub is_isolated: Option<String>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl MarginAccountCancelAllOpenOrdersOnASymbolParams {
/// Create a builder for [`margin_account_cancel_all_open_orders_on_a_symbol`].
///
/// Required parameters:
///
/// * `symbol` — String
///
#[must_use]
pub fn builder(symbol: String) -> MarginAccountCancelAllOpenOrdersOnASymbolParamsBuilder {
MarginAccountCancelAllOpenOrdersOnASymbolParamsBuilder::default().symbol(symbol)
}
}
/// Request parameters for the [`margin_account_cancel_oco`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`margin_account_cancel_oco`](#method.margin_account_cancel_oco).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct MarginAccountCancelOcoParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
/// For isolated margin or not, "TRUE", "FALSE", default "FALSE"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub is_isolated: Option<String>,
/// Either `orderListId` or `listClientOrderId` must be provided
///
/// This field is **optional.
#[builder(setter(into), default)]
pub order_list_id: Option<i64>,
/// Either `orderListId` or `listClientOrderId` must be provided
///
/// This field is **optional.
#[builder(setter(into), default)]
pub list_client_order_id: Option<String>,
/// Used to uniquely identify this cancel. Automatically generated by default
///
/// This field is **optional.
#[builder(setter(into), default)]
pub new_client_order_id: Option<String>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl MarginAccountCancelOcoParams {
/// Create a builder for [`margin_account_cancel_oco`].
///
/// Required parameters:
///
/// * `symbol` — String
///
#[must_use]
pub fn builder(symbol: String) -> MarginAccountCancelOcoParamsBuilder {
MarginAccountCancelOcoParamsBuilder::default().symbol(symbol)
}
}
/// Request parameters for the [`margin_account_cancel_order`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`margin_account_cancel_order`](#method.margin_account_cancel_order).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct MarginAccountCancelOrderParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
/// For isolated margin or not, "TRUE", "FALSE", default "FALSE"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub is_isolated: Option<String>,
///
/// The `order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub order_id: Option<i64>,
///
/// The `orig_client_order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub orig_client_order_id: Option<String>,
/// Used to uniquely identify this cancel. Automatically generated by default
///
/// This field is **optional.
#[builder(setter(into), default)]
pub new_client_order_id: Option<String>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl MarginAccountCancelOrderParams {
/// Create a builder for [`margin_account_cancel_order`].
///
/// Required parameters:
///
/// * `symbol` — String
///
#[must_use]
pub fn builder(symbol: String) -> MarginAccountCancelOrderParamsBuilder {
MarginAccountCancelOrderParamsBuilder::default().symbol(symbol)
}
}
/// Request parameters for the [`margin_account_new_oco`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`margin_account_new_oco`](#method.margin_account_new_oco).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct MarginAccountNewOcoParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
///
/// The `side` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub side: MarginAccountNewOcoSideEnum,
///
/// The `quantity` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub quantity: rust_decimal::Decimal,
///
/// The `price` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub price: rust_decimal::Decimal,
///
/// The `stop_price` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub stop_price: rust_decimal::Decimal,
/// For isolated margin or not, "TRUE", "FALSE", default "FALSE"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub is_isolated: Option<String>,
/// Either `orderListId` or `listClientOrderId` must be provided
///
/// This field is **optional.
#[builder(setter(into), default)]
pub list_client_order_id: Option<String>,
/// A unique Id for the limit order
///
/// This field is **optional.
#[builder(setter(into), default)]
pub limit_client_order_id: Option<String>,
///
/// The `limit_iceberg_qty` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub limit_iceberg_qty: Option<rust_decimal::Decimal>,
/// A unique Id for the stop loss/stop loss limit leg
///
/// This field is **optional.
#[builder(setter(into), default)]
pub stop_client_order_id: Option<String>,
/// If provided, `stopLimitTimeInForce` is required.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub stop_limit_price: Option<rust_decimal::Decimal>,
///
/// The `stop_iceberg_qty` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub stop_iceberg_qty: Option<rust_decimal::Decimal>,
/// Valid values are `GTC`/`FOK`/`IOC`
///
/// This field is **optional.
#[builder(setter(into), default)]
pub stop_limit_time_in_force: Option<String>,
/// Set the response JSON. ACK, RESULT, or FULL; MARKET and LIMIT order types default to FULL, all other orders default to ACK.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub new_order_resp_type: Option<MarginAccountNewOcoNewOrderRespTypeEnum>,
/// `NO_SIDE_EFFECT`, `MARGIN_BUY`, `AUTO_REPAY,AUTO_BORROW_REPAY`; default `NO_SIDE_EFFECT`. More info in [FAQ](https://www.binance.com/en/support/faq/how-to-use-the-sideeffecttype-parameter-with-the-margin-order-endpoints-f9fc51cda1984bf08b95e0d96c4570bc)
///
/// This field is **optional.
#[builder(setter(into), default)]
pub side_effect_type: Option<String>,
/// The allowed enums is dependent on what is configured on the symbol. The possible supported values are `EXPIRE_TAKER`, `EXPIRE_MAKER`, `EXPIRE_BOTH`, NONE
///
/// This field is **optional.
#[builder(setter(into), default)]
pub self_trade_prevention_mode: Option<String>,
/// Only when `MARGIN_BUY` or `AUTO_BORROW_REPAY` order takes effect, true means that the debt generated by the order needs to be repay after the order is cancelled. The default is true
///
/// This field is **optional.
#[builder(setter(into), default)]
pub auto_repay_at_cancel: Option<bool>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl MarginAccountNewOcoParams {
/// Create a builder for [`margin_account_new_oco`].
///
/// Required parameters:
///
/// * `symbol` — String
/// * `side` — String
/// * `quantity` — `rust_decimal::Decimal`
/// * `price` — `rust_decimal::Decimal`
/// * `stop_price` — `rust_decimal::Decimal`
///
#[must_use]
pub fn builder(
symbol: String,
side: MarginAccountNewOcoSideEnum,
quantity: rust_decimal::Decimal,
price: rust_decimal::Decimal,
stop_price: rust_decimal::Decimal,
) -> MarginAccountNewOcoParamsBuilder {
MarginAccountNewOcoParamsBuilder::default()
.symbol(symbol)
.side(side)
.quantity(quantity)
.price(price)
.stop_price(stop_price)
}
}
/// Request parameters for the [`margin_account_new_order`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`margin_account_new_order`](#method.margin_account_new_order).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct MarginAccountNewOrderParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
///
/// The `side` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub side: MarginAccountNewOrderSideEnum,
/// `MARGIN`,`ISOLATED`
///
/// This field is **required.
#[builder(setter(into))]
pub r#type: String,
/// For isolated margin or not, "TRUE", "FALSE", default "FALSE"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub is_isolated: Option<String>,
///
/// The `quantity` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub quantity: Option<rust_decimal::Decimal>,
///
/// The `quote_order_qty` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub quote_order_qty: Option<rust_decimal::Decimal>,
///
/// The `price` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub price: Option<rust_decimal::Decimal>,
/// Used with `STOP_LOSS`, `STOP_LOSS_LIMIT`, `TAKE_PROFIT`, and `TAKE_PROFIT_LIMIT` orders.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub stop_price: Option<rust_decimal::Decimal>,
/// Used to uniquely identify this cancel. Automatically generated by default
///
/// This field is **optional.
#[builder(setter(into), default)]
pub new_client_order_id: Option<String>,
/// Used with `LIMIT`, `STOP_LOSS_LIMIT`, and `TAKE_PROFIT_LIMIT` to create an iceberg order.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub iceberg_qty: Option<rust_decimal::Decimal>,
/// Set the response JSON. ACK, RESULT, or FULL; MARKET and LIMIT order types default to FULL, all other orders default to ACK.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub new_order_resp_type: Option<MarginAccountNewOrderNewOrderRespTypeEnum>,
/// `NO_SIDE_EFFECT`, `MARGIN_BUY`, `AUTO_REPAY,AUTO_BORROW_REPAY`; default `NO_SIDE_EFFECT`. More info in [FAQ](https://www.binance.com/en/support/faq/how-to-use-the-sideeffecttype-parameter-with-the-margin-order-endpoints-f9fc51cda1984bf08b95e0d96c4570bc)
///
/// This field is **optional.
#[builder(setter(into), default)]
pub side_effect_type: Option<String>,
/// GTC,IOC,FOK
///
/// This field is **optional.
#[builder(setter(into), default)]
pub time_in_force: Option<MarginAccountNewOrderTimeInForceEnum>,
/// The allowed enums is dependent on what is configured on the symbol. The possible supported values are `EXPIRE_TAKER`, `EXPIRE_MAKER`, `EXPIRE_BOTH`, NONE
///
/// This field is **optional.
#[builder(setter(into), default)]
pub self_trade_prevention_mode: Option<String>,
/// Only when `MARGIN_BUY` or `AUTO_BORROW_REPAY` order takes effect, true means that the debt generated by the order needs to be repay after the order is cancelled. The default is true
///
/// This field is **optional.
#[builder(setter(into), default)]
pub auto_repay_at_cancel: Option<bool>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl MarginAccountNewOrderParams {
/// Create a builder for [`margin_account_new_order`].
///
/// Required parameters:
///
/// * `symbol` — String
/// * `side` — String
/// * `r#type` — `MARGIN`,`ISOLATED`
///
#[must_use]
pub fn builder(
symbol: String,
side: MarginAccountNewOrderSideEnum,
r#type: String,
) -> MarginAccountNewOrderParamsBuilder {
MarginAccountNewOrderParamsBuilder::default()
.symbol(symbol)
.side(side)
.r#type(r#type)
}
}
/// Request parameters for the [`margin_account_new_oto`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`margin_account_new_oto`](#method.margin_account_new_oto).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct MarginAccountNewOtoParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
/// Supported values: `LIMIT`, `LIMIT_MAKER`
///
/// This field is **required.
#[builder(setter(into))]
pub working_type: String,
/// BUY, SELL
///
/// This field is **required.
#[builder(setter(into))]
pub working_side: String,
///
/// The `working_price` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub working_price: rust_decimal::Decimal,
///
/// The `working_quantity` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub working_quantity: rust_decimal::Decimal,
/// This can only be used if `workingTimeInForce` is `GTC`.
///
/// This field is **required.
#[builder(setter(into))]
pub working_iceberg_qty: rust_decimal::Decimal,
/// Supported values: [Order Types](https://developers.binance.com/docs/binance-spot-api-docs/enums#order-types-ordertypes-type) Note that `MARKET` orders using `quoteOrderQty` are not supported.
///
/// This field is **required.
#[builder(setter(into))]
pub pending_type: String,
/// BUY, SELL
///
/// This field is **required.
#[builder(setter(into))]
pub pending_side: String,
///
/// The `pending_quantity` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub pending_quantity: rust_decimal::Decimal,
/// For isolated margin or not, "TRUE", "FALSE", default "FALSE"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub is_isolated: Option<String>,
/// Either `orderListId` or `listClientOrderId` must be provided
///
/// This field is **optional.
#[builder(setter(into), default)]
pub list_client_order_id: Option<String>,
/// Set the response JSON. ACK, RESULT, or FULL; MARKET and LIMIT order types default to FULL, all other orders default to ACK.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub new_order_resp_type: Option<MarginAccountNewOtoNewOrderRespTypeEnum>,
/// `NO_SIDE_EFFECT`, `MARGIN_BUY`, `AUTO_REPAY,AUTO_BORROW_REPAY`; default `NO_SIDE_EFFECT`. More info in [FAQ](https://www.binance.com/en/support/faq/how-to-use-the-sideeffecttype-parameter-with-the-margin-order-endpoints-f9fc51cda1984bf08b95e0d96c4570bc)
///
/// This field is **optional.
#[builder(setter(into), default)]
pub side_effect_type: Option<String>,
/// The allowed enums is dependent on what is configured on the symbol. The possible supported values are `EXPIRE_TAKER`, `EXPIRE_MAKER`, `EXPIRE_BOTH`, NONE
///
/// This field is **optional.
#[builder(setter(into), default)]
pub self_trade_prevention_mode: Option<String>,
/// Only when `MARGIN_BUY` or `AUTO_BORROW_REPAY` order takes effect, true means that the debt generated by the order needs to be repay after the order is cancelled. The default is true
///
/// This field is **optional.
#[builder(setter(into), default)]
pub auto_repay_at_cancel: Option<bool>,
/// Arbitrary unique ID among open orders for the working order. Automatically generated if not sent.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub working_client_order_id: Option<String>,
/// GTC,IOC,FOK
///
/// This field is **optional.
#[builder(setter(into), default)]
pub working_time_in_force: Option<String>,
/// Arbitrary unique ID among open orders for the pending order. Automatically generated if not sent.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_client_order_id: Option<String>,
///
/// The `pending_price` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_price: Option<rust_decimal::Decimal>,
///
/// The `pending_stop_price` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_stop_price: Option<rust_decimal::Decimal>,
///
/// The `pending_trailing_delta` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_trailing_delta: Option<rust_decimal::Decimal>,
/// This can only be used if `pendingTimeInForce` is `GTC`.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_iceberg_qty: Option<rust_decimal::Decimal>,
/// GTC,IOC,FOK
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_time_in_force: Option<String>,
}
impl MarginAccountNewOtoParams {
/// Create a builder for [`margin_account_new_oto`].
///
/// Required parameters:
///
/// * `symbol` — String
/// * `working_type` — Supported values: `LIMIT`, `LIMIT_MAKER`
/// * `working_side` — BUY, SELL
/// * `working_price` — `rust_decimal::Decimal`
/// * `working_quantity` — `rust_decimal::Decimal`
/// * `working_iceberg_qty` — This can only be used if `workingTimeInForce` is `GTC`.
/// * `pending_type` — Supported values: [Order Types](https://developers.binance.com/docs/binance-spot-api-docs/enums#order-types-ordertypes-type) Note that `MARKET` orders using `quoteOrderQty` are not supported.
/// * `pending_side` — BUY, SELL
/// * `pending_quantity` — `rust_decimal::Decimal`
///
#[must_use]
pub fn builder(
symbol: String,
working_type: String,
working_side: String,
working_price: rust_decimal::Decimal,
working_quantity: rust_decimal::Decimal,
working_iceberg_qty: rust_decimal::Decimal,
pending_type: String,
pending_side: String,
pending_quantity: rust_decimal::Decimal,
) -> MarginAccountNewOtoParamsBuilder {
MarginAccountNewOtoParamsBuilder::default()
.symbol(symbol)
.working_type(working_type)
.working_side(working_side)
.working_price(working_price)
.working_quantity(working_quantity)
.working_iceberg_qty(working_iceberg_qty)
.pending_type(pending_type)
.pending_side(pending_side)
.pending_quantity(pending_quantity)
}
}
/// Request parameters for the [`margin_account_new_otoco`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`margin_account_new_otoco`](#method.margin_account_new_otoco).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct MarginAccountNewOtocoParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
/// Supported values: `LIMIT`, `LIMIT_MAKER`
///
/// This field is **required.
#[builder(setter(into))]
pub working_type: String,
/// BUY, SELL
///
/// This field is **required.
#[builder(setter(into))]
pub working_side: String,
///
/// The `working_price` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub working_price: rust_decimal::Decimal,
///
/// The `working_quantity` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub working_quantity: rust_decimal::Decimal,
/// BUY, SELL
///
/// This field is **required.
#[builder(setter(into))]
pub pending_side: String,
///
/// The `pending_quantity` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub pending_quantity: rust_decimal::Decimal,
/// Supported values: `LIMIT_MAKER`, `STOP_LOSS`, and `STOP_LOSS_LIMIT`
///
/// This field is **required.
#[builder(setter(into))]
pub pending_above_type: String,
/// For isolated margin or not, "TRUE", "FALSE", default "FALSE"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub is_isolated: Option<String>,
/// `NO_SIDE_EFFECT`, `MARGIN_BUY`, `AUTO_REPAY,AUTO_BORROW_REPAY`; default `NO_SIDE_EFFECT`. More info in [FAQ](https://www.binance.com/en/support/faq/how-to-use-the-sideeffecttype-parameter-with-the-margin-order-endpoints-f9fc51cda1984bf08b95e0d96c4570bc)
///
/// This field is **optional.
#[builder(setter(into), default)]
pub side_effect_type: Option<String>,
/// Only when `MARGIN_BUY` or `AUTO_BORROW_REPAY` order takes effect, true means that the debt generated by the order needs to be repay after the order is cancelled. The default is true
///
/// This field is **optional.
#[builder(setter(into), default)]
pub auto_repay_at_cancel: Option<bool>,
/// Either `orderListId` or `listClientOrderId` must be provided
///
/// This field is **optional.
#[builder(setter(into), default)]
pub list_client_order_id: Option<String>,
/// Set the response JSON. ACK, RESULT, or FULL; MARKET and LIMIT order types default to FULL, all other orders default to ACK.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub new_order_resp_type: Option<MarginAccountNewOtocoNewOrderRespTypeEnum>,
/// The allowed enums is dependent on what is configured on the symbol. The possible supported values are `EXPIRE_TAKER`, `EXPIRE_MAKER`, `EXPIRE_BOTH`, NONE
///
/// This field is **optional.
#[builder(setter(into), default)]
pub self_trade_prevention_mode: Option<String>,
/// Arbitrary unique ID among open orders for the working order. Automatically generated if not sent.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub working_client_order_id: Option<String>,
/// This can only be used if `workingTimeInForce` is `GTC`.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub working_iceberg_qty: Option<rust_decimal::Decimal>,
/// GTC,IOC,FOK
///
/// This field is **optional.
#[builder(setter(into), default)]
pub working_time_in_force: Option<String>,
/// Arbitrary unique ID among open orders for the pending above order. Automatically generated if not sent.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_above_client_order_id: Option<String>,
///
/// The `pending_above_price` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_above_price: Option<rust_decimal::Decimal>,
///
/// The `pending_above_stop_price` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_above_stop_price: Option<rust_decimal::Decimal>,
///
/// The `pending_above_trailing_delta` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_above_trailing_delta: Option<rust_decimal::Decimal>,
/// This can only be used if `pendingAboveTimeInForce` is `GTC`.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_above_iceberg_qty: Option<rust_decimal::Decimal>,
///
/// The `pending_above_time_in_force` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_above_time_in_force: Option<String>,
/// Supported values: `LIMIT_MAKER`, `STOP_LOSS`, and `STOP_LOSS_LIMIT`
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_below_type: Option<String>,
/// Arbitrary unique ID among open orders for the pending below order. Automatically generated if not sent.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_below_client_order_id: Option<String>,
///
/// The `pending_below_price` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_below_price: Option<rust_decimal::Decimal>,
///
/// The `pending_below_stop_price` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_below_stop_price: Option<rust_decimal::Decimal>,
///
/// The `pending_below_trailing_delta` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_below_trailing_delta: Option<rust_decimal::Decimal>,
/// This can only be used if `pendingBelowTimeInForce` is `GTC`.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_below_iceberg_qty: Option<rust_decimal::Decimal>,
///
/// The `pending_below_time_in_force` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pending_below_time_in_force: Option<String>,
}
impl MarginAccountNewOtocoParams {
/// Create a builder for [`margin_account_new_otoco`].
///
/// Required parameters:
///
/// * `symbol` — String
/// * `working_type` — Supported values: `LIMIT`, `LIMIT_MAKER`
/// * `working_side` — BUY, SELL
/// * `working_price` — `rust_decimal::Decimal`
/// * `working_quantity` — `rust_decimal::Decimal`
/// * `pending_side` — BUY, SELL
/// * `pending_quantity` — `rust_decimal::Decimal`
/// * `pending_above_type` — Supported values: `LIMIT_MAKER`, `STOP_LOSS`, and `STOP_LOSS_LIMIT`
///
#[must_use]
pub fn builder(
symbol: String,
working_type: String,
working_side: String,
working_price: rust_decimal::Decimal,
working_quantity: rust_decimal::Decimal,
pending_side: String,
pending_quantity: rust_decimal::Decimal,
pending_above_type: String,
) -> MarginAccountNewOtocoParamsBuilder {
MarginAccountNewOtocoParamsBuilder::default()
.symbol(symbol)
.working_type(working_type)
.working_side(working_side)
.working_price(working_price)
.working_quantity(working_quantity)
.pending_side(pending_side)
.pending_quantity(pending_quantity)
.pending_above_type(pending_above_type)
}
}
/// Request parameters for the [`margin_manual_liquidation`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`margin_manual_liquidation`](#method.margin_manual_liquidation).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct MarginManualLiquidationParams {
/// `MARGIN`,`ISOLATED`
///
/// This field is **required.
#[builder(setter(into))]
pub r#type: String,
/// isolated margin pair
///
/// This field is **optional.
#[builder(setter(into), default)]
pub symbol: Option<String>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl MarginManualLiquidationParams {
/// Create a builder for [`margin_manual_liquidation`].
///
/// Required parameters:
///
/// * `r#type` — `MARGIN`,`ISOLATED`
///
#[must_use]
pub fn builder(r#type: String) -> MarginManualLiquidationParamsBuilder {
MarginManualLiquidationParamsBuilder::default().r#type(r#type)
}
}
/// Request parameters for the [`query_current_margin_order_count_usage`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_current_margin_order_count_usage`](#method.query_current_margin_order_count_usage).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryCurrentMarginOrderCountUsageParams {
/// For isolated margin or not, "TRUE", "FALSE", default "FALSE"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub is_isolated: Option<String>,
/// isolated margin pair
///
/// This field is **optional.
#[builder(setter(into), default)]
pub symbol: Option<String>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl QueryCurrentMarginOrderCountUsageParams {
/// Create a builder for [`query_current_margin_order_count_usage`].
///
#[must_use]
pub fn builder() -> QueryCurrentMarginOrderCountUsageParamsBuilder {
QueryCurrentMarginOrderCountUsageParamsBuilder::default()
}
}
/// Request parameters for the [`query_margin_accounts_all_oco`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_margin_accounts_all_oco`](#method.query_margin_accounts_all_oco).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryMarginAccountsAllOcoParams {
/// For isolated margin or not, "TRUE", "FALSE", default "FALSE"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub is_isolated: Option<String>,
/// isolated margin pair
///
/// This field is **optional.
#[builder(setter(into), default)]
pub symbol: Option<String>,
/// If `fromId` is set, data with `id` greater than `fromId` will be returned. Otherwise, the latest data will be returned.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub from_id: Option<i64>,
/// Only supports querying data from the past 90 days.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub start_time: Option<i64>,
///
/// The `end_time` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub end_time: Option<i64>,
/// Limit on the number of data records returned per request. Default: 500; Maximum: 1000.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub limit: Option<i64>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl QueryMarginAccountsAllOcoParams {
/// Create a builder for [`query_margin_accounts_all_oco`].
///
#[must_use]
pub fn builder() -> QueryMarginAccountsAllOcoParamsBuilder {
QueryMarginAccountsAllOcoParamsBuilder::default()
}
}
/// Request parameters for the [`query_margin_accounts_all_orders`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_margin_accounts_all_orders`](#method.query_margin_accounts_all_orders).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryMarginAccountsAllOrdersParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
/// For isolated margin or not, "TRUE", "FALSE", default "FALSE"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub is_isolated: Option<String>,
///
/// The `order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub order_id: Option<i64>,
/// Only supports querying data from the past 90 days.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub start_time: Option<i64>,
///
/// The `end_time` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub end_time: Option<i64>,
/// Limit on the number of data records returned per request. Default: 500; Maximum: 1000.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub limit: Option<i64>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl QueryMarginAccountsAllOrdersParams {
/// Create a builder for [`query_margin_accounts_all_orders`].
///
/// Required parameters:
///
/// * `symbol` — String
///
#[must_use]
pub fn builder(symbol: String) -> QueryMarginAccountsAllOrdersParamsBuilder {
QueryMarginAccountsAllOrdersParamsBuilder::default().symbol(symbol)
}
}
/// Request parameters for the [`query_margin_accounts_oco`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_margin_accounts_oco`](#method.query_margin_accounts_oco).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryMarginAccountsOcoParams {
/// For isolated margin or not, "TRUE", "FALSE", default "FALSE"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub is_isolated: Option<String>,
/// isolated margin pair
///
/// This field is **optional.
#[builder(setter(into), default)]
pub symbol: Option<String>,
/// Either `orderListId` or `listClientOrderId` must be provided
///
/// This field is **optional.
#[builder(setter(into), default)]
pub order_list_id: Option<i64>,
///
/// The `orig_client_order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub orig_client_order_id: Option<String>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl QueryMarginAccountsOcoParams {
/// Create a builder for [`query_margin_accounts_oco`].
///
#[must_use]
pub fn builder() -> QueryMarginAccountsOcoParamsBuilder {
QueryMarginAccountsOcoParamsBuilder::default()
}
}
/// Request parameters for the [`query_margin_accounts_open_oco`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_margin_accounts_open_oco`](#method.query_margin_accounts_open_oco).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryMarginAccountsOpenOcoParams {
/// For isolated margin or not, "TRUE", "FALSE", default "FALSE"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub is_isolated: Option<String>,
/// isolated margin pair
///
/// This field is **optional.
#[builder(setter(into), default)]
pub symbol: Option<String>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl QueryMarginAccountsOpenOcoParams {
/// Create a builder for [`query_margin_accounts_open_oco`].
///
#[must_use]
pub fn builder() -> QueryMarginAccountsOpenOcoParamsBuilder {
QueryMarginAccountsOpenOcoParamsBuilder::default()
}
}
/// Request parameters for the [`query_margin_accounts_open_orders`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_margin_accounts_open_orders`](#method.query_margin_accounts_open_orders).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryMarginAccountsOpenOrdersParams {
/// isolated margin pair
///
/// This field is **optional.
#[builder(setter(into), default)]
pub symbol: Option<String>,
/// For isolated margin or not, "TRUE", "FALSE", default "FALSE"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub is_isolated: Option<String>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl QueryMarginAccountsOpenOrdersParams {
/// Create a builder for [`query_margin_accounts_open_orders`].
///
#[must_use]
pub fn builder() -> QueryMarginAccountsOpenOrdersParamsBuilder {
QueryMarginAccountsOpenOrdersParamsBuilder::default()
}
}
/// Request parameters for the [`query_margin_accounts_order`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_margin_accounts_order`](#method.query_margin_accounts_order).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryMarginAccountsOrderParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
/// For isolated margin or not, "TRUE", "FALSE", default "FALSE"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub is_isolated: Option<String>,
///
/// The `order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub order_id: Option<i64>,
///
/// The `orig_client_order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub orig_client_order_id: Option<String>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl QueryMarginAccountsOrderParams {
/// Create a builder for [`query_margin_accounts_order`].
///
/// Required parameters:
///
/// * `symbol` — String
///
#[must_use]
pub fn builder(symbol: String) -> QueryMarginAccountsOrderParamsBuilder {
QueryMarginAccountsOrderParamsBuilder::default().symbol(symbol)
}
}
/// Request parameters for the [`query_margin_accounts_trade_list`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_margin_accounts_trade_list`](#method.query_margin_accounts_trade_list).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryMarginAccountsTradeListParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
/// For isolated margin or not, "TRUE", "FALSE", default "FALSE"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub is_isolated: Option<String>,
///
/// The `order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub order_id: Option<i64>,
/// Only supports querying data from the past 90 days.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub start_time: Option<i64>,
///
/// The `end_time` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub end_time: Option<i64>,
/// If `fromId` is set, data with `id` greater than `fromId` will be returned. Otherwise, the latest data will be returned.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub from_id: Option<i64>,
/// Limit on the number of data records returned per request. Default: 500; Maximum: 1000.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub limit: Option<i64>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl QueryMarginAccountsTradeListParams {
/// Create a builder for [`query_margin_accounts_trade_list`].
///
/// Required parameters:
///
/// * `symbol` — String
///
#[must_use]
pub fn builder(symbol: String) -> QueryMarginAccountsTradeListParamsBuilder {
QueryMarginAccountsTradeListParamsBuilder::default().symbol(symbol)
}
}
/// Request parameters for the [`query_prevented_matches`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_prevented_matches`](#method.query_prevented_matches).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryPreventedMatchesParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
///
/// The `prevented_match_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub prevented_match_id: Option<i64>,
///
/// The `order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub order_id: Option<i64>,
///
/// The `from_prevented_match_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub from_prevented_match_id: Option<i64>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
/// For isolated margin or not, "TRUE", "FALSE", default "FALSE"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub is_isolated: Option<String>,
}
impl QueryPreventedMatchesParams {
/// Create a builder for [`query_prevented_matches`].
///
/// Required parameters:
///
/// * `symbol` — String
///
#[must_use]
pub fn builder(symbol: String) -> QueryPreventedMatchesParamsBuilder {
QueryPreventedMatchesParamsBuilder::default().symbol(symbol)
}
}
/// Request parameters for the [`query_special_key`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_special_key`](#method.query_special_key).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QuerySpecialKeyParams {
/// isolated margin pair
///
/// This field is **optional.
#[builder(setter(into), default)]
pub symbol: Option<String>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl QuerySpecialKeyParams {
/// Create a builder for [`query_special_key`].
///
#[must_use]
pub fn builder() -> QuerySpecialKeyParamsBuilder {
QuerySpecialKeyParamsBuilder::default()
}
}
/// Request parameters for the [`query_special_key_list`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_special_key_list`](#method.query_special_key_list).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QuerySpecialKeyListParams {
/// isolated margin pair
///
/// This field is **optional.
#[builder(setter(into), default)]
pub symbol: Option<String>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl QuerySpecialKeyListParams {
/// Create a builder for [`query_special_key_list`].
///
#[must_use]
pub fn builder() -> QuerySpecialKeyListParamsBuilder {
QuerySpecialKeyListParamsBuilder::default()
}
}
/// Request parameters for the [`small_liability_exchange`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`small_liability_exchange`](#method.small_liability_exchange).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct SmallLiabilityExchangeParams {
/// The assets list of small liability exchange, Example: assetNames = BTC,ETH
///
/// This field is **required.
#[builder(setter(into))]
pub asset_names: Vec<String>,
/// No more than 60000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl SmallLiabilityExchangeParams {
/// Create a builder for [`small_liability_exchange`].
///
/// Required parameters:
///
/// * `asset_names` — The assets list of small liability exchange, Example: assetNames = BTC,ETH
///
#[must_use]
pub fn builder(asset_names: Vec<String>) -> SmallLiabilityExchangeParamsBuilder {
SmallLiabilityExchangeParamsBuilder::default().asset_names(asset_names)
}
}
#[async_trait]
impl TradeApi for TradeApiClient {
async fn create_special_key(
&self,
params: CreateSpecialKeyParams,
) -> anyhow::Result<RestApiResponse<models::CreateSpecialKeyResponse>> {
let CreateSpecialKeyParams {
api_name,
symbol,
ip,
public_key,
permission_mode,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("apiName".to_string(), json!(api_name));
if let Some(rw) = symbol {
query_params.insert("symbol".to_string(), json!(rw));
}
if let Some(rw) = ip {
query_params.insert("ip".to_string(), json!(rw));
}
if let Some(rw) = public_key {
query_params.insert("publicKey".to_string(), json!(rw));
}
if let Some(rw) = permission_mode {
query_params.insert("permissionMode".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::CreateSpecialKeyResponse>(
&self.configuration,
"/sapi/v1/margin/apiKey",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn delete_special_key(
&self,
params: DeleteSpecialKeyParams,
) -> anyhow::Result<RestApiResponse<Value>> {
let DeleteSpecialKeyParams {
api_name,
symbol,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = api_name {
query_params.insert("apiName".to_string(), json!(rw));
}
if let Some(rw) = symbol {
query_params.insert("symbol".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Value>(
&self.configuration,
"/sapi/v1/margin/apiKey",
reqwest::Method::DELETE,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn edit_ip_for_special_key(
&self,
params: EditIpForSpecialKeyParams,
) -> anyhow::Result<RestApiResponse<Value>> {
let EditIpForSpecialKeyParams {
ip,
symbol,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = symbol {
query_params.insert("symbol".to_string(), json!(rw));
}
query_params.insert("ip".to_string(), json!(ip));
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Value>(
&self.configuration,
"/sapi/v1/margin/apiKey/ip",
reqwest::Method::PUT,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn get_force_liquidation_record(
&self,
params: GetForceLiquidationRecordParams,
) -> anyhow::Result<RestApiResponse<models::GetForceLiquidationRecordResponse>> {
let GetForceLiquidationRecordParams {
start_time,
end_time,
isolated_symbol,
current,
size,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = start_time {
query_params.insert("startTime".to_string(), json!(rw));
}
if let Some(rw) = end_time {
query_params.insert("endTime".to_string(), json!(rw));
}
if let Some(rw) = isolated_symbol {
query_params.insert("isolatedSymbol".to_string(), json!(rw));
}
if let Some(rw) = current {
query_params.insert("current".to_string(), json!(rw));
}
if let Some(rw) = size {
query_params.insert("size".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::GetForceLiquidationRecordResponse>(
&self.configuration,
"/sapi/v1/margin/forceLiquidationRec",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn get_small_liability_exchange_coin_list(
&self,
params: GetSmallLiabilityExchangeCoinListParams,
) -> anyhow::Result<RestApiResponse<Vec<models::GetSmallLiabilityExchangeCoinListResponseInner>>>
{
let GetSmallLiabilityExchangeCoinListParams { recv_window } = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::GetSmallLiabilityExchangeCoinListResponseInner>>(
&self.configuration,
"/sapi/v1/margin/exchange-small-liability",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn get_small_liability_exchange_history(
&self,
params: GetSmallLiabilityExchangeHistoryParams,
) -> anyhow::Result<RestApiResponse<models::GetSmallLiabilityExchangeHistoryResponse>> {
let GetSmallLiabilityExchangeHistoryParams {
current,
size,
start_time,
end_time,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("current".to_string(), json!(current));
query_params.insert("size".to_string(), json!(size));
if let Some(rw) = start_time {
query_params.insert("startTime".to_string(), json!(rw));
}
if let Some(rw) = end_time {
query_params.insert("endTime".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::GetSmallLiabilityExchangeHistoryResponse>(
&self.configuration,
"/sapi/v1/margin/exchange-small-liability-history",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn margin_account_cancel_all_open_orders_on_a_symbol(
&self,
params: MarginAccountCancelAllOpenOrdersOnASymbolParams,
) -> anyhow::Result<
RestApiResponse<Vec<models::MarginAccountCancelAllOpenOrdersOnASymbolResponseInner>>,
> {
let MarginAccountCancelAllOpenOrdersOnASymbolParams {
symbol,
is_isolated,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("symbol".to_string(), json!(symbol));
if let Some(rw) = is_isolated {
query_params.insert("isIsolated".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::MarginAccountCancelAllOpenOrdersOnASymbolResponseInner>>(
&self.configuration,
"/sapi/v1/margin/openOrders",
reqwest::Method::DELETE,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn margin_account_cancel_oco(
&self,
params: MarginAccountCancelOcoParams,
) -> anyhow::Result<RestApiResponse<models::MarginAccountCancelOcoResponse>> {
let MarginAccountCancelOcoParams {
symbol,
is_isolated,
order_list_id,
list_client_order_id,
new_client_order_id,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("symbol".to_string(), json!(symbol));
if let Some(rw) = is_isolated {
query_params.insert("isIsolated".to_string(), json!(rw));
}
if let Some(rw) = order_list_id {
query_params.insert("orderListId".to_string(), json!(rw));
}
if let Some(rw) = list_client_order_id {
query_params.insert("listClientOrderId".to_string(), json!(rw));
}
if let Some(rw) = new_client_order_id {
query_params.insert("newClientOrderId".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::MarginAccountCancelOcoResponse>(
&self.configuration,
"/sapi/v1/margin/orderList",
reqwest::Method::DELETE,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn margin_account_cancel_order(
&self,
params: MarginAccountCancelOrderParams,
) -> anyhow::Result<RestApiResponse<models::MarginAccountCancelOrderResponse>> {
let MarginAccountCancelOrderParams {
symbol,
is_isolated,
order_id,
orig_client_order_id,
new_client_order_id,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("symbol".to_string(), json!(symbol));
if let Some(rw) = is_isolated {
query_params.insert("isIsolated".to_string(), json!(rw));
}
if let Some(rw) = order_id {
query_params.insert("orderId".to_string(), json!(rw));
}
if let Some(rw) = orig_client_order_id {
query_params.insert("origClientOrderId".to_string(), json!(rw));
}
if let Some(rw) = new_client_order_id {
query_params.insert("newClientOrderId".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::MarginAccountCancelOrderResponse>(
&self.configuration,
"/sapi/v1/margin/order",
reqwest::Method::DELETE,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn margin_account_new_oco(
&self,
params: MarginAccountNewOcoParams,
) -> anyhow::Result<RestApiResponse<models::MarginAccountNewOcoResponse>> {
let MarginAccountNewOcoParams {
symbol,
side,
quantity,
price,
stop_price,
is_isolated,
list_client_order_id,
limit_client_order_id,
limit_iceberg_qty,
stop_client_order_id,
stop_limit_price,
stop_iceberg_qty,
stop_limit_time_in_force,
new_order_resp_type,
side_effect_type,
self_trade_prevention_mode,
auto_repay_at_cancel,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("symbol".to_string(), json!(symbol));
if let Some(rw) = is_isolated {
query_params.insert("isIsolated".to_string(), json!(rw));
}
if let Some(rw) = list_client_order_id {
query_params.insert("listClientOrderId".to_string(), json!(rw));
}
query_params.insert("side".to_string(), json!(side));
query_params.insert("quantity".to_string(), json!(quantity));
if let Some(rw) = limit_client_order_id {
query_params.insert("limitClientOrderId".to_string(), json!(rw));
}
query_params.insert("price".to_string(), json!(price));
if let Some(rw) = limit_iceberg_qty {
query_params.insert("limitIcebergQty".to_string(), json!(rw));
}
if let Some(rw) = stop_client_order_id {
query_params.insert("stopClientOrderId".to_string(), json!(rw));
}
query_params.insert("stopPrice".to_string(), json!(stop_price));
if let Some(rw) = stop_limit_price {
query_params.insert("stopLimitPrice".to_string(), json!(rw));
}
if let Some(rw) = stop_iceberg_qty {
query_params.insert("stopIcebergQty".to_string(), json!(rw));
}
if let Some(rw) = stop_limit_time_in_force {
query_params.insert("stopLimitTimeInForce".to_string(), json!(rw));
}
if let Some(rw) = new_order_resp_type {
query_params.insert("newOrderRespType".to_string(), json!(rw));
}
if let Some(rw) = side_effect_type {
query_params.insert("sideEffectType".to_string(), json!(rw));
}
if let Some(rw) = self_trade_prevention_mode {
query_params.insert("selfTradePreventionMode".to_string(), json!(rw));
}
if let Some(rw) = auto_repay_at_cancel {
query_params.insert("autoRepayAtCancel".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::MarginAccountNewOcoResponse>(
&self.configuration,
"/sapi/v1/margin/order/oco",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn margin_account_new_order(
&self,
params: MarginAccountNewOrderParams,
) -> anyhow::Result<RestApiResponse<models::MarginAccountNewOrderResponse>> {
let MarginAccountNewOrderParams {
symbol,
side,
r#type,
is_isolated,
quantity,
quote_order_qty,
price,
stop_price,
new_client_order_id,
iceberg_qty,
new_order_resp_type,
side_effect_type,
time_in_force,
self_trade_prevention_mode,
auto_repay_at_cancel,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("symbol".to_string(), json!(symbol));
if let Some(rw) = is_isolated {
query_params.insert("isIsolated".to_string(), json!(rw));
}
query_params.insert("side".to_string(), json!(side));
query_params.insert("type".to_string(), json!(r#type));
if let Some(rw) = quantity {
query_params.insert("quantity".to_string(), json!(rw));
}
if let Some(rw) = quote_order_qty {
query_params.insert("quoteOrderQty".to_string(), json!(rw));
}
if let Some(rw) = price {
query_params.insert("price".to_string(), json!(rw));
}
if let Some(rw) = stop_price {
query_params.insert("stopPrice".to_string(), json!(rw));
}
if let Some(rw) = new_client_order_id {
query_params.insert("newClientOrderId".to_string(), json!(rw));
}
if let Some(rw) = iceberg_qty {
query_params.insert("icebergQty".to_string(), json!(rw));
}
if let Some(rw) = new_order_resp_type {
query_params.insert("newOrderRespType".to_string(), json!(rw));
}
if let Some(rw) = side_effect_type {
query_params.insert("sideEffectType".to_string(), json!(rw));
}
if let Some(rw) = time_in_force {
query_params.insert("timeInForce".to_string(), json!(rw));
}
if let Some(rw) = self_trade_prevention_mode {
query_params.insert("selfTradePreventionMode".to_string(), json!(rw));
}
if let Some(rw) = auto_repay_at_cancel {
query_params.insert("autoRepayAtCancel".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::MarginAccountNewOrderResponse>(
&self.configuration,
"/sapi/v1/margin/order",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn margin_account_new_oto(
&self,
params: MarginAccountNewOtoParams,
) -> anyhow::Result<RestApiResponse<models::MarginAccountNewOtoResponse>> {
let MarginAccountNewOtoParams {
symbol,
working_type,
working_side,
working_price,
working_quantity,
working_iceberg_qty,
pending_type,
pending_side,
pending_quantity,
is_isolated,
list_client_order_id,
new_order_resp_type,
side_effect_type,
self_trade_prevention_mode,
auto_repay_at_cancel,
working_client_order_id,
working_time_in_force,
pending_client_order_id,
pending_price,
pending_stop_price,
pending_trailing_delta,
pending_iceberg_qty,
pending_time_in_force,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("symbol".to_string(), json!(symbol));
if let Some(rw) = is_isolated {
query_params.insert("isIsolated".to_string(), json!(rw));
}
if let Some(rw) = list_client_order_id {
query_params.insert("listClientOrderId".to_string(), json!(rw));
}
if let Some(rw) = new_order_resp_type {
query_params.insert("newOrderRespType".to_string(), json!(rw));
}
if let Some(rw) = side_effect_type {
query_params.insert("sideEffectType".to_string(), json!(rw));
}
if let Some(rw) = self_trade_prevention_mode {
query_params.insert("selfTradePreventionMode".to_string(), json!(rw));
}
if let Some(rw) = auto_repay_at_cancel {
query_params.insert("autoRepayAtCancel".to_string(), json!(rw));
}
query_params.insert("workingType".to_string(), json!(working_type));
query_params.insert("workingSide".to_string(), json!(working_side));
if let Some(rw) = working_client_order_id {
query_params.insert("workingClientOrderId".to_string(), json!(rw));
}
query_params.insert("workingPrice".to_string(), json!(working_price));
query_params.insert("workingQuantity".to_string(), json!(working_quantity));
query_params.insert("workingIcebergQty".to_string(), json!(working_iceberg_qty));
if let Some(rw) = working_time_in_force {
query_params.insert("workingTimeInForce".to_string(), json!(rw));
}
query_params.insert("pendingType".to_string(), json!(pending_type));
query_params.insert("pendingSide".to_string(), json!(pending_side));
if let Some(rw) = pending_client_order_id {
query_params.insert("pendingClientOrderId".to_string(), json!(rw));
}
if let Some(rw) = pending_price {
query_params.insert("pendingPrice".to_string(), json!(rw));
}
if let Some(rw) = pending_stop_price {
query_params.insert("pendingStopPrice".to_string(), json!(rw));
}
if let Some(rw) = pending_trailing_delta {
query_params.insert("pendingTrailingDelta".to_string(), json!(rw));
}
query_params.insert("pendingQuantity".to_string(), json!(pending_quantity));
if let Some(rw) = pending_iceberg_qty {
query_params.insert("pendingIcebergQty".to_string(), json!(rw));
}
if let Some(rw) = pending_time_in_force {
query_params.insert("pendingTimeInForce".to_string(), json!(rw));
}
send_request::<models::MarginAccountNewOtoResponse>(
&self.configuration,
"/sapi/v1/margin/order/oto",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn margin_account_new_otoco(
&self,
params: MarginAccountNewOtocoParams,
) -> anyhow::Result<RestApiResponse<models::MarginAccountNewOtocoResponse>> {
let MarginAccountNewOtocoParams {
symbol,
working_type,
working_side,
working_price,
working_quantity,
pending_side,
pending_quantity,
pending_above_type,
is_isolated,
side_effect_type,
auto_repay_at_cancel,
list_client_order_id,
new_order_resp_type,
self_trade_prevention_mode,
working_client_order_id,
working_iceberg_qty,
working_time_in_force,
pending_above_client_order_id,
pending_above_price,
pending_above_stop_price,
pending_above_trailing_delta,
pending_above_iceberg_qty,
pending_above_time_in_force,
pending_below_type,
pending_below_client_order_id,
pending_below_price,
pending_below_stop_price,
pending_below_trailing_delta,
pending_below_iceberg_qty,
pending_below_time_in_force,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("symbol".to_string(), json!(symbol));
if let Some(rw) = is_isolated {
query_params.insert("isIsolated".to_string(), json!(rw));
}
if let Some(rw) = side_effect_type {
query_params.insert("sideEffectType".to_string(), json!(rw));
}
if let Some(rw) = auto_repay_at_cancel {
query_params.insert("autoRepayAtCancel".to_string(), json!(rw));
}
if let Some(rw) = list_client_order_id {
query_params.insert("listClientOrderId".to_string(), json!(rw));
}
if let Some(rw) = new_order_resp_type {
query_params.insert("newOrderRespType".to_string(), json!(rw));
}
if let Some(rw) = self_trade_prevention_mode {
query_params.insert("selfTradePreventionMode".to_string(), json!(rw));
}
query_params.insert("workingType".to_string(), json!(working_type));
query_params.insert("workingSide".to_string(), json!(working_side));
if let Some(rw) = working_client_order_id {
query_params.insert("workingClientOrderId".to_string(), json!(rw));
}
query_params.insert("workingPrice".to_string(), json!(working_price));
query_params.insert("workingQuantity".to_string(), json!(working_quantity));
if let Some(rw) = working_iceberg_qty {
query_params.insert("workingIcebergQty".to_string(), json!(rw));
}
if let Some(rw) = working_time_in_force {
query_params.insert("workingTimeInForce".to_string(), json!(rw));
}
query_params.insert("pendingSide".to_string(), json!(pending_side));
query_params.insert("pendingQuantity".to_string(), json!(pending_quantity));
query_params.insert("pendingAboveType".to_string(), json!(pending_above_type));
if let Some(rw) = pending_above_client_order_id {
query_params.insert("pendingAboveClientOrderId".to_string(), json!(rw));
}
if let Some(rw) = pending_above_price {
query_params.insert("pendingAbovePrice".to_string(), json!(rw));
}
if let Some(rw) = pending_above_stop_price {
query_params.insert("pendingAboveStopPrice".to_string(), json!(rw));
}
if let Some(rw) = pending_above_trailing_delta {
query_params.insert("pendingAboveTrailingDelta".to_string(), json!(rw));
}
if let Some(rw) = pending_above_iceberg_qty {
query_params.insert("pendingAboveIcebergQty".to_string(), json!(rw));
}
if let Some(rw) = pending_above_time_in_force {
query_params.insert("pendingAboveTimeInForce".to_string(), json!(rw));
}
if let Some(rw) = pending_below_type {
query_params.insert("pendingBelowType".to_string(), json!(rw));
}
if let Some(rw) = pending_below_client_order_id {
query_params.insert("pendingBelowClientOrderId".to_string(), json!(rw));
}
if let Some(rw) = pending_below_price {
query_params.insert("pendingBelowPrice".to_string(), json!(rw));
}
if let Some(rw) = pending_below_stop_price {
query_params.insert("pendingBelowStopPrice".to_string(), json!(rw));
}
if let Some(rw) = pending_below_trailing_delta {
query_params.insert("pendingBelowTrailingDelta".to_string(), json!(rw));
}
if let Some(rw) = pending_below_iceberg_qty {
query_params.insert("pendingBelowIcebergQty".to_string(), json!(rw));
}
if let Some(rw) = pending_below_time_in_force {
query_params.insert("pendingBelowTimeInForce".to_string(), json!(rw));
}
send_request::<models::MarginAccountNewOtocoResponse>(
&self.configuration,
"/sapi/v1/margin/order/otoco",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn margin_manual_liquidation(
&self,
params: MarginManualLiquidationParams,
) -> anyhow::Result<RestApiResponse<models::MarginManualLiquidationResponse>> {
let MarginManualLiquidationParams {
r#type,
symbol,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("type".to_string(), json!(r#type));
if let Some(rw) = symbol {
query_params.insert("symbol".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::MarginManualLiquidationResponse>(
&self.configuration,
"/sapi/v1/margin/manual-liquidation",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn query_current_margin_order_count_usage(
&self,
params: QueryCurrentMarginOrderCountUsageParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryCurrentMarginOrderCountUsageResponseInner>>>
{
let QueryCurrentMarginOrderCountUsageParams {
is_isolated,
symbol,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = is_isolated {
query_params.insert("isIsolated".to_string(), json!(rw));
}
if let Some(rw) = symbol {
query_params.insert("symbol".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::QueryCurrentMarginOrderCountUsageResponseInner>>(
&self.configuration,
"/sapi/v1/margin/rateLimit/order",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn query_margin_accounts_all_oco(
&self,
params: QueryMarginAccountsAllOcoParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryMarginAccountsAllOcoResponseInner>>> {
let QueryMarginAccountsAllOcoParams {
is_isolated,
symbol,
from_id,
start_time,
end_time,
limit,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = is_isolated {
query_params.insert("isIsolated".to_string(), json!(rw));
}
if let Some(rw) = symbol {
query_params.insert("symbol".to_string(), json!(rw));
}
if let Some(rw) = from_id {
query_params.insert("fromId".to_string(), json!(rw));
}
if let Some(rw) = start_time {
query_params.insert("startTime".to_string(), json!(rw));
}
if let Some(rw) = end_time {
query_params.insert("endTime".to_string(), json!(rw));
}
if let Some(rw) = limit {
query_params.insert("limit".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::QueryMarginAccountsAllOcoResponseInner>>(
&self.configuration,
"/sapi/v1/margin/allOrderList",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn query_margin_accounts_all_orders(
&self,
params: QueryMarginAccountsAllOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryMarginAccountsAllOrdersResponseInner>>>
{
let QueryMarginAccountsAllOrdersParams {
symbol,
is_isolated,
order_id,
start_time,
end_time,
limit,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("symbol".to_string(), json!(symbol));
if let Some(rw) = is_isolated {
query_params.insert("isIsolated".to_string(), json!(rw));
}
if let Some(rw) = order_id {
query_params.insert("orderId".to_string(), json!(rw));
}
if let Some(rw) = start_time {
query_params.insert("startTime".to_string(), json!(rw));
}
if let Some(rw) = end_time {
query_params.insert("endTime".to_string(), json!(rw));
}
if let Some(rw) = limit {
query_params.insert("limit".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::QueryMarginAccountsAllOrdersResponseInner>>(
&self.configuration,
"/sapi/v1/margin/allOrders",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn query_margin_accounts_oco(
&self,
params: QueryMarginAccountsOcoParams,
) -> anyhow::Result<RestApiResponse<models::QueryMarginAccountsOcoResponse>> {
let QueryMarginAccountsOcoParams {
is_isolated,
symbol,
order_list_id,
orig_client_order_id,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = is_isolated {
query_params.insert("isIsolated".to_string(), json!(rw));
}
if let Some(rw) = symbol {
query_params.insert("symbol".to_string(), json!(rw));
}
if let Some(rw) = order_list_id {
query_params.insert("orderListId".to_string(), json!(rw));
}
if let Some(rw) = orig_client_order_id {
query_params.insert("origClientOrderId".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::QueryMarginAccountsOcoResponse>(
&self.configuration,
"/sapi/v1/margin/orderList",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn query_margin_accounts_open_oco(
&self,
params: QueryMarginAccountsOpenOcoParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryMarginAccountsOpenOcoResponseInner>>> {
let QueryMarginAccountsOpenOcoParams {
is_isolated,
symbol,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = is_isolated {
query_params.insert("isIsolated".to_string(), json!(rw));
}
if let Some(rw) = symbol {
query_params.insert("symbol".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::QueryMarginAccountsOpenOcoResponseInner>>(
&self.configuration,
"/sapi/v1/margin/openOrderList",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn query_margin_accounts_open_orders(
&self,
params: QueryMarginAccountsOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryMarginAccountsOpenOrdersResponseInner>>>
{
let QueryMarginAccountsOpenOrdersParams {
symbol,
is_isolated,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = symbol {
query_params.insert("symbol".to_string(), json!(rw));
}
if let Some(rw) = is_isolated {
query_params.insert("isIsolated".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::QueryMarginAccountsOpenOrdersResponseInner>>(
&self.configuration,
"/sapi/v1/margin/openOrders",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn query_margin_accounts_order(
&self,
params: QueryMarginAccountsOrderParams,
) -> anyhow::Result<RestApiResponse<models::QueryMarginAccountsOrderResponse>> {
let QueryMarginAccountsOrderParams {
symbol,
is_isolated,
order_id,
orig_client_order_id,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("symbol".to_string(), json!(symbol));
if let Some(rw) = is_isolated {
query_params.insert("isIsolated".to_string(), json!(rw));
}
if let Some(rw) = order_id {
query_params.insert("orderId".to_string(), json!(rw));
}
if let Some(rw) = orig_client_order_id {
query_params.insert("origClientOrderId".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::QueryMarginAccountsOrderResponse>(
&self.configuration,
"/sapi/v1/margin/order",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn query_margin_accounts_trade_list(
&self,
params: QueryMarginAccountsTradeListParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryMarginAccountsTradeListResponseInner>>>
{
let QueryMarginAccountsTradeListParams {
symbol,
is_isolated,
order_id,
start_time,
end_time,
from_id,
limit,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("symbol".to_string(), json!(symbol));
if let Some(rw) = is_isolated {
query_params.insert("isIsolated".to_string(), json!(rw));
}
if let Some(rw) = order_id {
query_params.insert("orderId".to_string(), json!(rw));
}
if let Some(rw) = start_time {
query_params.insert("startTime".to_string(), json!(rw));
}
if let Some(rw) = end_time {
query_params.insert("endTime".to_string(), json!(rw));
}
if let Some(rw) = from_id {
query_params.insert("fromId".to_string(), json!(rw));
}
if let Some(rw) = limit {
query_params.insert("limit".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::QueryMarginAccountsTradeListResponseInner>>(
&self.configuration,
"/sapi/v1/margin/myTrades",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn query_prevented_matches(
&self,
params: QueryPreventedMatchesParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryPreventedMatchesResponseInner>>> {
let QueryPreventedMatchesParams {
symbol,
prevented_match_id,
order_id,
from_prevented_match_id,
recv_window,
is_isolated,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("symbol".to_string(), json!(symbol));
if let Some(rw) = prevented_match_id {
query_params.insert("preventedMatchId".to_string(), json!(rw));
}
if let Some(rw) = order_id {
query_params.insert("orderId".to_string(), json!(rw));
}
if let Some(rw) = from_prevented_match_id {
query_params.insert("fromPreventedMatchId".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
if let Some(rw) = is_isolated {
query_params.insert("isIsolated".to_string(), json!(rw));
}
send_request::<Vec<models::QueryPreventedMatchesResponseInner>>(
&self.configuration,
"/sapi/v1/margin/myPreventedMatches",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn query_special_key(
&self,
params: QuerySpecialKeyParams,
) -> anyhow::Result<RestApiResponse<models::QuerySpecialKeyResponse>> {
let QuerySpecialKeyParams {
symbol,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = symbol {
query_params.insert("symbol".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::QuerySpecialKeyResponse>(
&self.configuration,
"/sapi/v1/margin/apiKey",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn query_special_key_list(
&self,
params: QuerySpecialKeyListParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QuerySpecialKeyListResponseInner>>> {
let QuerySpecialKeyListParams {
symbol,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = symbol {
query_params.insert("symbol".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::QuerySpecialKeyListResponseInner>>(
&self.configuration,
"/sapi/v1/margin/api-key-list",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn small_liability_exchange(
&self,
params: SmallLiabilityExchangeParams,
) -> anyhow::Result<RestApiResponse<Value>> {
let SmallLiabilityExchangeParams {
asset_names,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("assetNames".to_string(), json!(asset_names));
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Value>(
&self.configuration,
"/sapi/v1/margin/exchange-small-liability",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
}
#[cfg(all(test, feature = "margin_trading"))]
mod tests {
use super::*;
use crate::TOKIO_SHARED_RT;
use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
use async_trait::async_trait;
use std::collections::HashMap;
struct DummyRestApiResponse<T> {
inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
status: u16,
headers: HashMap<String, String>,
rate_limits: Option<Vec<RestApiRateLimit>>,
}
impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
fn from(dummy: DummyRestApiResponse<T>) -> Self {
Self {
data_fn: dummy.inner,
status: dummy.status,
headers: dummy.headers,
rate_limits: dummy.rate_limits,
}
}
}
struct MockTradeApiClient {
force_error: bool,
}
#[async_trait]
impl TradeApi for MockTradeApiClient {
async fn create_special_key(
&self,
_params: CreateSpecialKeyParams,
) -> anyhow::Result<RestApiResponse<models::CreateSpecialKeyResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"apiKey":"npOzOAeLVgr2TuxWfNo43AaPWpBbJEoKezh1o8mSQb6ryE2odE11A4AoVlJbQoGx","secretKey":"87ssWB7azoy6ACRfyp6OVOL5U3rtZptX31QWw2kWjl1jHEYRbyM1pd6qykRBQw8p","type":"HMAC_SHA256"}"#).unwrap();
let dummy_response: models::CreateSpecialKeyResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::CreateSpecialKeyResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn delete_special_key(
&self,
_params: DeleteSpecialKeyParams,
) -> anyhow::Result<RestApiResponse<Value>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let dummy_response = Value::Null;
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn edit_ip_for_special_key(
&self,
_params: EditIpForSpecialKeyParams,
) -> anyhow::Result<RestApiResponse<Value>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let dummy_response = Value::Null;
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn get_force_liquidation_record(
&self,
_params: GetForceLiquidationRecordParams,
) -> anyhow::Result<RestApiResponse<models::GetForceLiquidationRecordResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"rows":[{"avgPrice":"0.00388359","executedQty":"31.39000000","orderId":180015097,"price":"0.00388110","qty":"31.39000000","side":"SELL","symbol":"BNBBTC","timeInForce":"GTC","isIsolated":true,"updatedTime":1558941374745}],"total":1}"#).unwrap();
let dummy_response: models::GetForceLiquidationRecordResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::GetForceLiquidationRecordResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn get_small_liability_exchange_coin_list(
&self,
_params: GetSmallLiabilityExchangeCoinListParams,
) -> anyhow::Result<
RestApiResponse<Vec<models::GetSmallLiabilityExchangeCoinListResponseInner>>,
> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"asset":"ETH","interest":"0.00083334","principal":"0.001","liabilityAsset":"USDT","liabilityQty":0.3552}]"#).unwrap();
let dummy_response: Vec<models::GetSmallLiabilityExchangeCoinListResponseInner> =
serde_json::from_value(resp_json.clone()).expect(
"should parse into Vec<models::GetSmallLiabilityExchangeCoinListResponseInner>",
);
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn get_small_liability_exchange_history(
&self,
_params: GetSmallLiabilityExchangeHistoryParams,
) -> anyhow::Result<RestApiResponse<models::GetSmallLiabilityExchangeHistoryResponse>>
{
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"total":1,"rows":[{"asset":"ETH","amount":"0.00083434","targetAsset":"BUSD","targetAmount":"1.37576819","bizType":"EXCHANGE_SMALL_LIABILITY","timestamp":1672801339253}]}"#).unwrap();
let dummy_response: models::GetSmallLiabilityExchangeHistoryResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::GetSmallLiabilityExchangeHistoryResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn margin_account_cancel_all_open_orders_on_a_symbol(
&self,
_params: MarginAccountCancelAllOpenOrdersOnASymbolParams,
) -> anyhow::Result<
RestApiResponse<Vec<models::MarginAccountCancelAllOpenOrdersOnASymbolResponseInner>>,
> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSDT","isIsolated":true,"origClientOrderId":"E6APeyTJvkMvLMYMqu1KQ4","orderId":11,"orderListId":-1,"clientOrderId":"pXLV6Hz6mprAcVYpVMTGgx","price":"0.089853","origQty":"0.178622","executedQty":"0.000000","cummulativeQuoteQty":"0.000000","status":"CANCELED","timeInForce":"GTC","type":"LIMIT","side":"BUY","selfTradePreventionMode":"NONE"},{"symbol":"BTCUSDT","isIsolated":false,"origClientOrderId":"A3EF2HCwxgZPFMrfwbgrhv","orderId":13,"orderListId":-1,"clientOrderId":"pXLV6Hz6mprAcVYpVMTGgx","price":"0.090430","origQty":"0.178622","executedQty":"0.000000","cummulativeQuoteQty":"0.000000","status":"CANCELED","timeInForce":"GTC","type":"LIMIT","side":"BUY","selfTradePreventionMode":"NONE"},{"orderListId":1929,"contingencyType":"OCO","listStatusType":"ALL_DONE","listOrderStatus":"ALL_DONE","listClientOrderId":"2inzWQdDvZLHbbAmAozX2N","transactionTime":1585230948299,"symbol":"BTCUSDT","isIsolated":true,"orders":[{"symbol":"BTCUSDT","orderId":20,"clientOrderId":"CwOOIPHSmYywx6jZX77TdL"},{"symbol":"BTCUSDT","orderId":21,"clientOrderId":"461cPg51vQjV3zIMOXNz39"}],"orderReports":[{"symbol":"BTCUSDT","origClientOrderId":"CwOOIPHSmYywx6jZX77TdL","orderId":20,"orderListId":1929,"clientOrderId":"pXLV6Hz6mprAcVYpVMTGgx","price":"0.668611","origQty":"0.690354","executedQty":"0.000000","cummulativeQuoteQty":"0.000000","status":"CANCELED","timeInForce":"GTC","type":"STOP_LOSS_LIMIT","side":"BUY","stopPrice":"0.378131","icebergQty":"0.017083"},{"symbol":"BTCUSDT","origClientOrderId":"461cPg51vQjV3zIMOXNz39","orderId":21,"orderListId":1929,"clientOrderId":"pXLV6Hz6mprAcVYpVMTGgx","price":"0.008791","origQty":"0.690354","executedQty":"0.000000","cummulativeQuoteQty":"0.000000","status":"CANCELED","timeInForce":"GTC","type":"LIMIT_MAKER","side":"BUY","icebergQty":"0.639962"}]}]"#).unwrap();
let dummy_response : Vec<models::MarginAccountCancelAllOpenOrdersOnASymbolResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::MarginAccountCancelAllOpenOrdersOnASymbolResponseInner>");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn margin_account_cancel_oco(
&self,
_params: MarginAccountCancelOcoParams,
) -> anyhow::Result<RestApiResponse<models::MarginAccountCancelOcoResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"orderListId":0,"contingencyType":"OCO","listStatusType":"ALL_DONE","listOrderStatus":"ALL_DONE","listClientOrderId":"C3wyj4WVEktd7u9aVBRXcN","transactionTime":1574040868128,"symbol":"LTCBTC","isIsolated":false,"orders":[{"symbol":"LTCBTC","orderId":2,"clientOrderId":"pO9ufTiFGg3nw2fOdgeOXa"},{"symbol":"LTCBTC","orderId":3,"clientOrderId":"TXOvglzXuaubXAaENpaRCB"}],"orderReports":[{"symbol":"LTCBTC","origClientOrderId":"pO9ufTiFGg3nw2fOdgeOXa","orderId":2,"orderListId":0,"clientOrderId":"unfWT8ig8i0uj6lPuYLez6","price":"1.00000000","origQty":"10.00000000","executedQty":"0.00000000","cummulativeQuoteQty":"0.00000000","status":"CANCELED","timeInForce":"GTC","type":"STOP_LOSS_LIMIT","side":"SELL","stopPrice":"1.00000000","selfTradePreventionMode":"NONE"},{"symbol":"LTCBTC","origClientOrderId":"TXOvglzXuaubXAaENpaRCB","orderId":3,"orderListId":0,"clientOrderId":"unfWT8ig8i0uj6lPuYLez6","price":"3.00000000","origQty":"10.00000000","executedQty":"0.00000000","cummulativeQuoteQty":"0.00000000","status":"CANCELED","timeInForce":"GTC","type":"LIMIT_MAKER","side":"SELL","selfTradePreventionMode":"NONE"}]}"#).unwrap();
let dummy_response: models::MarginAccountCancelOcoResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::MarginAccountCancelOcoResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn margin_account_cancel_order(
&self,
_params: MarginAccountCancelOrderParams,
) -> anyhow::Result<RestApiResponse<models::MarginAccountCancelOrderResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"symbol":"LTCBTC","isIsolated":true,"orderId":"28","origClientOrderId":"myOrder1","clientOrderId":"cancelMyOrder1","price":"1.00000000","origQty":"10.00000000","executedQty":"8.00000000","cummulativeQuoteQty":"8.00000000","status":"CANCELED","timeInForce":"GTC","type":"LIMIT","side":"SELL"}"#).unwrap();
let dummy_response: models::MarginAccountCancelOrderResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::MarginAccountCancelOrderResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn margin_account_new_oco(
&self,
_params: MarginAccountNewOcoParams,
) -> anyhow::Result<RestApiResponse<models::MarginAccountNewOcoResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"orderListId":0,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"JYVpp3F0f5CAG15DhtrqLp","transactionTime":1563417480525,"symbol":"LTCBTC","marginBuyBorrowAmount":"5","marginBuyBorrowAsset":"BTC","isIsolated":false,"orders":[{"symbol":"LTCBTC","orderId":2,"clientOrderId":"Kk7sqHb9J6mJWTMDVW7Vos"},{"symbol":"LTCBTC","orderId":3,"clientOrderId":"xTXKaGYd4bluPVp78IVRvl"}],"orderReports":[{"symbol":"LTCBTC","orderId":2,"orderListId":0,"clientOrderId":"Kk7sqHb9J6mJWTMDVW7Vos","transactTime":1563417480525,"price":"0.000000","origQty":"0.624363","executedQty":"0.000000","cummulativeQuoteQty":"0.000000","status":"NEW","timeInForce":"GTC","type":"STOP_LOSS","side":"BUY","stopPrice":"0.960664","selfTradePreventionMode":"NONE"},{"symbol":"LTCBTC","orderId":3,"orderListId":0,"clientOrderId":"xTXKaGYd4bluPVp78IVRvl","transactTime":1563417480525,"price":"0.036435","origQty":"0.624363","executedQty":"0.000000","cummulativeQuoteQty":"0.000000","status":"NEW","timeInForce":"GTC","type":"LIMIT_MAKER","side":"BUY","selfTradePreventionMode":"NONE"}]}"#).unwrap();
let dummy_response: models::MarginAccountNewOcoResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::MarginAccountNewOcoResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn margin_account_new_order(
&self,
_params: MarginAccountNewOrderParams,
) -> anyhow::Result<RestApiResponse<models::MarginAccountNewOrderResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"symbol":"BTCUSDT","orderId":26769564559,"clientOrderId":"E156O3KP4gOif65bjuUK5V","isIsolated":false,"transactTime":1713873075893,"price":"0","origQty":"0.001","executedQty":"0.001","cummulativeQuoteQty":"65.98253","status":"FILLED","timeInForce":"GTC","type":"MARKET","side":"SELL","selfTradePreventionMode":"EXPIRE_MAKER","marginBuyBorrowAmount":5,"marginBuyBorrowAsset":"BTC","fills":[{"price":"65982.53","qty":"0.001","commission":"0.06598253","commissionAsset":"USDT","tradeId":3570680726}]}"#).unwrap();
let dummy_response: models::MarginAccountNewOrderResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::MarginAccountNewOrderResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn margin_account_new_oto(
&self,
_params: MarginAccountNewOtoParams,
) -> anyhow::Result<RestApiResponse<models::MarginAccountNewOtoResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"orderListId":13551,"contingencyType":"OTO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"JDuOrsu0Ge8GTyvx8J7VTD","transactionTime":1725521998054,"symbol":"BTCUSDT","isIsolated":false,"orders":[{"symbol":"BTCUSDT","orderId":29896699,"clientOrderId":"y8RB6tQEMuHUXybqbtzTxk"},{"symbol":"BTCUSDT","orderId":29896700,"clientOrderId":"dKQEdh5HhXb7Lpp85jz1dQ"}],"orderReports":[{"symbol":"BTCUSDT","orderId":29896699,"orderListId":13551,"clientOrderId":"y8RB6tQEMuHUXybqbtzTxk","transactTime":1725521998054,"price":"80000.00000000","origQty":"0.02000000","executedQty":"0","cummulativeQuoteQty":"0","status":"NEW","timeInForce":"GTC","type":"LIMIT","side":"SELL","selfTradePreventionMode":"NONE"},{"symbol":"BTCUSDT","orderId":29896700,"orderListId":13551,"clientOrderId":"dKQEdh5HhXb7Lpp85jz1dQ","transactTime":1725521998054,"price":"50000.00000000","origQty":"0.02000000","executedQty":"0","cummulativeQuoteQty":"0","status":"PENDING_NEW","timeInForce":"GTC","type":"LIMIT","side":"BUY","selfTradePreventionMode":"NONE"}]}"#).unwrap();
let dummy_response: models::MarginAccountNewOtoResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::MarginAccountNewOtoResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn margin_account_new_otoco(
&self,
_params: MarginAccountNewOtocoParams,
) -> anyhow::Result<RestApiResponse<models::MarginAccountNewOtocoResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"orderListId":13509,"contingencyType":"OTO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"u2AUo48LLef5qVenRtwJZy","transactionTime":1725521881300,"symbol":"BNBUSDT","isIsolated":false,"orders":[{"symbol":"BNBUSDT","orderId":28282534,"clientOrderId":"IfYDxvrZI4kiyqYpRH13iI"},{"symbol":"BNBUSDT","orderId":28282535,"clientOrderId":"0HCSsPRxVfW8BkTUy9z4np"},{"symbol":"BNBUSDT","orderId":28282536,"clientOrderId":"dypsgdxWnLY75kwT930cbD"}],"orderReports":[{"symbol":"BNBUSDT","orderId":28282534,"orderListId":13509,"clientOrderId":"IfYDxvrZI4kiyqYpRH13iI","transactTime":1725521881300,"price":"300.00000000","origQty":"1.00000000","executedQty":"0","cummulativeQuoteQty":"0","status":"NEW","timeInForce":"GTC","type":"LIMIT","side":"BUY","selfTradePreventionMode":"NONE"},{"symbol":"BNBUSDT","orderId":28282535,"orderListId":13509,"clientOrderId":"0HCSsPRxVfW8BkTUy9z4np","transactTime":1725521881300,"price":"0E-8","origQty":"1.00000000","executedQty":"0","cummulativeQuoteQty":"0","status":"PENDING_NEW","timeInForce":"GTC","type":"STOP_LOSS","side":"SELL","stopPrice":"299.00000000","selfTradePreventionMode":"NONE"},{"symbol":"BNBUSDT","orderId":28282536,"orderListId":13509,"clientOrderId":"dypsgdxWnLY75kwT930cbD","transactTime":1725521881300,"price":"301.00000000","origQty":"1.00000000","executedQty":"0","cummulativeQuoteQty":"0","status":"PENDING_NEW","timeInForce":"GTC","type":"LIMIT_MAKER","side":"SELL","selfTradePreventionMode":"NONE"}]}"#).unwrap();
let dummy_response: models::MarginAccountNewOtocoResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::MarginAccountNewOtocoResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn margin_manual_liquidation(
&self,
_params: MarginManualLiquidationParams,
) -> anyhow::Result<RestApiResponse<models::MarginManualLiquidationResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"asset":"ETH","interest":"0.00083334","principal":"0.001","liabilityAsset":"USDT","liabilityQty":0.3552}"#).unwrap();
let dummy_response: models::MarginManualLiquidationResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::MarginManualLiquidationResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn query_current_margin_order_count_usage(
&self,
_params: QueryCurrentMarginOrderCountUsageParams,
) -> anyhow::Result<
RestApiResponse<Vec<models::QueryCurrentMarginOrderCountUsageResponseInner>>,
> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"rateLimitType":"ORDERS","interval":"SECOND","intervalNum":10,"limit":10000,"count":0},{"rateLimitType":"ORDERS","interval":"DAY","intervalNum":1,"limit":20000,"count":0}]"#).unwrap();
let dummy_response: Vec<models::QueryCurrentMarginOrderCountUsageResponseInner> =
serde_json::from_value(resp_json.clone()).expect(
"should parse into Vec<models::QueryCurrentMarginOrderCountUsageResponseInner>",
);
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn query_margin_accounts_all_oco(
&self,
_params: QueryMarginAccountsAllOcoParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryMarginAccountsAllOcoResponseInner>>>
{
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"orderListId":29,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"amEEAXryFzFwYF1FeRpUoZ","transactionTime":1565245913483,"symbol":"LTCBTC","isIsolated":true,"orders":[{"symbol":"LTCBTC","orderId":4,"clientOrderId":"oD7aesZqjEGlZrbtRpy5zB"},{"symbol":"LTCBTC","orderId":5,"clientOrderId":"Jr1h6xirOxgeJOUuYQS7V3"}]},{"orderListId":28,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"hG7hFNxJV6cZy3Ze4AUT4d","transactionTime":1565245913407,"symbol":"LTCBTC","orders":[{"symbol":"LTCBTC","orderId":2,"clientOrderId":"j6lFOfbmFMRjTYA7rRJ0LP"},{"symbol":"LTCBTC","orderId":3,"clientOrderId":"z0KCjOdditiLS5ekAFtK81"}]}]"#).unwrap();
let dummy_response: Vec<models::QueryMarginAccountsAllOcoResponseInner> =
serde_json::from_value(resp_json.clone()).expect(
"should parse into Vec<models::QueryMarginAccountsAllOcoResponseInner>",
);
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn query_margin_accounts_all_orders(
&self,
_params: QueryMarginAccountsAllOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryMarginAccountsAllOrdersResponseInner>>>
{
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"clientOrderId":"D2KDy4DIeS56PvkM13f8cP","cummulativeQuoteQty":"0.00000000","executedQty":"0.00000000","icebergQty":"0.00000000","isWorking":false,"orderId":41295,"origQty":"5.31000000","price":"0.22500000","side":"SELL","status":"CANCELED","stopPrice":"0.18000000","symbol":"BNBBTC","isIsolated":false,"time":1565769338806,"timeInForce":"GTC","type":"TAKE_PROFIT_LIMIT","selfTradePreventionMode":"NONE","updateTime":1565769342148},{"clientOrderId":"gXYtqhcEAs2Rn9SUD9nRKx","cummulativeQuoteQty":"0.00000000","executedQty":"0.00000000","icebergQty":"1.00000000","isWorking":true,"orderId":41296,"origQty":"6.65000000","price":"0.18000000","side":"SELL","status":"CANCELED","stopPrice":"0.00000000","symbol":"BNBBTC","isIsolated":false,"time":1565769348687,"timeInForce":"GTC","type":"LIMIT","selfTradePreventionMode":"NONE","updateTime":1565769352226}]"#).unwrap();
let dummy_response: Vec<models::QueryMarginAccountsAllOrdersResponseInner> =
serde_json::from_value(resp_json.clone()).expect(
"should parse into Vec<models::QueryMarginAccountsAllOrdersResponseInner>",
);
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn query_margin_accounts_oco(
&self,
_params: QueryMarginAccountsOcoParams,
) -> anyhow::Result<RestApiResponse<models::QueryMarginAccountsOcoResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"orderListId":27,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"h2USkA5YQpaXHPIrkd96xE","transactionTime":1565245656253,"symbol":"LTCBTC","isIsolated":false,"orders":[{"symbol":"LTCBTC","orderId":4,"clientOrderId":"qD1gy3kc3Gx0rihm9Y3xwS"},{"symbol":"LTCBTC","orderId":5,"clientOrderId":"ARzZ9I00CPM8i3NhmU9Ega"}]}"#).unwrap();
let dummy_response: models::QueryMarginAccountsOcoResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::QueryMarginAccountsOcoResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn query_margin_accounts_open_oco(
&self,
_params: QueryMarginAccountsOpenOcoParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryMarginAccountsOpenOcoResponseInner>>>
{
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"orderListId":31,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"wuB13fmulKj3YjdqWEcsnp","transactionTime":1565246080644,"symbol":"LTCBTC","isIsolated":false,"orders":[{"symbol":"LTCBTC","orderId":4,"clientOrderId":"r3EH2N76dHfLoSZWIUw1bT"},{"symbol":"LTCBTC","orderId":5,"clientOrderId":"Cv1SnyPD3qhqpbjpYEHbd2"}]}]"#).unwrap();
let dummy_response: Vec<models::QueryMarginAccountsOpenOcoResponseInner> =
serde_json::from_value(resp_json.clone()).expect(
"should parse into Vec<models::QueryMarginAccountsOpenOcoResponseInner>",
);
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn query_margin_accounts_open_orders(
&self,
_params: QueryMarginAccountsOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryMarginAccountsOpenOrdersResponseInner>>>
{
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"clientOrderId":"qhcZw71gAkCCTv0t0k8LUK","cummulativeQuoteQty":"0.00000000","executedQty":"0.00000000","icebergQty":"0.00000000","isWorking":true,"orderId":211842552,"origQty":"0.30000000","price":"0.00475010","side":"SELL","status":"NEW","stopPrice":"0.00000000","symbol":"BNBBTC","isIsolated":true,"time":1562040170089,"timeInForce":"GTC","type":"LIMIT","selfTradePreventionMode":"NONE","updateTime":1562040170089}]"#).unwrap();
let dummy_response: Vec<models::QueryMarginAccountsOpenOrdersResponseInner> =
serde_json::from_value(resp_json.clone()).expect(
"should parse into Vec<models::QueryMarginAccountsOpenOrdersResponseInner>",
);
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn query_margin_accounts_order(
&self,
_params: QueryMarginAccountsOrderParams,
) -> anyhow::Result<RestApiResponse<models::QueryMarginAccountsOrderResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"clientOrderId":"ZwfQzuDIGpceVhKW5DvCmO","cummulativeQuoteQty":"0.00000000","executedQty":"0.00000000","icebergQty":"0.00000000","isWorking":true,"orderId":213205622,"origQty":"0.30000000","price":"0.00493630","side":"SELL","status":"NEW","stopPrice":"0.00000000","symbol":"BNBBTC","isIsolated":true,"time":1562133008725,"timeInForce":"GTC","type":"LIMIT","selfTradePreventionMode":"NONE","updateTime":1562133008725}"#).unwrap();
let dummy_response: models::QueryMarginAccountsOrderResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::QueryMarginAccountsOrderResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn query_margin_accounts_trade_list(
&self,
_params: QueryMarginAccountsTradeListParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryMarginAccountsTradeListResponseInner>>>
{
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"commission":"0.00006000","commissionAsset":"BTC","id":34,"isBestMatch":true,"isBuyer":false,"isMaker":false,"orderId":39324,"price":"0.02000000","qty":"3.00000000","symbol":"BNBBTC","isIsolated":false,"time":1561973357171}]"#).unwrap();
let dummy_response: Vec<models::QueryMarginAccountsTradeListResponseInner> =
serde_json::from_value(resp_json.clone()).expect(
"should parse into Vec<models::QueryMarginAccountsTradeListResponseInner>",
);
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn query_prevented_matches(
&self,
_params: QueryPreventedMatchesParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryPreventedMatchesResponseInner>>>
{
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSDT","preventedMatchId":1,"takerOrderId":5,"makerSymbol":"BTCUSDT","makerOrderId":3,"tradeGroupId":1,"selfTradePreventionMode":"EXPIRE_MAKER","price":"1.100000","makerPreventedQuantity":"1.300000","transactTime":1669101687094}]"#).unwrap();
let dummy_response: Vec<models::QueryPreventedMatchesResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::QueryPreventedMatchesResponseInner>");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn query_special_key(
&self,
_params: QuerySpecialKeyParams,
) -> anyhow::Result<RestApiResponse<models::QuerySpecialKeyResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"apiKey":"npOzOAeLVgr2TuxWfNo43AaPWpBbJEoKezh1o8mSQb6ryE2odE11A4AoVlJbQoGx","ip":"0.0.0.0,192.168.0.1,192.168.0.2","apiName":"testName","type":"RSA","permissionMode":"TRADE"}"#).unwrap();
let dummy_response: models::QuerySpecialKeyResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::QuerySpecialKeyResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn query_special_key_list(
&self,
_params: QuerySpecialKeyListParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QuerySpecialKeyListResponseInner>>>
{
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"apiName":"testName1","apiKey":"znpOzOAeLVgr2TuxWfNo43AaPWpBbJEoKezh1o8mSQb6ryE2odE11A4AoVlJbQoG","ip":"192.168.0.1,192.168.0.2","type":"RSA","permissionMode":"TRADE"},{"apiName":"testName2","apiKey":"znpOzOAeLVgr2TuxWfNo43AaPWpBbJEoKezh1o8mSQb6ryE2odE11A4AoVlJbQoG","ip":"192.168.0.1,192.168.0.2","type":"Ed25519","permissionMode":"READ"}]"#).unwrap();
let dummy_response: Vec<models::QuerySpecialKeyListResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::QuerySpecialKeyListResponseInner>");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn small_liability_exchange(
&self,
_params: SmallLiabilityExchangeParams,
) -> anyhow::Result<RestApiResponse<Value>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let dummy_response = Value::Null;
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
}
#[test]
fn create_special_key_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = CreateSpecialKeyParams::builder("api_name_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"apiKey":"npOzOAeLVgr2TuxWfNo43AaPWpBbJEoKezh1o8mSQb6ryE2odE11A4AoVlJbQoGx","secretKey":"87ssWB7azoy6ACRfyp6OVOL5U3rtZptX31QWw2kWjl1jHEYRbyM1pd6qykRBQw8p","type":"HMAC_SHA256"}"#).unwrap();
let expected_response : models::CreateSpecialKeyResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::CreateSpecialKeyResponse");
let resp = client.create_special_key(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn create_special_key_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = CreateSpecialKeyParams::builder("api_name_example".to_string(),).symbol("symbol_example".to_string()).ip("ip_example".to_string()).public_key("public_key_example".to_string()).permission_mode("value".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"apiKey":"npOzOAeLVgr2TuxWfNo43AaPWpBbJEoKezh1o8mSQb6ryE2odE11A4AoVlJbQoGx","secretKey":"87ssWB7azoy6ACRfyp6OVOL5U3rtZptX31QWw2kWjl1jHEYRbyM1pd6qykRBQw8p","type":"HMAC_SHA256"}"#).unwrap();
let expected_response : models::CreateSpecialKeyResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::CreateSpecialKeyResponse");
let resp = client.create_special_key(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn create_special_key_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = CreateSpecialKeyParams::builder("api_name_example".to_string())
.build()
.unwrap();
match client.create_special_key(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn delete_special_key_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = DeleteSpecialKeyParams::builder().build().unwrap();
let expected_response = Value::Null;
let resp = client
.delete_special_key(params)
.await
.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn delete_special_key_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = DeleteSpecialKeyParams::builder()
.api_name("api_name_example".to_string())
.symbol("symbol_example".to_string())
.recv_window(5000)
.build()
.unwrap();
let expected_response = Value::Null;
let resp = client
.delete_special_key(params)
.await
.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn delete_special_key_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = DeleteSpecialKeyParams::builder().build().unwrap();
match client.delete_special_key(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn edit_ip_for_special_key_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = EditIpForSpecialKeyParams::builder("ip_example".to_string())
.build()
.unwrap();
let expected_response = Value::Null;
let resp = client
.edit_ip_for_special_key(params)
.await
.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn edit_ip_for_special_key_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = EditIpForSpecialKeyParams::builder("ip_example".to_string())
.symbol("symbol_example".to_string())
.recv_window(5000)
.build()
.unwrap();
let expected_response = Value::Null;
let resp = client
.edit_ip_for_special_key(params)
.await
.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn edit_ip_for_special_key_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = EditIpForSpecialKeyParams::builder("ip_example".to_string())
.build()
.unwrap();
match client.edit_ip_for_special_key(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn get_force_liquidation_record_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = GetForceLiquidationRecordParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"rows":[{"avgPrice":"0.00388359","executedQty":"31.39000000","orderId":180015097,"price":"0.00388110","qty":"31.39000000","side":"SELL","symbol":"BNBBTC","timeInForce":"GTC","isIsolated":true,"updatedTime":1558941374745}],"total":1}"#).unwrap();
let expected_response : models::GetForceLiquidationRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetForceLiquidationRecordResponse");
let resp = client.get_force_liquidation_record(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn get_force_liquidation_record_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = GetForceLiquidationRecordParams::builder().start_time(1623319461670).end_time(1641782889000).isolated_symbol("isolated_symbol_example".to_string()).current(1).size(10).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"rows":[{"avgPrice":"0.00388359","executedQty":"31.39000000","orderId":180015097,"price":"0.00388110","qty":"31.39000000","side":"SELL","symbol":"BNBBTC","timeInForce":"GTC","isIsolated":true,"updatedTime":1558941374745}],"total":1}"#).unwrap();
let expected_response : models::GetForceLiquidationRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetForceLiquidationRecordResponse");
let resp = client.get_force_liquidation_record(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn get_force_liquidation_record_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = GetForceLiquidationRecordParams::builder().build().unwrap();
match client.get_force_liquidation_record(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn get_small_liability_exchange_coin_list_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = GetSmallLiabilityExchangeCoinListParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"asset":"ETH","interest":"0.00083334","principal":"0.001","liabilityAsset":"USDT","liabilityQty":0.3552}]"#).unwrap();
let expected_response : Vec<models::GetSmallLiabilityExchangeCoinListResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetSmallLiabilityExchangeCoinListResponseInner>");
let resp = client.get_small_liability_exchange_coin_list(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn get_small_liability_exchange_coin_list_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = GetSmallLiabilityExchangeCoinListParams::builder().recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"asset":"ETH","interest":"0.00083334","principal":"0.001","liabilityAsset":"USDT","liabilityQty":0.3552}]"#).unwrap();
let expected_response : Vec<models::GetSmallLiabilityExchangeCoinListResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetSmallLiabilityExchangeCoinListResponseInner>");
let resp = client.get_small_liability_exchange_coin_list(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn get_small_liability_exchange_coin_list_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = GetSmallLiabilityExchangeCoinListParams::builder()
.build()
.unwrap();
match client.get_small_liability_exchange_coin_list(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn get_small_liability_exchange_history_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = GetSmallLiabilityExchangeHistoryParams::builder(1,10,).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"total":1,"rows":[{"asset":"ETH","amount":"0.00083434","targetAsset":"BUSD","targetAmount":"1.37576819","bizType":"EXCHANGE_SMALL_LIABILITY","timestamp":1672801339253}]}"#).unwrap();
let expected_response : models::GetSmallLiabilityExchangeHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSmallLiabilityExchangeHistoryResponse");
let resp = client.get_small_liability_exchange_history(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn get_small_liability_exchange_history_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = GetSmallLiabilityExchangeHistoryParams::builder(1,10,).start_time(1623319461670).end_time(1641782889000).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"total":1,"rows":[{"asset":"ETH","amount":"0.00083434","targetAsset":"BUSD","targetAmount":"1.37576819","bizType":"EXCHANGE_SMALL_LIABILITY","timestamp":1672801339253}]}"#).unwrap();
let expected_response : models::GetSmallLiabilityExchangeHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSmallLiabilityExchangeHistoryResponse");
let resp = client.get_small_liability_exchange_history(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn get_small_liability_exchange_history_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = GetSmallLiabilityExchangeHistoryParams::builder(1, 10)
.build()
.unwrap();
match client.get_small_liability_exchange_history(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn margin_account_cancel_all_open_orders_on_a_symbol_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = MarginAccountCancelAllOpenOrdersOnASymbolParams::builder("symbol_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSDT","isIsolated":true,"origClientOrderId":"E6APeyTJvkMvLMYMqu1KQ4","orderId":11,"orderListId":-1,"clientOrderId":"pXLV6Hz6mprAcVYpVMTGgx","price":"0.089853","origQty":"0.178622","executedQty":"0.000000","cummulativeQuoteQty":"0.000000","status":"CANCELED","timeInForce":"GTC","type":"LIMIT","side":"BUY","selfTradePreventionMode":"NONE"},{"symbol":"BTCUSDT","isIsolated":false,"origClientOrderId":"A3EF2HCwxgZPFMrfwbgrhv","orderId":13,"orderListId":-1,"clientOrderId":"pXLV6Hz6mprAcVYpVMTGgx","price":"0.090430","origQty":"0.178622","executedQty":"0.000000","cummulativeQuoteQty":"0.000000","status":"CANCELED","timeInForce":"GTC","type":"LIMIT","side":"BUY","selfTradePreventionMode":"NONE"},{"orderListId":1929,"contingencyType":"OCO","listStatusType":"ALL_DONE","listOrderStatus":"ALL_DONE","listClientOrderId":"2inzWQdDvZLHbbAmAozX2N","transactionTime":1585230948299,"symbol":"BTCUSDT","isIsolated":true,"orders":[{"symbol":"BTCUSDT","orderId":20,"clientOrderId":"CwOOIPHSmYywx6jZX77TdL"},{"symbol":"BTCUSDT","orderId":21,"clientOrderId":"461cPg51vQjV3zIMOXNz39"}],"orderReports":[{"symbol":"BTCUSDT","origClientOrderId":"CwOOIPHSmYywx6jZX77TdL","orderId":20,"orderListId":1929,"clientOrderId":"pXLV6Hz6mprAcVYpVMTGgx","price":"0.668611","origQty":"0.690354","executedQty":"0.000000","cummulativeQuoteQty":"0.000000","status":"CANCELED","timeInForce":"GTC","type":"STOP_LOSS_LIMIT","side":"BUY","stopPrice":"0.378131","icebergQty":"0.017083"},{"symbol":"BTCUSDT","origClientOrderId":"461cPg51vQjV3zIMOXNz39","orderId":21,"orderListId":1929,"clientOrderId":"pXLV6Hz6mprAcVYpVMTGgx","price":"0.008791","origQty":"0.690354","executedQty":"0.000000","cummulativeQuoteQty":"0.000000","status":"CANCELED","timeInForce":"GTC","type":"LIMIT_MAKER","side":"BUY","icebergQty":"0.639962"}]}]"#).unwrap();
let expected_response : Vec<models::MarginAccountCancelAllOpenOrdersOnASymbolResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::MarginAccountCancelAllOpenOrdersOnASymbolResponseInner>");
let resp = client.margin_account_cancel_all_open_orders_on_a_symbol(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn margin_account_cancel_all_open_orders_on_a_symbol_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = MarginAccountCancelAllOpenOrdersOnASymbolParams::builder("symbol_example".to_string(),).is_isolated("false".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSDT","isIsolated":true,"origClientOrderId":"E6APeyTJvkMvLMYMqu1KQ4","orderId":11,"orderListId":-1,"clientOrderId":"pXLV6Hz6mprAcVYpVMTGgx","price":"0.089853","origQty":"0.178622","executedQty":"0.000000","cummulativeQuoteQty":"0.000000","status":"CANCELED","timeInForce":"GTC","type":"LIMIT","side":"BUY","selfTradePreventionMode":"NONE"},{"symbol":"BTCUSDT","isIsolated":false,"origClientOrderId":"A3EF2HCwxgZPFMrfwbgrhv","orderId":13,"orderListId":-1,"clientOrderId":"pXLV6Hz6mprAcVYpVMTGgx","price":"0.090430","origQty":"0.178622","executedQty":"0.000000","cummulativeQuoteQty":"0.000000","status":"CANCELED","timeInForce":"GTC","type":"LIMIT","side":"BUY","selfTradePreventionMode":"NONE"},{"orderListId":1929,"contingencyType":"OCO","listStatusType":"ALL_DONE","listOrderStatus":"ALL_DONE","listClientOrderId":"2inzWQdDvZLHbbAmAozX2N","transactionTime":1585230948299,"symbol":"BTCUSDT","isIsolated":true,"orders":[{"symbol":"BTCUSDT","orderId":20,"clientOrderId":"CwOOIPHSmYywx6jZX77TdL"},{"symbol":"BTCUSDT","orderId":21,"clientOrderId":"461cPg51vQjV3zIMOXNz39"}],"orderReports":[{"symbol":"BTCUSDT","origClientOrderId":"CwOOIPHSmYywx6jZX77TdL","orderId":20,"orderListId":1929,"clientOrderId":"pXLV6Hz6mprAcVYpVMTGgx","price":"0.668611","origQty":"0.690354","executedQty":"0.000000","cummulativeQuoteQty":"0.000000","status":"CANCELED","timeInForce":"GTC","type":"STOP_LOSS_LIMIT","side":"BUY","stopPrice":"0.378131","icebergQty":"0.017083"},{"symbol":"BTCUSDT","origClientOrderId":"461cPg51vQjV3zIMOXNz39","orderId":21,"orderListId":1929,"clientOrderId":"pXLV6Hz6mprAcVYpVMTGgx","price":"0.008791","origQty":"0.690354","executedQty":"0.000000","cummulativeQuoteQty":"0.000000","status":"CANCELED","timeInForce":"GTC","type":"LIMIT_MAKER","side":"BUY","icebergQty":"0.639962"}]}]"#).unwrap();
let expected_response : Vec<models::MarginAccountCancelAllOpenOrdersOnASymbolResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::MarginAccountCancelAllOpenOrdersOnASymbolResponseInner>");
let resp = client.margin_account_cancel_all_open_orders_on_a_symbol(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn margin_account_cancel_all_open_orders_on_a_symbol_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = MarginAccountCancelAllOpenOrdersOnASymbolParams::builder(
"symbol_example".to_string(),
)
.build()
.unwrap();
match client
.margin_account_cancel_all_open_orders_on_a_symbol(params)
.await
{
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn margin_account_cancel_oco_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = MarginAccountCancelOcoParams::builder("symbol_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"orderListId":0,"contingencyType":"OCO","listStatusType":"ALL_DONE","listOrderStatus":"ALL_DONE","listClientOrderId":"C3wyj4WVEktd7u9aVBRXcN","transactionTime":1574040868128,"symbol":"LTCBTC","isIsolated":false,"orders":[{"symbol":"LTCBTC","orderId":2,"clientOrderId":"pO9ufTiFGg3nw2fOdgeOXa"},{"symbol":"LTCBTC","orderId":3,"clientOrderId":"TXOvglzXuaubXAaENpaRCB"}],"orderReports":[{"symbol":"LTCBTC","origClientOrderId":"pO9ufTiFGg3nw2fOdgeOXa","orderId":2,"orderListId":0,"clientOrderId":"unfWT8ig8i0uj6lPuYLez6","price":"1.00000000","origQty":"10.00000000","executedQty":"0.00000000","cummulativeQuoteQty":"0.00000000","status":"CANCELED","timeInForce":"GTC","type":"STOP_LOSS_LIMIT","side":"SELL","stopPrice":"1.00000000","selfTradePreventionMode":"NONE"},{"symbol":"LTCBTC","origClientOrderId":"TXOvglzXuaubXAaENpaRCB","orderId":3,"orderListId":0,"clientOrderId":"unfWT8ig8i0uj6lPuYLez6","price":"3.00000000","origQty":"10.00000000","executedQty":"0.00000000","cummulativeQuoteQty":"0.00000000","status":"CANCELED","timeInForce":"GTC","type":"LIMIT_MAKER","side":"SELL","selfTradePreventionMode":"NONE"}]}"#).unwrap();
let expected_response : models::MarginAccountCancelOcoResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MarginAccountCancelOcoResponse");
let resp = client.margin_account_cancel_oco(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn margin_account_cancel_oco_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = MarginAccountCancelOcoParams::builder("symbol_example".to_string(),).is_isolated("false".to_string()).order_list_id(1).list_client_order_id("1".to_string()).new_client_order_id("1".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"orderListId":0,"contingencyType":"OCO","listStatusType":"ALL_DONE","listOrderStatus":"ALL_DONE","listClientOrderId":"C3wyj4WVEktd7u9aVBRXcN","transactionTime":1574040868128,"symbol":"LTCBTC","isIsolated":false,"orders":[{"symbol":"LTCBTC","orderId":2,"clientOrderId":"pO9ufTiFGg3nw2fOdgeOXa"},{"symbol":"LTCBTC","orderId":3,"clientOrderId":"TXOvglzXuaubXAaENpaRCB"}],"orderReports":[{"symbol":"LTCBTC","origClientOrderId":"pO9ufTiFGg3nw2fOdgeOXa","orderId":2,"orderListId":0,"clientOrderId":"unfWT8ig8i0uj6lPuYLez6","price":"1.00000000","origQty":"10.00000000","executedQty":"0.00000000","cummulativeQuoteQty":"0.00000000","status":"CANCELED","timeInForce":"GTC","type":"STOP_LOSS_LIMIT","side":"SELL","stopPrice":"1.00000000","selfTradePreventionMode":"NONE"},{"symbol":"LTCBTC","origClientOrderId":"TXOvglzXuaubXAaENpaRCB","orderId":3,"orderListId":0,"clientOrderId":"unfWT8ig8i0uj6lPuYLez6","price":"3.00000000","origQty":"10.00000000","executedQty":"0.00000000","cummulativeQuoteQty":"0.00000000","status":"CANCELED","timeInForce":"GTC","type":"LIMIT_MAKER","side":"SELL","selfTradePreventionMode":"NONE"}]}"#).unwrap();
let expected_response : models::MarginAccountCancelOcoResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MarginAccountCancelOcoResponse");
let resp = client.margin_account_cancel_oco(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn margin_account_cancel_oco_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = MarginAccountCancelOcoParams::builder("symbol_example".to_string())
.build()
.unwrap();
match client.margin_account_cancel_oco(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn margin_account_cancel_order_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = MarginAccountCancelOrderParams::builder("symbol_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"symbol":"LTCBTC","isIsolated":true,"orderId":"28","origClientOrderId":"myOrder1","clientOrderId":"cancelMyOrder1","price":"1.00000000","origQty":"10.00000000","executedQty":"8.00000000","cummulativeQuoteQty":"8.00000000","status":"CANCELED","timeInForce":"GTC","type":"LIMIT","side":"SELL"}"#).unwrap();
let expected_response : models::MarginAccountCancelOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MarginAccountCancelOrderResponse");
let resp = client.margin_account_cancel_order(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn margin_account_cancel_order_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = MarginAccountCancelOrderParams::builder("symbol_example".to_string(),).is_isolated("false".to_string()).order_id(1).orig_client_order_id("1".to_string()).new_client_order_id("1".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"symbol":"LTCBTC","isIsolated":true,"orderId":"28","origClientOrderId":"myOrder1","clientOrderId":"cancelMyOrder1","price":"1.00000000","origQty":"10.00000000","executedQty":"8.00000000","cummulativeQuoteQty":"8.00000000","status":"CANCELED","timeInForce":"GTC","type":"LIMIT","side":"SELL"}"#).unwrap();
let expected_response : models::MarginAccountCancelOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MarginAccountCancelOrderResponse");
let resp = client.margin_account_cancel_order(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn margin_account_cancel_order_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = MarginAccountCancelOrderParams::builder("symbol_example".to_string())
.build()
.unwrap();
match client.margin_account_cancel_order(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn margin_account_new_oco_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = MarginAccountNewOcoParams::builder("symbol_example".to_string(),MarginAccountNewOcoSideEnum::Buy,dec!(1.0),dec!(1.0),dec!(1.0),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"orderListId":0,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"JYVpp3F0f5CAG15DhtrqLp","transactionTime":1563417480525,"symbol":"LTCBTC","marginBuyBorrowAmount":"5","marginBuyBorrowAsset":"BTC","isIsolated":false,"orders":[{"symbol":"LTCBTC","orderId":2,"clientOrderId":"Kk7sqHb9J6mJWTMDVW7Vos"},{"symbol":"LTCBTC","orderId":3,"clientOrderId":"xTXKaGYd4bluPVp78IVRvl"}],"orderReports":[{"symbol":"LTCBTC","orderId":2,"orderListId":0,"clientOrderId":"Kk7sqHb9J6mJWTMDVW7Vos","transactTime":1563417480525,"price":"0.000000","origQty":"0.624363","executedQty":"0.000000","cummulativeQuoteQty":"0.000000","status":"NEW","timeInForce":"GTC","type":"STOP_LOSS","side":"BUY","stopPrice":"0.960664","selfTradePreventionMode":"NONE"},{"symbol":"LTCBTC","orderId":3,"orderListId":0,"clientOrderId":"xTXKaGYd4bluPVp78IVRvl","transactTime":1563417480525,"price":"0.036435","origQty":"0.624363","executedQty":"0.000000","cummulativeQuoteQty":"0.000000","status":"NEW","timeInForce":"GTC","type":"LIMIT_MAKER","side":"BUY","selfTradePreventionMode":"NONE"}]}"#).unwrap();
let expected_response : models::MarginAccountNewOcoResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MarginAccountNewOcoResponse");
let resp = client.margin_account_new_oco(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn margin_account_new_oco_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = MarginAccountNewOcoParams::builder("symbol_example".to_string(),MarginAccountNewOcoSideEnum::Buy,dec!(1.0),dec!(1.0),dec!(1.0),).is_isolated("false".to_string()).list_client_order_id("1".to_string()).limit_client_order_id("1".to_string()).limit_iceberg_qty(dec!(1.0)).stop_client_order_id("1".to_string()).stop_limit_price(dec!(1.0)).stop_iceberg_qty(dec!(1.0)).stop_limit_time_in_force("stop_limit_time_in_force_example".to_string()).new_order_resp_type(MarginAccountNewOcoNewOrderRespTypeEnum::Ack).side_effect_type("NO_SIDE_EFFECT".to_string()).self_trade_prevention_mode("NONE".to_string()).auto_repay_at_cancel(true).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"orderListId":0,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"JYVpp3F0f5CAG15DhtrqLp","transactionTime":1563417480525,"symbol":"LTCBTC","marginBuyBorrowAmount":"5","marginBuyBorrowAsset":"BTC","isIsolated":false,"orders":[{"symbol":"LTCBTC","orderId":2,"clientOrderId":"Kk7sqHb9J6mJWTMDVW7Vos"},{"symbol":"LTCBTC","orderId":3,"clientOrderId":"xTXKaGYd4bluPVp78IVRvl"}],"orderReports":[{"symbol":"LTCBTC","orderId":2,"orderListId":0,"clientOrderId":"Kk7sqHb9J6mJWTMDVW7Vos","transactTime":1563417480525,"price":"0.000000","origQty":"0.624363","executedQty":"0.000000","cummulativeQuoteQty":"0.000000","status":"NEW","timeInForce":"GTC","type":"STOP_LOSS","side":"BUY","stopPrice":"0.960664","selfTradePreventionMode":"NONE"},{"symbol":"LTCBTC","orderId":3,"orderListId":0,"clientOrderId":"xTXKaGYd4bluPVp78IVRvl","transactTime":1563417480525,"price":"0.036435","origQty":"0.624363","executedQty":"0.000000","cummulativeQuoteQty":"0.000000","status":"NEW","timeInForce":"GTC","type":"LIMIT_MAKER","side":"BUY","selfTradePreventionMode":"NONE"}]}"#).unwrap();
let expected_response : models::MarginAccountNewOcoResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MarginAccountNewOcoResponse");
let resp = client.margin_account_new_oco(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn margin_account_new_oco_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = MarginAccountNewOcoParams::builder(
"symbol_example".to_string(),
MarginAccountNewOcoSideEnum::Buy,
dec!(1.0),
dec!(1.0),
dec!(1.0),
)
.build()
.unwrap();
match client.margin_account_new_oco(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn margin_account_new_order_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = MarginAccountNewOrderParams::builder("symbol_example".to_string(),MarginAccountNewOrderSideEnum::Buy,"r#type_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"symbol":"BTCUSDT","orderId":26769564559,"clientOrderId":"E156O3KP4gOif65bjuUK5V","isIsolated":false,"transactTime":1713873075893,"price":"0","origQty":"0.001","executedQty":"0.001","cummulativeQuoteQty":"65.98253","status":"FILLED","timeInForce":"GTC","type":"MARKET","side":"SELL","selfTradePreventionMode":"EXPIRE_MAKER","marginBuyBorrowAmount":5,"marginBuyBorrowAsset":"BTC","fills":[{"price":"65982.53","qty":"0.001","commission":"0.06598253","commissionAsset":"USDT","tradeId":3570680726}]}"#).unwrap();
let expected_response : models::MarginAccountNewOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MarginAccountNewOrderResponse");
let resp = client.margin_account_new_order(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn margin_account_new_order_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = MarginAccountNewOrderParams::builder("symbol_example".to_string(),MarginAccountNewOrderSideEnum::Buy,"r#type_example".to_string(),).is_isolated("false".to_string()).quantity(dec!(1.0)).quote_order_qty(dec!(1.0)).price(dec!(1.0)).stop_price(dec!(1.0)).new_client_order_id("1".to_string()).iceberg_qty(dec!(1.0)).new_order_resp_type(MarginAccountNewOrderNewOrderRespTypeEnum::Ack).side_effect_type("NO_SIDE_EFFECT".to_string()).time_in_force(MarginAccountNewOrderTimeInForceEnum::Gtc).self_trade_prevention_mode("NONE".to_string()).auto_repay_at_cancel(true).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"symbol":"BTCUSDT","orderId":26769564559,"clientOrderId":"E156O3KP4gOif65bjuUK5V","isIsolated":false,"transactTime":1713873075893,"price":"0","origQty":"0.001","executedQty":"0.001","cummulativeQuoteQty":"65.98253","status":"FILLED","timeInForce":"GTC","type":"MARKET","side":"SELL","selfTradePreventionMode":"EXPIRE_MAKER","marginBuyBorrowAmount":5,"marginBuyBorrowAsset":"BTC","fills":[{"price":"65982.53","qty":"0.001","commission":"0.06598253","commissionAsset":"USDT","tradeId":3570680726}]}"#).unwrap();
let expected_response : models::MarginAccountNewOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MarginAccountNewOrderResponse");
let resp = client.margin_account_new_order(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn margin_account_new_order_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = MarginAccountNewOrderParams::builder(
"symbol_example".to_string(),
MarginAccountNewOrderSideEnum::Buy,
"r#type_example".to_string(),
)
.build()
.unwrap();
match client.margin_account_new_order(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn margin_account_new_oto_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = MarginAccountNewOtoParams::builder("symbol_example".to_string(),"working_type_example".to_string(),"working_side_example".to_string(),dec!(1.0),dec!(1.0),dec!(1.0),"Order Types".to_string(),"pending_side_example".to_string(),dec!(1.0),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"orderListId":13551,"contingencyType":"OTO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"JDuOrsu0Ge8GTyvx8J7VTD","transactionTime":1725521998054,"symbol":"BTCUSDT","isIsolated":false,"orders":[{"symbol":"BTCUSDT","orderId":29896699,"clientOrderId":"y8RB6tQEMuHUXybqbtzTxk"},{"symbol":"BTCUSDT","orderId":29896700,"clientOrderId":"dKQEdh5HhXb7Lpp85jz1dQ"}],"orderReports":[{"symbol":"BTCUSDT","orderId":29896699,"orderListId":13551,"clientOrderId":"y8RB6tQEMuHUXybqbtzTxk","transactTime":1725521998054,"price":"80000.00000000","origQty":"0.02000000","executedQty":"0","cummulativeQuoteQty":"0","status":"NEW","timeInForce":"GTC","type":"LIMIT","side":"SELL","selfTradePreventionMode":"NONE"},{"symbol":"BTCUSDT","orderId":29896700,"orderListId":13551,"clientOrderId":"dKQEdh5HhXb7Lpp85jz1dQ","transactTime":1725521998054,"price":"50000.00000000","origQty":"0.02000000","executedQty":"0","cummulativeQuoteQty":"0","status":"PENDING_NEW","timeInForce":"GTC","type":"LIMIT","side":"BUY","selfTradePreventionMode":"NONE"}]}"#).unwrap();
let expected_response : models::MarginAccountNewOtoResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MarginAccountNewOtoResponse");
let resp = client.margin_account_new_oto(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn margin_account_new_oto_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = MarginAccountNewOtoParams::builder("symbol_example".to_string(),"working_type_example".to_string(),"working_side_example".to_string(),dec!(1.0),dec!(1.0),dec!(1.0),"Order Types".to_string(),"pending_side_example".to_string(),dec!(1.0),).is_isolated("false".to_string()).list_client_order_id("1".to_string()).new_order_resp_type(MarginAccountNewOtoNewOrderRespTypeEnum::Ack).side_effect_type("NO_SIDE_EFFECT".to_string()).self_trade_prevention_mode("NONE".to_string()).auto_repay_at_cancel(true).working_client_order_id("1".to_string()).working_time_in_force("working_time_in_force_example".to_string()).pending_client_order_id("1".to_string()).pending_price(dec!(1.0)).pending_stop_price(dec!(1.0)).pending_trailing_delta(dec!(1.0)).pending_iceberg_qty(dec!(1.0)).pending_time_in_force("pending_time_in_force_example".to_string()).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"orderListId":13551,"contingencyType":"OTO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"JDuOrsu0Ge8GTyvx8J7VTD","transactionTime":1725521998054,"symbol":"BTCUSDT","isIsolated":false,"orders":[{"symbol":"BTCUSDT","orderId":29896699,"clientOrderId":"y8RB6tQEMuHUXybqbtzTxk"},{"symbol":"BTCUSDT","orderId":29896700,"clientOrderId":"dKQEdh5HhXb7Lpp85jz1dQ"}],"orderReports":[{"symbol":"BTCUSDT","orderId":29896699,"orderListId":13551,"clientOrderId":"y8RB6tQEMuHUXybqbtzTxk","transactTime":1725521998054,"price":"80000.00000000","origQty":"0.02000000","executedQty":"0","cummulativeQuoteQty":"0","status":"NEW","timeInForce":"GTC","type":"LIMIT","side":"SELL","selfTradePreventionMode":"NONE"},{"symbol":"BTCUSDT","orderId":29896700,"orderListId":13551,"clientOrderId":"dKQEdh5HhXb7Lpp85jz1dQ","transactTime":1725521998054,"price":"50000.00000000","origQty":"0.02000000","executedQty":"0","cummulativeQuoteQty":"0","status":"PENDING_NEW","timeInForce":"GTC","type":"LIMIT","side":"BUY","selfTradePreventionMode":"NONE"}]}"#).unwrap();
let expected_response : models::MarginAccountNewOtoResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MarginAccountNewOtoResponse");
let resp = client.margin_account_new_oto(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn margin_account_new_oto_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = MarginAccountNewOtoParams::builder(
"symbol_example".to_string(),
"working_type_example".to_string(),
"working_side_example".to_string(),
dec!(1.0),
dec!(1.0),
dec!(1.0),
"Order Types".to_string(),
"pending_side_example".to_string(),
dec!(1.0),
)
.build()
.unwrap();
match client.margin_account_new_oto(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn margin_account_new_otoco_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = MarginAccountNewOtocoParams::builder("symbol_example".to_string(),"working_type_example".to_string(),"working_side_example".to_string(),dec!(1.0),dec!(1.0),"pending_side_example".to_string(),dec!(1.0),"pending_above_type_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"orderListId":13509,"contingencyType":"OTO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"u2AUo48LLef5qVenRtwJZy","transactionTime":1725521881300,"symbol":"BNBUSDT","isIsolated":false,"orders":[{"symbol":"BNBUSDT","orderId":28282534,"clientOrderId":"IfYDxvrZI4kiyqYpRH13iI"},{"symbol":"BNBUSDT","orderId":28282535,"clientOrderId":"0HCSsPRxVfW8BkTUy9z4np"},{"symbol":"BNBUSDT","orderId":28282536,"clientOrderId":"dypsgdxWnLY75kwT930cbD"}],"orderReports":[{"symbol":"BNBUSDT","orderId":28282534,"orderListId":13509,"clientOrderId":"IfYDxvrZI4kiyqYpRH13iI","transactTime":1725521881300,"price":"300.00000000","origQty":"1.00000000","executedQty":"0","cummulativeQuoteQty":"0","status":"NEW","timeInForce":"GTC","type":"LIMIT","side":"BUY","selfTradePreventionMode":"NONE"},{"symbol":"BNBUSDT","orderId":28282535,"orderListId":13509,"clientOrderId":"0HCSsPRxVfW8BkTUy9z4np","transactTime":1725521881300,"price":"0E-8","origQty":"1.00000000","executedQty":"0","cummulativeQuoteQty":"0","status":"PENDING_NEW","timeInForce":"GTC","type":"STOP_LOSS","side":"SELL","stopPrice":"299.00000000","selfTradePreventionMode":"NONE"},{"symbol":"BNBUSDT","orderId":28282536,"orderListId":13509,"clientOrderId":"dypsgdxWnLY75kwT930cbD","transactTime":1725521881300,"price":"301.00000000","origQty":"1.00000000","executedQty":"0","cummulativeQuoteQty":"0","status":"PENDING_NEW","timeInForce":"GTC","type":"LIMIT_MAKER","side":"SELL","selfTradePreventionMode":"NONE"}]}"#).unwrap();
let expected_response : models::MarginAccountNewOtocoResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MarginAccountNewOtocoResponse");
let resp = client.margin_account_new_otoco(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn margin_account_new_otoco_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = MarginAccountNewOtocoParams::builder("symbol_example".to_string(),"working_type_example".to_string(),"working_side_example".to_string(),dec!(1.0),dec!(1.0),"pending_side_example".to_string(),dec!(1.0),"pending_above_type_example".to_string(),).is_isolated("false".to_string()).side_effect_type("NO_SIDE_EFFECT".to_string()).auto_repay_at_cancel(true).list_client_order_id("1".to_string()).new_order_resp_type(MarginAccountNewOtocoNewOrderRespTypeEnum::Ack).self_trade_prevention_mode("NONE".to_string()).working_client_order_id("1".to_string()).working_iceberg_qty(dec!(1.0)).working_time_in_force("working_time_in_force_example".to_string()).pending_above_client_order_id("1".to_string()).pending_above_price(dec!(1.0)).pending_above_stop_price(dec!(1.0)).pending_above_trailing_delta(dec!(1.0)).pending_above_iceberg_qty(dec!(1.0)).pending_above_time_in_force("pending_above_time_in_force_example".to_string()).pending_below_type("pending_below_type_example".to_string()).pending_below_client_order_id("1".to_string()).pending_below_price(dec!(1.0)).pending_below_stop_price(dec!(1.0)).pending_below_trailing_delta(dec!(1.0)).pending_below_iceberg_qty(dec!(1.0)).pending_below_time_in_force("pending_below_time_in_force_example".to_string()).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"orderListId":13509,"contingencyType":"OTO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"u2AUo48LLef5qVenRtwJZy","transactionTime":1725521881300,"symbol":"BNBUSDT","isIsolated":false,"orders":[{"symbol":"BNBUSDT","orderId":28282534,"clientOrderId":"IfYDxvrZI4kiyqYpRH13iI"},{"symbol":"BNBUSDT","orderId":28282535,"clientOrderId":"0HCSsPRxVfW8BkTUy9z4np"},{"symbol":"BNBUSDT","orderId":28282536,"clientOrderId":"dypsgdxWnLY75kwT930cbD"}],"orderReports":[{"symbol":"BNBUSDT","orderId":28282534,"orderListId":13509,"clientOrderId":"IfYDxvrZI4kiyqYpRH13iI","transactTime":1725521881300,"price":"300.00000000","origQty":"1.00000000","executedQty":"0","cummulativeQuoteQty":"0","status":"NEW","timeInForce":"GTC","type":"LIMIT","side":"BUY","selfTradePreventionMode":"NONE"},{"symbol":"BNBUSDT","orderId":28282535,"orderListId":13509,"clientOrderId":"0HCSsPRxVfW8BkTUy9z4np","transactTime":1725521881300,"price":"0E-8","origQty":"1.00000000","executedQty":"0","cummulativeQuoteQty":"0","status":"PENDING_NEW","timeInForce":"GTC","type":"STOP_LOSS","side":"SELL","stopPrice":"299.00000000","selfTradePreventionMode":"NONE"},{"symbol":"BNBUSDT","orderId":28282536,"orderListId":13509,"clientOrderId":"dypsgdxWnLY75kwT930cbD","transactTime":1725521881300,"price":"301.00000000","origQty":"1.00000000","executedQty":"0","cummulativeQuoteQty":"0","status":"PENDING_NEW","timeInForce":"GTC","type":"LIMIT_MAKER","side":"SELL","selfTradePreventionMode":"NONE"}]}"#).unwrap();
let expected_response : models::MarginAccountNewOtocoResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MarginAccountNewOtocoResponse");
let resp = client.margin_account_new_otoco(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn margin_account_new_otoco_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = MarginAccountNewOtocoParams::builder(
"symbol_example".to_string(),
"working_type_example".to_string(),
"working_side_example".to_string(),
dec!(1.0),
dec!(1.0),
"pending_side_example".to_string(),
dec!(1.0),
"pending_above_type_example".to_string(),
)
.build()
.unwrap();
match client.margin_account_new_otoco(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn margin_manual_liquidation_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = MarginManualLiquidationParams::builder("r#type_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"asset":"ETH","interest":"0.00083334","principal":"0.001","liabilityAsset":"USDT","liabilityQty":0.3552}"#).unwrap();
let expected_response : models::MarginManualLiquidationResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MarginManualLiquidationResponse");
let resp = client.margin_manual_liquidation(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn margin_manual_liquidation_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = MarginManualLiquidationParams::builder("r#type_example".to_string(),).symbol("symbol_example".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"asset":"ETH","interest":"0.00083334","principal":"0.001","liabilityAsset":"USDT","liabilityQty":0.3552}"#).unwrap();
let expected_response : models::MarginManualLiquidationResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MarginManualLiquidationResponse");
let resp = client.margin_manual_liquidation(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn margin_manual_liquidation_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = MarginManualLiquidationParams::builder("r#type_example".to_string())
.build()
.unwrap();
match client.margin_manual_liquidation(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn query_current_margin_order_count_usage_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryCurrentMarginOrderCountUsageParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"rateLimitType":"ORDERS","interval":"SECOND","intervalNum":10,"limit":10000,"count":0},{"rateLimitType":"ORDERS","interval":"DAY","intervalNum":1,"limit":20000,"count":0}]"#).unwrap();
let expected_response : Vec<models::QueryCurrentMarginOrderCountUsageResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryCurrentMarginOrderCountUsageResponseInner>");
let resp = client.query_current_margin_order_count_usage(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_current_margin_order_count_usage_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryCurrentMarginOrderCountUsageParams::builder().is_isolated("false".to_string()).symbol("symbol_example".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"rateLimitType":"ORDERS","interval":"SECOND","intervalNum":10,"limit":10000,"count":0},{"rateLimitType":"ORDERS","interval":"DAY","intervalNum":1,"limit":20000,"count":0}]"#).unwrap();
let expected_response : Vec<models::QueryCurrentMarginOrderCountUsageResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryCurrentMarginOrderCountUsageResponseInner>");
let resp = client.query_current_margin_order_count_usage(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_current_margin_order_count_usage_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = QueryCurrentMarginOrderCountUsageParams::builder()
.build()
.unwrap();
match client.query_current_margin_order_count_usage(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn query_margin_accounts_all_oco_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryMarginAccountsAllOcoParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"orderListId":29,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"amEEAXryFzFwYF1FeRpUoZ","transactionTime":1565245913483,"symbol":"LTCBTC","isIsolated":true,"orders":[{"symbol":"LTCBTC","orderId":4,"clientOrderId":"oD7aesZqjEGlZrbtRpy5zB"},{"symbol":"LTCBTC","orderId":5,"clientOrderId":"Jr1h6xirOxgeJOUuYQS7V3"}]},{"orderListId":28,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"hG7hFNxJV6cZy3Ze4AUT4d","transactionTime":1565245913407,"symbol":"LTCBTC","orders":[{"symbol":"LTCBTC","orderId":2,"clientOrderId":"j6lFOfbmFMRjTYA7rRJ0LP"},{"symbol":"LTCBTC","orderId":3,"clientOrderId":"z0KCjOdditiLS5ekAFtK81"}]}]"#).unwrap();
let expected_response : Vec<models::QueryMarginAccountsAllOcoResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryMarginAccountsAllOcoResponseInner>");
let resp = client.query_margin_accounts_all_oco(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_margin_accounts_all_oco_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryMarginAccountsAllOcoParams::builder().is_isolated("false".to_string()).symbol("symbol_example".to_string()).from_id(1).start_time(1623319461670).end_time(1641782889000).limit(500).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"orderListId":29,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"amEEAXryFzFwYF1FeRpUoZ","transactionTime":1565245913483,"symbol":"LTCBTC","isIsolated":true,"orders":[{"symbol":"LTCBTC","orderId":4,"clientOrderId":"oD7aesZqjEGlZrbtRpy5zB"},{"symbol":"LTCBTC","orderId":5,"clientOrderId":"Jr1h6xirOxgeJOUuYQS7V3"}]},{"orderListId":28,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"hG7hFNxJV6cZy3Ze4AUT4d","transactionTime":1565245913407,"symbol":"LTCBTC","orders":[{"symbol":"LTCBTC","orderId":2,"clientOrderId":"j6lFOfbmFMRjTYA7rRJ0LP"},{"symbol":"LTCBTC","orderId":3,"clientOrderId":"z0KCjOdditiLS5ekAFtK81"}]}]"#).unwrap();
let expected_response : Vec<models::QueryMarginAccountsAllOcoResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryMarginAccountsAllOcoResponseInner>");
let resp = client.query_margin_accounts_all_oco(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_margin_accounts_all_oco_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = QueryMarginAccountsAllOcoParams::builder().build().unwrap();
match client.query_margin_accounts_all_oco(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn query_margin_accounts_all_orders_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryMarginAccountsAllOrdersParams::builder("symbol_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"clientOrderId":"D2KDy4DIeS56PvkM13f8cP","cummulativeQuoteQty":"0.00000000","executedQty":"0.00000000","icebergQty":"0.00000000","isWorking":false,"orderId":41295,"origQty":"5.31000000","price":"0.22500000","side":"SELL","status":"CANCELED","stopPrice":"0.18000000","symbol":"BNBBTC","isIsolated":false,"time":1565769338806,"timeInForce":"GTC","type":"TAKE_PROFIT_LIMIT","selfTradePreventionMode":"NONE","updateTime":1565769342148},{"clientOrderId":"gXYtqhcEAs2Rn9SUD9nRKx","cummulativeQuoteQty":"0.00000000","executedQty":"0.00000000","icebergQty":"1.00000000","isWorking":true,"orderId":41296,"origQty":"6.65000000","price":"0.18000000","side":"SELL","status":"CANCELED","stopPrice":"0.00000000","symbol":"BNBBTC","isIsolated":false,"time":1565769348687,"timeInForce":"GTC","type":"LIMIT","selfTradePreventionMode":"NONE","updateTime":1565769352226}]"#).unwrap();
let expected_response : Vec<models::QueryMarginAccountsAllOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryMarginAccountsAllOrdersResponseInner>");
let resp = client.query_margin_accounts_all_orders(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_margin_accounts_all_orders_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryMarginAccountsAllOrdersParams::builder("symbol_example".to_string(),).is_isolated("false".to_string()).order_id(1).start_time(1623319461670).end_time(1641782889000).limit(500).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"clientOrderId":"D2KDy4DIeS56PvkM13f8cP","cummulativeQuoteQty":"0.00000000","executedQty":"0.00000000","icebergQty":"0.00000000","isWorking":false,"orderId":41295,"origQty":"5.31000000","price":"0.22500000","side":"SELL","status":"CANCELED","stopPrice":"0.18000000","symbol":"BNBBTC","isIsolated":false,"time":1565769338806,"timeInForce":"GTC","type":"TAKE_PROFIT_LIMIT","selfTradePreventionMode":"NONE","updateTime":1565769342148},{"clientOrderId":"gXYtqhcEAs2Rn9SUD9nRKx","cummulativeQuoteQty":"0.00000000","executedQty":"0.00000000","icebergQty":"1.00000000","isWorking":true,"orderId":41296,"origQty":"6.65000000","price":"0.18000000","side":"SELL","status":"CANCELED","stopPrice":"0.00000000","symbol":"BNBBTC","isIsolated":false,"time":1565769348687,"timeInForce":"GTC","type":"LIMIT","selfTradePreventionMode":"NONE","updateTime":1565769352226}]"#).unwrap();
let expected_response : Vec<models::QueryMarginAccountsAllOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryMarginAccountsAllOrdersResponseInner>");
let resp = client.query_margin_accounts_all_orders(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_margin_accounts_all_orders_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = QueryMarginAccountsAllOrdersParams::builder("symbol_example".to_string())
.build()
.unwrap();
match client.query_margin_accounts_all_orders(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn query_margin_accounts_oco_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryMarginAccountsOcoParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"orderListId":27,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"h2USkA5YQpaXHPIrkd96xE","transactionTime":1565245656253,"symbol":"LTCBTC","isIsolated":false,"orders":[{"symbol":"LTCBTC","orderId":4,"clientOrderId":"qD1gy3kc3Gx0rihm9Y3xwS"},{"symbol":"LTCBTC","orderId":5,"clientOrderId":"ARzZ9I00CPM8i3NhmU9Ega"}]}"#).unwrap();
let expected_response : models::QueryMarginAccountsOcoResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryMarginAccountsOcoResponse");
let resp = client.query_margin_accounts_oco(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_margin_accounts_oco_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryMarginAccountsOcoParams::builder().is_isolated("false".to_string()).symbol("symbol_example".to_string()).order_list_id(1).orig_client_order_id("1".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"orderListId":27,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"h2USkA5YQpaXHPIrkd96xE","transactionTime":1565245656253,"symbol":"LTCBTC","isIsolated":false,"orders":[{"symbol":"LTCBTC","orderId":4,"clientOrderId":"qD1gy3kc3Gx0rihm9Y3xwS"},{"symbol":"LTCBTC","orderId":5,"clientOrderId":"ARzZ9I00CPM8i3NhmU9Ega"}]}"#).unwrap();
let expected_response : models::QueryMarginAccountsOcoResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryMarginAccountsOcoResponse");
let resp = client.query_margin_accounts_oco(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_margin_accounts_oco_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = QueryMarginAccountsOcoParams::builder().build().unwrap();
match client.query_margin_accounts_oco(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn query_margin_accounts_open_oco_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryMarginAccountsOpenOcoParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"orderListId":31,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"wuB13fmulKj3YjdqWEcsnp","transactionTime":1565246080644,"symbol":"LTCBTC","isIsolated":false,"orders":[{"symbol":"LTCBTC","orderId":4,"clientOrderId":"r3EH2N76dHfLoSZWIUw1bT"},{"symbol":"LTCBTC","orderId":5,"clientOrderId":"Cv1SnyPD3qhqpbjpYEHbd2"}]}]"#).unwrap();
let expected_response : Vec<models::QueryMarginAccountsOpenOcoResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryMarginAccountsOpenOcoResponseInner>");
let resp = client.query_margin_accounts_open_oco(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_margin_accounts_open_oco_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryMarginAccountsOpenOcoParams::builder().is_isolated("false".to_string()).symbol("symbol_example".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"orderListId":31,"contingencyType":"OCO","listStatusType":"EXEC_STARTED","listOrderStatus":"EXECUTING","listClientOrderId":"wuB13fmulKj3YjdqWEcsnp","transactionTime":1565246080644,"symbol":"LTCBTC","isIsolated":false,"orders":[{"symbol":"LTCBTC","orderId":4,"clientOrderId":"r3EH2N76dHfLoSZWIUw1bT"},{"symbol":"LTCBTC","orderId":5,"clientOrderId":"Cv1SnyPD3qhqpbjpYEHbd2"}]}]"#).unwrap();
let expected_response : Vec<models::QueryMarginAccountsOpenOcoResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryMarginAccountsOpenOcoResponseInner>");
let resp = client.query_margin_accounts_open_oco(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_margin_accounts_open_oco_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = QueryMarginAccountsOpenOcoParams::builder().build().unwrap();
match client.query_margin_accounts_open_oco(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn query_margin_accounts_open_orders_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryMarginAccountsOpenOrdersParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"clientOrderId":"qhcZw71gAkCCTv0t0k8LUK","cummulativeQuoteQty":"0.00000000","executedQty":"0.00000000","icebergQty":"0.00000000","isWorking":true,"orderId":211842552,"origQty":"0.30000000","price":"0.00475010","side":"SELL","status":"NEW","stopPrice":"0.00000000","symbol":"BNBBTC","isIsolated":true,"time":1562040170089,"timeInForce":"GTC","type":"LIMIT","selfTradePreventionMode":"NONE","updateTime":1562040170089}]"#).unwrap();
let expected_response : Vec<models::QueryMarginAccountsOpenOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryMarginAccountsOpenOrdersResponseInner>");
let resp = client.query_margin_accounts_open_orders(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_margin_accounts_open_orders_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryMarginAccountsOpenOrdersParams::builder().symbol("symbol_example".to_string()).is_isolated("false".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"clientOrderId":"qhcZw71gAkCCTv0t0k8LUK","cummulativeQuoteQty":"0.00000000","executedQty":"0.00000000","icebergQty":"0.00000000","isWorking":true,"orderId":211842552,"origQty":"0.30000000","price":"0.00475010","side":"SELL","status":"NEW","stopPrice":"0.00000000","symbol":"BNBBTC","isIsolated":true,"time":1562040170089,"timeInForce":"GTC","type":"LIMIT","selfTradePreventionMode":"NONE","updateTime":1562040170089}]"#).unwrap();
let expected_response : Vec<models::QueryMarginAccountsOpenOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryMarginAccountsOpenOrdersResponseInner>");
let resp = client.query_margin_accounts_open_orders(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_margin_accounts_open_orders_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = QueryMarginAccountsOpenOrdersParams::builder()
.build()
.unwrap();
match client.query_margin_accounts_open_orders(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn query_margin_accounts_order_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryMarginAccountsOrderParams::builder("symbol_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"clientOrderId":"ZwfQzuDIGpceVhKW5DvCmO","cummulativeQuoteQty":"0.00000000","executedQty":"0.00000000","icebergQty":"0.00000000","isWorking":true,"orderId":213205622,"origQty":"0.30000000","price":"0.00493630","side":"SELL","status":"NEW","stopPrice":"0.00000000","symbol":"BNBBTC","isIsolated":true,"time":1562133008725,"timeInForce":"GTC","type":"LIMIT","selfTradePreventionMode":"NONE","updateTime":1562133008725}"#).unwrap();
let expected_response : models::QueryMarginAccountsOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryMarginAccountsOrderResponse");
let resp = client.query_margin_accounts_order(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_margin_accounts_order_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryMarginAccountsOrderParams::builder("symbol_example".to_string(),).is_isolated("false".to_string()).order_id(1).orig_client_order_id("1".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"clientOrderId":"ZwfQzuDIGpceVhKW5DvCmO","cummulativeQuoteQty":"0.00000000","executedQty":"0.00000000","icebergQty":"0.00000000","isWorking":true,"orderId":213205622,"origQty":"0.30000000","price":"0.00493630","side":"SELL","status":"NEW","stopPrice":"0.00000000","symbol":"BNBBTC","isIsolated":true,"time":1562133008725,"timeInForce":"GTC","type":"LIMIT","selfTradePreventionMode":"NONE","updateTime":1562133008725}"#).unwrap();
let expected_response : models::QueryMarginAccountsOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryMarginAccountsOrderResponse");
let resp = client.query_margin_accounts_order(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_margin_accounts_order_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = QueryMarginAccountsOrderParams::builder("symbol_example".to_string())
.build()
.unwrap();
match client.query_margin_accounts_order(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn query_margin_accounts_trade_list_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryMarginAccountsTradeListParams::builder("symbol_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"commission":"0.00006000","commissionAsset":"BTC","id":34,"isBestMatch":true,"isBuyer":false,"isMaker":false,"orderId":39324,"price":"0.02000000","qty":"3.00000000","symbol":"BNBBTC","isIsolated":false,"time":1561973357171}]"#).unwrap();
let expected_response : Vec<models::QueryMarginAccountsTradeListResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryMarginAccountsTradeListResponseInner>");
let resp = client.query_margin_accounts_trade_list(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_margin_accounts_trade_list_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryMarginAccountsTradeListParams::builder("symbol_example".to_string(),).is_isolated("false".to_string()).order_id(1).start_time(1623319461670).end_time(1641782889000).from_id(1).limit(500).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"commission":"0.00006000","commissionAsset":"BTC","id":34,"isBestMatch":true,"isBuyer":false,"isMaker":false,"orderId":39324,"price":"0.02000000","qty":"3.00000000","symbol":"BNBBTC","isIsolated":false,"time":1561973357171}]"#).unwrap();
let expected_response : Vec<models::QueryMarginAccountsTradeListResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryMarginAccountsTradeListResponseInner>");
let resp = client.query_margin_accounts_trade_list(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_margin_accounts_trade_list_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = QueryMarginAccountsTradeListParams::builder("symbol_example".to_string())
.build()
.unwrap();
match client.query_margin_accounts_trade_list(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn query_prevented_matches_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryPreventedMatchesParams::builder("symbol_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSDT","preventedMatchId":1,"takerOrderId":5,"makerSymbol":"BTCUSDT","makerOrderId":3,"tradeGroupId":1,"selfTradePreventionMode":"EXPIRE_MAKER","price":"1.100000","makerPreventedQuantity":"1.300000","transactTime":1669101687094}]"#).unwrap();
let expected_response : Vec<models::QueryPreventedMatchesResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryPreventedMatchesResponseInner>");
let resp = client.query_prevented_matches(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_prevented_matches_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryPreventedMatchesParams::builder("symbol_example".to_string(),).prevented_match_id(1).order_id(1).from_prevented_match_id(1).recv_window(5000).is_isolated("false".to_string()).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSDT","preventedMatchId":1,"takerOrderId":5,"makerSymbol":"BTCUSDT","makerOrderId":3,"tradeGroupId":1,"selfTradePreventionMode":"EXPIRE_MAKER","price":"1.100000","makerPreventedQuantity":"1.300000","transactTime":1669101687094}]"#).unwrap();
let expected_response : Vec<models::QueryPreventedMatchesResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryPreventedMatchesResponseInner>");
let resp = client.query_prevented_matches(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_prevented_matches_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = QueryPreventedMatchesParams::builder("symbol_example".to_string())
.build()
.unwrap();
match client.query_prevented_matches(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn query_special_key_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QuerySpecialKeyParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"apiKey":"npOzOAeLVgr2TuxWfNo43AaPWpBbJEoKezh1o8mSQb6ryE2odE11A4AoVlJbQoGx","ip":"0.0.0.0,192.168.0.1,192.168.0.2","apiName":"testName","type":"RSA","permissionMode":"TRADE"}"#).unwrap();
let expected_response : models::QuerySpecialKeyResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySpecialKeyResponse");
let resp = client.query_special_key(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_special_key_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QuerySpecialKeyParams::builder().symbol("symbol_example".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"apiKey":"npOzOAeLVgr2TuxWfNo43AaPWpBbJEoKezh1o8mSQb6ryE2odE11A4AoVlJbQoGx","ip":"0.0.0.0,192.168.0.1,192.168.0.2","apiName":"testName","type":"RSA","permissionMode":"TRADE"}"#).unwrap();
let expected_response : models::QuerySpecialKeyResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySpecialKeyResponse");
let resp = client.query_special_key(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_special_key_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = QuerySpecialKeyParams::builder().build().unwrap();
match client.query_special_key(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn query_special_key_list_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QuerySpecialKeyListParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"apiName":"testName1","apiKey":"znpOzOAeLVgr2TuxWfNo43AaPWpBbJEoKezh1o8mSQb6ryE2odE11A4AoVlJbQoG","ip":"192.168.0.1,192.168.0.2","type":"RSA","permissionMode":"TRADE"},{"apiName":"testName2","apiKey":"znpOzOAeLVgr2TuxWfNo43AaPWpBbJEoKezh1o8mSQb6ryE2odE11A4AoVlJbQoG","ip":"192.168.0.1,192.168.0.2","type":"Ed25519","permissionMode":"READ"}]"#).unwrap();
let expected_response : Vec<models::QuerySpecialKeyListResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QuerySpecialKeyListResponseInner>");
let resp = client.query_special_key_list(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_special_key_list_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QuerySpecialKeyListParams::builder().symbol("symbol_example".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"apiName":"testName1","apiKey":"znpOzOAeLVgr2TuxWfNo43AaPWpBbJEoKezh1o8mSQb6ryE2odE11A4AoVlJbQoG","ip":"192.168.0.1,192.168.0.2","type":"RSA","permissionMode":"TRADE"},{"apiName":"testName2","apiKey":"znpOzOAeLVgr2TuxWfNo43AaPWpBbJEoKezh1o8mSQb6ryE2odE11A4AoVlJbQoG","ip":"192.168.0.1,192.168.0.2","type":"Ed25519","permissionMode":"READ"}]"#).unwrap();
let expected_response : Vec<models::QuerySpecialKeyListResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QuerySpecialKeyListResponseInner>");
let resp = client.query_special_key_list(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_special_key_list_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = QuerySpecialKeyListParams::builder().build().unwrap();
match client.query_special_key_list(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn small_liability_exchange_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = SmallLiabilityExchangeParams::builder(["BTC".to_string()].to_vec())
.build()
.unwrap();
let expected_response = Value::Null;
let resp = client
.small_liability_exchange(params)
.await
.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn small_liability_exchange_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = SmallLiabilityExchangeParams::builder(["BTC".to_string()].to_vec())
.recv_window(5000)
.build()
.unwrap();
let expected_response = Value::Null;
let resp = client
.small_liability_exchange(params)
.await
.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn small_liability_exchange_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = SmallLiabilityExchangeParams::builder(["BTC".to_string()].to_vec())
.build()
.unwrap();
match client.small_liability_exchange(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
}