/*
 * Binance Derivatives Trading Portfolio Margin REST API
 *
 * OpenAPI Specification for the Binance Derivatives Trading Portfolio Margin 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::derivatives_trading_portfolio_margin::rest_api::models;

const HAS_TIME_UNIT: bool = false;

#[async_trait]
pub trait AccountApi: Send + Sync {
    async fn account_balance(
        &self,
        params: AccountBalanceParams,
    ) -> anyhow::Result<RestApiResponse<models::AccountBalanceResponse>>;
    async fn account_information(
        &self,
        params: AccountInformationParams,
    ) -> anyhow::Result<RestApiResponse<models::AccountInformationResponse>>;
    async fn bnb_transfer(
        &self,
        params: BnbTransferParams,
    ) -> anyhow::Result<RestApiResponse<models::BnbTransferResponse>>;
    async fn change_auto_repay_futures_status(
        &self,
        params: ChangeAutoRepayFuturesStatusParams,
    ) -> anyhow::Result<RestApiResponse<models::ChangeAutoRepayFuturesStatusResponse>>;
    async fn change_cm_initial_leverage(
        &self,
        params: ChangeCmInitialLeverageParams,
    ) -> anyhow::Result<RestApiResponse<models::ChangeCmInitialLeverageResponse>>;
    async fn change_cm_position_mode(
        &self,
        params: ChangeCmPositionModeParams,
    ) -> anyhow::Result<RestApiResponse<models::ChangeCmPositionModeResponse>>;
    async fn change_um_initial_leverage(
        &self,
        params: ChangeUmInitialLeverageParams,
    ) -> anyhow::Result<RestApiResponse<models::ChangeUmInitialLeverageResponse>>;
    async fn change_um_position_mode(
        &self,
        params: ChangeUmPositionModeParams,
    ) -> anyhow::Result<RestApiResponse<models::ChangeUmPositionModeResponse>>;
    async fn cm_notional_and_leverage_brackets(
        &self,
        params: CmNotionalAndLeverageBracketsParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::CmNotionalAndLeverageBracketsResponseInner>>>;
    async fn fund_auto_collection(
        &self,
        params: FundAutoCollectionParams,
    ) -> anyhow::Result<RestApiResponse<models::FundAutoCollectionResponse>>;
    async fn fund_collection_by_asset(
        &self,
        params: FundCollectionByAssetParams,
    ) -> anyhow::Result<RestApiResponse<models::FundCollectionByAssetResponse>>;
    async fn get_auto_repay_futures_status(
        &self,
        params: GetAutoRepayFuturesStatusParams,
    ) -> anyhow::Result<RestApiResponse<models::GetAutoRepayFuturesStatusResponse>>;
    async fn get_cm_account_detail(
        &self,
        params: GetCmAccountDetailParams,
    ) -> anyhow::Result<RestApiResponse<models::GetCmAccountDetailResponse>>;
    async fn get_cm_current_position_mode(
        &self,
        params: GetCmCurrentPositionModeParams,
    ) -> anyhow::Result<RestApiResponse<models::GetCmCurrentPositionModeResponse>>;
    async fn get_cm_income_history(
        &self,
        params: GetCmIncomeHistoryParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::GetCmIncomeHistoryResponseInner>>>;
    async fn get_download_id_for_um_futures_order_history(
        &self,
        params: GetDownloadIdForUmFuturesOrderHistoryParams,
    ) -> anyhow::Result<RestApiResponse<models::GetDownloadIdForUmFuturesOrderHistoryResponse>>;
    async fn get_download_id_for_um_futures_trade_history(
        &self,
        params: GetDownloadIdForUmFuturesTradeHistoryParams,
    ) -> anyhow::Result<RestApiResponse<models::GetDownloadIdForUmFuturesTradeHistoryResponse>>;
    async fn get_download_id_for_um_futures_transaction_history(
        &self,
        params: GetDownloadIdForUmFuturesTransactionHistoryParams,
    ) -> anyhow::Result<RestApiResponse<models::GetDownloadIdForUmFuturesTransactionHistoryResponse>>;
    async fn get_margin_borrow_loan_interest_history(
        &self,
        params: GetMarginBorrowLoanInterestHistoryParams,
    ) -> anyhow::Result<RestApiResponse<models::GetMarginBorrowLoanInterestHistoryResponse>>;
    async fn get_um_account_detail(
        &self,
        params: GetUmAccountDetailParams,
    ) -> anyhow::Result<RestApiResponse<models::GetUmAccountDetailResponse>>;
    async fn get_um_account_detail_v2(
        &self,
        params: GetUmAccountDetailV2Params,
    ) -> anyhow::Result<RestApiResponse<models::GetUmAccountDetailV2Response>>;
    async fn get_um_current_position_mode(
        &self,
        params: GetUmCurrentPositionModeParams,
    ) -> anyhow::Result<RestApiResponse<models::GetUmCurrentPositionModeResponse>>;
    async fn get_um_futures_order_download_link_by_id(
        &self,
        params: GetUmFuturesOrderDownloadLinkByIdParams,
    ) -> anyhow::Result<RestApiResponse<models::GetUmFuturesOrderDownloadLinkByIdResponse>>;
    async fn get_um_futures_trade_download_link_by_id(
        &self,
        params: GetUmFuturesTradeDownloadLinkByIdParams,
    ) -> anyhow::Result<RestApiResponse<models::GetUmFuturesTradeDownloadLinkByIdResponse>>;
    async fn get_um_futures_transaction_download_link_by_id(
        &self,
        params: GetUmFuturesTransactionDownloadLinkByIdParams,
    ) -> anyhow::Result<RestApiResponse<models::GetUmFuturesTransactionDownloadLinkByIdResponse>>;
    async fn get_um_income_history(
        &self,
        params: GetUmIncomeHistoryParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::GetUmIncomeHistoryResponseInner>>>;
    async fn get_user_commission_rate_for_cm(
        &self,
        params: GetUserCommissionRateForCmParams,
    ) -> anyhow::Result<RestApiResponse<models::GetUserCommissionRateForCmResponse>>;
    async fn get_user_commission_rate_for_um(
        &self,
        params: GetUserCommissionRateForUmParams,
    ) -> anyhow::Result<RestApiResponse<models::GetUserCommissionRateForUmResponse>>;
    async fn margin_max_borrow(
        &self,
        params: MarginMaxBorrowParams,
    ) -> anyhow::Result<RestApiResponse<models::MarginMaxBorrowResponse>>;
    async fn portfolio_margin_um_trading_quantitative_rules_indicators(
        &self,
        params: PortfolioMarginUmTradingQuantitativeRulesIndicatorsParams,
    ) -> anyhow::Result<
        RestApiResponse<models::PortfolioMarginUmTradingQuantitativeRulesIndicatorsResponse>,
    >;
    async fn query_cm_position_information(
        &self,
        params: QueryCmPositionInformationParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::QueryCmPositionInformationResponseInner>>>;
    async fn query_margin_loan_record(
        &self,
        params: QueryMarginLoanRecordParams,
    ) -> anyhow::Result<RestApiResponse<models::QueryMarginLoanRecordResponse>>;
    async fn query_margin_max_withdraw(
        &self,
        params: QueryMarginMaxWithdrawParams,
    ) -> anyhow::Result<RestApiResponse<models::QueryMarginMaxWithdrawResponse>>;
    async fn query_margin_repay_record(
        &self,
        params: QueryMarginRepayRecordParams,
    ) -> anyhow::Result<RestApiResponse<models::QueryMarginRepayRecordResponse>>;
    async fn query_portfolio_margin_negative_balance_interest_history(
        &self,
        params: QueryPortfolioMarginNegativeBalanceInterestHistoryParams,
    ) -> anyhow::Result<
        RestApiResponse<
            Vec<models::QueryPortfolioMarginNegativeBalanceInterestHistoryResponseInner>,
        >,
    >;
    async fn query_um_position_information(
        &self,
        params: QueryUmPositionInformationParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::QueryUmPositionInformationResponseInner>>>;
    async fn query_user_negative_balance_auto_exchange_record(
        &self,
        params: QueryUserNegativeBalanceAutoExchangeRecordParams,
    ) -> anyhow::Result<RestApiResponse<models::QueryUserNegativeBalanceAutoExchangeRecordResponse>>;
    async fn query_user_rate_limit(
        &self,
        params: QueryUserRateLimitParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::QueryUserRateLimitResponseInner>>>;
    async fn repay_futures_negative_balance(
        &self,
        params: RepayFuturesNegativeBalanceParams,
    ) -> anyhow::Result<RestApiResponse<models::RepayFuturesNegativeBalanceResponse>>;
    async fn um_futures_account_configuration(
        &self,
        params: UmFuturesAccountConfigurationParams,
    ) -> anyhow::Result<RestApiResponse<models::UmFuturesAccountConfigurationResponse>>;
    async fn um_futures_symbol_configuration(
        &self,
        params: UmFuturesSymbolConfigurationParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::UmFuturesSymbolConfigurationResponseInner>>>;
    async fn um_notional_and_leverage_brackets(
        &self,
        params: UmNotionalAndLeverageBracketsParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::UmNotionalAndLeverageBracketsResponseInner>>>;
}

#[derive(Debug, Clone)]
pub struct AccountApiClient {
    configuration: ConfigurationRestApi,
}

impl AccountApiClient {
    pub fn new(configuration: ConfigurationRestApi) -> Self {
        Self { configuration }
    }
}

/// Request parameters for the [`account_balance`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`account_balance`](#method.account_balance).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct AccountBalanceParams {
    ///
    /// The `asset` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub asset: Option<String>,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl AccountBalanceParams {
    /// Create a builder for [`account_balance`].
    ///
    #[must_use]
    pub fn builder() -> AccountBalanceParamsBuilder {
        AccountBalanceParamsBuilder::default()
    }
}
/// Request parameters for the [`account_information`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`account_information`](#method.account_information).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct AccountInformationParams {
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl AccountInformationParams {
    /// Create a builder for [`account_information`].
    ///
    #[must_use]
    pub fn builder() -> AccountInformationParamsBuilder {
        AccountInformationParamsBuilder::default()
    }
}
/// Request parameters for the [`bnb_transfer`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`bnb_transfer`](#method.bnb_transfer).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct BnbTransferParams {
    ///
    /// The `amount` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub amount: rust_decimal::Decimal,
    /// "`TO_UM","FROM_UM`"
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub transfer_side: String,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl BnbTransferParams {
    /// Create a builder for [`bnb_transfer`].
    ///
    /// Required parameters:
    ///
    /// * `amount` — `rust_decimal::Decimal`
    /// * `transfer_side` — \"`TO_UM`\",\"`FROM_UM`\"
    ///
    #[must_use]
    pub fn builder(
        amount: rust_decimal::Decimal,
        transfer_side: String,
    ) -> BnbTransferParamsBuilder {
        BnbTransferParamsBuilder::default()
            .amount(amount)
            .transfer_side(transfer_side)
    }
}
/// Request parameters for the [`change_auto_repay_futures_status`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`change_auto_repay_futures_status`](#method.change_auto_repay_futures_status).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct ChangeAutoRepayFuturesStatusParams {
    /// Default: `true`; `false` for turn off the auto-repay futures negative balance function
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub auto_repay: String,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl ChangeAutoRepayFuturesStatusParams {
    /// Create a builder for [`change_auto_repay_futures_status`].
    ///
    /// Required parameters:
    ///
    /// * `auto_repay` — Default: `true`; `false` for turn off the auto-repay futures negative balance function
    ///
    #[must_use]
    pub fn builder(auto_repay: String) -> ChangeAutoRepayFuturesStatusParamsBuilder {
        ChangeAutoRepayFuturesStatusParamsBuilder::default().auto_repay(auto_repay)
    }
}
/// Request parameters for the [`change_cm_initial_leverage`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`change_cm_initial_leverage`](#method.change_cm_initial_leverage).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct ChangeCmInitialLeverageParams {
    ///
    /// The `symbol` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub symbol: String,
    /// target initial leverage: int from 1 to 125
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub leverage: i64,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl ChangeCmInitialLeverageParams {
    /// Create a builder for [`change_cm_initial_leverage`].
    ///
    /// Required parameters:
    ///
    /// * `symbol` — String
    /// * `leverage` — target initial leverage: int from 1 to 125
    ///
    #[must_use]
    pub fn builder(symbol: String, leverage: i64) -> ChangeCmInitialLeverageParamsBuilder {
        ChangeCmInitialLeverageParamsBuilder::default()
            .symbol(symbol)
            .leverage(leverage)
    }
}
/// Request parameters for the [`change_cm_position_mode`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`change_cm_position_mode`](#method.change_cm_position_mode).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct ChangeCmPositionModeParams {
    /// "true": Hedge Mode; "false": One-way Mode
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub dual_side_position: String,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl ChangeCmPositionModeParams {
    /// Create a builder for [`change_cm_position_mode`].
    ///
    /// Required parameters:
    ///
    /// * `dual_side_position` — \"true\": Hedge Mode; \"false\": One-way Mode
    ///
    #[must_use]
    pub fn builder(dual_side_position: String) -> ChangeCmPositionModeParamsBuilder {
        ChangeCmPositionModeParamsBuilder::default().dual_side_position(dual_side_position)
    }
}
/// Request parameters for the [`change_um_initial_leverage`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`change_um_initial_leverage`](#method.change_um_initial_leverage).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct ChangeUmInitialLeverageParams {
    ///
    /// The `symbol` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub symbol: String,
    /// target initial leverage: int from 1 to 125
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub leverage: i64,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl ChangeUmInitialLeverageParams {
    /// Create a builder for [`change_um_initial_leverage`].
    ///
    /// Required parameters:
    ///
    /// * `symbol` — String
    /// * `leverage` — target initial leverage: int from 1 to 125
    ///
    #[must_use]
    pub fn builder(symbol: String, leverage: i64) -> ChangeUmInitialLeverageParamsBuilder {
        ChangeUmInitialLeverageParamsBuilder::default()
            .symbol(symbol)
            .leverage(leverage)
    }
}
/// Request parameters for the [`change_um_position_mode`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`change_um_position_mode`](#method.change_um_position_mode).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct ChangeUmPositionModeParams {
    /// "true": Hedge Mode; "false": One-way Mode
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub dual_side_position: String,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl ChangeUmPositionModeParams {
    /// Create a builder for [`change_um_position_mode`].
    ///
    /// Required parameters:
    ///
    /// * `dual_side_position` — \"true\": Hedge Mode; \"false\": One-way Mode
    ///
    #[must_use]
    pub fn builder(dual_side_position: String) -> ChangeUmPositionModeParamsBuilder {
        ChangeUmPositionModeParamsBuilder::default().dual_side_position(dual_side_position)
    }
}
/// Request parameters for the [`cm_notional_and_leverage_brackets`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`cm_notional_and_leverage_brackets`](#method.cm_notional_and_leverage_brackets).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct CmNotionalAndLeverageBracketsParams {
    ///
    /// The `symbol` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub symbol: Option<String>,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl CmNotionalAndLeverageBracketsParams {
    /// Create a builder for [`cm_notional_and_leverage_brackets`].
    ///
    #[must_use]
    pub fn builder() -> CmNotionalAndLeverageBracketsParamsBuilder {
        CmNotionalAndLeverageBracketsParamsBuilder::default()
    }
}
/// Request parameters for the [`fund_auto_collection`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`fund_auto_collection`](#method.fund_auto_collection).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct FundAutoCollectionParams {
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl FundAutoCollectionParams {
    /// Create a builder for [`fund_auto_collection`].
    ///
    #[must_use]
    pub fn builder() -> FundAutoCollectionParamsBuilder {
        FundAutoCollectionParamsBuilder::default()
    }
}
/// Request parameters for the [`fund_collection_by_asset`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`fund_collection_by_asset`](#method.fund_collection_by_asset).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct FundCollectionByAssetParams {
    ///
    /// The `asset` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub asset: String,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl FundCollectionByAssetParams {
    /// Create a builder for [`fund_collection_by_asset`].
    ///
    /// Required parameters:
    ///
    /// * `asset` — String
    ///
    #[must_use]
    pub fn builder(asset: String) -> FundCollectionByAssetParamsBuilder {
        FundCollectionByAssetParamsBuilder::default().asset(asset)
    }
}
/// Request parameters for the [`get_auto_repay_futures_status`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_auto_repay_futures_status`](#method.get_auto_repay_futures_status).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetAutoRepayFuturesStatusParams {
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetAutoRepayFuturesStatusParams {
    /// Create a builder for [`get_auto_repay_futures_status`].
    ///
    #[must_use]
    pub fn builder() -> GetAutoRepayFuturesStatusParamsBuilder {
        GetAutoRepayFuturesStatusParamsBuilder::default()
    }
}
/// Request parameters for the [`get_cm_account_detail`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_cm_account_detail`](#method.get_cm_account_detail).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetCmAccountDetailParams {
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetCmAccountDetailParams {
    /// Create a builder for [`get_cm_account_detail`].
    ///
    #[must_use]
    pub fn builder() -> GetCmAccountDetailParamsBuilder {
        GetCmAccountDetailParamsBuilder::default()
    }
}
/// Request parameters for the [`get_cm_current_position_mode`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_cm_current_position_mode`](#method.get_cm_current_position_mode).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetCmCurrentPositionModeParams {
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetCmCurrentPositionModeParams {
    /// Create a builder for [`get_cm_current_position_mode`].
    ///
    #[must_use]
    pub fn builder() -> GetCmCurrentPositionModeParamsBuilder {
        GetCmCurrentPositionModeParamsBuilder::default()
    }
}
/// Request parameters for the [`get_cm_income_history`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_cm_income_history`](#method.get_cm_income_history).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetCmIncomeHistoryParams {
    ///
    /// The `symbol` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub symbol: Option<String>,
    /// TRANSFER, `WELCOME_BONUS`, `REALIZED_PNL`, `FUNDING_FEE`, COMMISSION, `INSURANCE_CLEAR`, `REFERRAL_KICKBACK`, `COMMISSION_REBATE`, `API_REBATE`, `CONTEST_REWARD`, `CROSS_COLLATERAL_TRANSFER`, `OPTIONS_PREMIUM_FEE`, `OPTIONS_SETTLE_PROFIT`, `INTERNAL_TRANSFER`, `AUTO_EXCHANGE`, `DELIVERED_SETTELMENT`, `COIN_SWAP_DEPOSIT`, `COIN_SWAP_WITHDRAW`, `POSITION_LIMIT_INCREASE_FEE`
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub income_type: Option<String>,
    /// Timestamp in ms to get funding from INCLUSIVE.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub start_time: Option<i64>,
    /// Timestamp in ms to get funding until INCLUSIVE.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub end_time: Option<i64>,
    ///
    /// The `page` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub page: Option<i64>,
    /// Default 100; max 1000
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub limit: Option<i64>,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetCmIncomeHistoryParams {
    /// Create a builder for [`get_cm_income_history`].
    ///
    #[must_use]
    pub fn builder() -> GetCmIncomeHistoryParamsBuilder {
        GetCmIncomeHistoryParamsBuilder::default()
    }
}
/// Request parameters for the [`get_download_id_for_um_futures_order_history`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_download_id_for_um_futures_order_history`](#method.get_download_id_for_um_futures_order_history).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetDownloadIdForUmFuturesOrderHistoryParams {
    ///
    /// The `start_time` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub start_time: i64,
    ///
    /// The `end_time` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub end_time: i64,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetDownloadIdForUmFuturesOrderHistoryParams {
    /// Create a builder for [`get_download_id_for_um_futures_order_history`].
    ///
    /// Required parameters:
    ///
    /// * `start_time` — i64
    /// * `end_time` — i64
    ///
    #[must_use]
    pub fn builder(
        start_time: i64,
        end_time: i64,
    ) -> GetDownloadIdForUmFuturesOrderHistoryParamsBuilder {
        GetDownloadIdForUmFuturesOrderHistoryParamsBuilder::default()
            .start_time(start_time)
            .end_time(end_time)
    }
}
/// Request parameters for the [`get_download_id_for_um_futures_trade_history`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_download_id_for_um_futures_trade_history`](#method.get_download_id_for_um_futures_trade_history).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetDownloadIdForUmFuturesTradeHistoryParams {
    ///
    /// The `start_time` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub start_time: i64,
    ///
    /// The `end_time` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub end_time: i64,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetDownloadIdForUmFuturesTradeHistoryParams {
    /// Create a builder for [`get_download_id_for_um_futures_trade_history`].
    ///
    /// Required parameters:
    ///
    /// * `start_time` — i64
    /// * `end_time` — i64
    ///
    #[must_use]
    pub fn builder(
        start_time: i64,
        end_time: i64,
    ) -> GetDownloadIdForUmFuturesTradeHistoryParamsBuilder {
        GetDownloadIdForUmFuturesTradeHistoryParamsBuilder::default()
            .start_time(start_time)
            .end_time(end_time)
    }
}
/// Request parameters for the [`get_download_id_for_um_futures_transaction_history`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_download_id_for_um_futures_transaction_history`](#method.get_download_id_for_um_futures_transaction_history).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetDownloadIdForUmFuturesTransactionHistoryParams {
    ///
    /// The `start_time` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub start_time: i64,
    ///
    /// The `end_time` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub end_time: i64,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetDownloadIdForUmFuturesTransactionHistoryParams {
    /// Create a builder for [`get_download_id_for_um_futures_transaction_history`].
    ///
    /// Required parameters:
    ///
    /// * `start_time` — i64
    /// * `end_time` — i64
    ///
    #[must_use]
    pub fn builder(
        start_time: i64,
        end_time: i64,
    ) -> GetDownloadIdForUmFuturesTransactionHistoryParamsBuilder {
        GetDownloadIdForUmFuturesTransactionHistoryParamsBuilder::default()
            .start_time(start_time)
            .end_time(end_time)
    }
}
/// Request parameters for the [`get_margin_borrow_loan_interest_history`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_margin_borrow_loan_interest_history`](#method.get_margin_borrow_loan_interest_history).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetMarginBorrowLoanInterestHistoryParams {
    ///
    /// The `asset` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub asset: Option<String>,
    /// Timestamp in ms to get funding from INCLUSIVE.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub start_time: Option<i64>,
    /// Timestamp in ms to get funding until INCLUSIVE.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub end_time: Option<i64>,
    /// 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>,
    /// Default: `false`. Set to `true` for archived data from 6 months ago
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub archived: Option<String>,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetMarginBorrowLoanInterestHistoryParams {
    /// Create a builder for [`get_margin_borrow_loan_interest_history`].
    ///
    #[must_use]
    pub fn builder() -> GetMarginBorrowLoanInterestHistoryParamsBuilder {
        GetMarginBorrowLoanInterestHistoryParamsBuilder::default()
    }
}
/// Request parameters for the [`get_um_account_detail`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_um_account_detail`](#method.get_um_account_detail).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetUmAccountDetailParams {
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetUmAccountDetailParams {
    /// Create a builder for [`get_um_account_detail`].
    ///
    #[must_use]
    pub fn builder() -> GetUmAccountDetailParamsBuilder {
        GetUmAccountDetailParamsBuilder::default()
    }
}
/// Request parameters for the [`get_um_account_detail_v2`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_um_account_detail_v2`](#method.get_um_account_detail_v2).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetUmAccountDetailV2Params {
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetUmAccountDetailV2Params {
    /// Create a builder for [`get_um_account_detail_v2`].
    ///
    #[must_use]
    pub fn builder() -> GetUmAccountDetailV2ParamsBuilder {
        GetUmAccountDetailV2ParamsBuilder::default()
    }
}
/// Request parameters for the [`get_um_current_position_mode`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_um_current_position_mode`](#method.get_um_current_position_mode).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetUmCurrentPositionModeParams {
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetUmCurrentPositionModeParams {
    /// Create a builder for [`get_um_current_position_mode`].
    ///
    #[must_use]
    pub fn builder() -> GetUmCurrentPositionModeParamsBuilder {
        GetUmCurrentPositionModeParamsBuilder::default()
    }
}
/// Request parameters for the [`get_um_futures_order_download_link_by_id`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_um_futures_order_download_link_by_id`](#method.get_um_futures_order_download_link_by_id).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetUmFuturesOrderDownloadLinkByIdParams {
    /// get by download id api
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub download_id: String,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetUmFuturesOrderDownloadLinkByIdParams {
    /// Create a builder for [`get_um_futures_order_download_link_by_id`].
    ///
    /// Required parameters:
    ///
    /// * `download_id` — get by download id api
    ///
    #[must_use]
    pub fn builder(download_id: String) -> GetUmFuturesOrderDownloadLinkByIdParamsBuilder {
        GetUmFuturesOrderDownloadLinkByIdParamsBuilder::default().download_id(download_id)
    }
}
/// Request parameters for the [`get_um_futures_trade_download_link_by_id`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_um_futures_trade_download_link_by_id`](#method.get_um_futures_trade_download_link_by_id).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetUmFuturesTradeDownloadLinkByIdParams {
    /// get by download id api
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub download_id: String,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetUmFuturesTradeDownloadLinkByIdParams {
    /// Create a builder for [`get_um_futures_trade_download_link_by_id`].
    ///
    /// Required parameters:
    ///
    /// * `download_id` — get by download id api
    ///
    #[must_use]
    pub fn builder(download_id: String) -> GetUmFuturesTradeDownloadLinkByIdParamsBuilder {
        GetUmFuturesTradeDownloadLinkByIdParamsBuilder::default().download_id(download_id)
    }
}
/// Request parameters for the [`get_um_futures_transaction_download_link_by_id`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_um_futures_transaction_download_link_by_id`](#method.get_um_futures_transaction_download_link_by_id).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetUmFuturesTransactionDownloadLinkByIdParams {
    /// get by download id api
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub download_id: String,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetUmFuturesTransactionDownloadLinkByIdParams {
    /// Create a builder for [`get_um_futures_transaction_download_link_by_id`].
    ///
    /// Required parameters:
    ///
    /// * `download_id` — get by download id api
    ///
    #[must_use]
    pub fn builder(download_id: String) -> GetUmFuturesTransactionDownloadLinkByIdParamsBuilder {
        GetUmFuturesTransactionDownloadLinkByIdParamsBuilder::default().download_id(download_id)
    }
}
/// Request parameters for the [`get_um_income_history`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_um_income_history`](#method.get_um_income_history).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetUmIncomeHistoryParams {
    ///
    /// The `symbol` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub symbol: Option<String>,
    /// TRANSFER, `WELCOME_BONUS`, `REALIZED_PNL`, `FUNDING_FEE`, COMMISSION, `INSURANCE_CLEAR`, `REFERRAL_KICKBACK`, `COMMISSION_REBATE`, `API_REBATE`, `CONTEST_REWARD`, `CROSS_COLLATERAL_TRANSFER`, `OPTIONS_PREMIUM_FEE`, `OPTIONS_SETTLE_PROFIT`, `INTERNAL_TRANSFER`, `AUTO_EXCHANGE`, `DELIVERED_SETTELMENT`, `COIN_SWAP_DEPOSIT`, `COIN_SWAP_WITHDRAW`, `POSITION_LIMIT_INCREASE_FEE`
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub income_type: Option<String>,
    /// Timestamp in ms to get funding from INCLUSIVE.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub start_time: Option<i64>,
    /// Timestamp in ms to get funding until INCLUSIVE.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub end_time: Option<i64>,
    ///
    /// The `page` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub page: Option<i64>,
    /// Default 100; max 1000
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub limit: Option<i64>,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetUmIncomeHistoryParams {
    /// Create a builder for [`get_um_income_history`].
    ///
    #[must_use]
    pub fn builder() -> GetUmIncomeHistoryParamsBuilder {
        GetUmIncomeHistoryParamsBuilder::default()
    }
}
/// Request parameters for the [`get_user_commission_rate_for_cm`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_user_commission_rate_for_cm`](#method.get_user_commission_rate_for_cm).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetUserCommissionRateForCmParams {
    ///
    /// The `symbol` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub symbol: String,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetUserCommissionRateForCmParams {
    /// Create a builder for [`get_user_commission_rate_for_cm`].
    ///
    /// Required parameters:
    ///
    /// * `symbol` — String
    ///
    #[must_use]
    pub fn builder(symbol: String) -> GetUserCommissionRateForCmParamsBuilder {
        GetUserCommissionRateForCmParamsBuilder::default().symbol(symbol)
    }
}
/// Request parameters for the [`get_user_commission_rate_for_um`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_user_commission_rate_for_um`](#method.get_user_commission_rate_for_um).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetUserCommissionRateForUmParams {
    ///
    /// The `symbol` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub symbol: String,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl GetUserCommissionRateForUmParams {
    /// Create a builder for [`get_user_commission_rate_for_um`].
    ///
    /// Required parameters:
    ///
    /// * `symbol` — String
    ///
    #[must_use]
    pub fn builder(symbol: String) -> GetUserCommissionRateForUmParamsBuilder {
        GetUserCommissionRateForUmParamsBuilder::default().symbol(symbol)
    }
}
/// Request parameters for the [`margin_max_borrow`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`margin_max_borrow`](#method.margin_max_borrow).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct MarginMaxBorrowParams {
    ///
    /// The `asset` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub asset: String,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl MarginMaxBorrowParams {
    /// Create a builder for [`margin_max_borrow`].
    ///
    /// Required parameters:
    ///
    /// * `asset` — String
    ///
    #[must_use]
    pub fn builder(asset: String) -> MarginMaxBorrowParamsBuilder {
        MarginMaxBorrowParamsBuilder::default().asset(asset)
    }
}
/// Request parameters for the [`portfolio_margin_um_trading_quantitative_rules_indicators`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`portfolio_margin_um_trading_quantitative_rules_indicators`](#method.portfolio_margin_um_trading_quantitative_rules_indicators).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct PortfolioMarginUmTradingQuantitativeRulesIndicatorsParams {
    ///
    /// The `symbol` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub symbol: Option<String>,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl PortfolioMarginUmTradingQuantitativeRulesIndicatorsParams {
    /// Create a builder for [`portfolio_margin_um_trading_quantitative_rules_indicators`].
    ///
    #[must_use]
    pub fn builder() -> PortfolioMarginUmTradingQuantitativeRulesIndicatorsParamsBuilder {
        PortfolioMarginUmTradingQuantitativeRulesIndicatorsParamsBuilder::default()
    }
}
/// Request parameters for the [`query_cm_position_information`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_cm_position_information`](#method.query_cm_position_information).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryCmPositionInformationParams {
    ///
    /// The `margin_asset` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub margin_asset: Option<String>,
    ///
    /// The `pair` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub pair: Option<String>,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl QueryCmPositionInformationParams {
    /// Create a builder for [`query_cm_position_information`].
    ///
    #[must_use]
    pub fn builder() -> QueryCmPositionInformationParamsBuilder {
        QueryCmPositionInformationParamsBuilder::default()
    }
}
/// Request parameters for the [`query_margin_loan_record`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_margin_loan_record`](#method.query_margin_loan_record).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryMarginLoanRecordParams {
    ///
    /// The `asset` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub asset: String,
    /// the `tranId` in `POST/papi/v1/marginLoan`
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub tx_id: Option<i64>,
    /// Timestamp in ms to get funding from INCLUSIVE.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub start_time: Option<i64>,
    /// Timestamp in ms to get funding until INCLUSIVE.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub end_time: Option<i64>,
    /// 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>,
    /// Default: `false`. Set to `true` for archived data from 6 months ago
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub archived: Option<String>,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl QueryMarginLoanRecordParams {
    /// Create a builder for [`query_margin_loan_record`].
    ///
    /// Required parameters:
    ///
    /// * `asset` — String
    ///
    #[must_use]
    pub fn builder(asset: String) -> QueryMarginLoanRecordParamsBuilder {
        QueryMarginLoanRecordParamsBuilder::default().asset(asset)
    }
}
/// Request parameters for the [`query_margin_max_withdraw`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_margin_max_withdraw`](#method.query_margin_max_withdraw).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryMarginMaxWithdrawParams {
    ///
    /// The `asset` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub asset: String,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl QueryMarginMaxWithdrawParams {
    /// Create a builder for [`query_margin_max_withdraw`].
    ///
    /// Required parameters:
    ///
    /// * `asset` — String
    ///
    #[must_use]
    pub fn builder(asset: String) -> QueryMarginMaxWithdrawParamsBuilder {
        QueryMarginMaxWithdrawParamsBuilder::default().asset(asset)
    }
}
/// Request parameters for the [`query_margin_repay_record`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_margin_repay_record`](#method.query_margin_repay_record).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryMarginRepayRecordParams {
    ///
    /// The `asset` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub asset: String,
    /// the `tranId` in `POST/papi/v1/marginLoan`
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub tx_id: Option<i64>,
    /// Timestamp in ms to get funding from INCLUSIVE.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub start_time: Option<i64>,
    /// Timestamp in ms to get funding until INCLUSIVE.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub end_time: Option<i64>,
    /// 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>,
    /// Default: `false`. Set to `true` for archived data from 6 months ago
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub archived: Option<String>,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl QueryMarginRepayRecordParams {
    /// Create a builder for [`query_margin_repay_record`].
    ///
    /// Required parameters:
    ///
    /// * `asset` — String
    ///
    #[must_use]
    pub fn builder(asset: String) -> QueryMarginRepayRecordParamsBuilder {
        QueryMarginRepayRecordParamsBuilder::default().asset(asset)
    }
}
/// Request parameters for the [`query_portfolio_margin_negative_balance_interest_history`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_portfolio_margin_negative_balance_interest_history`](#method.query_portfolio_margin_negative_balance_interest_history).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryPortfolioMarginNegativeBalanceInterestHistoryParams {
    ///
    /// The `asset` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub asset: Option<String>,
    /// Timestamp in ms to get funding from INCLUSIVE.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub start_time: Option<i64>,
    /// Timestamp in ms to get funding until INCLUSIVE.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub end_time: Option<i64>,
    /// Default:10 Max:100
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub size: Option<i64>,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl QueryPortfolioMarginNegativeBalanceInterestHistoryParams {
    /// Create a builder for [`query_portfolio_margin_negative_balance_interest_history`].
    ///
    #[must_use]
    pub fn builder() -> QueryPortfolioMarginNegativeBalanceInterestHistoryParamsBuilder {
        QueryPortfolioMarginNegativeBalanceInterestHistoryParamsBuilder::default()
    }
}
/// Request parameters for the [`query_um_position_information`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_um_position_information`](#method.query_um_position_information).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryUmPositionInformationParams {
    ///
    /// The `symbol` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub symbol: Option<String>,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl QueryUmPositionInformationParams {
    /// Create a builder for [`query_um_position_information`].
    ///
    #[must_use]
    pub fn builder() -> QueryUmPositionInformationParamsBuilder {
        QueryUmPositionInformationParamsBuilder::default()
    }
}
/// Request parameters for the [`query_user_negative_balance_auto_exchange_record`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_user_negative_balance_auto_exchange_record`](#method.query_user_negative_balance_auto_exchange_record).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryUserNegativeBalanceAutoExchangeRecordParams {
    ///
    /// The `start_time` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub start_time: i64,
    ///
    /// The `end_time` parameter.
    ///
    /// This field is **required.
    #[builder(setter(into))]
    pub end_time: i64,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl QueryUserNegativeBalanceAutoExchangeRecordParams {
    /// Create a builder for [`query_user_negative_balance_auto_exchange_record`].
    ///
    /// Required parameters:
    ///
    /// * `start_time` — i64
    /// * `end_time` — i64
    ///
    #[must_use]
    pub fn builder(
        start_time: i64,
        end_time: i64,
    ) -> QueryUserNegativeBalanceAutoExchangeRecordParamsBuilder {
        QueryUserNegativeBalanceAutoExchangeRecordParamsBuilder::default()
            .start_time(start_time)
            .end_time(end_time)
    }
}
/// Request parameters for the [`query_user_rate_limit`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_user_rate_limit`](#method.query_user_rate_limit).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryUserRateLimitParams {
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl QueryUserRateLimitParams {
    /// Create a builder for [`query_user_rate_limit`].
    ///
    #[must_use]
    pub fn builder() -> QueryUserRateLimitParamsBuilder {
        QueryUserRateLimitParamsBuilder::default()
    }
}
/// Request parameters for the [`repay_futures_negative_balance`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`repay_futures_negative_balance`](#method.repay_futures_negative_balance).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct RepayFuturesNegativeBalanceParams {
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl RepayFuturesNegativeBalanceParams {
    /// Create a builder for [`repay_futures_negative_balance`].
    ///
    #[must_use]
    pub fn builder() -> RepayFuturesNegativeBalanceParamsBuilder {
        RepayFuturesNegativeBalanceParamsBuilder::default()
    }
}
/// Request parameters for the [`um_futures_account_configuration`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`um_futures_account_configuration`](#method.um_futures_account_configuration).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct UmFuturesAccountConfigurationParams {
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl UmFuturesAccountConfigurationParams {
    /// Create a builder for [`um_futures_account_configuration`].
    ///
    #[must_use]
    pub fn builder() -> UmFuturesAccountConfigurationParamsBuilder {
        UmFuturesAccountConfigurationParamsBuilder::default()
    }
}
/// Request parameters for the [`um_futures_symbol_configuration`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`um_futures_symbol_configuration`](#method.um_futures_symbol_configuration).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct UmFuturesSymbolConfigurationParams {
    ///
    /// The `symbol` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub symbol: Option<String>,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl UmFuturesSymbolConfigurationParams {
    /// Create a builder for [`um_futures_symbol_configuration`].
    ///
    #[must_use]
    pub fn builder() -> UmFuturesSymbolConfigurationParamsBuilder {
        UmFuturesSymbolConfigurationParamsBuilder::default()
    }
}
/// Request parameters for the [`um_notional_and_leverage_brackets`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`um_notional_and_leverage_brackets`](#method.um_notional_and_leverage_brackets).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct UmNotionalAndLeverageBracketsParams {
    ///
    /// The `symbol` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub symbol: Option<String>,
    ///
    /// The `recv_window` parameter.
    ///
    /// This field is **optional.
    #[builder(setter(into), default)]
    pub recv_window: Option<i64>,
}

impl UmNotionalAndLeverageBracketsParams {
    /// Create a builder for [`um_notional_and_leverage_brackets`].
    ///
    #[must_use]
    pub fn builder() -> UmNotionalAndLeverageBracketsParamsBuilder {
        UmNotionalAndLeverageBracketsParamsBuilder::default()
    }
}

#[async_trait]
impl AccountApi for AccountApiClient {
    async fn account_balance(
        &self,
        params: AccountBalanceParams,
    ) -> anyhow::Result<RestApiResponse<models::AccountBalanceResponse>> {
        let AccountBalanceParams { asset, recv_window } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        if let Some(rw) = asset {
            query_params.insert("asset".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::AccountBalanceResponse>(
            &self.configuration,
            "/papi/v1/balance",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn account_information(
        &self,
        params: AccountInformationParams,
    ) -> anyhow::Result<RestApiResponse<models::AccountInformationResponse>> {
        let AccountInformationParams { 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::<models::AccountInformationResponse>(
            &self.configuration,
            "/papi/v1/account",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn bnb_transfer(
        &self,
        params: BnbTransferParams,
    ) -> anyhow::Result<RestApiResponse<models::BnbTransferResponse>> {
        let BnbTransferParams {
            amount,
            transfer_side,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("amount".to_string(), json!(amount));

        query_params.insert("transferSide".to_string(), json!(transfer_side));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::BnbTransferResponse>(
            &self.configuration,
            "/papi/v1/bnb-transfer",
            reqwest::Method::POST,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn change_auto_repay_futures_status(
        &self,
        params: ChangeAutoRepayFuturesStatusParams,
    ) -> anyhow::Result<RestApiResponse<models::ChangeAutoRepayFuturesStatusResponse>> {
        let ChangeAutoRepayFuturesStatusParams {
            auto_repay,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("autoRepay".to_string(), json!(auto_repay));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::ChangeAutoRepayFuturesStatusResponse>(
            &self.configuration,
            "/papi/v1/repay-futures-switch",
            reqwest::Method::POST,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn change_cm_initial_leverage(
        &self,
        params: ChangeCmInitialLeverageParams,
    ) -> anyhow::Result<RestApiResponse<models::ChangeCmInitialLeverageResponse>> {
        let ChangeCmInitialLeverageParams {
            symbol,
            leverage,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("symbol".to_string(), json!(symbol));

        query_params.insert("leverage".to_string(), json!(leverage));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::ChangeCmInitialLeverageResponse>(
            &self.configuration,
            "/papi/v1/cm/leverage",
            reqwest::Method::POST,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn change_cm_position_mode(
        &self,
        params: ChangeCmPositionModeParams,
    ) -> anyhow::Result<RestApiResponse<models::ChangeCmPositionModeResponse>> {
        let ChangeCmPositionModeParams {
            dual_side_position,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("dualSidePosition".to_string(), json!(dual_side_position));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::ChangeCmPositionModeResponse>(
            &self.configuration,
            "/papi/v1/cm/positionSide/dual",
            reqwest::Method::POST,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn change_um_initial_leverage(
        &self,
        params: ChangeUmInitialLeverageParams,
    ) -> anyhow::Result<RestApiResponse<models::ChangeUmInitialLeverageResponse>> {
        let ChangeUmInitialLeverageParams {
            symbol,
            leverage,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("symbol".to_string(), json!(symbol));

        query_params.insert("leverage".to_string(), json!(leverage));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::ChangeUmInitialLeverageResponse>(
            &self.configuration,
            "/papi/v1/um/leverage",
            reqwest::Method::POST,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn change_um_position_mode(
        &self,
        params: ChangeUmPositionModeParams,
    ) -> anyhow::Result<RestApiResponse<models::ChangeUmPositionModeResponse>> {
        let ChangeUmPositionModeParams {
            dual_side_position,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("dualSidePosition".to_string(), json!(dual_side_position));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::ChangeUmPositionModeResponse>(
            &self.configuration,
            "/papi/v1/um/positionSide/dual",
            reqwest::Method::POST,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn cm_notional_and_leverage_brackets(
        &self,
        params: CmNotionalAndLeverageBracketsParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::CmNotionalAndLeverageBracketsResponseInner>>>
    {
        let CmNotionalAndLeverageBracketsParams {
            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::CmNotionalAndLeverageBracketsResponseInner>>(
            &self.configuration,
            "/papi/v1/cm/leverageBracket",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn fund_auto_collection(
        &self,
        params: FundAutoCollectionParams,
    ) -> anyhow::Result<RestApiResponse<models::FundAutoCollectionResponse>> {
        let FundAutoCollectionParams { 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::<models::FundAutoCollectionResponse>(
            &self.configuration,
            "/papi/v1/auto-collection",
            reqwest::Method::POST,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn fund_collection_by_asset(
        &self,
        params: FundCollectionByAssetParams,
    ) -> anyhow::Result<RestApiResponse<models::FundCollectionByAssetResponse>> {
        let FundCollectionByAssetParams { asset, recv_window } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("asset".to_string(), json!(asset));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::FundCollectionByAssetResponse>(
            &self.configuration,
            "/papi/v1/asset-collection",
            reqwest::Method::POST,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_auto_repay_futures_status(
        &self,
        params: GetAutoRepayFuturesStatusParams,
    ) -> anyhow::Result<RestApiResponse<models::GetAutoRepayFuturesStatusResponse>> {
        let GetAutoRepayFuturesStatusParams { 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::<models::GetAutoRepayFuturesStatusResponse>(
            &self.configuration,
            "/papi/v1/repay-futures-switch",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_cm_account_detail(
        &self,
        params: GetCmAccountDetailParams,
    ) -> anyhow::Result<RestApiResponse<models::GetCmAccountDetailResponse>> {
        let GetCmAccountDetailParams { 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::<models::GetCmAccountDetailResponse>(
            &self.configuration,
            "/papi/v1/cm/account",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_cm_current_position_mode(
        &self,
        params: GetCmCurrentPositionModeParams,
    ) -> anyhow::Result<RestApiResponse<models::GetCmCurrentPositionModeResponse>> {
        let GetCmCurrentPositionModeParams { 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::<models::GetCmCurrentPositionModeResponse>(
            &self.configuration,
            "/papi/v1/cm/positionSide/dual",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_cm_income_history(
        &self,
        params: GetCmIncomeHistoryParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::GetCmIncomeHistoryResponseInner>>> {
        let GetCmIncomeHistoryParams {
            symbol,
            income_type,
            start_time,
            end_time,
            page,
            limit,
            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) = income_type {
            query_params.insert("incomeType".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) = page {
            query_params.insert("page".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::GetCmIncomeHistoryResponseInner>>(
            &self.configuration,
            "/papi/v1/cm/income",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_download_id_for_um_futures_order_history(
        &self,
        params: GetDownloadIdForUmFuturesOrderHistoryParams,
    ) -> anyhow::Result<RestApiResponse<models::GetDownloadIdForUmFuturesOrderHistoryResponse>>
    {
        let GetDownloadIdForUmFuturesOrderHistoryParams {
            start_time,
            end_time,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("startTime".to_string(), json!(start_time));

        query_params.insert("endTime".to_string(), json!(end_time));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetDownloadIdForUmFuturesOrderHistoryResponse>(
            &self.configuration,
            "/papi/v1/um/order/asyn",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_download_id_for_um_futures_trade_history(
        &self,
        params: GetDownloadIdForUmFuturesTradeHistoryParams,
    ) -> anyhow::Result<RestApiResponse<models::GetDownloadIdForUmFuturesTradeHistoryResponse>>
    {
        let GetDownloadIdForUmFuturesTradeHistoryParams {
            start_time,
            end_time,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("startTime".to_string(), json!(start_time));

        query_params.insert("endTime".to_string(), json!(end_time));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetDownloadIdForUmFuturesTradeHistoryResponse>(
            &self.configuration,
            "/papi/v1/um/trade/asyn",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_download_id_for_um_futures_transaction_history(
        &self,
        params: GetDownloadIdForUmFuturesTransactionHistoryParams,
    ) -> anyhow::Result<RestApiResponse<models::GetDownloadIdForUmFuturesTransactionHistoryResponse>>
    {
        let GetDownloadIdForUmFuturesTransactionHistoryParams {
            start_time,
            end_time,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("startTime".to_string(), json!(start_time));

        query_params.insert("endTime".to_string(), json!(end_time));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetDownloadIdForUmFuturesTransactionHistoryResponse>(
            &self.configuration,
            "/papi/v1/um/income/asyn",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_margin_borrow_loan_interest_history(
        &self,
        params: GetMarginBorrowLoanInterestHistoryParams,
    ) -> anyhow::Result<RestApiResponse<models::GetMarginBorrowLoanInterestHistoryResponse>> {
        let GetMarginBorrowLoanInterestHistoryParams {
            asset,
            start_time,
            end_time,
            current,
            size,
            archived,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        if let Some(rw) = asset {
            query_params.insert("asset".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) = 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) = archived {
            query_params.insert("archived".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetMarginBorrowLoanInterestHistoryResponse>(
            &self.configuration,
            "/papi/v1/margin/marginInterestHistory",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_um_account_detail(
        &self,
        params: GetUmAccountDetailParams,
    ) -> anyhow::Result<RestApiResponse<models::GetUmAccountDetailResponse>> {
        let GetUmAccountDetailParams { 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::<models::GetUmAccountDetailResponse>(
            &self.configuration,
            "/papi/v1/um/account",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_um_account_detail_v2(
        &self,
        params: GetUmAccountDetailV2Params,
    ) -> anyhow::Result<RestApiResponse<models::GetUmAccountDetailV2Response>> {
        let GetUmAccountDetailV2Params { 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::<models::GetUmAccountDetailV2Response>(
            &self.configuration,
            "/papi/v2/um/account",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_um_current_position_mode(
        &self,
        params: GetUmCurrentPositionModeParams,
    ) -> anyhow::Result<RestApiResponse<models::GetUmCurrentPositionModeResponse>> {
        let GetUmCurrentPositionModeParams { 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::<models::GetUmCurrentPositionModeResponse>(
            &self.configuration,
            "/papi/v1/um/positionSide/dual",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_um_futures_order_download_link_by_id(
        &self,
        params: GetUmFuturesOrderDownloadLinkByIdParams,
    ) -> anyhow::Result<RestApiResponse<models::GetUmFuturesOrderDownloadLinkByIdResponse>> {
        let GetUmFuturesOrderDownloadLinkByIdParams {
            download_id,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("downloadId".to_string(), json!(download_id));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetUmFuturesOrderDownloadLinkByIdResponse>(
            &self.configuration,
            "/papi/v1/um/order/asyn/id",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_um_futures_trade_download_link_by_id(
        &self,
        params: GetUmFuturesTradeDownloadLinkByIdParams,
    ) -> anyhow::Result<RestApiResponse<models::GetUmFuturesTradeDownloadLinkByIdResponse>> {
        let GetUmFuturesTradeDownloadLinkByIdParams {
            download_id,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("downloadId".to_string(), json!(download_id));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetUmFuturesTradeDownloadLinkByIdResponse>(
            &self.configuration,
            "/papi/v1/um/trade/asyn/id",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_um_futures_transaction_download_link_by_id(
        &self,
        params: GetUmFuturesTransactionDownloadLinkByIdParams,
    ) -> anyhow::Result<RestApiResponse<models::GetUmFuturesTransactionDownloadLinkByIdResponse>>
    {
        let GetUmFuturesTransactionDownloadLinkByIdParams {
            download_id,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("downloadId".to_string(), json!(download_id));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetUmFuturesTransactionDownloadLinkByIdResponse>(
            &self.configuration,
            "/papi/v1/um/income/asyn/id",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_um_income_history(
        &self,
        params: GetUmIncomeHistoryParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::GetUmIncomeHistoryResponseInner>>> {
        let GetUmIncomeHistoryParams {
            symbol,
            income_type,
            start_time,
            end_time,
            page,
            limit,
            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) = income_type {
            query_params.insert("incomeType".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) = page {
            query_params.insert("page".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::GetUmIncomeHistoryResponseInner>>(
            &self.configuration,
            "/papi/v1/um/income",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_user_commission_rate_for_cm(
        &self,
        params: GetUserCommissionRateForCmParams,
    ) -> anyhow::Result<RestApiResponse<models::GetUserCommissionRateForCmResponse>> {
        let GetUserCommissionRateForCmParams {
            symbol,
            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) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetUserCommissionRateForCmResponse>(
            &self.configuration,
            "/papi/v1/cm/commissionRate",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn get_user_commission_rate_for_um(
        &self,
        params: GetUserCommissionRateForUmParams,
    ) -> anyhow::Result<RestApiResponse<models::GetUserCommissionRateForUmResponse>> {
        let GetUserCommissionRateForUmParams {
            symbol,
            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) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::GetUserCommissionRateForUmResponse>(
            &self.configuration,
            "/papi/v1/um/commissionRate",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn margin_max_borrow(
        &self,
        params: MarginMaxBorrowParams,
    ) -> anyhow::Result<RestApiResponse<models::MarginMaxBorrowResponse>> {
        let MarginMaxBorrowParams { asset, recv_window } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("asset".to_string(), json!(asset));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::MarginMaxBorrowResponse>(
            &self.configuration,
            "/papi/v1/margin/maxBorrowable",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn portfolio_margin_um_trading_quantitative_rules_indicators(
        &self,
        params: PortfolioMarginUmTradingQuantitativeRulesIndicatorsParams,
    ) -> anyhow::Result<
        RestApiResponse<models::PortfolioMarginUmTradingQuantitativeRulesIndicatorsResponse>,
    > {
        let PortfolioMarginUmTradingQuantitativeRulesIndicatorsParams {
            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::PortfolioMarginUmTradingQuantitativeRulesIndicatorsResponse>(
            &self.configuration,
            "/papi/v1/um/apiTradingStatus",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn query_cm_position_information(
        &self,
        params: QueryCmPositionInformationParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::QueryCmPositionInformationResponseInner>>> {
        let QueryCmPositionInformationParams {
            margin_asset,
            pair,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        if let Some(rw) = margin_asset {
            query_params.insert("marginAsset".to_string(), json!(rw));
        }

        if let Some(rw) = pair {
            query_params.insert("pair".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<Vec<models::QueryCmPositionInformationResponseInner>>(
            &self.configuration,
            "/papi/v1/cm/positionRisk",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn query_margin_loan_record(
        &self,
        params: QueryMarginLoanRecordParams,
    ) -> anyhow::Result<RestApiResponse<models::QueryMarginLoanRecordResponse>> {
        let QueryMarginLoanRecordParams {
            asset,
            tx_id,
            start_time,
            end_time,
            current,
            size,
            archived,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("asset".to_string(), json!(asset));

        if let Some(rw) = tx_id {
            query_params.insert("txId".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) = 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) = archived {
            query_params.insert("archived".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::QueryMarginLoanRecordResponse>(
            &self.configuration,
            "/papi/v1/margin/marginLoan",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn query_margin_max_withdraw(
        &self,
        params: QueryMarginMaxWithdrawParams,
    ) -> anyhow::Result<RestApiResponse<models::QueryMarginMaxWithdrawResponse>> {
        let QueryMarginMaxWithdrawParams { asset, recv_window } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("asset".to_string(), json!(asset));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::QueryMarginMaxWithdrawResponse>(
            &self.configuration,
            "/papi/v1/margin/maxWithdraw",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn query_margin_repay_record(
        &self,
        params: QueryMarginRepayRecordParams,
    ) -> anyhow::Result<RestApiResponse<models::QueryMarginRepayRecordResponse>> {
        let QueryMarginRepayRecordParams {
            asset,
            tx_id,
            start_time,
            end_time,
            current,
            size,
            archived,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("asset".to_string(), json!(asset));

        if let Some(rw) = tx_id {
            query_params.insert("txId".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) = 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) = archived {
            query_params.insert("archived".to_string(), json!(rw));
        }

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::QueryMarginRepayRecordResponse>(
            &self.configuration,
            "/papi/v1/margin/repayLoan",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn query_portfolio_margin_negative_balance_interest_history(
        &self,
        params: QueryPortfolioMarginNegativeBalanceInterestHistoryParams,
    ) -> anyhow::Result<
        RestApiResponse<
            Vec<models::QueryPortfolioMarginNegativeBalanceInterestHistoryResponseInner>,
        >,
    > {
        let QueryPortfolioMarginNegativeBalanceInterestHistoryParams {
            asset,
            start_time,
            end_time,
            size,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        if let Some(rw) = asset {
            query_params.insert("asset".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) = 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::<Vec<models::QueryPortfolioMarginNegativeBalanceInterestHistoryResponseInner>>(
            &self.configuration,
            "/papi/v1/portfolio/interest-history",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT { self.configuration.time_unit } else { None },
            true
        ).await
    }

    async fn query_um_position_information(
        &self,
        params: QueryUmPositionInformationParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::QueryUmPositionInformationResponseInner>>> {
        let QueryUmPositionInformationParams {
            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::QueryUmPositionInformationResponseInner>>(
            &self.configuration,
            "/papi/v1/um/positionRisk",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn query_user_negative_balance_auto_exchange_record(
        &self,
        params: QueryUserNegativeBalanceAutoExchangeRecordParams,
    ) -> anyhow::Result<RestApiResponse<models::QueryUserNegativeBalanceAutoExchangeRecordResponse>>
    {
        let QueryUserNegativeBalanceAutoExchangeRecordParams {
            start_time,
            end_time,
            recv_window,
        } = params;

        let mut query_params = BTreeMap::new();
        let body_params = BTreeMap::new();

        query_params.insert("startTime".to_string(), json!(start_time));

        query_params.insert("endTime".to_string(), json!(end_time));

        if let Some(rw) = recv_window {
            query_params.insert("recvWindow".to_string(), json!(rw));
        }

        send_request::<models::QueryUserNegativeBalanceAutoExchangeRecordResponse>(
            &self.configuration,
            "/papi/v1/portfolio/negative-balance-exchange-record",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn query_user_rate_limit(
        &self,
        params: QueryUserRateLimitParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::QueryUserRateLimitResponseInner>>> {
        let QueryUserRateLimitParams { 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::QueryUserRateLimitResponseInner>>(
            &self.configuration,
            "/papi/v1/rateLimit/order",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn repay_futures_negative_balance(
        &self,
        params: RepayFuturesNegativeBalanceParams,
    ) -> anyhow::Result<RestApiResponse<models::RepayFuturesNegativeBalanceResponse>> {
        let RepayFuturesNegativeBalanceParams { 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::<models::RepayFuturesNegativeBalanceResponse>(
            &self.configuration,
            "/papi/v1/repay-futures-negative-balance",
            reqwest::Method::POST,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn um_futures_account_configuration(
        &self,
        params: UmFuturesAccountConfigurationParams,
    ) -> anyhow::Result<RestApiResponse<models::UmFuturesAccountConfigurationResponse>> {
        let UmFuturesAccountConfigurationParams { 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::<models::UmFuturesAccountConfigurationResponse>(
            &self.configuration,
            "/papi/v1/um/accountConfig",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn um_futures_symbol_configuration(
        &self,
        params: UmFuturesSymbolConfigurationParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::UmFuturesSymbolConfigurationResponseInner>>>
    {
        let UmFuturesSymbolConfigurationParams {
            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::UmFuturesSymbolConfigurationResponseInner>>(
            &self.configuration,
            "/papi/v1/um/symbolConfig",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }

    async fn um_notional_and_leverage_brackets(
        &self,
        params: UmNotionalAndLeverageBracketsParams,
    ) -> anyhow::Result<RestApiResponse<Vec<models::UmNotionalAndLeverageBracketsResponseInner>>>
    {
        let UmNotionalAndLeverageBracketsParams {
            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::UmNotionalAndLeverageBracketsResponseInner>>(
            &self.configuration,
            "/papi/v1/um/leverageBracket",
            reqwest::Method::GET,
            query_params,
            body_params,
            if HAS_TIME_UNIT {
                self.configuration.time_unit
            } else {
                None
            },
            true,
        )
        .await
    }
}

#[cfg(all(test, feature = "derivatives_trading_portfolio_margin"))]
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 MockAccountApiClient {
        force_error: bool,
    }

    #[async_trait]
    impl AccountApi for MockAccountApiClient {
        async fn account_balance(
            &self,
            _params: AccountBalanceParams,
        ) -> anyhow::Result<RestApiResponse<models::AccountBalanceResponse>> {
            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":"USDT","totalWalletBalance":"122607.35137903","crossMarginAsset":"92.27530794","crossMarginBorrowed":"10.00000000","crossMarginFree":"100.00000000","crossMarginInterest":"0.72469206","crossMarginLocked":"3.00000000","umWalletBalance":"0.00000000","umUnrealizedPNL":"23.72469206","cmWalletBalance":"23.72469206","cmUnrealizedPNL":"","updateTime":1617939110373,"negativeBalance":"0"}]"#).unwrap();
            let dummy_response: models::AccountBalanceResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::AccountBalanceResponse");

            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 account_information(
            &self,
            _params: AccountInformationParams,
        ) -> anyhow::Result<RestApiResponse<models::AccountInformationResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"uniMMR":"5167.92171923","accountEquity":"122607.35137903","actualEquity":"73.47428058","accountInitialMargin":"23.72469206","accountMaintMargin":"23.72469206","accountStatus":"NORMAL","virtualMaxWithdrawAmount":"1627523.32459208","totalAvailableBalance":"","totalMarginOpenLoss":"","updateTime":1657707212154}"#).unwrap();
            let dummy_response: models::AccountInformationResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::AccountInformationResponse");

            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 bnb_transfer(
            &self,
            _params: BnbTransferParams,
        ) -> anyhow::Result<RestApiResponse<models::BnbTransferResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"tranId":100000001}"#).unwrap();
            let dummy_response: models::BnbTransferResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::BnbTransferResponse");

            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 change_auto_repay_futures_status(
            &self,
            _params: ChangeAutoRepayFuturesStatusParams,
        ) -> anyhow::Result<RestApiResponse<models::ChangeAutoRepayFuturesStatusResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"msg":"success"}"#).unwrap();
            let dummy_response: models::ChangeAutoRepayFuturesStatusResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::ChangeAutoRepayFuturesStatusResponse");

            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 change_cm_initial_leverage(
            &self,
            _params: ChangeCmInitialLeverageParams,
        ) -> anyhow::Result<RestApiResponse<models::ChangeCmInitialLeverageResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value =
                serde_json::from_str(r#"{"leverage":21,"maxQty":"1000","symbol":"BTCUSD_200925"}"#)
                    .unwrap();
            let dummy_response: models::ChangeCmInitialLeverageResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::ChangeCmInitialLeverageResponse");

            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 change_cm_position_mode(
            &self,
            _params: ChangeCmPositionModeParams,
        ) -> anyhow::Result<RestApiResponse<models::ChangeCmPositionModeResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"code":200,"msg":"success"}"#).unwrap();
            let dummy_response: models::ChangeCmPositionModeResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::ChangeCmPositionModeResponse");

            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 change_um_initial_leverage(
            &self,
            _params: ChangeUmInitialLeverageParams,
        ) -> anyhow::Result<RestApiResponse<models::ChangeUmInitialLeverageResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(
                r#"{"leverage":21,"maxNotionalValue":"1000000","symbol":"BTCUSDT"}"#,
            )
            .unwrap();
            let dummy_response: models::ChangeUmInitialLeverageResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::ChangeUmInitialLeverageResponse");

            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 change_um_position_mode(
            &self,
            _params: ChangeUmPositionModeParams,
        ) -> anyhow::Result<RestApiResponse<models::ChangeUmPositionModeResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"code":200,"msg":"success"}"#).unwrap();
            let dummy_response: models::ChangeUmPositionModeResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::ChangeUmPositionModeResponse");

            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 cm_notional_and_leverage_brackets(
            &self,
            _params: CmNotionalAndLeverageBracketsParams,
        ) -> anyhow::Result<RestApiResponse<Vec<models::CmNotionalAndLeverageBracketsResponseInner>>>
        {
            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":"BTCUSD_PERP","brackets":[{"bracket":1,"initialLeverage":125,"qtyCap":50,"qtyFloor":0,"maintMarginRatio":0.004,"cum":0}]}]"#).unwrap();
            let dummy_response: Vec<models::CmNotionalAndLeverageBracketsResponseInner> =
                serde_json::from_value(resp_json.clone()).expect(
                    "should parse into Vec<models::CmNotionalAndLeverageBracketsResponseInner>",
                );

            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 fund_auto_collection(
            &self,
            _params: FundAutoCollectionParams,
        ) -> anyhow::Result<RestApiResponse<models::FundAutoCollectionResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"msg":"success"}"#).unwrap();
            let dummy_response: models::FundAutoCollectionResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::FundAutoCollectionResponse");

            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 fund_collection_by_asset(
            &self,
            _params: FundCollectionByAssetParams,
        ) -> anyhow::Result<RestApiResponse<models::FundCollectionByAssetResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"msg":"success"}"#).unwrap();
            let dummy_response: models::FundCollectionByAssetResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::FundCollectionByAssetResponse");

            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_auto_repay_futures_status(
            &self,
            _params: GetAutoRepayFuturesStatusParams,
        ) -> anyhow::Result<RestApiResponse<models::GetAutoRepayFuturesStatusResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"autoRepay":true}"#).unwrap();
            let dummy_response: models::GetAutoRepayFuturesStatusResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetAutoRepayFuturesStatusResponse");

            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_cm_account_detail(
            &self,
            _params: GetCmAccountDetailParams,
        ) -> anyhow::Result<RestApiResponse<models::GetCmAccountDetailResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"assets":[{"asset":"BTC","crossWalletBalance":"0.00241969","crossUnPnl":"0.00000000","maintMargin":"0.00000000","initialMargin":"0.00000000","positionInitialMargin":"0.00000000","openOrderInitialMargin":"0.00000000","updateTime":1625474304765}],"positions":[{"symbol":"BTCUSD_201225","positionAmt":"0","initialMargin":"0","maintMargin":"0","unrealizedProfit":"0.00000000","positionInitialMargin":"0","openOrderInitialMargin":"0","leverage":"125","positionSide":"BOTH","entryPrice":"0.0","maxQty":"50","updateTime":0}]}"#).unwrap();
            let dummy_response: models::GetCmAccountDetailResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetCmAccountDetailResponse");

            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_cm_current_position_mode(
            &self,
            _params: GetCmCurrentPositionModeParams,
        ) -> anyhow::Result<RestApiResponse<models::GetCmCurrentPositionModeResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"dualSidePosition":true}"#).unwrap();
            let dummy_response: models::GetCmCurrentPositionModeResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetCmCurrentPositionModeResponse");

            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_cm_income_history(
            &self,
            _params: GetCmIncomeHistoryParams,
        ) -> anyhow::Result<RestApiResponse<Vec<models::GetCmIncomeHistoryResponseInner>>> {
            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":"","incomeType":"TRANSFER","income":"-0.37500000","asset":"BTC","info":"WITHDRAW","time":1570608000000,"tranId":"9689322392","tradeId":""},{"symbol":"BTCUSD_200925","incomeType":"COMMISSION","income":"-0.01000000","asset":"BTC","info":"","time":1570636800000,"tranId":"9689322392","tradeId":"2059192"}]"#).unwrap();
            let dummy_response: Vec<models::GetCmIncomeHistoryResponseInner> =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into Vec<models::GetCmIncomeHistoryResponseInner>");

            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_download_id_for_um_futures_order_history(
            &self,
            _params: GetDownloadIdForUmFuturesOrderHistoryParams,
        ) -> anyhow::Result<RestApiResponse<models::GetDownloadIdForUmFuturesOrderHistoryResponse>>
        {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(
                r#"{"avgCostTimestampOfLast30d":7241837,"downloadId":"546975389218332672"}"#,
            )
            .unwrap();
            let dummy_response: models::GetDownloadIdForUmFuturesOrderHistoryResponse =
                serde_json::from_value(resp_json.clone()).expect(
                    "should parse into models::GetDownloadIdForUmFuturesOrderHistoryResponse",
                );

            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_download_id_for_um_futures_trade_history(
            &self,
            _params: GetDownloadIdForUmFuturesTradeHistoryParams,
        ) -> anyhow::Result<RestApiResponse<models::GetDownloadIdForUmFuturesTradeHistoryResponse>>
        {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(
                r#"{"avgCostTimestampOfLast30d":7241837,"downloadId":"546975389218332672"}"#,
            )
            .unwrap();
            let dummy_response: models::GetDownloadIdForUmFuturesTradeHistoryResponse =
                serde_json::from_value(resp_json.clone()).expect(
                    "should parse into models::GetDownloadIdForUmFuturesTradeHistoryResponse",
                );

            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_download_id_for_um_futures_transaction_history(
            &self,
            _params: GetDownloadIdForUmFuturesTransactionHistoryParams,
        ) -> anyhow::Result<
            RestApiResponse<models::GetDownloadIdForUmFuturesTransactionHistoryResponse>,
        > {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(
                r#"{"avgCostTimestampOfLast30d":7241837,"downloadId":"546975389218332672"}"#,
            )
            .unwrap();
            let dummy_response: models::GetDownloadIdForUmFuturesTransactionHistoryResponse =
                serde_json::from_value(resp_json.clone()).expect(
                    "should parse into models::GetDownloadIdForUmFuturesTransactionHistoryResponse",
                );

            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_margin_borrow_loan_interest_history(
            &self,
            _params: GetMarginBorrowLoanInterestHistoryParams,
        ) -> anyhow::Result<RestApiResponse<models::GetMarginBorrowLoanInterestHistoryResponse>>
        {
            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":[{"txId":1352286576452864800,"interestAccuredTime":1672160400000,"asset":"USDT","rawAsset":"USDT","principal":"45.3313","interest":"0.00024995","interestRate":"0.00013233","type":"ON_BORROW"}],"total":1}"#).unwrap();
            let dummy_response: models::GetMarginBorrowLoanInterestHistoryResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetMarginBorrowLoanInterestHistoryResponse");

            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_um_account_detail(
            &self,
            _params: GetUmAccountDetailParams,
        ) -> anyhow::Result<RestApiResponse<models::GetUmAccountDetailResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"assets":[{"asset":"USDT","crossWalletBalance":"23.72469206","crossUnPnl":"0.00000000","maintMargin":"0.00000000","initialMargin":"0.00000000","positionInitialMargin":"0.00000000","openOrderInitialMargin":"0.00000000","updateTime":1625474304765}],"positions":[{"symbol":"BTCUSDT","initialMargin":"0","maintMargin":"0","unrealizedProfit":"0.00000000","positionInitialMargin":"0","openOrderInitialMargin":"0","leverage":"100","entryPrice":"0.00000","maxNotional":"250000","bidNotional":"0","askNotional":"0","positionSide":"BOTH","positionAmt":"0","updateTime":0}]}"#).unwrap();
            let dummy_response: models::GetUmAccountDetailResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetUmAccountDetailResponse");

            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_um_account_detail_v2(
            &self,
            _params: GetUmAccountDetailV2Params,
        ) -> anyhow::Result<RestApiResponse<models::GetUmAccountDetailV2Response>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"assets":[{"asset":"USDT","crossWalletBalance":"23.72469206","crossUnPnl":"0.00000000","maintMargin":"0.00000000","initialMargin":"0.00000000","positionInitialMargin":"0.00000000","openOrderInitialMargin":"0.00000000","updateTime":1625474304765}],"positions":[{"symbol":"BTCUSDT","initialMargin":"0","maintMargin":"0","unrealizedProfit":"0.00000000","positionSide":"BOTH","positionAmt":"0","updateTime":0,"notional":"86.98650000"}]}"#).unwrap();
            let dummy_response: models::GetUmAccountDetailV2Response =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetUmAccountDetailV2Response");

            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_um_current_position_mode(
            &self,
            _params: GetUmCurrentPositionModeParams,
        ) -> anyhow::Result<RestApiResponse<models::GetUmCurrentPositionModeResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"dualSidePosition":true}"#).unwrap();
            let dummy_response: models::GetUmCurrentPositionModeResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetUmCurrentPositionModeResponse");

            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_um_futures_order_download_link_by_id(
            &self,
            _params: GetUmFuturesOrderDownloadLinkByIdParams,
        ) -> anyhow::Result<RestApiResponse<models::GetUmFuturesOrderDownloadLinkByIdResponse>>
        {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"downloadId":"545923594199212032","status":"processing","url":"","s3Link":null,"notified":false,"expirationTimestamp":-1,"isExpired":null}"#).unwrap();
            let dummy_response: models::GetUmFuturesOrderDownloadLinkByIdResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetUmFuturesOrderDownloadLinkByIdResponse");

            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_um_futures_trade_download_link_by_id(
            &self,
            _params: GetUmFuturesTradeDownloadLinkByIdParams,
        ) -> anyhow::Result<RestApiResponse<models::GetUmFuturesTradeDownloadLinkByIdResponse>>
        {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"downloadId":"545923594199212032","status":"processing","url":"","s3Link":null,"notified":false,"expirationTimestamp":-1,"isExpired":null}"#).unwrap();
            let dummy_response: models::GetUmFuturesTradeDownloadLinkByIdResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetUmFuturesTradeDownloadLinkByIdResponse");

            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_um_futures_transaction_download_link_by_id(
            &self,
            _params: GetUmFuturesTransactionDownloadLinkByIdParams,
        ) -> anyhow::Result<RestApiResponse<models::GetUmFuturesTransactionDownloadLinkByIdResponse>>
        {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"downloadId":"545923594199212032","status":"processing","url":"","s3Link":null,"notified":false,"expirationTimestamp":-1,"isExpired":null}"#).unwrap();
            let dummy_response: models::GetUmFuturesTransactionDownloadLinkByIdResponse =
                serde_json::from_value(resp_json.clone()).expect(
                    "should parse into models::GetUmFuturesTransactionDownloadLinkByIdResponse",
                );

            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_um_income_history(
            &self,
            _params: GetUmIncomeHistoryParams,
        ) -> anyhow::Result<RestApiResponse<Vec<models::GetUmIncomeHistoryResponseInner>>> {
            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":"","incomeType":"TRANSFER","income":"-0.37500000","asset":"USDT","info":"TRANSFER","time":1570608000000,"tranId":9689322392,"tradeId":""},{"symbol":"BTCUSDT","incomeType":"COMMISSION","income":"-0.01000000","asset":"USDT","info":"COMMISSION","time":1570636800000,"tranId":9689322392,"tradeId":"2059192"}]"#).unwrap();
            let dummy_response: Vec<models::GetUmIncomeHistoryResponseInner> =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into Vec<models::GetUmIncomeHistoryResponseInner>");

            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_user_commission_rate_for_cm(
            &self,
            _params: GetUserCommissionRateForCmParams,
        ) -> anyhow::Result<RestApiResponse<models::GetUserCommissionRateForCmResponse>> {
            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":"BTCUSD_PERP","makerCommissionRate":"0.00015","takerCommissionRate":"0.00040"}"#).unwrap();
            let dummy_response: models::GetUserCommissionRateForCmResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetUserCommissionRateForCmResponse");

            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_user_commission_rate_for_um(
            &self,
            _params: GetUserCommissionRateForUmParams,
        ) -> anyhow::Result<RestApiResponse<models::GetUserCommissionRateForUmResponse>> {
            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","makerCommissionRate":"0.0002","takerCommissionRate":"0.0004"}"#).unwrap();
            let dummy_response: models::GetUserCommissionRateForUmResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetUserCommissionRateForUmResponse");

            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_max_borrow(
            &self,
            _params: MarginMaxBorrowParams,
        ) -> anyhow::Result<RestApiResponse<models::MarginMaxBorrowResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value =
                serde_json::from_str(r#"{"amount":"1.69248805","borrowLimit":"60"}"#).unwrap();
            let dummy_response: models::MarginMaxBorrowResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::MarginMaxBorrowResponse");

            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 portfolio_margin_um_trading_quantitative_rules_indicators(
            &self,
            _params: PortfolioMarginUmTradingQuantitativeRulesIndicatorsParams,
        ) -> anyhow::Result<
            RestApiResponse<models::PortfolioMarginUmTradingQuantitativeRulesIndicatorsResponse>,
        > {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"indicators":{"BTCUSDT":[{"isLocked":true,"plannedRecoverTime":1545741270000,"indicator":"UFR","value":0.05,"triggerValue":0.995},{"isLocked":true,"plannedRecoverTime":1545741270000,"indicator":"IFER","value":0.99,"triggerValue":0.99},{"isLocked":true,"plannedRecoverTime":1545741270000,"indicator":"GCR","value":0.99,"triggerValue":0.99},{"isLocked":true,"plannedRecoverTime":1545741270000,"indicator":"DR","value":0.99,"triggerValue":0.99}],"ACCOUNT":[{"indicator":"TMV","value":10,"triggerValue":1,"plannedRecoverTime":1644919865000,"isLocked":true}]},"updateTime":1644913304748}"#).unwrap();
            let dummy_response : models::PortfolioMarginUmTradingQuantitativeRulesIndicatorsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::PortfolioMarginUmTradingQuantitativeRulesIndicatorsResponse");

            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_cm_position_information(
            &self,
            _params: QueryCmPositionInformationParams,
        ) -> anyhow::Result<RestApiResponse<Vec<models::QueryCmPositionInformationResponseInner>>>
        {
            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":"BTCUSD_201225","positionAmt":"1","entryPrice":"11707.70000003","markPrice":"11788.66626667","unRealizedProfit":"0.00005866","liquidationPrice":"6170.20509059","leverage":"125","positionSide":"LONG","updateTime":1627026881327,"maxQty":"50","notionalValue":"0.00084827"},{"symbol":"BTCUSD_201225","positionAmt":"1","entryPrice":"11707.70000003","markPrice":"11788.66626667","unRealizedProfit":"0.00005866","liquidationPrice":"6170.20509059","leverage":"125","positionSide":"LONG","updateTime":1627026881327,"maxQty":"50","notionalValue":"0.00084827"},{"symbol":"BTCUSD_201225","positionAmt":"1","entryPrice":"11707.70000003","markPrice":"11788.66626667","unRealizedProfit":"0.00005866","liquidationPrice":"6170.20509059","leverage":"125","positionSide":"LONG","updateTime":1627026881327,"maxQty":"50","notionalValue":"0.00084827"}]"#).unwrap();
            let dummy_response: Vec<models::QueryCmPositionInformationResponseInner> =
                serde_json::from_value(resp_json.clone()).expect(
                    "should parse into Vec<models::QueryCmPositionInformationResponseInner>",
                );

            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_loan_record(
            &self,
            _params: QueryMarginLoanRecordParams,
        ) -> anyhow::Result<RestApiResponse<models::QueryMarginLoanRecordResponse>> {
            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":[{"txId":12807067523,"asset":"BNB","principal":"0.84624403","timestamp":1555056425000,"status":"CONFIRMED"}],"total":1}"#).unwrap();
            let dummy_response: models::QueryMarginLoanRecordResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::QueryMarginLoanRecordResponse");

            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_max_withdraw(
            &self,
            _params: QueryMarginMaxWithdrawParams,
        ) -> anyhow::Result<RestApiResponse<models::QueryMarginMaxWithdrawResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"amount":"60"}"#).unwrap();
            let dummy_response: models::QueryMarginMaxWithdrawResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::QueryMarginMaxWithdrawResponse");

            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_repay_record(
            &self,
            _params: QueryMarginRepayRecordParams,
        ) -> anyhow::Result<RestApiResponse<models::QueryMarginRepayRecordResponse>> {
            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":[{"amount":"14.00000000","asset":"BNB","interest":"0.01866667","principal":"13.98133333","status":"CONFIRMED","timestamp":1563438204000,"txId":2970933056}],"total":1}"#).unwrap();
            let dummy_response: models::QueryMarginRepayRecordResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::QueryMarginRepayRecordResponse");

            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_portfolio_margin_negative_balance_interest_history(
            &self,
            _params: QueryPortfolioMarginNegativeBalanceInterestHistoryParams,
        ) -> anyhow::Result<
            RestApiResponse<
                Vec<models::QueryPortfolioMarginNegativeBalanceInterestHistoryResponseInner>,
            >,
        > {
            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":"USDT","interest":"24.4440","interestAccuredTime":1670227200000,"interestRate":"0.0001164","principal":"210000"}]"#).unwrap();
            let dummy_response : Vec<models::QueryPortfolioMarginNegativeBalanceInterestHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryPortfolioMarginNegativeBalanceInterestHistoryResponseInner>");

            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_um_position_information(
            &self,
            _params: QueryUmPositionInformationParams,
        ) -> anyhow::Result<RestApiResponse<Vec<models::QueryUmPositionInformationResponseInner>>>
        {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"[{"entryPrice":"0.00000","leverage":"10","markPrice":"6679.50671178","maxNotionalValue":"20000000","positionAmt":"0.000","notional":"0","symbol":"BTCUSDT","unRealizedProfit":"0.00000000","liquidationPrice":"6170.20509059","positionSide":"BOTH","updateTime":1625474304765},{"symbol":"BTCUSDT","positionAmt":"0.001","entryPrice":"22185.2","markPrice":"21123.05052574","unRealizedProfit":"-1.06214947","liquidationPrice":"6170.20509059","leverage":"4","maxNotionalValue":"100000000","positionSide":"LONG","notional":"21.12305052","updateTime":1655217461579},{"symbol":"BTCUSDT","positionAmt":"0.000","entryPrice":"0.0","markPrice":"21123.05052574","unRealizedProfit":"0.00000000","liquidationPrice":"6170.20509059","leverage":"4","maxNotionalValue":"100000000","positionSide":"SHORT","notional":"0","updateTime":0}]"#).unwrap();
            let dummy_response: Vec<models::QueryUmPositionInformationResponseInner> =
                serde_json::from_value(resp_json.clone()).expect(
                    "should parse into Vec<models::QueryUmPositionInformationResponseInner>",
                );

            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_user_negative_balance_auto_exchange_record(
            &self,
            _params: QueryUserNegativeBalanceAutoExchangeRecordParams,
        ) -> anyhow::Result<
            RestApiResponse<models::QueryUserNegativeBalanceAutoExchangeRecordResponse>,
        > {
            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":2,"rows":[{"startTime":1736263046841,"endTime":1736263248179,"details":[{"asset":"ETH","negativeBalance":18,"negativeMaxThreshold":5}]},{"startTime":1736184913252,"endTime":1736184965474,"details":[{"asset":"BNB","negativeBalance":1.10264488,"negativeMaxThreshold":0}]}]}"#).unwrap();
            let dummy_response: models::QueryUserNegativeBalanceAutoExchangeRecordResponse =
                serde_json::from_value(resp_json.clone()).expect(
                    "should parse into models::QueryUserNegativeBalanceAutoExchangeRecordResponse",
                );

            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_user_rate_limit(
            &self,
            _params: QueryUserRateLimitParams,
        ) -> anyhow::Result<RestApiResponse<Vec<models::QueryUserRateLimitResponseInner>>> {
            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":"MINUTE","intervalNum":1,"limit":1200}]"#,
            )
            .unwrap();
            let dummy_response: Vec<models::QueryUserRateLimitResponseInner> =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into Vec<models::QueryUserRateLimitResponseInner>");

            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 repay_futures_negative_balance(
            &self,
            _params: RepayFuturesNegativeBalanceParams,
        ) -> anyhow::Result<RestApiResponse<models::RepayFuturesNegativeBalanceResponse>> {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"msg":"success"}"#).unwrap();
            let dummy_response: models::RepayFuturesNegativeBalanceResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::RepayFuturesNegativeBalanceResponse");

            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 um_futures_account_configuration(
            &self,
            _params: UmFuturesAccountConfigurationParams,
        ) -> anyhow::Result<RestApiResponse<models::UmFuturesAccountConfigurationResponse>>
        {
            if self.force_error {
                return Err(ConnectorError::ConnectorClientError {
                    msg: "ResponseError".to_string(),
                    code: None,
                }
                .into());
            }

            let resp_json: Value = serde_json::from_str(r#"{"feeTier":0,"canTrade":true,"canDeposit":true,"canWithdraw":true,"dualSidePosition":true,"updateTime":1724416653850,"multiAssetsMargin":false,"tradeGroupId":-1}"#).unwrap();
            let dummy_response: models::UmFuturesAccountConfigurationResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::UmFuturesAccountConfigurationResponse");

            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 um_futures_symbol_configuration(
            &self,
            _params: UmFuturesSymbolConfigurationParams,
        ) -> anyhow::Result<RestApiResponse<Vec<models::UmFuturesSymbolConfigurationResponseInner>>>
        {
            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","marginType":"CROSSED","isAutoAddMargin":"false","leverage":21,"maxNotionalValue":"1000000"}]"#).unwrap();
            let dummy_response: Vec<models::UmFuturesSymbolConfigurationResponseInner> =
                serde_json::from_value(resp_json.clone()).expect(
                    "should parse into Vec<models::UmFuturesSymbolConfigurationResponseInner>",
                );

            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 um_notional_and_leverage_brackets(
            &self,
            _params: UmNotionalAndLeverageBracketsParams,
        ) -> anyhow::Result<RestApiResponse<Vec<models::UmNotionalAndLeverageBracketsResponseInner>>>
        {
            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":"ETHUSDT","notionalCoef":"4.0","brackets":[{"bracket":1,"initialLeverage":75,"notionalCap":10000,"notionalFloor":0,"maintMarginRatio":0.0065,"cum":0}]}]"#).unwrap();
            let dummy_response: Vec<models::UmNotionalAndLeverageBracketsResponseInner> =
                serde_json::from_value(resp_json.clone()).expect(
                    "should parse into Vec<models::UmNotionalAndLeverageBracketsResponseInner>",
                );

            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 account_balance_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = AccountBalanceParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"asset":"USDT","totalWalletBalance":"122607.35137903","crossMarginAsset":"92.27530794","crossMarginBorrowed":"10.00000000","crossMarginFree":"100.00000000","crossMarginInterest":"0.72469206","crossMarginLocked":"3.00000000","umWalletBalance":"0.00000000","umUnrealizedPNL":"23.72469206","cmWalletBalance":"23.72469206","cmUnrealizedPNL":"","updateTime":1617939110373,"negativeBalance":"0"}]"#).unwrap();
            let expected_response : models::AccountBalanceResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AccountBalanceResponse");

            let resp = client.account_balance(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 account_balance_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = AccountBalanceParams::builder().asset("asset_example".to_string()).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"asset":"USDT","totalWalletBalance":"122607.35137903","crossMarginAsset":"92.27530794","crossMarginBorrowed":"10.00000000","crossMarginFree":"100.00000000","crossMarginInterest":"0.72469206","crossMarginLocked":"3.00000000","umWalletBalance":"0.00000000","umUnrealizedPNL":"23.72469206","cmWalletBalance":"23.72469206","cmUnrealizedPNL":"","updateTime":1617939110373,"negativeBalance":"0"}]"#).unwrap();
            let expected_response : models::AccountBalanceResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AccountBalanceResponse");

            let resp = client.account_balance(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 account_balance_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = AccountBalanceParams::builder().build().unwrap();

            match client.account_balance(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn account_information_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = AccountInformationParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"uniMMR":"5167.92171923","accountEquity":"122607.35137903","actualEquity":"73.47428058","accountInitialMargin":"23.72469206","accountMaintMargin":"23.72469206","accountStatus":"NORMAL","virtualMaxWithdrawAmount":"1627523.32459208","totalAvailableBalance":"","totalMarginOpenLoss":"","updateTime":1657707212154}"#).unwrap();
            let expected_response : models::AccountInformationResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AccountInformationResponse");

            let resp = client.account_information(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 account_information_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = AccountInformationParams::builder().recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"uniMMR":"5167.92171923","accountEquity":"122607.35137903","actualEquity":"73.47428058","accountInitialMargin":"23.72469206","accountMaintMargin":"23.72469206","accountStatus":"NORMAL","virtualMaxWithdrawAmount":"1627523.32459208","totalAvailableBalance":"","totalMarginOpenLoss":"","updateTime":1657707212154}"#).unwrap();
            let expected_response : models::AccountInformationResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AccountInformationResponse");

            let resp = client.account_information(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 account_information_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = AccountInformationParams::builder().build().unwrap();

            match client.account_information(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn bnb_transfer_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = BnbTransferParams::builder(dec!(1.0), "transfer_side_example".to_string())
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"tranId":100000001}"#).unwrap();
            let expected_response: models::BnbTransferResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::BnbTransferResponse");

            let resp = client
                .bnb_transfer(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 bnb_transfer_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = BnbTransferParams::builder(dec!(1.0), "transfer_side_example".to_string())
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"tranId":100000001}"#).unwrap();
            let expected_response: models::BnbTransferResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::BnbTransferResponse");

            let resp = client
                .bnb_transfer(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 bnb_transfer_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = BnbTransferParams::builder(dec!(1.0), "transfer_side_example".to_string())
                .build()
                .unwrap();

            match client.bnb_transfer(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn change_auto_repay_futures_status_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = ChangeAutoRepayFuturesStatusParams::builder("true".to_string())
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"msg":"success"}"#).unwrap();
            let expected_response: models::ChangeAutoRepayFuturesStatusResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::ChangeAutoRepayFuturesStatusResponse");

            let resp = client
                .change_auto_repay_futures_status(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 change_auto_repay_futures_status_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = ChangeAutoRepayFuturesStatusParams::builder("true".to_string())
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"msg":"success"}"#).unwrap();
            let expected_response: models::ChangeAutoRepayFuturesStatusResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::ChangeAutoRepayFuturesStatusResponse");

            let resp = client
                .change_auto_repay_futures_status(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 change_auto_repay_futures_status_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = ChangeAutoRepayFuturesStatusParams::builder("true".to_string())
                .build()
                .unwrap();

            match client.change_auto_repay_futures_status(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn change_cm_initial_leverage_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = ChangeCmInitialLeverageParams::builder("symbol_example".to_string(), 789)
                .build()
                .unwrap();

            let resp_json: Value =
                serde_json::from_str(r#"{"leverage":21,"maxQty":"1000","symbol":"BTCUSD_200925"}"#)
                    .unwrap();
            let expected_response: models::ChangeCmInitialLeverageResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::ChangeCmInitialLeverageResponse");

            let resp = client
                .change_cm_initial_leverage(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 change_cm_initial_leverage_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = ChangeCmInitialLeverageParams::builder("symbol_example".to_string(), 789)
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value =
                serde_json::from_str(r#"{"leverage":21,"maxQty":"1000","symbol":"BTCUSD_200925"}"#)
                    .unwrap();
            let expected_response: models::ChangeCmInitialLeverageResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::ChangeCmInitialLeverageResponse");

            let resp = client
                .change_cm_initial_leverage(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 change_cm_initial_leverage_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = ChangeCmInitialLeverageParams::builder("symbol_example".to_string(), 789)
                .build()
                .unwrap();

            match client.change_cm_initial_leverage(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn change_cm_position_mode_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params =
                ChangeCmPositionModeParams::builder("dual_side_position_example".to_string())
                    .build()
                    .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"code":200,"msg":"success"}"#).unwrap();
            let expected_response: models::ChangeCmPositionModeResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::ChangeCmPositionModeResponse");

            let resp = client
                .change_cm_position_mode(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 change_cm_position_mode_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params =
                ChangeCmPositionModeParams::builder("dual_side_position_example".to_string())
                    .recv_window(5000)
                    .build()
                    .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"code":200,"msg":"success"}"#).unwrap();
            let expected_response: models::ChangeCmPositionModeResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::ChangeCmPositionModeResponse");

            let resp = client
                .change_cm_position_mode(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 change_cm_position_mode_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params =
                ChangeCmPositionModeParams::builder("dual_side_position_example".to_string())
                    .build()
                    .unwrap();

            match client.change_cm_position_mode(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn change_um_initial_leverage_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = ChangeUmInitialLeverageParams::builder("symbol_example".to_string(), 789)
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(
                r#"{"leverage":21,"maxNotionalValue":"1000000","symbol":"BTCUSDT"}"#,
            )
            .unwrap();
            let expected_response: models::ChangeUmInitialLeverageResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::ChangeUmInitialLeverageResponse");

            let resp = client
                .change_um_initial_leverage(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 change_um_initial_leverage_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = ChangeUmInitialLeverageParams::builder("symbol_example".to_string(), 789)
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(
                r#"{"leverage":21,"maxNotionalValue":"1000000","symbol":"BTCUSDT"}"#,
            )
            .unwrap();
            let expected_response: models::ChangeUmInitialLeverageResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::ChangeUmInitialLeverageResponse");

            let resp = client
                .change_um_initial_leverage(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 change_um_initial_leverage_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = ChangeUmInitialLeverageParams::builder("symbol_example".to_string(), 789)
                .build()
                .unwrap();

            match client.change_um_initial_leverage(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn change_um_position_mode_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params =
                ChangeUmPositionModeParams::builder("dual_side_position_example".to_string())
                    .build()
                    .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"code":200,"msg":"success"}"#).unwrap();
            let expected_response: models::ChangeUmPositionModeResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::ChangeUmPositionModeResponse");

            let resp = client
                .change_um_position_mode(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 change_um_position_mode_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params =
                ChangeUmPositionModeParams::builder("dual_side_position_example".to_string())
                    .recv_window(5000)
                    .build()
                    .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"code":200,"msg":"success"}"#).unwrap();
            let expected_response: models::ChangeUmPositionModeResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::ChangeUmPositionModeResponse");

            let resp = client
                .change_um_position_mode(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 change_um_position_mode_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params =
                ChangeUmPositionModeParams::builder("dual_side_position_example".to_string())
                    .build()
                    .unwrap();

            match client.change_um_position_mode(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn cm_notional_and_leverage_brackets_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = CmNotionalAndLeverageBracketsParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSD_PERP","brackets":[{"bracket":1,"initialLeverage":125,"qtyCap":50,"qtyFloor":0,"maintMarginRatio":0.004,"cum":0}]}]"#).unwrap();
            let expected_response : Vec<models::CmNotionalAndLeverageBracketsResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::CmNotionalAndLeverageBracketsResponseInner>");

            let resp = client.cm_notional_and_leverage_brackets(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 cm_notional_and_leverage_brackets_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = CmNotionalAndLeverageBracketsParams::builder().symbol("symbol_example".to_string()).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSD_PERP","brackets":[{"bracket":1,"initialLeverage":125,"qtyCap":50,"qtyFloor":0,"maintMarginRatio":0.004,"cum":0}]}]"#).unwrap();
            let expected_response : Vec<models::CmNotionalAndLeverageBracketsResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::CmNotionalAndLeverageBracketsResponseInner>");

            let resp = client.cm_notional_and_leverage_brackets(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 cm_notional_and_leverage_brackets_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = CmNotionalAndLeverageBracketsParams::builder()
                .build()
                .unwrap();

            match client.cm_notional_and_leverage_brackets(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn fund_auto_collection_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = FundAutoCollectionParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"msg":"success"}"#).unwrap();
            let expected_response: models::FundAutoCollectionResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::FundAutoCollectionResponse");

            let resp = client
                .fund_auto_collection(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 fund_auto_collection_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = FundAutoCollectionParams::builder()
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"msg":"success"}"#).unwrap();
            let expected_response: models::FundAutoCollectionResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::FundAutoCollectionResponse");

            let resp = client
                .fund_auto_collection(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 fund_auto_collection_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = FundAutoCollectionParams::builder().build().unwrap();

            match client.fund_auto_collection(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn fund_collection_by_asset_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = FundCollectionByAssetParams::builder("asset_example".to_string())
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"msg":"success"}"#).unwrap();
            let expected_response: models::FundCollectionByAssetResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::FundCollectionByAssetResponse");

            let resp = client
                .fund_collection_by_asset(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 fund_collection_by_asset_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = FundCollectionByAssetParams::builder("asset_example".to_string())
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"msg":"success"}"#).unwrap();
            let expected_response: models::FundCollectionByAssetResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::FundCollectionByAssetResponse");

            let resp = client
                .fund_collection_by_asset(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 fund_collection_by_asset_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = FundCollectionByAssetParams::builder("asset_example".to_string())
                .build()
                .unwrap();

            match client.fund_collection_by_asset(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_auto_repay_futures_status_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetAutoRepayFuturesStatusParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"autoRepay":true}"#).unwrap();
            let expected_response: models::GetAutoRepayFuturesStatusResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetAutoRepayFuturesStatusResponse");

            let resp = client
                .get_auto_repay_futures_status(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_auto_repay_futures_status_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetAutoRepayFuturesStatusParams::builder()
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"autoRepay":true}"#).unwrap();
            let expected_response: models::GetAutoRepayFuturesStatusResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetAutoRepayFuturesStatusResponse");

            let resp = client
                .get_auto_repay_futures_status(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_auto_repay_futures_status_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = GetAutoRepayFuturesStatusParams::builder().build().unwrap();

            match client.get_auto_repay_futures_status(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_cm_account_detail_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetCmAccountDetailParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"assets":[{"asset":"BTC","crossWalletBalance":"0.00241969","crossUnPnl":"0.00000000","maintMargin":"0.00000000","initialMargin":"0.00000000","positionInitialMargin":"0.00000000","openOrderInitialMargin":"0.00000000","updateTime":1625474304765}],"positions":[{"symbol":"BTCUSD_201225","positionAmt":"0","initialMargin":"0","maintMargin":"0","unrealizedProfit":"0.00000000","positionInitialMargin":"0","openOrderInitialMargin":"0","leverage":"125","positionSide":"BOTH","entryPrice":"0.0","maxQty":"50","updateTime":0}]}"#).unwrap();
            let expected_response : models::GetCmAccountDetailResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetCmAccountDetailResponse");

            let resp = client.get_cm_account_detail(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_cm_account_detail_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetCmAccountDetailParams::builder().recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"assets":[{"asset":"BTC","crossWalletBalance":"0.00241969","crossUnPnl":"0.00000000","maintMargin":"0.00000000","initialMargin":"0.00000000","positionInitialMargin":"0.00000000","openOrderInitialMargin":"0.00000000","updateTime":1625474304765}],"positions":[{"symbol":"BTCUSD_201225","positionAmt":"0","initialMargin":"0","maintMargin":"0","unrealizedProfit":"0.00000000","positionInitialMargin":"0","openOrderInitialMargin":"0","leverage":"125","positionSide":"BOTH","entryPrice":"0.0","maxQty":"50","updateTime":0}]}"#).unwrap();
            let expected_response : models::GetCmAccountDetailResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetCmAccountDetailResponse");

            let resp = client.get_cm_account_detail(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_cm_account_detail_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = GetCmAccountDetailParams::builder().build().unwrap();

            match client.get_cm_account_detail(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_cm_current_position_mode_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetCmCurrentPositionModeParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"dualSidePosition":true}"#).unwrap();
            let expected_response: models::GetCmCurrentPositionModeResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetCmCurrentPositionModeResponse");

            let resp = client
                .get_cm_current_position_mode(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_cm_current_position_mode_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetCmCurrentPositionModeParams::builder()
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"dualSidePosition":true}"#).unwrap();
            let expected_response: models::GetCmCurrentPositionModeResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetCmCurrentPositionModeResponse");

            let resp = client
                .get_cm_current_position_mode(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_cm_current_position_mode_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = GetCmCurrentPositionModeParams::builder().build().unwrap();

            match client.get_cm_current_position_mode(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_cm_income_history_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetCmIncomeHistoryParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"","incomeType":"TRANSFER","income":"-0.37500000","asset":"BTC","info":"WITHDRAW","time":1570608000000,"tranId":"9689322392","tradeId":""},{"symbol":"BTCUSD_200925","incomeType":"COMMISSION","income":"-0.01000000","asset":"BTC","info":"","time":1570636800000,"tranId":"9689322392","tradeId":"2059192"}]"#).unwrap();
            let expected_response : Vec<models::GetCmIncomeHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetCmIncomeHistoryResponseInner>");

            let resp = client.get_cm_income_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_cm_income_history_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetCmIncomeHistoryParams::builder().symbol("symbol_example".to_string()).income_type("income_type_example".to_string()).start_time(1623319461670).end_time(1641782889000).page(789).limit(100).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"","incomeType":"TRANSFER","income":"-0.37500000","asset":"BTC","info":"WITHDRAW","time":1570608000000,"tranId":"9689322392","tradeId":""},{"symbol":"BTCUSD_200925","incomeType":"COMMISSION","income":"-0.01000000","asset":"BTC","info":"","time":1570636800000,"tranId":"9689322392","tradeId":"2059192"}]"#).unwrap();
            let expected_response : Vec<models::GetCmIncomeHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetCmIncomeHistoryResponseInner>");

            let resp = client.get_cm_income_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_cm_income_history_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = GetCmIncomeHistoryParams::builder().build().unwrap();

            match client.get_cm_income_history(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_download_id_for_um_futures_order_history_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params =
                GetDownloadIdForUmFuturesOrderHistoryParams::builder(1623319461670, 1641782889000)
                    .build()
                    .unwrap();

            let resp_json: Value = serde_json::from_str(
                r#"{"avgCostTimestampOfLast30d":7241837,"downloadId":"546975389218332672"}"#,
            )
            .unwrap();
            let expected_response: models::GetDownloadIdForUmFuturesOrderHistoryResponse =
                serde_json::from_value(resp_json.clone()).expect(
                    "should parse into models::GetDownloadIdForUmFuturesOrderHistoryResponse",
                );

            let resp = client
                .get_download_id_for_um_futures_order_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_download_id_for_um_futures_order_history_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params =
                GetDownloadIdForUmFuturesOrderHistoryParams::builder(1623319461670, 1641782889000)
                    .recv_window(5000)
                    .build()
                    .unwrap();

            let resp_json: Value = serde_json::from_str(
                r#"{"avgCostTimestampOfLast30d":7241837,"downloadId":"546975389218332672"}"#,
            )
            .unwrap();
            let expected_response: models::GetDownloadIdForUmFuturesOrderHistoryResponse =
                serde_json::from_value(resp_json.clone()).expect(
                    "should parse into models::GetDownloadIdForUmFuturesOrderHistoryResponse",
                );

            let resp = client
                .get_download_id_for_um_futures_order_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_download_id_for_um_futures_order_history_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params =
                GetDownloadIdForUmFuturesOrderHistoryParams::builder(1623319461670, 1641782889000)
                    .build()
                    .unwrap();

            match client
                .get_download_id_for_um_futures_order_history(params)
                .await
            {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_download_id_for_um_futures_trade_history_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params =
                GetDownloadIdForUmFuturesTradeHistoryParams::builder(1623319461670, 1641782889000)
                    .build()
                    .unwrap();

            let resp_json: Value = serde_json::from_str(
                r#"{"avgCostTimestampOfLast30d":7241837,"downloadId":"546975389218332672"}"#,
            )
            .unwrap();
            let expected_response: models::GetDownloadIdForUmFuturesTradeHistoryResponse =
                serde_json::from_value(resp_json.clone()).expect(
                    "should parse into models::GetDownloadIdForUmFuturesTradeHistoryResponse",
                );

            let resp = client
                .get_download_id_for_um_futures_trade_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_download_id_for_um_futures_trade_history_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params =
                GetDownloadIdForUmFuturesTradeHistoryParams::builder(1623319461670, 1641782889000)
                    .recv_window(5000)
                    .build()
                    .unwrap();

            let resp_json: Value = serde_json::from_str(
                r#"{"avgCostTimestampOfLast30d":7241837,"downloadId":"546975389218332672"}"#,
            )
            .unwrap();
            let expected_response: models::GetDownloadIdForUmFuturesTradeHistoryResponse =
                serde_json::from_value(resp_json.clone()).expect(
                    "should parse into models::GetDownloadIdForUmFuturesTradeHistoryResponse",
                );

            let resp = client
                .get_download_id_for_um_futures_trade_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_download_id_for_um_futures_trade_history_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params =
                GetDownloadIdForUmFuturesTradeHistoryParams::builder(1623319461670, 1641782889000)
                    .build()
                    .unwrap();

            match client
                .get_download_id_for_um_futures_trade_history(params)
                .await
            {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_download_id_for_um_futures_transaction_history_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetDownloadIdForUmFuturesTransactionHistoryParams::builder(
                1623319461670,
                1641782889000,
            )
            .build()
            .unwrap();

            let resp_json: Value = serde_json::from_str(
                r#"{"avgCostTimestampOfLast30d":7241837,"downloadId":"546975389218332672"}"#,
            )
            .unwrap();
            let expected_response: models::GetDownloadIdForUmFuturesTransactionHistoryResponse =
                serde_json::from_value(resp_json.clone()).expect(
                    "should parse into models::GetDownloadIdForUmFuturesTransactionHistoryResponse",
                );

            let resp = client
                .get_download_id_for_um_futures_transaction_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_download_id_for_um_futures_transaction_history_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetDownloadIdForUmFuturesTransactionHistoryParams::builder(
                1623319461670,
                1641782889000,
            )
            .recv_window(5000)
            .build()
            .unwrap();

            let resp_json: Value = serde_json::from_str(
                r#"{"avgCostTimestampOfLast30d":7241837,"downloadId":"546975389218332672"}"#,
            )
            .unwrap();
            let expected_response: models::GetDownloadIdForUmFuturesTransactionHistoryResponse =
                serde_json::from_value(resp_json.clone()).expect(
                    "should parse into models::GetDownloadIdForUmFuturesTransactionHistoryResponse",
                );

            let resp = client
                .get_download_id_for_um_futures_transaction_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_download_id_for_um_futures_transaction_history_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = GetDownloadIdForUmFuturesTransactionHistoryParams::builder(
                1623319461670,
                1641782889000,
            )
            .build()
            .unwrap();

            match client
                .get_download_id_for_um_futures_transaction_history(params)
                .await
            {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_margin_borrow_loan_interest_history_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetMarginBorrowLoanInterestHistoryParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"txId":1352286576452864800,"interestAccuredTime":1672160400000,"asset":"USDT","rawAsset":"USDT","principal":"45.3313","interest":"0.00024995","interestRate":"0.00013233","type":"ON_BORROW"}],"total":1}"#).unwrap();
            let expected_response : models::GetMarginBorrowLoanInterestHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetMarginBorrowLoanInterestHistoryResponse");

            let resp = client.get_margin_borrow_loan_interest_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_margin_borrow_loan_interest_history_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetMarginBorrowLoanInterestHistoryParams::builder().asset("asset_example".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).size(10).archived(String::new()).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"txId":1352286576452864800,"interestAccuredTime":1672160400000,"asset":"USDT","rawAsset":"USDT","principal":"45.3313","interest":"0.00024995","interestRate":"0.00013233","type":"ON_BORROW"}],"total":1}"#).unwrap();
            let expected_response : models::GetMarginBorrowLoanInterestHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetMarginBorrowLoanInterestHistoryResponse");

            let resp = client.get_margin_borrow_loan_interest_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_margin_borrow_loan_interest_history_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = GetMarginBorrowLoanInterestHistoryParams::builder()
                .build()
                .unwrap();

            match client.get_margin_borrow_loan_interest_history(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_um_account_detail_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetUmAccountDetailParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"assets":[{"asset":"USDT","crossWalletBalance":"23.72469206","crossUnPnl":"0.00000000","maintMargin":"0.00000000","initialMargin":"0.00000000","positionInitialMargin":"0.00000000","openOrderInitialMargin":"0.00000000","updateTime":1625474304765}],"positions":[{"symbol":"BTCUSDT","initialMargin":"0","maintMargin":"0","unrealizedProfit":"0.00000000","positionInitialMargin":"0","openOrderInitialMargin":"0","leverage":"100","entryPrice":"0.00000","maxNotional":"250000","bidNotional":"0","askNotional":"0","positionSide":"BOTH","positionAmt":"0","updateTime":0}]}"#).unwrap();
            let expected_response : models::GetUmAccountDetailResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetUmAccountDetailResponse");

            let resp = client.get_um_account_detail(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_um_account_detail_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetUmAccountDetailParams::builder().recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"assets":[{"asset":"USDT","crossWalletBalance":"23.72469206","crossUnPnl":"0.00000000","maintMargin":"0.00000000","initialMargin":"0.00000000","positionInitialMargin":"0.00000000","openOrderInitialMargin":"0.00000000","updateTime":1625474304765}],"positions":[{"symbol":"BTCUSDT","initialMargin":"0","maintMargin":"0","unrealizedProfit":"0.00000000","positionInitialMargin":"0","openOrderInitialMargin":"0","leverage":"100","entryPrice":"0.00000","maxNotional":"250000","bidNotional":"0","askNotional":"0","positionSide":"BOTH","positionAmt":"0","updateTime":0}]}"#).unwrap();
            let expected_response : models::GetUmAccountDetailResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetUmAccountDetailResponse");

            let resp = client.get_um_account_detail(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_um_account_detail_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = GetUmAccountDetailParams::builder().build().unwrap();

            match client.get_um_account_detail(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_um_account_detail_v2_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetUmAccountDetailV2Params::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"assets":[{"asset":"USDT","crossWalletBalance":"23.72469206","crossUnPnl":"0.00000000","maintMargin":"0.00000000","initialMargin":"0.00000000","positionInitialMargin":"0.00000000","openOrderInitialMargin":"0.00000000","updateTime":1625474304765}],"positions":[{"symbol":"BTCUSDT","initialMargin":"0","maintMargin":"0","unrealizedProfit":"0.00000000","positionSide":"BOTH","positionAmt":"0","updateTime":0,"notional":"86.98650000"}]}"#).unwrap();
            let expected_response : models::GetUmAccountDetailV2Response = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetUmAccountDetailV2Response");

            let resp = client.get_um_account_detail_v2(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_um_account_detail_v2_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetUmAccountDetailV2Params::builder().recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"assets":[{"asset":"USDT","crossWalletBalance":"23.72469206","crossUnPnl":"0.00000000","maintMargin":"0.00000000","initialMargin":"0.00000000","positionInitialMargin":"0.00000000","openOrderInitialMargin":"0.00000000","updateTime":1625474304765}],"positions":[{"symbol":"BTCUSDT","initialMargin":"0","maintMargin":"0","unrealizedProfit":"0.00000000","positionSide":"BOTH","positionAmt":"0","updateTime":0,"notional":"86.98650000"}]}"#).unwrap();
            let expected_response : models::GetUmAccountDetailV2Response = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetUmAccountDetailV2Response");

            let resp = client.get_um_account_detail_v2(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_um_account_detail_v2_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = GetUmAccountDetailV2Params::builder().build().unwrap();

            match client.get_um_account_detail_v2(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_um_current_position_mode_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetUmCurrentPositionModeParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"dualSidePosition":true}"#).unwrap();
            let expected_response: models::GetUmCurrentPositionModeResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetUmCurrentPositionModeResponse");

            let resp = client
                .get_um_current_position_mode(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_um_current_position_mode_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetUmCurrentPositionModeParams::builder()
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"dualSidePosition":true}"#).unwrap();
            let expected_response: models::GetUmCurrentPositionModeResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::GetUmCurrentPositionModeResponse");

            let resp = client
                .get_um_current_position_mode(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_um_current_position_mode_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = GetUmCurrentPositionModeParams::builder().build().unwrap();

            match client.get_um_current_position_mode(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_um_futures_order_download_link_by_id_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetUmFuturesOrderDownloadLinkByIdParams::builder("1".to_string(),).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"downloadId":"545923594199212032","status":"processing","url":"","s3Link":null,"notified":false,"expirationTimestamp":-1,"isExpired":null}"#).unwrap();
            let expected_response : models::GetUmFuturesOrderDownloadLinkByIdResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetUmFuturesOrderDownloadLinkByIdResponse");

            let resp = client.get_um_futures_order_download_link_by_id(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_um_futures_order_download_link_by_id_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetUmFuturesOrderDownloadLinkByIdParams::builder("1".to_string(),).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"downloadId":"545923594199212032","status":"processing","url":"","s3Link":null,"notified":false,"expirationTimestamp":-1,"isExpired":null}"#).unwrap();
            let expected_response : models::GetUmFuturesOrderDownloadLinkByIdResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetUmFuturesOrderDownloadLinkByIdResponse");

            let resp = client.get_um_futures_order_download_link_by_id(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_um_futures_order_download_link_by_id_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = GetUmFuturesOrderDownloadLinkByIdParams::builder("1".to_string())
                .build()
                .unwrap();

            match client
                .get_um_futures_order_download_link_by_id(params)
                .await
            {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_um_futures_trade_download_link_by_id_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetUmFuturesTradeDownloadLinkByIdParams::builder("1".to_string(),).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"downloadId":"545923594199212032","status":"processing","url":"","s3Link":null,"notified":false,"expirationTimestamp":-1,"isExpired":null}"#).unwrap();
            let expected_response : models::GetUmFuturesTradeDownloadLinkByIdResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetUmFuturesTradeDownloadLinkByIdResponse");

            let resp = client.get_um_futures_trade_download_link_by_id(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_um_futures_trade_download_link_by_id_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetUmFuturesTradeDownloadLinkByIdParams::builder("1".to_string(),).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"downloadId":"545923594199212032","status":"processing","url":"","s3Link":null,"notified":false,"expirationTimestamp":-1,"isExpired":null}"#).unwrap();
            let expected_response : models::GetUmFuturesTradeDownloadLinkByIdResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetUmFuturesTradeDownloadLinkByIdResponse");

            let resp = client.get_um_futures_trade_download_link_by_id(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_um_futures_trade_download_link_by_id_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = GetUmFuturesTradeDownloadLinkByIdParams::builder("1".to_string())
                .build()
                .unwrap();

            match client
                .get_um_futures_trade_download_link_by_id(params)
                .await
            {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_um_futures_transaction_download_link_by_id_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetUmFuturesTransactionDownloadLinkByIdParams::builder("1".to_string(),).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"downloadId":"545923594199212032","status":"processing","url":"","s3Link":null,"notified":false,"expirationTimestamp":-1,"isExpired":null}"#).unwrap();
            let expected_response : models::GetUmFuturesTransactionDownloadLinkByIdResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetUmFuturesTransactionDownloadLinkByIdResponse");

            let resp = client.get_um_futures_transaction_download_link_by_id(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_um_futures_transaction_download_link_by_id_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetUmFuturesTransactionDownloadLinkByIdParams::builder("1".to_string(),).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"downloadId":"545923594199212032","status":"processing","url":"","s3Link":null,"notified":false,"expirationTimestamp":-1,"isExpired":null}"#).unwrap();
            let expected_response : models::GetUmFuturesTransactionDownloadLinkByIdResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetUmFuturesTransactionDownloadLinkByIdResponse");

            let resp = client.get_um_futures_transaction_download_link_by_id(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_um_futures_transaction_download_link_by_id_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = GetUmFuturesTransactionDownloadLinkByIdParams::builder("1".to_string())
                .build()
                .unwrap();

            match client
                .get_um_futures_transaction_download_link_by_id(params)
                .await
            {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_um_income_history_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetUmIncomeHistoryParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"","incomeType":"TRANSFER","income":"-0.37500000","asset":"USDT","info":"TRANSFER","time":1570608000000,"tranId":9689322392,"tradeId":""},{"symbol":"BTCUSDT","incomeType":"COMMISSION","income":"-0.01000000","asset":"USDT","info":"COMMISSION","time":1570636800000,"tranId":9689322392,"tradeId":"2059192"}]"#).unwrap();
            let expected_response : Vec<models::GetUmIncomeHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetUmIncomeHistoryResponseInner>");

            let resp = client.get_um_income_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_um_income_history_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetUmIncomeHistoryParams::builder().symbol("symbol_example".to_string()).income_type("income_type_example".to_string()).start_time(1623319461670).end_time(1641782889000).page(789).limit(100).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"","incomeType":"TRANSFER","income":"-0.37500000","asset":"USDT","info":"TRANSFER","time":1570608000000,"tranId":9689322392,"tradeId":""},{"symbol":"BTCUSDT","incomeType":"COMMISSION","income":"-0.01000000","asset":"USDT","info":"COMMISSION","time":1570636800000,"tranId":9689322392,"tradeId":"2059192"}]"#).unwrap();
            let expected_response : Vec<models::GetUmIncomeHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetUmIncomeHistoryResponseInner>");

            let resp = client.get_um_income_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_um_income_history_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = GetUmIncomeHistoryParams::builder().build().unwrap();

            match client.get_um_income_history(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_user_commission_rate_for_cm_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetUserCommissionRateForCmParams::builder("symbol_example".to_string(),).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"symbol":"BTCUSD_PERP","makerCommissionRate":"0.00015","takerCommissionRate":"0.00040"}"#).unwrap();
            let expected_response : models::GetUserCommissionRateForCmResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetUserCommissionRateForCmResponse");

            let resp = client.get_user_commission_rate_for_cm(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_user_commission_rate_for_cm_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetUserCommissionRateForCmParams::builder("symbol_example".to_string(),).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"symbol":"BTCUSD_PERP","makerCommissionRate":"0.00015","takerCommissionRate":"0.00040"}"#).unwrap();
            let expected_response : models::GetUserCommissionRateForCmResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetUserCommissionRateForCmResponse");

            let resp = client.get_user_commission_rate_for_cm(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_user_commission_rate_for_cm_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = GetUserCommissionRateForCmParams::builder("symbol_example".to_string())
                .build()
                .unwrap();

            match client.get_user_commission_rate_for_cm(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn get_user_commission_rate_for_um_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetUserCommissionRateForUmParams::builder("symbol_example".to_string(),).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"symbol":"BTCUSDT","makerCommissionRate":"0.0002","takerCommissionRate":"0.0004"}"#).unwrap();
            let expected_response : models::GetUserCommissionRateForUmResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetUserCommissionRateForUmResponse");

            let resp = client.get_user_commission_rate_for_um(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_user_commission_rate_for_um_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = GetUserCommissionRateForUmParams::builder("symbol_example".to_string(),).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"symbol":"BTCUSDT","makerCommissionRate":"0.0002","takerCommissionRate":"0.0004"}"#).unwrap();
            let expected_response : models::GetUserCommissionRateForUmResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetUserCommissionRateForUmResponse");

            let resp = client.get_user_commission_rate_for_um(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_user_commission_rate_for_um_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = GetUserCommissionRateForUmParams::builder("symbol_example".to_string())
                .build()
                .unwrap();

            match client.get_user_commission_rate_for_um(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn margin_max_borrow_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = MarginMaxBorrowParams::builder("asset_example".to_string())
                .build()
                .unwrap();

            let resp_json: Value =
                serde_json::from_str(r#"{"amount":"1.69248805","borrowLimit":"60"}"#).unwrap();
            let expected_response: models::MarginMaxBorrowResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::MarginMaxBorrowResponse");

            let resp = client
                .margin_max_borrow(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_max_borrow_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = MarginMaxBorrowParams::builder("asset_example".to_string())
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value =
                serde_json::from_str(r#"{"amount":"1.69248805","borrowLimit":"60"}"#).unwrap();
            let expected_response: models::MarginMaxBorrowResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::MarginMaxBorrowResponse");

            let resp = client
                .margin_max_borrow(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_max_borrow_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = MarginMaxBorrowParams::builder("asset_example".to_string())
                .build()
                .unwrap();

            match client.margin_max_borrow(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn portfolio_margin_um_trading_quantitative_rules_indicators_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = PortfolioMarginUmTradingQuantitativeRulesIndicatorsParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"indicators":{"BTCUSDT":[{"isLocked":true,"plannedRecoverTime":1545741270000,"indicator":"UFR","value":0.05,"triggerValue":0.995},{"isLocked":true,"plannedRecoverTime":1545741270000,"indicator":"IFER","value":0.99,"triggerValue":0.99},{"isLocked":true,"plannedRecoverTime":1545741270000,"indicator":"GCR","value":0.99,"triggerValue":0.99},{"isLocked":true,"plannedRecoverTime":1545741270000,"indicator":"DR","value":0.99,"triggerValue":0.99}],"ACCOUNT":[{"indicator":"TMV","value":10,"triggerValue":1,"plannedRecoverTime":1644919865000,"isLocked":true}]},"updateTime":1644913304748}"#).unwrap();
            let expected_response : models::PortfolioMarginUmTradingQuantitativeRulesIndicatorsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::PortfolioMarginUmTradingQuantitativeRulesIndicatorsResponse");

            let resp = client.portfolio_margin_um_trading_quantitative_rules_indicators(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 portfolio_margin_um_trading_quantitative_rules_indicators_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = PortfolioMarginUmTradingQuantitativeRulesIndicatorsParams::builder().symbol("symbol_example".to_string()).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"indicators":{"BTCUSDT":[{"isLocked":true,"plannedRecoverTime":1545741270000,"indicator":"UFR","value":0.05,"triggerValue":0.995},{"isLocked":true,"plannedRecoverTime":1545741270000,"indicator":"IFER","value":0.99,"triggerValue":0.99},{"isLocked":true,"plannedRecoverTime":1545741270000,"indicator":"GCR","value":0.99,"triggerValue":0.99},{"isLocked":true,"plannedRecoverTime":1545741270000,"indicator":"DR","value":0.99,"triggerValue":0.99}],"ACCOUNT":[{"indicator":"TMV","value":10,"triggerValue":1,"plannedRecoverTime":1644919865000,"isLocked":true}]},"updateTime":1644913304748}"#).unwrap();
            let expected_response : models::PortfolioMarginUmTradingQuantitativeRulesIndicatorsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::PortfolioMarginUmTradingQuantitativeRulesIndicatorsResponse");

            let resp = client.portfolio_margin_um_trading_quantitative_rules_indicators(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 portfolio_margin_um_trading_quantitative_rules_indicators_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = PortfolioMarginUmTradingQuantitativeRulesIndicatorsParams::builder()
                .build()
                .unwrap();

            match client
                .portfolio_margin_um_trading_quantitative_rules_indicators(params)
                .await
            {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn query_cm_position_information_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = QueryCmPositionInformationParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSD_201225","positionAmt":"1","entryPrice":"11707.70000003","markPrice":"11788.66626667","unRealizedProfit":"0.00005866","liquidationPrice":"6170.20509059","leverage":"125","positionSide":"LONG","updateTime":1627026881327,"maxQty":"50","notionalValue":"0.00084827"},{"symbol":"BTCUSD_201225","positionAmt":"1","entryPrice":"11707.70000003","markPrice":"11788.66626667","unRealizedProfit":"0.00005866","liquidationPrice":"6170.20509059","leverage":"125","positionSide":"LONG","updateTime":1627026881327,"maxQty":"50","notionalValue":"0.00084827"},{"symbol":"BTCUSD_201225","positionAmt":"1","entryPrice":"11707.70000003","markPrice":"11788.66626667","unRealizedProfit":"0.00005866","liquidationPrice":"6170.20509059","leverage":"125","positionSide":"LONG","updateTime":1627026881327,"maxQty":"50","notionalValue":"0.00084827"}]"#).unwrap();
            let expected_response : Vec<models::QueryCmPositionInformationResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryCmPositionInformationResponseInner>");

            let resp = client.query_cm_position_information(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_cm_position_information_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = QueryCmPositionInformationParams::builder().margin_asset("margin_asset_example".to_string()).pair("pair_example".to_string()).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSD_201225","positionAmt":"1","entryPrice":"11707.70000003","markPrice":"11788.66626667","unRealizedProfit":"0.00005866","liquidationPrice":"6170.20509059","leverage":"125","positionSide":"LONG","updateTime":1627026881327,"maxQty":"50","notionalValue":"0.00084827"},{"symbol":"BTCUSD_201225","positionAmt":"1","entryPrice":"11707.70000003","markPrice":"11788.66626667","unRealizedProfit":"0.00005866","liquidationPrice":"6170.20509059","leverage":"125","positionSide":"LONG","updateTime":1627026881327,"maxQty":"50","notionalValue":"0.00084827"},{"symbol":"BTCUSD_201225","positionAmt":"1","entryPrice":"11707.70000003","markPrice":"11788.66626667","unRealizedProfit":"0.00005866","liquidationPrice":"6170.20509059","leverage":"125","positionSide":"LONG","updateTime":1627026881327,"maxQty":"50","notionalValue":"0.00084827"}]"#).unwrap();
            let expected_response : Vec<models::QueryCmPositionInformationResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryCmPositionInformationResponseInner>");

            let resp = client.query_cm_position_information(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_cm_position_information_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = QueryCmPositionInformationParams::builder().build().unwrap();

            match client.query_cm_position_information(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn query_margin_loan_record_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = QueryMarginLoanRecordParams::builder("asset_example".to_string(),).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"txId":12807067523,"asset":"BNB","principal":"0.84624403","timestamp":1555056425000,"status":"CONFIRMED"}],"total":1}"#).unwrap();
            let expected_response : models::QueryMarginLoanRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryMarginLoanRecordResponse");

            let resp = client.query_margin_loan_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 query_margin_loan_record_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = QueryMarginLoanRecordParams::builder("asset_example".to_string(),).tx_id(1).start_time(1623319461670).end_time(1641782889000).current(1).size(10).archived(String::new()).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"txId":12807067523,"asset":"BNB","principal":"0.84624403","timestamp":1555056425000,"status":"CONFIRMED"}],"total":1}"#).unwrap();
            let expected_response : models::QueryMarginLoanRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryMarginLoanRecordResponse");

            let resp = client.query_margin_loan_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 query_margin_loan_record_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = QueryMarginLoanRecordParams::builder("asset_example".to_string())
                .build()
                .unwrap();

            match client.query_margin_loan_record(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn query_margin_max_withdraw_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = QueryMarginMaxWithdrawParams::builder("asset_example".to_string())
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"amount":"60"}"#).unwrap();
            let expected_response: models::QueryMarginMaxWithdrawResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::QueryMarginMaxWithdrawResponse");

            let resp = client
                .query_margin_max_withdraw(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_max_withdraw_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = QueryMarginMaxWithdrawParams::builder("asset_example".to_string())
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"amount":"60"}"#).unwrap();
            let expected_response: models::QueryMarginMaxWithdrawResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::QueryMarginMaxWithdrawResponse");

            let resp = client
                .query_margin_max_withdraw(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_max_withdraw_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = QueryMarginMaxWithdrawParams::builder("asset_example".to_string())
                .build()
                .unwrap();

            match client.query_margin_max_withdraw(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn query_margin_repay_record_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = QueryMarginRepayRecordParams::builder("asset_example".to_string(),).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"amount":"14.00000000","asset":"BNB","interest":"0.01866667","principal":"13.98133333","status":"CONFIRMED","timestamp":1563438204000,"txId":2970933056}],"total":1}"#).unwrap();
            let expected_response : models::QueryMarginRepayRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryMarginRepayRecordResponse");

            let resp = client.query_margin_repay_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 query_margin_repay_record_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = QueryMarginRepayRecordParams::builder("asset_example".to_string(),).tx_id(1).start_time(1623319461670).end_time(1641782889000).current(1).size(10).archived(String::new()).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"amount":"14.00000000","asset":"BNB","interest":"0.01866667","principal":"13.98133333","status":"CONFIRMED","timestamp":1563438204000,"txId":2970933056}],"total":1}"#).unwrap();
            let expected_response : models::QueryMarginRepayRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryMarginRepayRecordResponse");

            let resp = client.query_margin_repay_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 query_margin_repay_record_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = QueryMarginRepayRecordParams::builder("asset_example".to_string())
                .build()
                .unwrap();

            match client.query_margin_repay_record(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn query_portfolio_margin_negative_balance_interest_history_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = QueryPortfolioMarginNegativeBalanceInterestHistoryParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"asset":"USDT","interest":"24.4440","interestAccuredTime":1670227200000,"interestRate":"0.0001164","principal":"210000"}]"#).unwrap();
            let expected_response : Vec<models::QueryPortfolioMarginNegativeBalanceInterestHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryPortfolioMarginNegativeBalanceInterestHistoryResponseInner>");

            let resp = client.query_portfolio_margin_negative_balance_interest_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 query_portfolio_margin_negative_balance_interest_history_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = QueryPortfolioMarginNegativeBalanceInterestHistoryParams::builder().asset("asset_example".to_string()).start_time(1623319461670).end_time(1641782889000).size(10).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"asset":"USDT","interest":"24.4440","interestAccuredTime":1670227200000,"interestRate":"0.0001164","principal":"210000"}]"#).unwrap();
            let expected_response : Vec<models::QueryPortfolioMarginNegativeBalanceInterestHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryPortfolioMarginNegativeBalanceInterestHistoryResponseInner>");

            let resp = client.query_portfolio_margin_negative_balance_interest_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 query_portfolio_margin_negative_balance_interest_history_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = QueryPortfolioMarginNegativeBalanceInterestHistoryParams::builder()
                .build()
                .unwrap();

            match client
                .query_portfolio_margin_negative_balance_interest_history(params)
                .await
            {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn query_um_position_information_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = QueryUmPositionInformationParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"entryPrice":"0.00000","leverage":"10","markPrice":"6679.50671178","maxNotionalValue":"20000000","positionAmt":"0.000","notional":"0","symbol":"BTCUSDT","unRealizedProfit":"0.00000000","liquidationPrice":"6170.20509059","positionSide":"BOTH","updateTime":1625474304765},{"symbol":"BTCUSDT","positionAmt":"0.001","entryPrice":"22185.2","markPrice":"21123.05052574","unRealizedProfit":"-1.06214947","liquidationPrice":"6170.20509059","leverage":"4","maxNotionalValue":"100000000","positionSide":"LONG","notional":"21.12305052","updateTime":1655217461579},{"symbol":"BTCUSDT","positionAmt":"0.000","entryPrice":"0.0","markPrice":"21123.05052574","unRealizedProfit":"0.00000000","liquidationPrice":"6170.20509059","leverage":"4","maxNotionalValue":"100000000","positionSide":"SHORT","notional":"0","updateTime":0}]"#).unwrap();
            let expected_response : Vec<models::QueryUmPositionInformationResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryUmPositionInformationResponseInner>");

            let resp = client.query_um_position_information(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_um_position_information_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = QueryUmPositionInformationParams::builder().symbol("symbol_example".to_string()).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"entryPrice":"0.00000","leverage":"10","markPrice":"6679.50671178","maxNotionalValue":"20000000","positionAmt":"0.000","notional":"0","symbol":"BTCUSDT","unRealizedProfit":"0.00000000","liquidationPrice":"6170.20509059","positionSide":"BOTH","updateTime":1625474304765},{"symbol":"BTCUSDT","positionAmt":"0.001","entryPrice":"22185.2","markPrice":"21123.05052574","unRealizedProfit":"-1.06214947","liquidationPrice":"6170.20509059","leverage":"4","maxNotionalValue":"100000000","positionSide":"LONG","notional":"21.12305052","updateTime":1655217461579},{"symbol":"BTCUSDT","positionAmt":"0.000","entryPrice":"0.0","markPrice":"21123.05052574","unRealizedProfit":"0.00000000","liquidationPrice":"6170.20509059","leverage":"4","maxNotionalValue":"100000000","positionSide":"SHORT","notional":"0","updateTime":0}]"#).unwrap();
            let expected_response : Vec<models::QueryUmPositionInformationResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryUmPositionInformationResponseInner>");

            let resp = client.query_um_position_information(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_um_position_information_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = QueryUmPositionInformationParams::builder().build().unwrap();

            match client.query_um_position_information(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn query_user_negative_balance_auto_exchange_record_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = QueryUserNegativeBalanceAutoExchangeRecordParams::builder(1623319461670,1641782889000,).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"total":2,"rows":[{"startTime":1736263046841,"endTime":1736263248179,"details":[{"asset":"ETH","negativeBalance":18,"negativeMaxThreshold":5}]},{"startTime":1736184913252,"endTime":1736184965474,"details":[{"asset":"BNB","negativeBalance":1.10264488,"negativeMaxThreshold":0}]}]}"#).unwrap();
            let expected_response : models::QueryUserNegativeBalanceAutoExchangeRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryUserNegativeBalanceAutoExchangeRecordResponse");

            let resp = client.query_user_negative_balance_auto_exchange_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 query_user_negative_balance_auto_exchange_record_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = QueryUserNegativeBalanceAutoExchangeRecordParams::builder(1623319461670,1641782889000,).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"total":2,"rows":[{"startTime":1736263046841,"endTime":1736263248179,"details":[{"asset":"ETH","negativeBalance":18,"negativeMaxThreshold":5}]},{"startTime":1736184913252,"endTime":1736184965474,"details":[{"asset":"BNB","negativeBalance":1.10264488,"negativeMaxThreshold":0}]}]}"#).unwrap();
            let expected_response : models::QueryUserNegativeBalanceAutoExchangeRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryUserNegativeBalanceAutoExchangeRecordResponse");

            let resp = client.query_user_negative_balance_auto_exchange_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 query_user_negative_balance_auto_exchange_record_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = QueryUserNegativeBalanceAutoExchangeRecordParams::builder(
                1623319461670,
                1641782889000,
            )
            .build()
            .unwrap();

            match client
                .query_user_negative_balance_auto_exchange_record(params)
                .await
            {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn query_user_rate_limit_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = QueryUserRateLimitParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(
                r#"[{"rateLimitType":"ORDERS","interval":"MINUTE","intervalNum":1,"limit":1200}]"#,
            )
            .unwrap();
            let expected_response: Vec<models::QueryUserRateLimitResponseInner> =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into Vec<models::QueryUserRateLimitResponseInner>");

            let resp = client
                .query_user_rate_limit(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_user_rate_limit_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = QueryUserRateLimitParams::builder()
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(
                r#"[{"rateLimitType":"ORDERS","interval":"MINUTE","intervalNum":1,"limit":1200}]"#,
            )
            .unwrap();
            let expected_response: Vec<models::QueryUserRateLimitResponseInner> =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into Vec<models::QueryUserRateLimitResponseInner>");

            let resp = client
                .query_user_rate_limit(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_user_rate_limit_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = QueryUserRateLimitParams::builder().build().unwrap();

            match client.query_user_rate_limit(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn repay_futures_negative_balance_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = RepayFuturesNegativeBalanceParams::builder()
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"msg":"success"}"#).unwrap();
            let expected_response: models::RepayFuturesNegativeBalanceResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::RepayFuturesNegativeBalanceResponse");

            let resp = client
                .repay_futures_negative_balance(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 repay_futures_negative_balance_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = RepayFuturesNegativeBalanceParams::builder()
                .recv_window(5000)
                .build()
                .unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"msg":"success"}"#).unwrap();
            let expected_response: models::RepayFuturesNegativeBalanceResponse =
                serde_json::from_value(resp_json.clone())
                    .expect("should parse into models::RepayFuturesNegativeBalanceResponse");

            let resp = client
                .repay_futures_negative_balance(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 repay_futures_negative_balance_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = RepayFuturesNegativeBalanceParams::builder()
                .build()
                .unwrap();

            match client.repay_futures_negative_balance(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn um_futures_account_configuration_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = UmFuturesAccountConfigurationParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"feeTier":0,"canTrade":true,"canDeposit":true,"canWithdraw":true,"dualSidePosition":true,"updateTime":1724416653850,"multiAssetsMargin":false,"tradeGroupId":-1}"#).unwrap();
            let expected_response : models::UmFuturesAccountConfigurationResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::UmFuturesAccountConfigurationResponse");

            let resp = client.um_futures_account_configuration(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 um_futures_account_configuration_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = UmFuturesAccountConfigurationParams::builder().recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"{"feeTier":0,"canTrade":true,"canDeposit":true,"canWithdraw":true,"dualSidePosition":true,"updateTime":1724416653850,"multiAssetsMargin":false,"tradeGroupId":-1}"#).unwrap();
            let expected_response : models::UmFuturesAccountConfigurationResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::UmFuturesAccountConfigurationResponse");

            let resp = client.um_futures_account_configuration(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 um_futures_account_configuration_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = UmFuturesAccountConfigurationParams::builder()
                .build()
                .unwrap();

            match client.um_futures_account_configuration(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn um_futures_symbol_configuration_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = UmFuturesSymbolConfigurationParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSDT","marginType":"CROSSED","isAutoAddMargin":"false","leverage":21,"maxNotionalValue":"1000000"}]"#).unwrap();
            let expected_response : Vec<models::UmFuturesSymbolConfigurationResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::UmFuturesSymbolConfigurationResponseInner>");

            let resp = client.um_futures_symbol_configuration(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 um_futures_symbol_configuration_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = UmFuturesSymbolConfigurationParams::builder().symbol("symbol_example".to_string()).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSDT","marginType":"CROSSED","isAutoAddMargin":"false","leverage":21,"maxNotionalValue":"1000000"}]"#).unwrap();
            let expected_response : Vec<models::UmFuturesSymbolConfigurationResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::UmFuturesSymbolConfigurationResponseInner>");

            let resp = client.um_futures_symbol_configuration(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 um_futures_symbol_configuration_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = UmFuturesSymbolConfigurationParams::builder()
                .build()
                .unwrap();

            match client.um_futures_symbol_configuration(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }

    #[test]
    fn um_notional_and_leverage_brackets_required_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = UmNotionalAndLeverageBracketsParams::builder().build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"ETHUSDT","notionalCoef":"4.0","brackets":[{"bracket":1,"initialLeverage":75,"notionalCap":10000,"notionalFloor":0,"maintMarginRatio":0.0065,"cum":0}]}]"#).unwrap();
            let expected_response : Vec<models::UmNotionalAndLeverageBracketsResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::UmNotionalAndLeverageBracketsResponseInner>");

            let resp = client.um_notional_and_leverage_brackets(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 um_notional_and_leverage_brackets_optional_params_success() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: false };

            let params = UmNotionalAndLeverageBracketsParams::builder().symbol("symbol_example".to_string()).recv_window(5000).build().unwrap();

            let resp_json: Value = serde_json::from_str(r#"[{"symbol":"ETHUSDT","notionalCoef":"4.0","brackets":[{"bracket":1,"initialLeverage":75,"notionalCap":10000,"notionalFloor":0,"maintMarginRatio":0.0065,"cum":0}]}]"#).unwrap();
            let expected_response : Vec<models::UmNotionalAndLeverageBracketsResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::UmNotionalAndLeverageBracketsResponseInner>");

            let resp = client.um_notional_and_leverage_brackets(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 um_notional_and_leverage_brackets_response_error() {
        TOKIO_SHARED_RT.block_on(async {
            let client = MockAccountApiClient { force_error: true };

            let params = UmNotionalAndLeverageBracketsParams::builder()
                .build()
                .unwrap();

            match client.um_notional_and_leverage_brackets(params).await {
                Ok(_) => panic!("Expected an error"),
                Err(err) => {
                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
                }
            }
        });
    }
}
