/*
 * 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");
                }
            }
        });
    }
}
