/*
* Binance Derivatives Trading COIN Futures REST API
*
* OpenAPI Specification for the Binance Derivatives Trading COIN Futures 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_coin_futures::rest_api::models;
const HAS_TIME_UNIT: bool = false;
#[async_trait]
pub trait TradeApi: Send + Sync {
async fn account_trade_list(
&self,
params: AccountTradeListParams,
) -> anyhow::Result<RestApiResponse<Vec<models::AccountTradeListResponseInner>>>;
async fn all_orders(
&self,
params: AllOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::AllOrdersResponseInner>>>;
async fn auto_cancel_all_open_orders(
&self,
params: AutoCancelAllOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<models::AutoCancelAllOpenOrdersResponse>>;
async fn cancel_all_open_orders(
&self,
params: CancelAllOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<models::CancelAllOpenOrdersResponse>>;
async fn cancel_multiple_orders(
&self,
params: CancelMultipleOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::CancelMultipleOrdersResponseInner>>>;
async fn cancel_order(
&self,
params: CancelOrderParams,
) -> anyhow::Result<RestApiResponse<models::CancelOrderResponse>>;
async fn change_initial_leverage(
&self,
params: ChangeInitialLeverageParams,
) -> anyhow::Result<RestApiResponse<models::ChangeInitialLeverageResponse>>;
async fn change_margin_type(
&self,
params: ChangeMarginTypeParams,
) -> anyhow::Result<RestApiResponse<models::ChangeMarginTypeResponse>>;
async fn change_position_mode(
&self,
params: ChangePositionModeParams,
) -> anyhow::Result<RestApiResponse<models::ChangePositionModeResponse>>;
async fn current_all_open_orders(
&self,
params: CurrentAllOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::AllOrdersResponseInner>>>;
async fn get_order_modify_history(
&self,
params: GetOrderModifyHistoryParams,
) -> anyhow::Result<RestApiResponse<Vec<models::GetOrderModifyHistoryResponseInner>>>;
async fn get_position_margin_change_history(
&self,
params: GetPositionMarginChangeHistoryParams,
) -> anyhow::Result<RestApiResponse<Vec<models::GetPositionMarginChangeHistoryResponseInner>>>;
async fn modify_isolated_position_margin(
&self,
params: ModifyIsolatedPositionMarginParams,
) -> anyhow::Result<RestApiResponse<models::ModifyIsolatedPositionMarginResponse>>;
async fn modify_multiple_orders(
&self,
params: ModifyMultipleOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::ModifyMultipleOrdersResponseInner>>>;
async fn modify_order(
&self,
params: ModifyOrderParams,
) -> anyhow::Result<RestApiResponse<models::ModifyOrderResponse>>;
async fn new_order(
&self,
params: NewOrderParams,
) -> anyhow::Result<RestApiResponse<models::NewOrderResponse>>;
async fn place_multiple_orders(
&self,
params: PlaceMultipleOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::PlaceMultipleOrdersResponseInner>>>;
async fn position_adl_quantile_estimation(
&self,
params: PositionAdlQuantileEstimationParams,
) -> anyhow::Result<RestApiResponse<Vec<models::PositionAdlQuantileEstimationResponseInner>>>;
async fn position_information(
&self,
params: PositionInformationParams,
) -> anyhow::Result<RestApiResponse<Vec<models::PositionInformationResponseInner>>>;
async fn query_current_open_order(
&self,
params: QueryCurrentOpenOrderParams,
) -> anyhow::Result<RestApiResponse<models::QueryCurrentOpenOrderResponse>>;
async fn query_order(
&self,
params: QueryOrderParams,
) -> anyhow::Result<RestApiResponse<models::QueryOrderResponse>>;
async fn users_force_orders(
&self,
params: UsersForceOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::UsersForceOrdersResponseInner>>>;
}
#[derive(Debug, Clone)]
pub struct TradeApiClient {
configuration: ConfigurationRestApi,
}
impl TradeApiClient {
pub fn new(configuration: ConfigurationRestApi) -> Self {
Self { configuration }
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ChangeMarginTypeMarginTypeEnum {
#[serde(rename = "ISOLATED")]
Isolated,
#[serde(rename = "CROSSED")]
Crossed,
}
impl ChangeMarginTypeMarginTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Isolated => "ISOLATED",
Self::Crossed => "CROSSED",
}
}
}
impl std::str::FromStr for ChangeMarginTypeMarginTypeEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"ISOLATED" => Ok(Self::Isolated),
"CROSSED" => Ok(Self::Crossed),
other => Err(format!("invalid ChangeMarginTypeMarginTypeEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ModifyIsolatedPositionMarginTypeEnum {
#[serde(rename = "LIMIT")]
Limit,
#[serde(rename = "MARKET")]
Market,
#[serde(rename = "STOP")]
Stop,
#[serde(rename = "STOP_MARKET")]
StopMarket,
#[serde(rename = "TAKE_PROFIT")]
TakeProfit,
#[serde(rename = "TAKE_PROFIT_MARKET")]
TakeProfitMarket,
#[serde(rename = "TRAILING_STOP_MARKET")]
TrailingStopMarket,
}
impl ModifyIsolatedPositionMarginTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Limit => "LIMIT",
Self::Market => "MARKET",
Self::Stop => "STOP",
Self::StopMarket => "STOP_MARKET",
Self::TakeProfit => "TAKE_PROFIT",
Self::TakeProfitMarket => "TAKE_PROFIT_MARKET",
Self::TrailingStopMarket => "TRAILING_STOP_MARKET",
}
}
}
impl std::str::FromStr for ModifyIsolatedPositionMarginTypeEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"LIMIT" => Ok(Self::Limit),
"MARKET" => Ok(Self::Market),
"STOP" => Ok(Self::Stop),
"STOP_MARKET" => Ok(Self::StopMarket),
"TAKE_PROFIT" => Ok(Self::TakeProfit),
"TAKE_PROFIT_MARKET" => Ok(Self::TakeProfitMarket),
"TRAILING_STOP_MARKET" => Ok(Self::TrailingStopMarket),
other => Err(format!("invalid ModifyIsolatedPositionMarginTypeEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ModifyIsolatedPositionMarginPositionSideEnum {
#[serde(rename = "BOTH")]
Both,
#[serde(rename = "LONG")]
Long,
#[serde(rename = "SHORT")]
Short,
}
impl ModifyIsolatedPositionMarginPositionSideEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Both => "BOTH",
Self::Long => "LONG",
Self::Short => "SHORT",
}
}
}
impl std::str::FromStr for ModifyIsolatedPositionMarginPositionSideEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"BOTH" => Ok(Self::Both),
"LONG" => Ok(Self::Long),
"SHORT" => Ok(Self::Short),
other => Err(format!(
"invalid ModifyIsolatedPositionMarginPositionSideEnum: {}",
other
)
.into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ModifyOrderSideEnum {
#[serde(rename = "BUY")]
Buy,
#[serde(rename = "SELL")]
Sell,
}
impl ModifyOrderSideEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Buy => "BUY",
Self::Sell => "SELL",
}
}
}
impl std::str::FromStr for ModifyOrderSideEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"BUY" => Ok(Self::Buy),
"SELL" => Ok(Self::Sell),
other => Err(format!("invalid ModifyOrderSideEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ModifyOrderPriceMatchEnum {
#[serde(rename = "NONE")]
None,
#[serde(rename = "OPPONENT")]
Opponent,
#[serde(rename = "OPPONENT_5")]
Opponent5,
#[serde(rename = "OPPONENT_10")]
Opponent10,
#[serde(rename = "OPPONENT_20")]
Opponent20,
#[serde(rename = "QUEUE")]
Queue,
#[serde(rename = "QUEUE_5")]
Queue5,
#[serde(rename = "QUEUE_10")]
Queue10,
#[serde(rename = "QUEUE_20")]
Queue20,
}
impl ModifyOrderPriceMatchEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::None => "NONE",
Self::Opponent => "OPPONENT",
Self::Opponent5 => "OPPONENT_5",
Self::Opponent10 => "OPPONENT_10",
Self::Opponent20 => "OPPONENT_20",
Self::Queue => "QUEUE",
Self::Queue5 => "QUEUE_5",
Self::Queue10 => "QUEUE_10",
Self::Queue20 => "QUEUE_20",
}
}
}
impl std::str::FromStr for ModifyOrderPriceMatchEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"NONE" => Ok(Self::None),
"OPPONENT" => Ok(Self::Opponent),
"OPPONENT_5" => Ok(Self::Opponent5),
"OPPONENT_10" => Ok(Self::Opponent10),
"OPPONENT_20" => Ok(Self::Opponent20),
"QUEUE" => Ok(Self::Queue),
"QUEUE_5" => Ok(Self::Queue5),
"QUEUE_10" => Ok(Self::Queue10),
"QUEUE_20" => Ok(Self::Queue20),
other => Err(format!("invalid ModifyOrderPriceMatchEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NewOrderSideEnum {
#[serde(rename = "BUY")]
Buy,
#[serde(rename = "SELL")]
Sell,
}
impl NewOrderSideEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Buy => "BUY",
Self::Sell => "SELL",
}
}
}
impl std::str::FromStr for NewOrderSideEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"BUY" => Ok(Self::Buy),
"SELL" => Ok(Self::Sell),
other => Err(format!("invalid NewOrderSideEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NewOrderTypeEnum {
#[serde(rename = "LIMIT")]
Limit,
#[serde(rename = "MARKET")]
Market,
#[serde(rename = "STOP")]
Stop,
#[serde(rename = "STOP_MARKET")]
StopMarket,
#[serde(rename = "TAKE_PROFIT")]
TakeProfit,
#[serde(rename = "TAKE_PROFIT_MARKET")]
TakeProfitMarket,
#[serde(rename = "TRAILING_STOP_MARKET")]
TrailingStopMarket,
}
impl NewOrderTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Limit => "LIMIT",
Self::Market => "MARKET",
Self::Stop => "STOP",
Self::StopMarket => "STOP_MARKET",
Self::TakeProfit => "TAKE_PROFIT",
Self::TakeProfitMarket => "TAKE_PROFIT_MARKET",
Self::TrailingStopMarket => "TRAILING_STOP_MARKET",
}
}
}
impl std::str::FromStr for NewOrderTypeEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"LIMIT" => Ok(Self::Limit),
"MARKET" => Ok(Self::Market),
"STOP" => Ok(Self::Stop),
"STOP_MARKET" => Ok(Self::StopMarket),
"TAKE_PROFIT" => Ok(Self::TakeProfit),
"TAKE_PROFIT_MARKET" => Ok(Self::TakeProfitMarket),
"TRAILING_STOP_MARKET" => Ok(Self::TrailingStopMarket),
other => Err(format!("invalid NewOrderTypeEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NewOrderPositionSideEnum {
#[serde(rename = "BOTH")]
Both,
#[serde(rename = "LONG")]
Long,
#[serde(rename = "SHORT")]
Short,
}
impl NewOrderPositionSideEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Both => "BOTH",
Self::Long => "LONG",
Self::Short => "SHORT",
}
}
}
impl std::str::FromStr for NewOrderPositionSideEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"BOTH" => Ok(Self::Both),
"LONG" => Ok(Self::Long),
"SHORT" => Ok(Self::Short),
other => Err(format!("invalid NewOrderPositionSideEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NewOrderTimeInForceEnum {
#[serde(rename = "GTC")]
Gtc,
#[serde(rename = "IOC")]
Ioc,
#[serde(rename = "FOK")]
Fok,
#[serde(rename = "GTX")]
Gtx,
}
impl NewOrderTimeInForceEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Gtc => "GTC",
Self::Ioc => "IOC",
Self::Fok => "FOK",
Self::Gtx => "GTX",
}
}
}
impl std::str::FromStr for NewOrderTimeInForceEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"GTC" => Ok(Self::Gtc),
"IOC" => Ok(Self::Ioc),
"FOK" => Ok(Self::Fok),
"GTX" => Ok(Self::Gtx),
other => Err(format!("invalid NewOrderTimeInForceEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NewOrderWorkingTypeEnum {
#[serde(rename = "MARK_PRICE")]
MarkPrice,
#[serde(rename = "CONTRACT_PRICE")]
ContractPrice,
}
impl NewOrderWorkingTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::MarkPrice => "MARK_PRICE",
Self::ContractPrice => "CONTRACT_PRICE",
}
}
}
impl std::str::FromStr for NewOrderWorkingTypeEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"MARK_PRICE" => Ok(Self::MarkPrice),
"CONTRACT_PRICE" => Ok(Self::ContractPrice),
other => Err(format!("invalid NewOrderWorkingTypeEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NewOrderNewOrderRespTypeEnum {
#[serde(rename = "ACK")]
Ack,
#[serde(rename = "RESULT")]
Result,
}
impl NewOrderNewOrderRespTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Ack => "ACK",
Self::Result => "RESULT",
}
}
}
impl std::str::FromStr for NewOrderNewOrderRespTypeEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"ACK" => Ok(Self::Ack),
"RESULT" => Ok(Self::Result),
other => Err(format!("invalid NewOrderNewOrderRespTypeEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NewOrderPriceMatchEnum {
#[serde(rename = "NONE")]
None,
#[serde(rename = "OPPONENT")]
Opponent,
#[serde(rename = "OPPONENT_5")]
Opponent5,
#[serde(rename = "OPPONENT_10")]
Opponent10,
#[serde(rename = "OPPONENT_20")]
Opponent20,
#[serde(rename = "QUEUE")]
Queue,
#[serde(rename = "QUEUE_5")]
Queue5,
#[serde(rename = "QUEUE_10")]
Queue10,
#[serde(rename = "QUEUE_20")]
Queue20,
}
impl NewOrderPriceMatchEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::None => "NONE",
Self::Opponent => "OPPONENT",
Self::Opponent5 => "OPPONENT_5",
Self::Opponent10 => "OPPONENT_10",
Self::Opponent20 => "OPPONENT_20",
Self::Queue => "QUEUE",
Self::Queue5 => "QUEUE_5",
Self::Queue10 => "QUEUE_10",
Self::Queue20 => "QUEUE_20",
}
}
}
impl std::str::FromStr for NewOrderPriceMatchEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"NONE" => Ok(Self::None),
"OPPONENT" => Ok(Self::Opponent),
"OPPONENT_5" => Ok(Self::Opponent5),
"OPPONENT_10" => Ok(Self::Opponent10),
"OPPONENT_20" => Ok(Self::Opponent20),
"QUEUE" => Ok(Self::Queue),
"QUEUE_5" => Ok(Self::Queue5),
"QUEUE_10" => Ok(Self::Queue10),
"QUEUE_20" => Ok(Self::Queue20),
other => Err(format!("invalid NewOrderPriceMatchEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NewOrderSelfTradePreventionModeEnum {
#[serde(rename = "NONE")]
None,
#[serde(rename = "EXPIRE_TAKER")]
ExpireTaker,
#[serde(rename = "EXPIRE_BOTH")]
ExpireBoth,
#[serde(rename = "EXPIRE_MAKER")]
ExpireMaker,
}
impl NewOrderSelfTradePreventionModeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::None => "NONE",
Self::ExpireTaker => "EXPIRE_TAKER",
Self::ExpireBoth => "EXPIRE_BOTH",
Self::ExpireMaker => "EXPIRE_MAKER",
}
}
}
impl std::str::FromStr for NewOrderSelfTradePreventionModeEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"NONE" => Ok(Self::None),
"EXPIRE_TAKER" => Ok(Self::ExpireTaker),
"EXPIRE_BOTH" => Ok(Self::ExpireBoth),
"EXPIRE_MAKER" => Ok(Self::ExpireMaker),
other => Err(format!("invalid NewOrderSelfTradePreventionModeEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum UsersForceOrdersAutoCloseTypeEnum {
#[serde(rename = "LIQUIDATION")]
Liquidation,
#[serde(rename = "ADL")]
Adl,
}
impl UsersForceOrdersAutoCloseTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Liquidation => "LIQUIDATION",
Self::Adl => "ADL",
}
}
}
impl std::str::FromStr for UsersForceOrdersAutoCloseTypeEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"LIQUIDATION" => Ok(Self::Liquidation),
"ADL" => Ok(Self::Adl),
other => Err(format!("invalid UsersForceOrdersAutoCloseTypeEnum: {}", other).into()),
}
}
}
/// Request parameters for the [`account_trade_list`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`account_trade_list`](#method.account_trade_list).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct AccountTradeListParams {
///
/// The `symbol` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub symbol: Option<String>,
///
/// The `pair` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pair: Option<String>,
///
/// The `order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub order_id: Option<String>,
///
/// The `start_time` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub start_time: Option<i64>,
///
/// The `end_time` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub end_time: Option<i64>,
/// ID to get aggregate trades from INCLUSIVE.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub from_id: 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 AccountTradeListParams {
/// Create a builder for [`account_trade_list`].
///
#[must_use]
pub fn builder() -> AccountTradeListParamsBuilder {
AccountTradeListParamsBuilder::default()
}
}
/// Request parameters for the [`all_orders`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`all_orders`](#method.all_orders).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct AllOrdersParams {
///
/// The `symbol` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub symbol: Option<String>,
///
/// The `pair` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub pair: Option<String>,
///
/// The `order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub order_id: Option<i64>,
///
/// The `start_time` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub start_time: Option<i64>,
///
/// The `end_time` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub end_time: Option<i64>,
/// 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 AllOrdersParams {
/// Create a builder for [`all_orders`].
///
#[must_use]
pub fn builder() -> AllOrdersParamsBuilder {
AllOrdersParamsBuilder::default()
}
}
/// Request parameters for the [`auto_cancel_all_open_orders`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`auto_cancel_all_open_orders`](#method.auto_cancel_all_open_orders).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct AutoCancelAllOpenOrdersParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
/// countdown time, 1000 for 1 second. 0 to cancel the timer
///
/// This field is **required.
#[builder(setter(into))]
pub countdown_time: i64,
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl AutoCancelAllOpenOrdersParams {
/// Create a builder for [`auto_cancel_all_open_orders`].
///
/// Required parameters:
///
/// * `symbol` — String
/// * `countdown_time` — countdown time, 1000 for 1 second. 0 to cancel the timer
///
#[must_use]
pub fn builder(symbol: String, countdown_time: i64) -> AutoCancelAllOpenOrdersParamsBuilder {
AutoCancelAllOpenOrdersParamsBuilder::default()
.symbol(symbol)
.countdown_time(countdown_time)
}
}
/// Request parameters for the [`cancel_all_open_orders`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`cancel_all_open_orders`](#method.cancel_all_open_orders).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct CancelAllOpenOrdersParams {
///
/// 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 CancelAllOpenOrdersParams {
/// Create a builder for [`cancel_all_open_orders`].
///
/// Required parameters:
///
/// * `symbol` — String
///
#[must_use]
pub fn builder(symbol: String) -> CancelAllOpenOrdersParamsBuilder {
CancelAllOpenOrdersParamsBuilder::default().symbol(symbol)
}
}
/// Request parameters for the [`cancel_multiple_orders`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`cancel_multiple_orders`](#method.cancel_multiple_orders).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct CancelMultipleOrdersParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
/// max length 10 <br /> e.g. [1234567,2345678]
///
/// This field is **optional.
#[builder(setter(into), default)]
pub order_id_list: Option<Vec<i64>>,
/// max length 10<br /> e.g. ["`my_id_1","my_id_2`"], encode the double quotes. No space after comma.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub orig_client_order_id_list: Option<Vec<String>>,
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl CancelMultipleOrdersParams {
/// Create a builder for [`cancel_multiple_orders`].
///
/// Required parameters:
///
/// * `symbol` — String
///
#[must_use]
pub fn builder(symbol: String) -> CancelMultipleOrdersParamsBuilder {
CancelMultipleOrdersParamsBuilder::default().symbol(symbol)
}
}
/// Request parameters for the [`cancel_order`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`cancel_order`](#method.cancel_order).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct CancelOrderParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
///
/// The `order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub order_id: Option<i64>,
///
/// The `orig_client_order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub orig_client_order_id: Option<String>,
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl CancelOrderParams {
/// Create a builder for [`cancel_order`].
///
/// Required parameters:
///
/// * `symbol` — String
///
#[must_use]
pub fn builder(symbol: String) -> CancelOrderParamsBuilder {
CancelOrderParamsBuilder::default().symbol(symbol)
}
}
/// Request parameters for the [`change_initial_leverage`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`change_initial_leverage`](#method.change_initial_leverage).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct ChangeInitialLeverageParams {
///
/// 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 ChangeInitialLeverageParams {
/// Create a builder for [`change_initial_leverage`].
///
/// Required parameters:
///
/// * `symbol` — String
/// * `leverage` — target initial leverage: int from 1 to 125
///
#[must_use]
pub fn builder(symbol: String, leverage: i64) -> ChangeInitialLeverageParamsBuilder {
ChangeInitialLeverageParamsBuilder::default()
.symbol(symbol)
.leverage(leverage)
}
}
/// Request parameters for the [`change_margin_type`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`change_margin_type`](#method.change_margin_type).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct ChangeMarginTypeParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
/// ISOLATED, CROSSED
///
/// This field is **required.
#[builder(setter(into))]
pub margin_type: ChangeMarginTypeMarginTypeEnum,
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl ChangeMarginTypeParams {
/// Create a builder for [`change_margin_type`].
///
/// Required parameters:
///
/// * `symbol` — String
/// * `margin_type` — ISOLATED, CROSSED
///
#[must_use]
pub fn builder(
symbol: String,
margin_type: ChangeMarginTypeMarginTypeEnum,
) -> ChangeMarginTypeParamsBuilder {
ChangeMarginTypeParamsBuilder::default()
.symbol(symbol)
.margin_type(margin_type)
}
}
/// Request parameters for the [`change_position_mode`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`change_position_mode`](#method.change_position_mode).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct ChangePositionModeParams {
/// "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 ChangePositionModeParams {
/// Create a builder for [`change_position_mode`].
///
/// Required parameters:
///
/// * `dual_side_position` — \"true\": Hedge Mode; \"false\": One-way Mode
///
#[must_use]
pub fn builder(dual_side_position: String) -> ChangePositionModeParamsBuilder {
ChangePositionModeParamsBuilder::default().dual_side_position(dual_side_position)
}
}
/// Request parameters for the [`current_all_open_orders`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`current_all_open_orders`](#method.current_all_open_orders).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct CurrentAllOpenOrdersParams {
///
/// The `symbol` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub symbol: 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 CurrentAllOpenOrdersParams {
/// Create a builder for [`current_all_open_orders`].
///
#[must_use]
pub fn builder() -> CurrentAllOpenOrdersParamsBuilder {
CurrentAllOpenOrdersParamsBuilder::default()
}
}
/// Request parameters for the [`get_order_modify_history`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_order_modify_history`](#method.get_order_modify_history).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetOrderModifyHistoryParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
///
/// The `order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub order_id: Option<i64>,
///
/// The `orig_client_order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub orig_client_order_id: Option<String>,
///
/// The `start_time` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub start_time: Option<i64>,
///
/// The `end_time` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub end_time: Option<i64>,
/// 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 GetOrderModifyHistoryParams {
/// Create a builder for [`get_order_modify_history`].
///
/// Required parameters:
///
/// * `symbol` — String
///
#[must_use]
pub fn builder(symbol: String) -> GetOrderModifyHistoryParamsBuilder {
GetOrderModifyHistoryParamsBuilder::default().symbol(symbol)
}
}
/// Request parameters for the [`get_position_margin_change_history`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`get_position_margin_change_history`](#method.get_position_margin_change_history).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetPositionMarginChangeHistoryParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
/// 1: Add position margin,2: Reduce position margin
///
/// This field is **optional.
#[builder(setter(into), default)]
pub r#type: Option<i64>,
///
/// The `start_time` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub start_time: Option<i64>,
///
/// The `end_time` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub end_time: Option<i64>,
/// 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 GetPositionMarginChangeHistoryParams {
/// Create a builder for [`get_position_margin_change_history`].
///
/// Required parameters:
///
/// * `symbol` — String
///
#[must_use]
pub fn builder(symbol: String) -> GetPositionMarginChangeHistoryParamsBuilder {
GetPositionMarginChangeHistoryParamsBuilder::default().symbol(symbol)
}
}
/// Request parameters for the [`modify_isolated_position_margin`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`modify_isolated_position_margin`](#method.modify_isolated_position_margin).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct ModifyIsolatedPositionMarginParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
///
/// The `amount` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub amount: rust_decimal::Decimal,
///
/// The `r#type` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub r#type: ModifyIsolatedPositionMarginTypeEnum,
/// Default `BOTH` for One-way Mode ; `LONG` or `SHORT` for Hedge Mode. It must be sent with Hedge Mode.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub position_side: Option<ModifyIsolatedPositionMarginPositionSideEnum>,
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl ModifyIsolatedPositionMarginParams {
/// Create a builder for [`modify_isolated_position_margin`].
///
/// Required parameters:
///
/// * `symbol` — String
/// * `amount` — `rust_decimal::Decimal`
/// * `r#type` — String
///
#[must_use]
pub fn builder(
symbol: String,
amount: rust_decimal::Decimal,
r#type: ModifyIsolatedPositionMarginTypeEnum,
) -> ModifyIsolatedPositionMarginParamsBuilder {
ModifyIsolatedPositionMarginParamsBuilder::default()
.symbol(symbol)
.amount(amount)
.r#type(r#type)
}
}
/// Request parameters for the [`modify_multiple_orders`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`modify_multiple_orders`](#method.modify_multiple_orders).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct ModifyMultipleOrdersParams {
/// order list. Max 5 orders
///
/// This field is **required.
#[builder(setter(into))]
pub batch_orders: Vec<models::ModifyMultipleOrdersBatchOrdersParameterInner>,
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl ModifyMultipleOrdersParams {
/// Create a builder for [`modify_multiple_orders`].
///
/// Required parameters:
///
/// * `batch_orders` — order list. Max 5 orders
///
#[must_use]
pub fn builder(
batch_orders: Vec<models::ModifyMultipleOrdersBatchOrdersParameterInner>,
) -> ModifyMultipleOrdersParamsBuilder {
ModifyMultipleOrdersParamsBuilder::default().batch_orders(batch_orders)
}
}
/// Request parameters for the [`modify_order`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`modify_order`](#method.modify_order).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct ModifyOrderParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
/// `SELL`, `BUY`
///
/// This field is **required.
#[builder(setter(into))]
pub side: ModifyOrderSideEnum,
///
/// The `order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub order_id: Option<i64>,
///
/// The `orig_client_order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub orig_client_order_id: Option<String>,
/// quantity measured by contract number, Cannot be sent with `closePosition`=`true`
///
/// This field is **optional.
#[builder(setter(into), default)]
pub quantity: Option<rust_decimal::Decimal>,
///
/// The `price` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub price: Option<rust_decimal::Decimal>,
/// only avaliable for `LIMIT`/`STOP`/`TAKE_PROFIT` order; can be set to `OPPONENT`/ `OPPONENT_5`/ `OPPONENT_10`/ `OPPONENT_20`: /`QUEUE`/ `QUEUE_5`/ `QUEUE_10`/ `QUEUE_20`; Can't be passed together with `price`
///
/// This field is **optional.
#[builder(setter(into), default)]
pub price_match: Option<ModifyOrderPriceMatchEnum>,
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl ModifyOrderParams {
/// Create a builder for [`modify_order`].
///
/// Required parameters:
///
/// * `symbol` — String
/// * `side` — `SELL`, `BUY`
///
#[must_use]
pub fn builder(symbol: String, side: ModifyOrderSideEnum) -> ModifyOrderParamsBuilder {
ModifyOrderParamsBuilder::default()
.symbol(symbol)
.side(side)
}
}
/// Request parameters for the [`new_order`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`new_order`](#method.new_order).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct NewOrderParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
/// `SELL`, `BUY`
///
/// This field is **required.
#[builder(setter(into))]
pub side: NewOrderSideEnum,
///
/// The `r#type` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub r#type: NewOrderTypeEnum,
/// Default `BOTH` for One-way Mode ; `LONG` or `SHORT` for Hedge Mode. It must be sent with Hedge Mode.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub position_side: Option<NewOrderPositionSideEnum>,
///
/// The `time_in_force` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub time_in_force: Option<NewOrderTimeInForceEnum>,
/// quantity measured by contract number, Cannot be sent with `closePosition`=`true`
///
/// This field is **optional.
#[builder(setter(into), default)]
pub quantity: Option<rust_decimal::Decimal>,
/// "true" or "false". default "false". Cannot be sent in Hedge Mode; cannot be sent with `closePosition`=`true`(Close-All)
///
/// This field is **optional.
#[builder(setter(into), default)]
pub reduce_only: Option<String>,
///
/// The `price` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub price: Option<rust_decimal::Decimal>,
/// A unique id among open orders. Automatically generated if not sent. Can only be string following the rule: `^[\.A-Z\:/a-z0-9_-]{1,36}$`
///
/// This field is **optional.
#[builder(setter(into), default)]
pub new_client_order_id: Option<String>,
/// Used with `STOP/STOP_MARKET` or `TAKE_PROFIT/TAKE_PROFIT_MARKET` orders.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub stop_price: Option<rust_decimal::Decimal>,
/// `true`, `false`ï¼›Close-All,used with `STOP_MARKET` or `TAKE_PROFIT_MARKET`.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub close_position: Option<String>,
/// Used with `TRAILING_STOP_MARKET` orders, default as the latest price(supporting different `workingType`)
///
/// This field is **optional.
#[builder(setter(into), default)]
pub activation_price: Option<rust_decimal::Decimal>,
/// Used with `TRAILING_STOP_MARKET` orders, min 0.1, max 10 where 1 for 1%
///
/// This field is **optional.
#[builder(setter(into), default)]
pub callback_rate: Option<rust_decimal::Decimal>,
/// stopPrice triggered by: "`MARK_PRICE`", "`CONTRACT_PRICE`". Default "`CONTRACT_PRICE`"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub working_type: Option<NewOrderWorkingTypeEnum>,
/// "TRUE" or "FALSE", default "FALSE". Used with `STOP/STOP_MARKET` or `TAKE_PROFIT/TAKE_PROFIT_MARKET` orders.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub price_protect: Option<String>,
/// "ACK", "RESULT", default "ACK"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub new_order_resp_type: Option<NewOrderNewOrderRespTypeEnum>,
/// only avaliable for `LIMIT`/`STOP`/`TAKE_PROFIT` order; can be set to `OPPONENT`/ `OPPONENT_5`/ `OPPONENT_10`/ `OPPONENT_20`: /`QUEUE`/ `QUEUE_5`/ `QUEUE_10`/ `QUEUE_20`; Can't be passed together with `price`
///
/// This field is **optional.
#[builder(setter(into), default)]
pub price_match: Option<NewOrderPriceMatchEnum>,
/// `EXPIRE_TAKER`:expire taker order when STP triggers/ `EXPIRE_MAKER`:expire taker order when STP triggers/ `EXPIRE_BOTH`:expire both orders when STP triggers; default `EXPIRE_MAKER`
///
/// This field is **optional.
#[builder(setter(into), default)]
pub self_trade_prevention_mode: Option<NewOrderSelfTradePreventionModeEnum>,
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl NewOrderParams {
/// Create a builder for [`new_order`].
///
/// Required parameters:
///
/// * `symbol` — String
/// * `side` — `SELL`, `BUY`
/// * `r#type` — String
///
#[must_use]
pub fn builder(
symbol: String,
side: NewOrderSideEnum,
r#type: NewOrderTypeEnum,
) -> NewOrderParamsBuilder {
NewOrderParamsBuilder::default()
.symbol(symbol)
.side(side)
.r#type(r#type)
}
}
/// Request parameters for the [`place_multiple_orders`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`place_multiple_orders`](#method.place_multiple_orders).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct PlaceMultipleOrdersParams {
/// order list. Max 5 orders
///
/// This field is **required.
#[builder(setter(into))]
pub batch_orders: Vec<models::PlaceMultipleOrdersBatchOrdersParameterInner>,
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl PlaceMultipleOrdersParams {
/// Create a builder for [`place_multiple_orders`].
///
/// Required parameters:
///
/// * `batch_orders` — order list. Max 5 orders
///
#[must_use]
pub fn builder(
batch_orders: Vec<models::PlaceMultipleOrdersBatchOrdersParameterInner>,
) -> PlaceMultipleOrdersParamsBuilder {
PlaceMultipleOrdersParamsBuilder::default().batch_orders(batch_orders)
}
}
/// Request parameters for the [`position_adl_quantile_estimation`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`position_adl_quantile_estimation`](#method.position_adl_quantile_estimation).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct PositionAdlQuantileEstimationParams {
///
/// 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 PositionAdlQuantileEstimationParams {
/// Create a builder for [`position_adl_quantile_estimation`].
///
#[must_use]
pub fn builder() -> PositionAdlQuantileEstimationParamsBuilder {
PositionAdlQuantileEstimationParamsBuilder::default()
}
}
/// Request parameters for the [`position_information`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`position_information`](#method.position_information).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct PositionInformationParams {
///
/// 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 PositionInformationParams {
/// Create a builder for [`position_information`].
///
#[must_use]
pub fn builder() -> PositionInformationParamsBuilder {
PositionInformationParamsBuilder::default()
}
}
/// Request parameters for the [`query_current_open_order`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_current_open_order`](#method.query_current_open_order).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryCurrentOpenOrderParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
///
/// The `order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub order_id: Option<i64>,
///
/// The `orig_client_order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub orig_client_order_id: Option<String>,
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl QueryCurrentOpenOrderParams {
/// Create a builder for [`query_current_open_order`].
///
/// Required parameters:
///
/// * `symbol` — String
///
#[must_use]
pub fn builder(symbol: String) -> QueryCurrentOpenOrderParamsBuilder {
QueryCurrentOpenOrderParamsBuilder::default().symbol(symbol)
}
}
/// Request parameters for the [`query_order`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_order`](#method.query_order).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryOrderParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
///
/// The `order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub order_id: Option<i64>,
///
/// The `orig_client_order_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub orig_client_order_id: Option<String>,
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl QueryOrderParams {
/// Create a builder for [`query_order`].
///
/// Required parameters:
///
/// * `symbol` — String
///
#[must_use]
pub fn builder(symbol: String) -> QueryOrderParamsBuilder {
QueryOrderParamsBuilder::default().symbol(symbol)
}
}
/// Request parameters for the [`users_force_orders`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`users_force_orders`](#method.users_force_orders).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct UsersForceOrdersParams {
///
/// The `symbol` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub symbol: Option<String>,
/// "LIQUIDATION" for liquidation orders, "ADL" for ADL orders.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub auto_close_type: Option<UsersForceOrdersAutoCloseTypeEnum>,
///
/// The `start_time` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub start_time: Option<i64>,
///
/// The `end_time` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub end_time: Option<i64>,
/// 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 UsersForceOrdersParams {
/// Create a builder for [`users_force_orders`].
///
#[must_use]
pub fn builder() -> UsersForceOrdersParamsBuilder {
UsersForceOrdersParamsBuilder::default()
}
}
#[async_trait]
impl TradeApi for TradeApiClient {
async fn account_trade_list(
&self,
params: AccountTradeListParams,
) -> anyhow::Result<RestApiResponse<Vec<models::AccountTradeListResponseInner>>> {
let AccountTradeListParams {
symbol,
pair,
order_id,
start_time,
end_time,
from_id,
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) = pair {
query_params.insert("pair".to_string(), json!(rw));
}
if let Some(rw) = order_id {
query_params.insert("orderId".to_string(), json!(rw));
}
if let Some(rw) = start_time {
query_params.insert("startTime".to_string(), json!(rw));
}
if let Some(rw) = end_time {
query_params.insert("endTime".to_string(), json!(rw));
}
if let Some(rw) = from_id {
query_params.insert("fromId".to_string(), json!(rw));
}
if let Some(rw) = limit {
query_params.insert("limit".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::AccountTradeListResponseInner>>(
&self.configuration,
"/dapi/v1/userTrades",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn all_orders(
&self,
params: AllOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::AllOrdersResponseInner>>> {
let AllOrdersParams {
symbol,
pair,
order_id,
start_time,
end_time,
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) = pair {
query_params.insert("pair".to_string(), json!(rw));
}
if let Some(rw) = order_id {
query_params.insert("orderId".to_string(), json!(rw));
}
if let Some(rw) = start_time {
query_params.insert("startTime".to_string(), json!(rw));
}
if let Some(rw) = end_time {
query_params.insert("endTime".to_string(), json!(rw));
}
if let Some(rw) = limit {
query_params.insert("limit".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::AllOrdersResponseInner>>(
&self.configuration,
"/dapi/v1/allOrders",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn auto_cancel_all_open_orders(
&self,
params: AutoCancelAllOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<models::AutoCancelAllOpenOrdersResponse>> {
let AutoCancelAllOpenOrdersParams {
symbol,
countdown_time,
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("countdownTime".to_string(), json!(countdown_time));
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::AutoCancelAllOpenOrdersResponse>(
&self.configuration,
"/dapi/v1/countdownCancelAll",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn cancel_all_open_orders(
&self,
params: CancelAllOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<models::CancelAllOpenOrdersResponse>> {
let CancelAllOpenOrdersParams {
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::CancelAllOpenOrdersResponse>(
&self.configuration,
"/dapi/v1/allOpenOrders",
reqwest::Method::DELETE,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn cancel_multiple_orders(
&self,
params: CancelMultipleOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::CancelMultipleOrdersResponseInner>>> {
let CancelMultipleOrdersParams {
symbol,
order_id_list,
orig_client_order_id_list,
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) = order_id_list {
query_params.insert("orderIdList".to_string(), json!(rw));
}
if let Some(rw) = orig_client_order_id_list {
query_params.insert("origClientOrderIdList".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::CancelMultipleOrdersResponseInner>>(
&self.configuration,
"/dapi/v1/batchOrders",
reqwest::Method::DELETE,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn cancel_order(
&self,
params: CancelOrderParams,
) -> anyhow::Result<RestApiResponse<models::CancelOrderResponse>> {
let CancelOrderParams {
symbol,
order_id,
orig_client_order_id,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("symbol".to_string(), json!(symbol));
if let Some(rw) = order_id {
query_params.insert("orderId".to_string(), json!(rw));
}
if let Some(rw) = orig_client_order_id {
query_params.insert("origClientOrderId".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::CancelOrderResponse>(
&self.configuration,
"/dapi/v1/order",
reqwest::Method::DELETE,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn change_initial_leverage(
&self,
params: ChangeInitialLeverageParams,
) -> anyhow::Result<RestApiResponse<models::ChangeInitialLeverageResponse>> {
let ChangeInitialLeverageParams {
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::ChangeInitialLeverageResponse>(
&self.configuration,
"/dapi/v1/leverage",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn change_margin_type(
&self,
params: ChangeMarginTypeParams,
) -> anyhow::Result<RestApiResponse<models::ChangeMarginTypeResponse>> {
let ChangeMarginTypeParams {
symbol,
margin_type,
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("marginType".to_string(), json!(margin_type));
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::ChangeMarginTypeResponse>(
&self.configuration,
"/dapi/v1/marginType",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn change_position_mode(
&self,
params: ChangePositionModeParams,
) -> anyhow::Result<RestApiResponse<models::ChangePositionModeResponse>> {
let ChangePositionModeParams {
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::ChangePositionModeResponse>(
&self.configuration,
"/dapi/v1/positionSide/dual",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn current_all_open_orders(
&self,
params: CurrentAllOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::AllOrdersResponseInner>>> {
let CurrentAllOpenOrdersParams {
symbol,
pair,
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) = 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::AllOrdersResponseInner>>(
&self.configuration,
"/dapi/v1/openOrders",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn get_order_modify_history(
&self,
params: GetOrderModifyHistoryParams,
) -> anyhow::Result<RestApiResponse<Vec<models::GetOrderModifyHistoryResponseInner>>> {
let GetOrderModifyHistoryParams {
symbol,
order_id,
orig_client_order_id,
start_time,
end_time,
limit,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("symbol".to_string(), json!(symbol));
if let Some(rw) = order_id {
query_params.insert("orderId".to_string(), json!(rw));
}
if let Some(rw) = orig_client_order_id {
query_params.insert("origClientOrderId".to_string(), json!(rw));
}
if let Some(rw) = start_time {
query_params.insert("startTime".to_string(), json!(rw));
}
if let Some(rw) = end_time {
query_params.insert("endTime".to_string(), json!(rw));
}
if let Some(rw) = limit {
query_params.insert("limit".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::GetOrderModifyHistoryResponseInner>>(
&self.configuration,
"/dapi/v1/orderAmendment",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn get_position_margin_change_history(
&self,
params: GetPositionMarginChangeHistoryParams,
) -> anyhow::Result<RestApiResponse<Vec<models::GetPositionMarginChangeHistoryResponseInner>>>
{
let GetPositionMarginChangeHistoryParams {
symbol,
r#type,
start_time,
end_time,
limit,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("symbol".to_string(), json!(symbol));
if let Some(rw) = r#type {
query_params.insert("type".to_string(), json!(rw));
}
if let Some(rw) = start_time {
query_params.insert("startTime".to_string(), json!(rw));
}
if let Some(rw) = end_time {
query_params.insert("endTime".to_string(), json!(rw));
}
if let Some(rw) = limit {
query_params.insert("limit".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::GetPositionMarginChangeHistoryResponseInner>>(
&self.configuration,
"/dapi/v1/positionMargin/history",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn modify_isolated_position_margin(
&self,
params: ModifyIsolatedPositionMarginParams,
) -> anyhow::Result<RestApiResponse<models::ModifyIsolatedPositionMarginResponse>> {
let ModifyIsolatedPositionMarginParams {
symbol,
amount,
r#type,
position_side,
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) = position_side {
query_params.insert("positionSide".to_string(), json!(rw));
}
query_params.insert("amount".to_string(), json!(amount));
query_params.insert("type".to_string(), json!(r#type));
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::ModifyIsolatedPositionMarginResponse>(
&self.configuration,
"/dapi/v1/positionMargin",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn modify_multiple_orders(
&self,
params: ModifyMultipleOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::ModifyMultipleOrdersResponseInner>>> {
let ModifyMultipleOrdersParams {
batch_orders,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("batchOrders".to_string(), json!(batch_orders));
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::ModifyMultipleOrdersResponseInner>>(
&self.configuration,
"/dapi/v1/batchOrders",
reqwest::Method::PUT,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn modify_order(
&self,
params: ModifyOrderParams,
) -> anyhow::Result<RestApiResponse<models::ModifyOrderResponse>> {
let ModifyOrderParams {
symbol,
side,
order_id,
orig_client_order_id,
quantity,
price,
price_match,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = order_id {
query_params.insert("orderId".to_string(), json!(rw));
}
if let Some(rw) = orig_client_order_id {
query_params.insert("origClientOrderId".to_string(), json!(rw));
}
query_params.insert("symbol".to_string(), json!(symbol));
query_params.insert("side".to_string(), json!(side));
if let Some(rw) = quantity {
query_params.insert("quantity".to_string(), json!(rw));
}
if let Some(rw) = price {
query_params.insert("price".to_string(), json!(rw));
}
if let Some(rw) = price_match {
query_params.insert("priceMatch".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::ModifyOrderResponse>(
&self.configuration,
"/dapi/v1/order",
reqwest::Method::PUT,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn new_order(
&self,
params: NewOrderParams,
) -> anyhow::Result<RestApiResponse<models::NewOrderResponse>> {
let NewOrderParams {
symbol,
side,
r#type,
position_side,
time_in_force,
quantity,
reduce_only,
price,
new_client_order_id,
stop_price,
close_position,
activation_price,
callback_rate,
working_type,
price_protect,
new_order_resp_type,
price_match,
self_trade_prevention_mode,
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("side".to_string(), json!(side));
if let Some(rw) = position_side {
query_params.insert("positionSide".to_string(), json!(rw));
}
query_params.insert("type".to_string(), json!(r#type));
if let Some(rw) = time_in_force {
query_params.insert("timeInForce".to_string(), json!(rw));
}
if let Some(rw) = quantity {
query_params.insert("quantity".to_string(), json!(rw));
}
if let Some(rw) = reduce_only {
query_params.insert("reduceOnly".to_string(), json!(rw));
}
if let Some(rw) = price {
query_params.insert("price".to_string(), json!(rw));
}
if let Some(rw) = new_client_order_id {
query_params.insert("newClientOrderId".to_string(), json!(rw));
}
if let Some(rw) = stop_price {
query_params.insert("stopPrice".to_string(), json!(rw));
}
if let Some(rw) = close_position {
query_params.insert("closePosition".to_string(), json!(rw));
}
if let Some(rw) = activation_price {
query_params.insert("activationPrice".to_string(), json!(rw));
}
if let Some(rw) = callback_rate {
query_params.insert("callbackRate".to_string(), json!(rw));
}
if let Some(rw) = working_type {
query_params.insert("workingType".to_string(), json!(rw));
}
if let Some(rw) = price_protect {
query_params.insert("priceProtect".to_string(), json!(rw));
}
if let Some(rw) = new_order_resp_type {
query_params.insert("newOrderRespType".to_string(), json!(rw));
}
if let Some(rw) = price_match {
query_params.insert("priceMatch".to_string(), json!(rw));
}
if let Some(rw) = self_trade_prevention_mode {
query_params.insert("selfTradePreventionMode".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::NewOrderResponse>(
&self.configuration,
"/dapi/v1/order",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn place_multiple_orders(
&self,
params: PlaceMultipleOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::PlaceMultipleOrdersResponseInner>>> {
let PlaceMultipleOrdersParams {
batch_orders,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("batchOrders".to_string(), json!(batch_orders));
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::PlaceMultipleOrdersResponseInner>>(
&self.configuration,
"/dapi/v1/batchOrders",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn position_adl_quantile_estimation(
&self,
params: PositionAdlQuantileEstimationParams,
) -> anyhow::Result<RestApiResponse<Vec<models::PositionAdlQuantileEstimationResponseInner>>>
{
let PositionAdlQuantileEstimationParams {
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::PositionAdlQuantileEstimationResponseInner>>(
&self.configuration,
"/dapi/v1/adlQuantile",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn position_information(
&self,
params: PositionInformationParams,
) -> anyhow::Result<RestApiResponse<Vec<models::PositionInformationResponseInner>>> {
let PositionInformationParams {
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::PositionInformationResponseInner>>(
&self.configuration,
"/dapi/v1/positionRisk",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn query_current_open_order(
&self,
params: QueryCurrentOpenOrderParams,
) -> anyhow::Result<RestApiResponse<models::QueryCurrentOpenOrderResponse>> {
let QueryCurrentOpenOrderParams {
symbol,
order_id,
orig_client_order_id,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("symbol".to_string(), json!(symbol));
if let Some(rw) = order_id {
query_params.insert("orderId".to_string(), json!(rw));
}
if let Some(rw) = orig_client_order_id {
query_params.insert("origClientOrderId".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::QueryCurrentOpenOrderResponse>(
&self.configuration,
"/dapi/v1/openOrder",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn query_order(
&self,
params: QueryOrderParams,
) -> anyhow::Result<RestApiResponse<models::QueryOrderResponse>> {
let QueryOrderParams {
symbol,
order_id,
orig_client_order_id,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("symbol".to_string(), json!(symbol));
if let Some(rw) = order_id {
query_params.insert("orderId".to_string(), json!(rw));
}
if let Some(rw) = orig_client_order_id {
query_params.insert("origClientOrderId".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::QueryOrderResponse>(
&self.configuration,
"/dapi/v1/order",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn users_force_orders(
&self,
params: UsersForceOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::UsersForceOrdersResponseInner>>> {
let UsersForceOrdersParams {
symbol,
auto_close_type,
start_time,
end_time,
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) = auto_close_type {
query_params.insert("autoCloseType".to_string(), json!(rw));
}
if let Some(rw) = start_time {
query_params.insert("startTime".to_string(), json!(rw));
}
if let Some(rw) = end_time {
query_params.insert("endTime".to_string(), json!(rw));
}
if let Some(rw) = limit {
query_params.insert("limit".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::UsersForceOrdersResponseInner>>(
&self.configuration,
"/dapi/v1/forceOrders",
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_coin_futures"))]
mod tests {
use super::*;
use crate::TOKIO_SHARED_RT;
use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
use async_trait::async_trait;
use std::collections::HashMap;
struct DummyRestApiResponse<T> {
inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
status: u16,
headers: HashMap<String, String>,
rate_limits: Option<Vec<RestApiRateLimit>>,
}
impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
fn from(dummy: DummyRestApiResponse<T>) -> Self {
Self {
data_fn: dummy.inner,
status: dummy.status,
headers: dummy.headers,
rate_limits: dummy.rate_limits,
}
}
}
struct MockTradeApiClient {
force_error: bool,
}
#[async_trait]
impl TradeApi for MockTradeApiClient {
async fn account_trade_list(
&self,
_params: AccountTradeListParams,
) -> anyhow::Result<RestApiResponse<Vec<models::AccountTradeListResponseInner>>> {
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_200626","id":6,"orderId":28,"pair":"BTCUSD","side":"SELL","price":"8800","qty":"1","realizedPnl":"0","marginAsset":"BTC","baseQty":"0.01136364","commission":"0.00000454","commissionAsset":"BTC","time":1590743483586,"positionSide":"BOTH","buyer":false,"maker":false}]"#).unwrap();
let dummy_response: Vec<models::AccountTradeListResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::AccountTradeListResponseInner>");
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 all_orders(
&self,
_params: AllOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::AllOrdersResponseInner>>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"avgPrice":"0.0","clientOrderId":"abc","cumBase":"0","executedQty":"0","orderId":1917641,"origQty":"0.40","origType":"TRAILING_STOP_MARKET","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"}]"#).unwrap();
let dummy_response: Vec<models::AllOrdersResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::AllOrdersResponseInner>");
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 auto_cancel_all_open_orders(
&self,
_params: AutoCancelAllOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<models::AutoCancelAllOpenOrdersResponse>> {
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_200925","countdownTime":"100000"}"#)
.unwrap();
let dummy_response: models::AutoCancelAllOpenOrdersResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::AutoCancelAllOpenOrdersResponse");
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 cancel_all_open_orders(
&self,
_params: CancelAllOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<models::CancelAllOpenOrdersResponse>> {
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":"The operation of cancel all open order is done."}"#,
)
.unwrap();
let dummy_response: models::CancelAllOpenOrdersResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::CancelAllOpenOrdersResponse");
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 cancel_multiple_orders(
&self,
_params: CancelMultipleOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::CancelMultipleOrdersResponseInner>>>
{
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"avgPrice":"0.0","clientOrderId":"myOrder1","cumQty":"0","cumBase":"0","executedQty":"0","orderId":283194212,"origQty":"11","origType":"TRAILING_STOP_MARKET","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"CANCELED","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","updateTime":1571110484038},{"code":-2011,"msg":"Unknown order sent."}]"#).unwrap();
let dummy_response: Vec<models::CancelMultipleOrdersResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::CancelMultipleOrdersResponseInner>");
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 cancel_order(
&self,
_params: CancelOrderParams,
) -> anyhow::Result<RestApiResponse<models::CancelOrderResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"avgPrice":"0.0","clientOrderId":"myOrder1","cumQty":"0","cumBase":"0","executedQty":"0","orderId":283194212,"origQty":"11","origType":"TRAILING_STOP_MARKET","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"CANCELED","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1571110484038,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"}"#).unwrap();
let dummy_response: models::CancelOrderResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::CancelOrderResponse");
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_initial_leverage(
&self,
_params: ChangeInitialLeverageParams,
) -> anyhow::Result<RestApiResponse<models::ChangeInitialLeverageResponse>> {
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::ChangeInitialLeverageResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::ChangeInitialLeverageResponse");
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_margin_type(
&self,
_params: ChangeMarginTypeParams,
) -> anyhow::Result<RestApiResponse<models::ChangeMarginTypeResponse>> {
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::ChangeMarginTypeResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::ChangeMarginTypeResponse");
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_position_mode(
&self,
_params: ChangePositionModeParams,
) -> anyhow::Result<RestApiResponse<models::ChangePositionModeResponse>> {
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::ChangePositionModeResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::ChangePositionModeResponse");
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 current_all_open_orders(
&self,
_params: CurrentAllOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::AllOrdersResponseInner>>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"avgPrice":"0.0","clientOrderId":"abc","cumBase":"0","executedQty":"0","orderId":1917641,"origQty":"0.40","origType":"TRAILING_STOP_MARKET","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"}]"#).unwrap();
let dummy_response: Vec<models::AllOrdersResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::AllOrdersResponseInner>");
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_order_modify_history(
&self,
_params: GetOrderModifyHistoryParams,
) -> anyhow::Result<RestApiResponse<Vec<models::GetOrderModifyHistoryResponseInner>>>
{
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"amendmentId":5363,"symbol":"BTCUSD_PERP","pair":"BTCUSD","orderId":20072994037,"clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","time":1629184560899,"amendment":{"price":{"before":"30004","after":"30003.2"},"origQty":{"before":"1","after":"1"},"count":3}},{"amendmentId":5361,"symbol":"BTCUSD_PERP","pair":"BTCUSD","orderId":20072994037,"clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","time":1629184533946,"amendment":{"price":{"before":"30005","after":"30004"},"origQty":{"before":"1","after":"1"},"count":2}},{"amendmentId":5325,"symbol":"BTCUSD_PERP","pair":"BTCUSD","orderId":20072994037,"clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","time":1629182711787,"amendment":{"price":{"before":"30002","after":"30005"},"origQty":{"before":"1","after":"1"},"count":1}}]"#).unwrap();
let dummy_response: Vec<models::GetOrderModifyHistoryResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::GetOrderModifyHistoryResponseInner>");
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_position_margin_change_history(
&self,
_params: GetPositionMarginChangeHistoryParams,
) -> anyhow::Result<RestApiResponse<Vec<models::GetPositionMarginChangeHistoryResponseInner>>>
{
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":"23.36332311","asset":"BTC","symbol":"BTCUSD_200925","time":1578047897183,"type":1,"positionSide":"BOTH"},{"amount":"100","asset":"BTC","symbol":"BTCUSD_200925","time":1578047900425,"type":1,"positionSide":"LONG"}]"#).unwrap();
let dummy_response: Vec<models::GetPositionMarginChangeHistoryResponseInner> =
serde_json::from_value(resp_json.clone()).expect(
"should parse into Vec<models::GetPositionMarginChangeHistoryResponseInner>",
);
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 modify_isolated_position_margin(
&self,
_params: ModifyIsolatedPositionMarginParams,
) -> anyhow::Result<RestApiResponse<models::ModifyIsolatedPositionMarginResponse>> {
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":100,"code":200,"msg":"Successfully modify position margin.","type":1}"#).unwrap();
let dummy_response: models::ModifyIsolatedPositionMarginResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::ModifyIsolatedPositionMarginResponse");
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 modify_multiple_orders(
&self,
_params: ModifyMultipleOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::ModifyMultipleOrdersResponseInner>>>
{
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"orderId":20072994037,"symbol":"BTCUSD_PERP","pair":"BTCUSD","status":"NEW","clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","price":"30005","avgPrice":"0.0","origQty":"1","executedQty":"0","cumQty":"0","cumBase":"0","timeInForce":"GTC","type":"LIMIT","reduceOnly":false,"closePosition":false,"side":"BUY","positionSide":"LONG","stopPrice":"0","workingType":"CONTRACT_PRICE","priceProtect":false,"origType":"LIMIT","priceMatch":"NONE","selfTradePreventionMode":"NONE","updateTime":1629182711600},{"code":-2022,"msg":"ReduceOnly Order is rejected."}]"#).unwrap();
let dummy_response: Vec<models::ModifyMultipleOrdersResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::ModifyMultipleOrdersResponseInner>");
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 modify_order(
&self,
_params: ModifyOrderParams,
) -> anyhow::Result<RestApiResponse<models::ModifyOrderResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"orderId":20072994037,"symbol":"BTCUSD_PERP","pair":"BTCUSD","status":"NEW","clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","price":"30005","avgPrice":"0.0","origQty":"1","executedQty":"0","cumQty":"0","cumBase":"0","timeInForce":"GTC","type":"LIMIT","reduceOnly":false,"closePosition":false,"side":"BUY","positionSide":"LONG","stopPrice":"0","workingType":"CONTRACT_PRICE","priceProtect":false,"origType":"LIMIT","priceMatch":"NONE","selfTradePreventionMode":"NONE","updateTime":1629182711600}"#).unwrap();
let dummy_response: models::ModifyOrderResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::ModifyOrderResponse");
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 new_order(
&self,
_params: NewOrderParams,
) -> anyhow::Result<RestApiResponse<models::NewOrderResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"clientOrderId":"testOrder","cumQty":"0","cumBase":"0","executedQty":"0","orderId":22542179,"avgPrice":"0.0","origQty":"10","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","origType":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1566818724722,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"}"#).unwrap();
let dummy_response: models::NewOrderResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::NewOrderResponse");
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 place_multiple_orders(
&self,
_params: PlaceMultipleOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::PlaceMultipleOrdersResponseInner>>>
{
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"clientOrderId":"testOrder","cumQty":"0","cumBase":"0","executedQty":"0","orderId":22542179,"avgPrice":"0.0","origQty":"10","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","symbol":"BTCUSD_200925","pair":"BTCUSD","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","origType":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1566818724722,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"},{"code":-2022,"msg":"ReduceOnly Order is rejected."}]"#).unwrap();
let dummy_response: Vec<models::PlaceMultipleOrdersResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::PlaceMultipleOrdersResponseInner>");
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 position_adl_quantile_estimation(
&self,
_params: PositionAdlQuantileEstimationParams,
) -> anyhow::Result<RestApiResponse<Vec<models::PositionAdlQuantileEstimationResponseInner>>>
{
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_200925","adlQuantile":{"LONG":3,"SHORT":3,"HEDGE":0}},{"symbol":"BTCUSD_201225","adlQuantile":{"LONG":1,"SHORT":2,"BOTH":0}}]"#).unwrap();
let dummy_response: Vec<models::PositionAdlQuantileEstimationResponseInner> =
serde_json::from_value(resp_json.clone()).expect(
"should parse into Vec<models::PositionAdlQuantileEstimationResponseInner>",
);
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 position_information(
&self,
_params: PositionInformationParams,
) -> anyhow::Result<RestApiResponse<Vec<models::PositionInformationResponseInner>>>
{
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":"0","entryPrice":"0.0","breakEvenPrice":"0.0","markPrice":"0.00000000","unRealizedProfit":"0.00000000","liquidationPrice":"0","leverage":"125","maxQty":"50","marginType":"cross","isolatedMargin":"0.00000000","isAutoAddMargin":"false","positionSide":"BOTH","updateTime":0},{"symbol":"BTCUSD_201225","positionAmt":"1","entryPrice":"11707.70000003","breakEvenPrice":"11707.80000005","markPrice":"11788.66626667","unRealizedProfit":"0.00005866","liquidationPrice":"11667.63509587","leverage":"125","maxQty":"50","marginType":"cross","isolatedMargin":"0.00000000","isAutoAddMargin":"false","positionSide":"LONG","updateTime":1627026881327},{"symbol":"BTCUSD_201225","positionAmt":"0","entryPrice":"0.0","breakEvenPrice":"0.0","markPrice":"0.00000000","unRealizedProfit":"0.00000000","liquidationPrice":"0","leverage":"125","maxQty":"50","marginType":"cross","isolatedMargin":"0.00000000","isAutoAddMargin":"false","positionSide":"SHORT","updateTime":1627026881327}]"#).unwrap();
let dummy_response: Vec<models::PositionInformationResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::PositionInformationResponseInner>");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn query_current_open_order(
&self,
_params: QueryCurrentOpenOrderParams,
) -> anyhow::Result<RestApiResponse<models::QueryCurrentOpenOrderResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"avgPrice":"0.0","clientOrderId":"abc","cumBase":"0","executedQty":"0","orderId":1917641,"origQty":"0.40","origType":"TRAILING_STOP_MARKET","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"}"#).unwrap();
let dummy_response: models::QueryCurrentOpenOrderResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::QueryCurrentOpenOrderResponse");
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_order(
&self,
_params: QueryOrderParams,
) -> anyhow::Result<RestApiResponse<models::QueryOrderResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"avgPrice":"0.0","clientOrderId":"abc","cumBase":"0","executedQty":"0","orderId":1917641,"origQty":"0.40","origType":"TRAILING_STOP_MARKET","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"}"#).unwrap();
let dummy_response: models::QueryOrderResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::QueryOrderResponse");
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 users_force_orders(
&self,
_params: UsersForceOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::UsersForceOrdersResponseInner>>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"orderId":165123080,"symbol":"BTCUSD_200925","pair":"BTCUSD","status":"FILLED","clientOrderId":"autoclose-1596542005017000006","price":"11326.9","avgPrice":"11326.9","origQty":"1","executedQty":"1","cumBase":"0.00882854","timeInForce":"IOC","type":"LIMIT","reduceOnly":false,"closePosition":false,"side":"SELL","positionSide":"BOTH","stopPrice":"0","workingType":"CONTRACT_PRICE","priceProtect":false,"origType":"LIMIT","time":1596542005019,"updateTime":1596542005050},{"orderId":207251986,"symbol":"BTCUSD_200925","pair":"BTCUSD","status":"FILLED","clientOrderId":"autoclose-1597307316020000006","price":"11619.4","avgPrice":"11661.2","origQty":"1","executedQty":"1","cumBase":"0.00857544","timeInForce":"IOC","type":"LIMIT","reduceOnly":false,"closePosition":false,"side":"SELL","positionSide":"LONG","stopPrice":"0","workingType":"CONTRACT_PRICE","priceProtect":false,"origType":"LIMIT","time":1597307316022,"updateTime":1597307316035}]"#).unwrap();
let dummy_response: Vec<models::UsersForceOrdersResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::UsersForceOrdersResponseInner>");
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_trade_list_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = AccountTradeListParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSD_200626","id":6,"orderId":28,"pair":"BTCUSD","side":"SELL","price":"8800","qty":"1","realizedPnl":"0","marginAsset":"BTC","baseQty":"0.01136364","commission":"0.00000454","commissionAsset":"BTC","time":1590743483586,"positionSide":"BOTH","buyer":false,"maker":false}]"#).unwrap();
let expected_response : Vec<models::AccountTradeListResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::AccountTradeListResponseInner>");
let resp = client.account_trade_list(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn account_trade_list_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = AccountTradeListParams::builder().symbol("symbol_example".to_string()).pair("pair_example".to_string()).order_id("1".to_string()).start_time(1623319461670).end_time(1641782889000).from_id(1).limit(100).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSD_200626","id":6,"orderId":28,"pair":"BTCUSD","side":"SELL","price":"8800","qty":"1","realizedPnl":"0","marginAsset":"BTC","baseQty":"0.01136364","commission":"0.00000454","commissionAsset":"BTC","time":1590743483586,"positionSide":"BOTH","buyer":false,"maker":false}]"#).unwrap();
let expected_response : Vec<models::AccountTradeListResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::AccountTradeListResponseInner>");
let resp = client.account_trade_list(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn account_trade_list_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = AccountTradeListParams::builder().build().unwrap();
match client.account_trade_list(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn all_orders_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = AllOrdersParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"avgPrice":"0.0","clientOrderId":"abc","cumBase":"0","executedQty":"0","orderId":1917641,"origQty":"0.40","origType":"TRAILING_STOP_MARKET","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"}]"#).unwrap();
let expected_response : Vec<models::AllOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::AllOrdersResponseInner>");
let resp = client.all_orders(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn all_orders_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = AllOrdersParams::builder().symbol("symbol_example".to_string()).pair("pair_example".to_string()).order_id(1).start_time(1623319461670).end_time(1641782889000).limit(100).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"avgPrice":"0.0","clientOrderId":"abc","cumBase":"0","executedQty":"0","orderId":1917641,"origQty":"0.40","origType":"TRAILING_STOP_MARKET","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"}]"#).unwrap();
let expected_response : Vec<models::AllOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::AllOrdersResponseInner>");
let resp = client.all_orders(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn all_orders_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = AllOrdersParams::builder().build().unwrap();
match client.all_orders(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn auto_cancel_all_open_orders_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = AutoCancelAllOpenOrdersParams::builder("symbol_example".to_string(), 789)
.build()
.unwrap();
let resp_json: Value =
serde_json::from_str(r#"{"symbol":"BTCUSD_200925","countdownTime":"100000"}"#)
.unwrap();
let expected_response: models::AutoCancelAllOpenOrdersResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::AutoCancelAllOpenOrdersResponse");
let resp = client
.auto_cancel_all_open_orders(params)
.await
.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn auto_cancel_all_open_orders_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = AutoCancelAllOpenOrdersParams::builder("symbol_example".to_string(), 789)
.recv_window(5000)
.build()
.unwrap();
let resp_json: Value =
serde_json::from_str(r#"{"symbol":"BTCUSD_200925","countdownTime":"100000"}"#)
.unwrap();
let expected_response: models::AutoCancelAllOpenOrdersResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::AutoCancelAllOpenOrdersResponse");
let resp = client
.auto_cancel_all_open_orders(params)
.await
.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn auto_cancel_all_open_orders_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = AutoCancelAllOpenOrdersParams::builder("symbol_example".to_string(), 789)
.build()
.unwrap();
match client.auto_cancel_all_open_orders(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn cancel_all_open_orders_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = CancelAllOpenOrdersParams::builder("symbol_example".to_string())
.build()
.unwrap();
let resp_json: Value = serde_json::from_str(
r#"{"code":200,"msg":"The operation of cancel all open order is done."}"#,
)
.unwrap();
let expected_response: models::CancelAllOpenOrdersResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::CancelAllOpenOrdersResponse");
let resp = client
.cancel_all_open_orders(params)
.await
.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn cancel_all_open_orders_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = CancelAllOpenOrdersParams::builder("symbol_example".to_string())
.recv_window(5000)
.build()
.unwrap();
let resp_json: Value = serde_json::from_str(
r#"{"code":200,"msg":"The operation of cancel all open order is done."}"#,
)
.unwrap();
let expected_response: models::CancelAllOpenOrdersResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::CancelAllOpenOrdersResponse");
let resp = client
.cancel_all_open_orders(params)
.await
.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn cancel_all_open_orders_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = CancelAllOpenOrdersParams::builder("symbol_example".to_string())
.build()
.unwrap();
match client.cancel_all_open_orders(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn cancel_multiple_orders_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = CancelMultipleOrdersParams::builder("symbol_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"avgPrice":"0.0","clientOrderId":"myOrder1","cumQty":"0","cumBase":"0","executedQty":"0","orderId":283194212,"origQty":"11","origType":"TRAILING_STOP_MARKET","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"CANCELED","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","updateTime":1571110484038},{"code":-2011,"msg":"Unknown order sent."}]"#).unwrap();
let expected_response : Vec<models::CancelMultipleOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::CancelMultipleOrdersResponseInner>");
let resp = client.cancel_multiple_orders(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn cancel_multiple_orders_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = CancelMultipleOrdersParams::builder("symbol_example".to_string(),).order_id_list([1234567,].to_vec()).orig_client_order_id_list(["my_id_1".to_string(),].to_vec()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"avgPrice":"0.0","clientOrderId":"myOrder1","cumQty":"0","cumBase":"0","executedQty":"0","orderId":283194212,"origQty":"11","origType":"TRAILING_STOP_MARKET","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"CANCELED","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","updateTime":1571110484038},{"code":-2011,"msg":"Unknown order sent."}]"#).unwrap();
let expected_response : Vec<models::CancelMultipleOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::CancelMultipleOrdersResponseInner>");
let resp = client.cancel_multiple_orders(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn cancel_multiple_orders_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = CancelMultipleOrdersParams::builder("symbol_example".to_string())
.build()
.unwrap();
match client.cancel_multiple_orders(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn cancel_order_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = CancelOrderParams::builder("symbol_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"avgPrice":"0.0","clientOrderId":"myOrder1","cumQty":"0","cumBase":"0","executedQty":"0","orderId":283194212,"origQty":"11","origType":"TRAILING_STOP_MARKET","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"CANCELED","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1571110484038,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"}"#).unwrap();
let expected_response : models::CancelOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::CancelOrderResponse");
let resp = client.cancel_order(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn cancel_order_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = CancelOrderParams::builder("symbol_example".to_string(),).order_id(1).orig_client_order_id("1".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"avgPrice":"0.0","clientOrderId":"myOrder1","cumQty":"0","cumBase":"0","executedQty":"0","orderId":283194212,"origQty":"11","origType":"TRAILING_STOP_MARKET","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"CANCELED","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1571110484038,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"}"#).unwrap();
let expected_response : models::CancelOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::CancelOrderResponse");
let resp = client.cancel_order(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn cancel_order_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = CancelOrderParams::builder("symbol_example".to_string())
.build()
.unwrap();
match client.cancel_order(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn change_initial_leverage_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = ChangeInitialLeverageParams::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::ChangeInitialLeverageResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::ChangeInitialLeverageResponse");
let resp = client
.change_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_initial_leverage_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = ChangeInitialLeverageParams::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::ChangeInitialLeverageResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::ChangeInitialLeverageResponse");
let resp = client
.change_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_initial_leverage_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = ChangeInitialLeverageParams::builder("symbol_example".to_string(), 789)
.build()
.unwrap();
match client.change_initial_leverage(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn change_margin_type_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = ChangeMarginTypeParams::builder(
"symbol_example".to_string(),
ChangeMarginTypeMarginTypeEnum::Isolated,
)
.build()
.unwrap();
let resp_json: Value = serde_json::from_str(r#"{"code":200,"msg":"success"}"#).unwrap();
let expected_response: models::ChangeMarginTypeResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::ChangeMarginTypeResponse");
let resp = client
.change_margin_type(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_margin_type_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = ChangeMarginTypeParams::builder(
"symbol_example".to_string(),
ChangeMarginTypeMarginTypeEnum::Isolated,
)
.recv_window(5000)
.build()
.unwrap();
let resp_json: Value = serde_json::from_str(r#"{"code":200,"msg":"success"}"#).unwrap();
let expected_response: models::ChangeMarginTypeResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::ChangeMarginTypeResponse");
let resp = client
.change_margin_type(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_margin_type_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = ChangeMarginTypeParams::builder(
"symbol_example".to_string(),
ChangeMarginTypeMarginTypeEnum::Isolated,
)
.build()
.unwrap();
match client.change_margin_type(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn change_position_mode_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params =
ChangePositionModeParams::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::ChangePositionModeResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::ChangePositionModeResponse");
let resp = client
.change_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_position_mode_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params =
ChangePositionModeParams::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::ChangePositionModeResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::ChangePositionModeResponse");
let resp = client
.change_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_position_mode_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params =
ChangePositionModeParams::builder("dual_side_position_example".to_string())
.build()
.unwrap();
match client.change_position_mode(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn current_all_open_orders_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = CurrentAllOpenOrdersParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"avgPrice":"0.0","clientOrderId":"abc","cumBase":"0","executedQty":"0","orderId":1917641,"origQty":"0.40","origType":"TRAILING_STOP_MARKET","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"}]"#).unwrap();
let expected_response : Vec<models::AllOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::AllOrdersResponseInner>");
let resp = client.current_all_open_orders(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn current_all_open_orders_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = CurrentAllOpenOrdersParams::builder().symbol("symbol_example".to_string()).pair("pair_example".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"avgPrice":"0.0","clientOrderId":"abc","cumBase":"0","executedQty":"0","orderId":1917641,"origQty":"0.40","origType":"TRAILING_STOP_MARKET","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"}]"#).unwrap();
let expected_response : Vec<models::AllOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::AllOrdersResponseInner>");
let resp = client.current_all_open_orders(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn current_all_open_orders_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = CurrentAllOpenOrdersParams::builder().build().unwrap();
match client.current_all_open_orders(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn get_order_modify_history_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = GetOrderModifyHistoryParams::builder("symbol_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"amendmentId":5363,"symbol":"BTCUSD_PERP","pair":"BTCUSD","orderId":20072994037,"clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","time":1629184560899,"amendment":{"price":{"before":"30004","after":"30003.2"},"origQty":{"before":"1","after":"1"},"count":3}},{"amendmentId":5361,"symbol":"BTCUSD_PERP","pair":"BTCUSD","orderId":20072994037,"clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","time":1629184533946,"amendment":{"price":{"before":"30005","after":"30004"},"origQty":{"before":"1","after":"1"},"count":2}},{"amendmentId":5325,"symbol":"BTCUSD_PERP","pair":"BTCUSD","orderId":20072994037,"clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","time":1629182711787,"amendment":{"price":{"before":"30002","after":"30005"},"origQty":{"before":"1","after":"1"},"count":1}}]"#).unwrap();
let expected_response : Vec<models::GetOrderModifyHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetOrderModifyHistoryResponseInner>");
let resp = client.get_order_modify_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_order_modify_history_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = GetOrderModifyHistoryParams::builder("symbol_example".to_string(),).order_id(1).orig_client_order_id("1".to_string()).start_time(1623319461670).end_time(1641782889000).limit(100).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"amendmentId":5363,"symbol":"BTCUSD_PERP","pair":"BTCUSD","orderId":20072994037,"clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","time":1629184560899,"amendment":{"price":{"before":"30004","after":"30003.2"},"origQty":{"before":"1","after":"1"},"count":3}},{"amendmentId":5361,"symbol":"BTCUSD_PERP","pair":"BTCUSD","orderId":20072994037,"clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","time":1629184533946,"amendment":{"price":{"before":"30005","after":"30004"},"origQty":{"before":"1","after":"1"},"count":2}},{"amendmentId":5325,"symbol":"BTCUSD_PERP","pair":"BTCUSD","orderId":20072994037,"clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","time":1629182711787,"amendment":{"price":{"before":"30002","after":"30005"},"origQty":{"before":"1","after":"1"},"count":1}}]"#).unwrap();
let expected_response : Vec<models::GetOrderModifyHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetOrderModifyHistoryResponseInner>");
let resp = client.get_order_modify_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_order_modify_history_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = GetOrderModifyHistoryParams::builder("symbol_example".to_string())
.build()
.unwrap();
match client.get_order_modify_history(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn get_position_margin_change_history_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = GetPositionMarginChangeHistoryParams::builder("symbol_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"amount":"23.36332311","asset":"BTC","symbol":"BTCUSD_200925","time":1578047897183,"type":1,"positionSide":"BOTH"},{"amount":"100","asset":"BTC","symbol":"BTCUSD_200925","time":1578047900425,"type":1,"positionSide":"LONG"}]"#).unwrap();
let expected_response : Vec<models::GetPositionMarginChangeHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetPositionMarginChangeHistoryResponseInner>");
let resp = client.get_position_margin_change_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_position_margin_change_history_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = GetPositionMarginChangeHistoryParams::builder("symbol_example".to_string(),).r#type(789).start_time(1623319461670).end_time(1641782889000).limit(100).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"amount":"23.36332311","asset":"BTC","symbol":"BTCUSD_200925","time":1578047897183,"type":1,"positionSide":"BOTH"},{"amount":"100","asset":"BTC","symbol":"BTCUSD_200925","time":1578047900425,"type":1,"positionSide":"LONG"}]"#).unwrap();
let expected_response : Vec<models::GetPositionMarginChangeHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetPositionMarginChangeHistoryResponseInner>");
let resp = client.get_position_margin_change_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_position_margin_change_history_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params =
GetPositionMarginChangeHistoryParams::builder("symbol_example".to_string())
.build()
.unwrap();
match client.get_position_margin_change_history(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn modify_isolated_position_margin_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = ModifyIsolatedPositionMarginParams::builder("symbol_example".to_string(),dec!(1.0),ModifyIsolatedPositionMarginTypeEnum::Limit,).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"amount":100,"code":200,"msg":"Successfully modify position margin.","type":1}"#).unwrap();
let expected_response : models::ModifyIsolatedPositionMarginResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::ModifyIsolatedPositionMarginResponse");
let resp = client.modify_isolated_position_margin(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 modify_isolated_position_margin_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = ModifyIsolatedPositionMarginParams::builder("symbol_example".to_string(),dec!(1.0),ModifyIsolatedPositionMarginTypeEnum::Limit,).position_side(ModifyIsolatedPositionMarginPositionSideEnum::Both).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"amount":100,"code":200,"msg":"Successfully modify position margin.","type":1}"#).unwrap();
let expected_response : models::ModifyIsolatedPositionMarginResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::ModifyIsolatedPositionMarginResponse");
let resp = client.modify_isolated_position_margin(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 modify_isolated_position_margin_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = ModifyIsolatedPositionMarginParams::builder(
"symbol_example".to_string(),
dec!(1.0),
ModifyIsolatedPositionMarginTypeEnum::Limit,
)
.build()
.unwrap();
match client.modify_isolated_position_margin(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn modify_multiple_orders_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = ModifyMultipleOrdersParams::builder(vec![],).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"orderId":20072994037,"symbol":"BTCUSD_PERP","pair":"BTCUSD","status":"NEW","clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","price":"30005","avgPrice":"0.0","origQty":"1","executedQty":"0","cumQty":"0","cumBase":"0","timeInForce":"GTC","type":"LIMIT","reduceOnly":false,"closePosition":false,"side":"BUY","positionSide":"LONG","stopPrice":"0","workingType":"CONTRACT_PRICE","priceProtect":false,"origType":"LIMIT","priceMatch":"NONE","selfTradePreventionMode":"NONE","updateTime":1629182711600},{"code":-2022,"msg":"ReduceOnly Order is rejected."}]"#).unwrap();
let expected_response : Vec<models::ModifyMultipleOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::ModifyMultipleOrdersResponseInner>");
let resp = client.modify_multiple_orders(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn modify_multiple_orders_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = ModifyMultipleOrdersParams::builder(vec![],).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"orderId":20072994037,"symbol":"BTCUSD_PERP","pair":"BTCUSD","status":"NEW","clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","price":"30005","avgPrice":"0.0","origQty":"1","executedQty":"0","cumQty":"0","cumBase":"0","timeInForce":"GTC","type":"LIMIT","reduceOnly":false,"closePosition":false,"side":"BUY","positionSide":"LONG","stopPrice":"0","workingType":"CONTRACT_PRICE","priceProtect":false,"origType":"LIMIT","priceMatch":"NONE","selfTradePreventionMode":"NONE","updateTime":1629182711600},{"code":-2022,"msg":"ReduceOnly Order is rejected."}]"#).unwrap();
let expected_response : Vec<models::ModifyMultipleOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::ModifyMultipleOrdersResponseInner>");
let resp = client.modify_multiple_orders(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn modify_multiple_orders_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = ModifyMultipleOrdersParams::builder(vec![]).build().unwrap();
match client.modify_multiple_orders(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn modify_order_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = ModifyOrderParams::builder("symbol_example".to_string(),ModifyOrderSideEnum::Buy,).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"orderId":20072994037,"symbol":"BTCUSD_PERP","pair":"BTCUSD","status":"NEW","clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","price":"30005","avgPrice":"0.0","origQty":"1","executedQty":"0","cumQty":"0","cumBase":"0","timeInForce":"GTC","type":"LIMIT","reduceOnly":false,"closePosition":false,"side":"BUY","positionSide":"LONG","stopPrice":"0","workingType":"CONTRACT_PRICE","priceProtect":false,"origType":"LIMIT","priceMatch":"NONE","selfTradePreventionMode":"NONE","updateTime":1629182711600}"#).unwrap();
let expected_response : models::ModifyOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::ModifyOrderResponse");
let resp = client.modify_order(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn modify_order_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = ModifyOrderParams::builder("symbol_example".to_string(),ModifyOrderSideEnum::Buy,).order_id(1).orig_client_order_id("1".to_string()).quantity(dec!(1.0)).price(dec!(1.0)).price_match(ModifyOrderPriceMatchEnum::None).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"orderId":20072994037,"symbol":"BTCUSD_PERP","pair":"BTCUSD","status":"NEW","clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","price":"30005","avgPrice":"0.0","origQty":"1","executedQty":"0","cumQty":"0","cumBase":"0","timeInForce":"GTC","type":"LIMIT","reduceOnly":false,"closePosition":false,"side":"BUY","positionSide":"LONG","stopPrice":"0","workingType":"CONTRACT_PRICE","priceProtect":false,"origType":"LIMIT","priceMatch":"NONE","selfTradePreventionMode":"NONE","updateTime":1629182711600}"#).unwrap();
let expected_response : models::ModifyOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::ModifyOrderResponse");
let resp = client.modify_order(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn modify_order_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params =
ModifyOrderParams::builder("symbol_example".to_string(), ModifyOrderSideEnum::Buy)
.build()
.unwrap();
match client.modify_order(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn new_order_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = NewOrderParams::builder("symbol_example".to_string(),NewOrderSideEnum::Buy,NewOrderTypeEnum::Limit,).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"clientOrderId":"testOrder","cumQty":"0","cumBase":"0","executedQty":"0","orderId":22542179,"avgPrice":"0.0","origQty":"10","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","origType":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1566818724722,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"}"#).unwrap();
let expected_response : models::NewOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::NewOrderResponse");
let resp = client.new_order(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn new_order_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = NewOrderParams::builder("symbol_example".to_string(),NewOrderSideEnum::Buy,NewOrderTypeEnum::Limit,).position_side(NewOrderPositionSideEnum::Both).time_in_force(NewOrderTimeInForceEnum::Gtc).quantity(dec!(1.0)).reduce_only("false".to_string()).price(dec!(1.0)).new_client_order_id("1".to_string()).stop_price(dec!(1.0)).close_position("close_position_example".to_string()).activation_price(dec!(1.0)).callback_rate(dec!(1.0)).working_type(NewOrderWorkingTypeEnum::MarkPrice).price_protect("false".to_string()).new_order_resp_type(NewOrderNewOrderRespTypeEnum::Ack).price_match(NewOrderPriceMatchEnum::None).self_trade_prevention_mode(NewOrderSelfTradePreventionModeEnum::None).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"clientOrderId":"testOrder","cumQty":"0","cumBase":"0","executedQty":"0","orderId":22542179,"avgPrice":"0.0","origQty":"10","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","origType":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1566818724722,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"}"#).unwrap();
let expected_response : models::NewOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::NewOrderResponse");
let resp = client.new_order(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn new_order_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = NewOrderParams::builder(
"symbol_example".to_string(),
NewOrderSideEnum::Buy,
NewOrderTypeEnum::Limit,
)
.build()
.unwrap();
match client.new_order(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn place_multiple_orders_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = PlaceMultipleOrdersParams::builder(vec![],).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"clientOrderId":"testOrder","cumQty":"0","cumBase":"0","executedQty":"0","orderId":22542179,"avgPrice":"0.0","origQty":"10","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","symbol":"BTCUSD_200925","pair":"BTCUSD","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","origType":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1566818724722,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"},{"code":-2022,"msg":"ReduceOnly Order is rejected."}]"#).unwrap();
let expected_response : Vec<models::PlaceMultipleOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::PlaceMultipleOrdersResponseInner>");
let resp = client.place_multiple_orders(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn place_multiple_orders_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = PlaceMultipleOrdersParams::builder(vec![],).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"clientOrderId":"testOrder","cumQty":"0","cumBase":"0","executedQty":"0","orderId":22542179,"avgPrice":"0.0","origQty":"10","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","symbol":"BTCUSD_200925","pair":"BTCUSD","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","origType":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1566818724722,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"},{"code":-2022,"msg":"ReduceOnly Order is rejected."}]"#).unwrap();
let expected_response : Vec<models::PlaceMultipleOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::PlaceMultipleOrdersResponseInner>");
let resp = client.place_multiple_orders(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn place_multiple_orders_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = PlaceMultipleOrdersParams::builder(vec![]).build().unwrap();
match client.place_multiple_orders(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn position_adl_quantile_estimation_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = PositionAdlQuantileEstimationParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSD_200925","adlQuantile":{"LONG":3,"SHORT":3,"HEDGE":0}},{"symbol":"BTCUSD_201225","adlQuantile":{"LONG":1,"SHORT":2,"BOTH":0}}]"#).unwrap();
let expected_response : Vec<models::PositionAdlQuantileEstimationResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::PositionAdlQuantileEstimationResponseInner>");
let resp = client.position_adl_quantile_estimation(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 position_adl_quantile_estimation_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = PositionAdlQuantileEstimationParams::builder().symbol("symbol_example".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSD_200925","adlQuantile":{"LONG":3,"SHORT":3,"HEDGE":0}},{"symbol":"BTCUSD_201225","adlQuantile":{"LONG":1,"SHORT":2,"BOTH":0}}]"#).unwrap();
let expected_response : Vec<models::PositionAdlQuantileEstimationResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::PositionAdlQuantileEstimationResponseInner>");
let resp = client.position_adl_quantile_estimation(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 position_adl_quantile_estimation_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = PositionAdlQuantileEstimationParams::builder()
.build()
.unwrap();
match client.position_adl_quantile_estimation(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn position_information_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = PositionInformationParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"symbol":"BTCUSD_201225","positionAmt":"0","entryPrice":"0.0","breakEvenPrice":"0.0","markPrice":"0.00000000","unRealizedProfit":"0.00000000","liquidationPrice":"0","leverage":"125","maxQty":"50","marginType":"cross","isolatedMargin":"0.00000000","isAutoAddMargin":"false","positionSide":"BOTH","updateTime":0},{"symbol":"BTCUSD_201225","positionAmt":"1","entryPrice":"11707.70000003","breakEvenPrice":"11707.80000005","markPrice":"11788.66626667","unRealizedProfit":"0.00005866","liquidationPrice":"11667.63509587","leverage":"125","maxQty":"50","marginType":"cross","isolatedMargin":"0.00000000","isAutoAddMargin":"false","positionSide":"LONG","updateTime":1627026881327},{"symbol":"BTCUSD_201225","positionAmt":"0","entryPrice":"0.0","breakEvenPrice":"0.0","markPrice":"0.00000000","unRealizedProfit":"0.00000000","liquidationPrice":"0","leverage":"125","maxQty":"50","marginType":"cross","isolatedMargin":"0.00000000","isAutoAddMargin":"false","positionSide":"SHORT","updateTime":1627026881327}]"#).unwrap();
let expected_response : Vec<models::PositionInformationResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::PositionInformationResponseInner>");
let resp = client.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 position_information_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = PositionInformationParams::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":"0","entryPrice":"0.0","breakEvenPrice":"0.0","markPrice":"0.00000000","unRealizedProfit":"0.00000000","liquidationPrice":"0","leverage":"125","maxQty":"50","marginType":"cross","isolatedMargin":"0.00000000","isAutoAddMargin":"false","positionSide":"BOTH","updateTime":0},{"symbol":"BTCUSD_201225","positionAmt":"1","entryPrice":"11707.70000003","breakEvenPrice":"11707.80000005","markPrice":"11788.66626667","unRealizedProfit":"0.00005866","liquidationPrice":"11667.63509587","leverage":"125","maxQty":"50","marginType":"cross","isolatedMargin":"0.00000000","isAutoAddMargin":"false","positionSide":"LONG","updateTime":1627026881327},{"symbol":"BTCUSD_201225","positionAmt":"0","entryPrice":"0.0","breakEvenPrice":"0.0","markPrice":"0.00000000","unRealizedProfit":"0.00000000","liquidationPrice":"0","leverage":"125","maxQty":"50","marginType":"cross","isolatedMargin":"0.00000000","isAutoAddMargin":"false","positionSide":"SHORT","updateTime":1627026881327}]"#).unwrap();
let expected_response : Vec<models::PositionInformationResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::PositionInformationResponseInner>");
let resp = client.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 position_information_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = PositionInformationParams::builder().build().unwrap();
match client.position_information(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn query_current_open_order_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryCurrentOpenOrderParams::builder("symbol_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"avgPrice":"0.0","clientOrderId":"abc","cumBase":"0","executedQty":"0","orderId":1917641,"origQty":"0.40","origType":"TRAILING_STOP_MARKET","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"}"#).unwrap();
let expected_response : models::QueryCurrentOpenOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryCurrentOpenOrderResponse");
let resp = client.query_current_open_order(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_current_open_order_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryCurrentOpenOrderParams::builder("symbol_example".to_string(),).order_id(1).orig_client_order_id("1".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"avgPrice":"0.0","clientOrderId":"abc","cumBase":"0","executedQty":"0","orderId":1917641,"origQty":"0.40","origType":"TRAILING_STOP_MARKET","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"}"#).unwrap();
let expected_response : models::QueryCurrentOpenOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryCurrentOpenOrderResponse");
let resp = client.query_current_open_order(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_current_open_order_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = QueryCurrentOpenOrderParams::builder("symbol_example".to_string())
.build()
.unwrap();
match client.query_current_open_order(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn query_order_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryOrderParams::builder("symbol_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"avgPrice":"0.0","clientOrderId":"abc","cumBase":"0","executedQty":"0","orderId":1917641,"origQty":"0.40","origType":"TRAILING_STOP_MARKET","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"}"#).unwrap();
let expected_response : models::QueryOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryOrderResponse");
let resp = client.query_order(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_order_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryOrderParams::builder("symbol_example".to_string(),).order_id(1).orig_client_order_id("1".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"avgPrice":"0.0","clientOrderId":"abc","cumBase":"0","executedQty":"0","orderId":1917641,"origQty":"0.40","origType":"TRAILING_STOP_MARKET","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSD_200925","pair":"BTCUSD","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE"}"#).unwrap();
let expected_response : models::QueryOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryOrderResponse");
let resp = client.query_order(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_order_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = QueryOrderParams::builder("symbol_example".to_string())
.build()
.unwrap();
match client.query_order(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn users_force_orders_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = UsersForceOrdersParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"orderId":165123080,"symbol":"BTCUSD_200925","pair":"BTCUSD","status":"FILLED","clientOrderId":"autoclose-1596542005017000006","price":"11326.9","avgPrice":"11326.9","origQty":"1","executedQty":"1","cumBase":"0.00882854","timeInForce":"IOC","type":"LIMIT","reduceOnly":false,"closePosition":false,"side":"SELL","positionSide":"BOTH","stopPrice":"0","workingType":"CONTRACT_PRICE","priceProtect":false,"origType":"LIMIT","time":1596542005019,"updateTime":1596542005050},{"orderId":207251986,"symbol":"BTCUSD_200925","pair":"BTCUSD","status":"FILLED","clientOrderId":"autoclose-1597307316020000006","price":"11619.4","avgPrice":"11661.2","origQty":"1","executedQty":"1","cumBase":"0.00857544","timeInForce":"IOC","type":"LIMIT","reduceOnly":false,"closePosition":false,"side":"SELL","positionSide":"LONG","stopPrice":"0","workingType":"CONTRACT_PRICE","priceProtect":false,"origType":"LIMIT","time":1597307316022,"updateTime":1597307316035}]"#).unwrap();
let expected_response : Vec<models::UsersForceOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::UsersForceOrdersResponseInner>");
let resp = client.users_force_orders(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn users_force_orders_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = UsersForceOrdersParams::builder().symbol("symbol_example".to_string()).auto_close_type(UsersForceOrdersAutoCloseTypeEnum::Liquidation).start_time(1623319461670).end_time(1641782889000).limit(100).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"orderId":165123080,"symbol":"BTCUSD_200925","pair":"BTCUSD","status":"FILLED","clientOrderId":"autoclose-1596542005017000006","price":"11326.9","avgPrice":"11326.9","origQty":"1","executedQty":"1","cumBase":"0.00882854","timeInForce":"IOC","type":"LIMIT","reduceOnly":false,"closePosition":false,"side":"SELL","positionSide":"BOTH","stopPrice":"0","workingType":"CONTRACT_PRICE","priceProtect":false,"origType":"LIMIT","time":1596542005019,"updateTime":1596542005050},{"orderId":207251986,"symbol":"BTCUSD_200925","pair":"BTCUSD","status":"FILLED","clientOrderId":"autoclose-1597307316020000006","price":"11619.4","avgPrice":"11661.2","origQty":"1","executedQty":"1","cumBase":"0.00857544","timeInForce":"IOC","type":"LIMIT","reduceOnly":false,"closePosition":false,"side":"SELL","positionSide":"LONG","stopPrice":"0","workingType":"CONTRACT_PRICE","priceProtect":false,"origType":"LIMIT","time":1597307316022,"updateTime":1597307316035}]"#).unwrap();
let expected_response : Vec<models::UsersForceOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::UsersForceOrdersResponseInner>");
let resp = client.users_force_orders(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn users_force_orders_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = UsersForceOrdersParams::builder().build().unwrap();
match client.users_force_orders(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
}