/*
* Binance Derivatives Trading USDS Futures REST API
*
* OpenAPI Specification for the Binance Derivatives Trading USDS 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_usds_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_algo_order(
&self,
params: CancelAlgoOrderParams,
) -> anyhow::Result<RestApiResponse<models::CancelAlgoOrderResponse>>;
async fn cancel_all_algo_open_orders(
&self,
params: CancelAllAlgoOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<models::CancelAllAlgoOpenOrdersResponse>>;
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_multi_assets_mode(
&self,
params: ChangeMultiAssetsModeParams,
) -> anyhow::Result<RestApiResponse<models::ChangeMultiAssetsModeResponse>>;
async fn change_position_mode(
&self,
params: ChangePositionModeParams,
) -> anyhow::Result<RestApiResponse<models::ChangePositionModeResponse>>;
async fn current_all_algo_open_orders(
&self,
params: CurrentAllAlgoOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::CurrentAllAlgoOpenOrdersResponseInner>>>;
async fn current_all_open_orders(
&self,
params: CurrentAllOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::AllOrdersResponseInner>>>;
async fn futures_tradfi_perps_contract(
&self,
params: FuturesTradfiPerpsContractParams,
) -> anyhow::Result<RestApiResponse<Value>>;
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_algo_order(
&self,
params: NewAlgoOrderParams,
) -> anyhow::Result<RestApiResponse<models::NewAlgoOrderResponse>>;
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_v2(
&self,
params: PositionInformationV2Params,
) -> anyhow::Result<RestApiResponse<Vec<models::PositionInformationV2ResponseInner>>>;
async fn position_information_v3(
&self,
params: PositionInformationV3Params,
) -> anyhow::Result<RestApiResponse<Vec<models::PositionInformationV3ResponseInner>>>;
async fn query_algo_order(
&self,
params: QueryAlgoOrderParams,
) -> anyhow::Result<RestApiResponse<models::QueryAlgoOrderResponse>>;
async fn query_all_algo_orders(
&self,
params: QueryAllAlgoOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryAllAlgoOrdersResponseInner>>>;
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 test_order(
&self,
params: TestOrderParams,
) -> anyhow::Result<RestApiResponse<models::TestOrderResponse>>;
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 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 NewAlgoOrderSideEnum {
#[serde(rename = "BUY")]
Buy,
#[serde(rename = "SELL")]
Sell,
}
impl NewAlgoOrderSideEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Buy => "BUY",
Self::Sell => "SELL",
}
}
}
impl std::str::FromStr for NewAlgoOrderSideEnum {
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 NewAlgoOrderSideEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NewAlgoOrderPositionSideEnum {
#[serde(rename = "BOTH")]
Both,
#[serde(rename = "LONG")]
Long,
#[serde(rename = "SHORT")]
Short,
}
impl NewAlgoOrderPositionSideEnum {
#[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 NewAlgoOrderPositionSideEnum {
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 NewAlgoOrderPositionSideEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NewAlgoOrderTimeInForceEnum {
#[serde(rename = "GTC")]
Gtc,
#[serde(rename = "IOC")]
Ioc,
#[serde(rename = "FOK")]
Fok,
#[serde(rename = "GTX")]
Gtx,
#[serde(rename = "GTD")]
Gtd,
#[serde(rename = "RPI")]
Rpi,
}
impl NewAlgoOrderTimeInForceEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Gtc => "GTC",
Self::Ioc => "IOC",
Self::Fok => "FOK",
Self::Gtx => "GTX",
Self::Gtd => "GTD",
Self::Rpi => "RPI",
}
}
}
impl std::str::FromStr for NewAlgoOrderTimeInForceEnum {
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),
"GTD" => Ok(Self::Gtd),
"RPI" => Ok(Self::Rpi),
other => Err(format!("invalid NewAlgoOrderTimeInForceEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NewAlgoOrderWorkingTypeEnum {
#[serde(rename = "MARK_PRICE")]
MarkPrice,
#[serde(rename = "CONTRACT_PRICE")]
ContractPrice,
}
impl NewAlgoOrderWorkingTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::MarkPrice => "MARK_PRICE",
Self::ContractPrice => "CONTRACT_PRICE",
}
}
}
impl std::str::FromStr for NewAlgoOrderWorkingTypeEnum {
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 NewAlgoOrderWorkingTypeEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NewAlgoOrderPriceMatchEnum {
#[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 NewAlgoOrderPriceMatchEnum {
#[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 NewAlgoOrderPriceMatchEnum {
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 NewAlgoOrderPriceMatchEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NewAlgoOrderNewOrderRespTypeEnum {
#[serde(rename = "ACK")]
Ack,
#[serde(rename = "RESULT")]
Result,
}
impl NewAlgoOrderNewOrderRespTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Ack => "ACK",
Self::Result => "RESULT",
}
}
}
impl std::str::FromStr for NewAlgoOrderNewOrderRespTypeEnum {
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 NewAlgoOrderNewOrderRespTypeEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NewAlgoOrderSelfTradePreventionModeEnum {
#[serde(rename = "EXPIRE_TAKER")]
ExpireTaker,
#[serde(rename = "EXPIRE_BOTH")]
ExpireBoth,
#[serde(rename = "EXPIRE_MAKER")]
ExpireMaker,
}
impl NewAlgoOrderSelfTradePreventionModeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::ExpireTaker => "EXPIRE_TAKER",
Self::ExpireBoth => "EXPIRE_BOTH",
Self::ExpireMaker => "EXPIRE_MAKER",
}
}
}
impl std::str::FromStr for NewAlgoOrderSelfTradePreventionModeEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"EXPIRE_TAKER" => Ok(Self::ExpireTaker),
"EXPIRE_BOTH" => Ok(Self::ExpireBoth),
"EXPIRE_MAKER" => Ok(Self::ExpireMaker),
other => {
Err(format!("invalid NewAlgoOrderSelfTradePreventionModeEnum: {}", 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 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,
#[serde(rename = "GTD")]
Gtd,
#[serde(rename = "RPI")]
Rpi,
}
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",
Self::Gtd => "GTD",
Self::Rpi => "RPI",
}
}
}
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),
"GTD" => Ok(Self::Gtd),
"RPI" => Ok(Self::Rpi),
other => Err(format!("invalid NewOrderTimeInForceEnum: {}", 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 = "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::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 {
"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 TestOrderSideEnum {
#[serde(rename = "BUY")]
Buy,
#[serde(rename = "SELL")]
Sell,
}
impl TestOrderSideEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Buy => "BUY",
Self::Sell => "SELL",
}
}
}
impl std::str::FromStr for TestOrderSideEnum {
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 TestOrderSideEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TestOrderPositionSideEnum {
#[serde(rename = "BOTH")]
Both,
#[serde(rename = "LONG")]
Long,
#[serde(rename = "SHORT")]
Short,
}
impl TestOrderPositionSideEnum {
#[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 TestOrderPositionSideEnum {
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 TestOrderPositionSideEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TestOrderTimeInForceEnum {
#[serde(rename = "GTC")]
Gtc,
#[serde(rename = "IOC")]
Ioc,
#[serde(rename = "FOK")]
Fok,
#[serde(rename = "GTX")]
Gtx,
#[serde(rename = "GTD")]
Gtd,
#[serde(rename = "RPI")]
Rpi,
}
impl TestOrderTimeInForceEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Gtc => "GTC",
Self::Ioc => "IOC",
Self::Fok => "FOK",
Self::Gtx => "GTX",
Self::Gtd => "GTD",
Self::Rpi => "RPI",
}
}
}
impl std::str::FromStr for TestOrderTimeInForceEnum {
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),
"GTD" => Ok(Self::Gtd),
"RPI" => Ok(Self::Rpi),
other => Err(format!("invalid TestOrderTimeInForceEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TestOrderWorkingTypeEnum {
#[serde(rename = "MARK_PRICE")]
MarkPrice,
#[serde(rename = "CONTRACT_PRICE")]
ContractPrice,
}
impl TestOrderWorkingTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::MarkPrice => "MARK_PRICE",
Self::ContractPrice => "CONTRACT_PRICE",
}
}
}
impl std::str::FromStr for TestOrderWorkingTypeEnum {
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 TestOrderWorkingTypeEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TestOrderNewOrderRespTypeEnum {
#[serde(rename = "ACK")]
Ack,
#[serde(rename = "RESULT")]
Result,
}
impl TestOrderNewOrderRespTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Ack => "ACK",
Self::Result => "RESULT",
}
}
}
impl std::str::FromStr for TestOrderNewOrderRespTypeEnum {
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 TestOrderNewOrderRespTypeEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TestOrderPriceMatchEnum {
#[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 TestOrderPriceMatchEnum {
#[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 TestOrderPriceMatchEnum {
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 TestOrderPriceMatchEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TestOrderSelfTradePreventionModeEnum {
#[serde(rename = "EXPIRE_TAKER")]
ExpireTaker,
#[serde(rename = "EXPIRE_BOTH")]
ExpireBoth,
#[serde(rename = "EXPIRE_MAKER")]
ExpireMaker,
}
impl TestOrderSelfTradePreventionModeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::ExpireTaker => "EXPIRE_TAKER",
Self::ExpireBoth => "EXPIRE_BOTH",
Self::ExpireMaker => "EXPIRE_MAKER",
}
}
}
impl std::str::FromStr for TestOrderSelfTradePreventionModeEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"EXPIRE_TAKER" => Ok(Self::ExpireTaker),
"EXPIRE_BOTH" => Ok(Self::ExpireBoth),
"EXPIRE_MAKER" => Ok(Self::ExpireMaker),
other => Err(format!("invalid TestOrderSelfTradePreventionModeEnum: {}", 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)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct AccountTradeListParams {
///
/// 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 `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`].
///
/// Required parameters:
///
/// * `symbol` — String
///
#[must_use]
pub fn builder(symbol: String) -> AccountTradeListParamsBuilder {
AccountTradeListParamsBuilder::default().symbol(symbol)
}
}
/// 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)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct AllOrdersParams {
///
/// 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 `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`].
///
/// Required parameters:
///
/// * `symbol` — String
///
#[must_use]
pub fn builder(symbol: String) -> AllOrdersParamsBuilder {
AllOrdersParamsBuilder::default().symbol(symbol)
}
}
/// 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_algo_order`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`cancel_algo_order`](#method.cancel_algo_order).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct CancelAlgoOrderParams {
///
/// The `algo_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub algo_id: Option<i64>,
///
/// The `client_algo_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub client_algo_id: Option<String>,
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl CancelAlgoOrderParams {
/// Create a builder for [`cancel_algo_order`].
///
#[must_use]
pub fn builder() -> CancelAlgoOrderParamsBuilder {
CancelAlgoOrderParamsBuilder::default()
}
}
/// Request parameters for the [`cancel_all_algo_open_orders`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`cancel_all_algo_open_orders`](#method.cancel_all_algo_open_orders).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct CancelAllAlgoOpenOrdersParams {
///
/// 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 CancelAllAlgoOpenOrdersParams {
/// Create a builder for [`cancel_all_algo_open_orders`].
///
/// Required parameters:
///
/// * `symbol` — String
///
#[must_use]
pub fn builder(symbol: String) -> CancelAllAlgoOpenOrdersParamsBuilder {
CancelAllAlgoOpenOrdersParamsBuilder::default().symbol(symbol)
}
}
/// 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_multi_assets_mode`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`change_multi_assets_mode`](#method.change_multi_assets_mode).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct ChangeMultiAssetsModeParams {
/// "true": Multi-Assets Mode; "false": Single-Asset Mode
///
/// This field is **required.
#[builder(setter(into))]
pub multi_assets_margin: String,
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl ChangeMultiAssetsModeParams {
/// Create a builder for [`change_multi_assets_mode`].
///
/// Required parameters:
///
/// * `multi_assets_margin` — \"true\": Multi-Assets Mode; \"false\": Single-Asset Mode
///
#[must_use]
pub fn builder(multi_assets_margin: String) -> ChangeMultiAssetsModeParamsBuilder {
ChangeMultiAssetsModeParamsBuilder::default().multi_assets_margin(multi_assets_margin)
}
}
/// 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_algo_open_orders`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`current_all_algo_open_orders`](#method.current_all_algo_open_orders).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct CurrentAllAlgoOpenOrdersParams {
///
/// The `algo_type` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub algo_type: Option<String>,
///
/// The `symbol` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub symbol: Option<String>,
///
/// The `algo_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub algo_id: Option<i64>,
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl CurrentAllAlgoOpenOrdersParams {
/// Create a builder for [`current_all_algo_open_orders`].
///
#[must_use]
pub fn builder() -> CurrentAllAlgoOpenOrdersParamsBuilder {
CurrentAllAlgoOpenOrdersParamsBuilder::default()
}
}
/// 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 `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 [`futures_tradfi_perps_contract`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`futures_tradfi_perps_contract`](#method.futures_tradfi_perps_contract).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct FuturesTradfiPerpsContractParams {
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl FuturesTradfiPerpsContractParams {
/// Create a builder for [`futures_tradfi_perps_contract`].
///
#[must_use]
pub fn builder() -> FuturesTradfiPerpsContractParamsBuilder {
FuturesTradfiPerpsContractParamsBuilder::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: String,
/// 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: String,
) -> 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,
/// Order quantity, cannot be sent with `closePosition=true`
///
/// This field is **required.
#[builder(setter(into))]
pub quantity: rust_decimal::Decimal,
///
/// The `price` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub price: rust_decimal::Decimal,
///
/// The `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>,
/// 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`
/// * `quantity` — Order quantity, cannot be sent with `closePosition=true`
/// * `price` — `rust_decimal::Decimal`
///
#[must_use]
pub fn builder(
symbol: String,
side: ModifyOrderSideEnum,
quantity: rust_decimal::Decimal,
price: rust_decimal::Decimal,
) -> ModifyOrderParamsBuilder {
ModifyOrderParamsBuilder::default()
.symbol(symbol)
.side(side)
.quantity(quantity)
.price(price)
}
}
/// Request parameters for the [`new_algo_order`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`new_algo_order`](#method.new_algo_order).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct NewAlgoOrderParams {
/// Only support `CONDITIONAL`
///
/// This field is **required.
#[builder(setter(into))]
pub algo_type: String,
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
/// `SELL`, `BUY`
///
/// This field is **required.
#[builder(setter(into))]
pub side: NewAlgoOrderSideEnum,
///
/// The `r#type` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub r#type: String,
/// 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<NewAlgoOrderPositionSideEnum>,
///
/// The `time_in_force` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub time_in_force: Option<NewAlgoOrderTimeInForceEnum>,
///
/// The `quantity` parameter.
///
/// 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>,
///
/// The `trigger_price` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub trigger_price: 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<NewAlgoOrderWorkingTypeEnum>,
/// 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<NewAlgoOrderPriceMatchEnum>,
/// `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>,
/// "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>,
/// "true" or "false". default "false". Cannot be sent in Hedge Mode
///
/// This field is **optional.
#[builder(setter(into), default)]
pub reduce_only: 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 activate_price: Option<rust_decimal::Decimal>,
/// Used with `TRAILING_STOP_MARKET` orders, min 0.1, max 5 where 1 for 1%
///
/// This field is **optional.
#[builder(setter(into), default)]
pub callback_rate: Option<rust_decimal::Decimal>,
///
/// The `client_algo_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub client_algo_id: Option<String>,
/// "ACK", "RESULT", default "ACK"
///
/// This field is **optional.
#[builder(setter(into), default)]
pub new_order_resp_type: Option<NewAlgoOrderNewOrderRespTypeEnum>,
/// `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 `NONE`
///
/// This field is **optional.
#[builder(setter(into), default)]
pub self_trade_prevention_mode: Option<NewAlgoOrderSelfTradePreventionModeEnum>,
/// order cancel time for timeInForce `GTD`, mandatory when `timeInforce` set to `GTD`; order the timestamp only retains second-level precision, ms part will be ignored; The goodTillDate timestamp must be greater than the current time plus 600 seconds and smaller than 253402300799000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub good_till_date: Option<i64>,
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl NewAlgoOrderParams {
/// Create a builder for [`new_algo_order`].
///
/// Required parameters:
///
/// * `algo_type` — Only support `CONDITIONAL`
/// * `symbol` — String
/// * `side` — `SELL`, `BUY`
/// * `r#type` — String
///
#[must_use]
pub fn builder(
algo_type: String,
symbol: String,
side: NewAlgoOrderSideEnum,
r#type: String,
) -> NewAlgoOrderParamsBuilder {
NewAlgoOrderParamsBuilder::default()
.algo_type(algo_type)
.symbol(symbol)
.side(side)
.r#type(r#type)
}
}
/// 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: String,
/// 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>,
///
/// The `quantity` parameter.
///
/// 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
///
/// 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>,
/// "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 `NONE`
///
/// This field is **optional.
#[builder(setter(into), default)]
pub self_trade_prevention_mode: Option<NewOrderSelfTradePreventionModeEnum>,
/// order cancel time for timeInForce `GTD`, mandatory when `timeInforce` set to `GTD`; order the timestamp only retains second-level precision, ms part will be ignored; The goodTillDate timestamp must be greater than the current time plus 600 seconds and smaller than 253402300799000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub good_till_date: Option<i64>,
///
/// 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: String,
) -> 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_v2`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`position_information_v2`](#method.position_information_v2).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct PositionInformationV2Params {
///
/// 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 PositionInformationV2Params {
/// Create a builder for [`position_information_v2`].
///
#[must_use]
pub fn builder() -> PositionInformationV2ParamsBuilder {
PositionInformationV2ParamsBuilder::default()
}
}
/// Request parameters for the [`position_information_v3`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`position_information_v3`](#method.position_information_v3).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct PositionInformationV3Params {
///
/// 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 PositionInformationV3Params {
/// Create a builder for [`position_information_v3`].
///
#[must_use]
pub fn builder() -> PositionInformationV3ParamsBuilder {
PositionInformationV3ParamsBuilder::default()
}
}
/// Request parameters for the [`query_algo_order`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_algo_order`](#method.query_algo_order).
#[derive(Clone, Debug, Builder, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryAlgoOrderParams {
///
/// The `algo_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub algo_id: Option<i64>,
///
/// The `client_algo_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub client_algo_id: Option<String>,
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl QueryAlgoOrderParams {
/// Create a builder for [`query_algo_order`].
///
#[must_use]
pub fn builder() -> QueryAlgoOrderParamsBuilder {
QueryAlgoOrderParamsBuilder::default()
}
}
/// Request parameters for the [`query_all_algo_orders`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`query_all_algo_orders`](#method.query_all_algo_orders).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryAllAlgoOrdersParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
///
/// The `algo_id` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub algo_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>,
///
/// The `page` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub page: Option<i64>,
/// Default 100; max 1000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub limit: Option<i64>,
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl QueryAllAlgoOrdersParams {
/// Create a builder for [`query_all_algo_orders`].
///
/// Required parameters:
///
/// * `symbol` — String
///
#[must_use]
pub fn builder(symbol: String) -> QueryAllAlgoOrdersParamsBuilder {
QueryAllAlgoOrdersParamsBuilder::default().symbol(symbol)
}
}
/// 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 [`test_order`] operation.
///
/// This struct holds all of the inputs you can pass when calling
/// [`test_order`](#method.test_order).
#[derive(Clone, Debug, Builder)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct TestOrderParams {
///
/// The `symbol` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub symbol: String,
/// `SELL`, `BUY`
///
/// This field is **required.
#[builder(setter(into))]
pub side: TestOrderSideEnum,
///
/// The `r#type` parameter.
///
/// This field is **required.
#[builder(setter(into))]
pub r#type: String,
/// 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<TestOrderPositionSideEnum>,
///
/// The `time_in_force` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub time_in_force: Option<TestOrderTimeInForceEnum>,
///
/// The `quantity` parameter.
///
/// 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
///
/// 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 5 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<TestOrderWorkingTypeEnum>,
/// "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<TestOrderNewOrderRespTypeEnum>,
/// 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<TestOrderPriceMatchEnum>,
/// `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 `NONE`
///
/// This field is **optional.
#[builder(setter(into), default)]
pub self_trade_prevention_mode: Option<TestOrderSelfTradePreventionModeEnum>,
/// order cancel time for timeInForce `GTD`, mandatory when `timeInforce` set to `GTD`; order the timestamp only retains second-level precision, ms part will be ignored; The goodTillDate timestamp must be greater than the current time plus 600 seconds and smaller than 253402300799000
///
/// This field is **optional.
#[builder(setter(into), default)]
pub good_till_date: Option<i64>,
///
/// The `recv_window` parameter.
///
/// This field is **optional.
#[builder(setter(into), default)]
pub recv_window: Option<i64>,
}
impl TestOrderParams {
/// Create a builder for [`test_order`].
///
/// Required parameters:
///
/// * `symbol` — String
/// * `side` — `SELL`, `BUY`
/// * `r#type` — String
///
#[must_use]
pub fn builder(
symbol: String,
side: TestOrderSideEnum,
r#type: String,
) -> TestOrderParamsBuilder {
TestOrderParamsBuilder::default()
.symbol(symbol)
.side(side)
.r#type(r#type)
}
}
/// 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,
order_id,
start_time,
end_time,
from_id,
limit,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("symbol".to_string(), json!(symbol));
if let Some(rw) = 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,
"/fapi/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,
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) = 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,
"/fapi/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,
"/fapi/v1/countdownCancelAll",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn cancel_algo_order(
&self,
params: CancelAlgoOrderParams,
) -> anyhow::Result<RestApiResponse<models::CancelAlgoOrderResponse>> {
let CancelAlgoOrderParams {
algo_id,
client_algo_id,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = algo_id {
query_params.insert("algoId".to_string(), json!(rw));
}
if let Some(rw) = client_algo_id {
query_params.insert("clientAlgoId".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::CancelAlgoOrderResponse>(
&self.configuration,
"/fapi/v1/algoOrder",
reqwest::Method::DELETE,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn cancel_all_algo_open_orders(
&self,
params: CancelAllAlgoOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<models::CancelAllAlgoOpenOrdersResponse>> {
let CancelAllAlgoOpenOrdersParams {
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::CancelAllAlgoOpenOrdersResponse>(
&self.configuration,
"/fapi/v1/algoOpenOrders",
reqwest::Method::DELETE,
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,
"/fapi/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,
"/fapi/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,
"/fapi/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,
"/fapi/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,
"/fapi/v1/marginType",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn change_multi_assets_mode(
&self,
params: ChangeMultiAssetsModeParams,
) -> anyhow::Result<RestApiResponse<models::ChangeMultiAssetsModeResponse>> {
let ChangeMultiAssetsModeParams {
multi_assets_margin,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("multiAssetsMargin".to_string(), json!(multi_assets_margin));
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::ChangeMultiAssetsModeResponse>(
&self.configuration,
"/fapi/v1/multiAssetsMargin",
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,
"/fapi/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_algo_open_orders(
&self,
params: CurrentAllAlgoOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::CurrentAllAlgoOpenOrdersResponseInner>>> {
let CurrentAllAlgoOpenOrdersParams {
algo_type,
symbol,
algo_id,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = algo_type {
query_params.insert("algoType".to_string(), json!(rw));
}
if let Some(rw) = symbol {
query_params.insert("symbol".to_string(), json!(rw));
}
if let Some(rw) = algo_id {
query_params.insert("algoId".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::CurrentAllAlgoOpenOrdersResponseInner>>(
&self.configuration,
"/fapi/v1/openAlgoOrders",
reqwest::Method::GET,
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,
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::AllOrdersResponseInner>>(
&self.configuration,
"/fapi/v1/openOrders",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn futures_tradfi_perps_contract(
&self,
params: FuturesTradfiPerpsContractParams,
) -> anyhow::Result<RestApiResponse<Value>> {
let FuturesTradfiPerpsContractParams { recv_window } = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Value>(
&self.configuration,
"/fapi/v1/stock/contract",
reqwest::Method::POST,
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,
"/fapi/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,
"/fapi/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,
"/fapi/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,
"/fapi/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,
quantity,
price,
order_id,
orig_client_order_id,
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));
query_params.insert("quantity".to_string(), json!(quantity));
query_params.insert("price".to_string(), json!(price));
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,
"/fapi/v1/order",
reqwest::Method::PUT,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn new_algo_order(
&self,
params: NewAlgoOrderParams,
) -> anyhow::Result<RestApiResponse<models::NewAlgoOrderResponse>> {
let NewAlgoOrderParams {
algo_type,
symbol,
side,
r#type,
position_side,
time_in_force,
quantity,
price,
trigger_price,
working_type,
price_match,
close_position,
price_protect,
reduce_only,
activate_price,
callback_rate,
client_algo_id,
new_order_resp_type,
self_trade_prevention_mode,
good_till_date,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("algoType".to_string(), json!(algo_type));
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) = price {
query_params.insert("price".to_string(), json!(rw));
}
if let Some(rw) = trigger_price {
query_params.insert("triggerPrice".to_string(), json!(rw));
}
if let Some(rw) = working_type {
query_params.insert("workingType".to_string(), json!(rw));
}
if let Some(rw) = price_match {
query_params.insert("priceMatch".to_string(), json!(rw));
}
if let Some(rw) = close_position {
query_params.insert("closePosition".to_string(), json!(rw));
}
if let Some(rw) = price_protect {
query_params.insert("priceProtect".to_string(), json!(rw));
}
if let Some(rw) = reduce_only {
query_params.insert("reduceOnly".to_string(), json!(rw));
}
if let Some(rw) = activate_price {
query_params.insert("activatePrice".to_string(), json!(rw));
}
if let Some(rw) = callback_rate {
query_params.insert("callbackRate".to_string(), json!(rw));
}
if let Some(rw) = client_algo_id {
query_params.insert("clientAlgoId".to_string(), json!(rw));
}
if let Some(rw) = new_order_resp_type {
query_params.insert("newOrderRespType".to_string(), json!(rw));
}
if let Some(rw) = self_trade_prevention_mode {
query_params.insert("selfTradePreventionMode".to_string(), json!(rw));
}
if let Some(rw) = good_till_date {
query_params.insert("goodTillDate".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::NewAlgoOrderResponse>(
&self.configuration,
"/fapi/v1/algoOrder",
reqwest::Method::POST,
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,
new_order_resp_type,
price_match,
self_trade_prevention_mode,
good_till_date,
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) = 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) = good_till_date {
query_params.insert("goodTillDate".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::NewOrderResponse>(
&self.configuration,
"/fapi/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,
"/fapi/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,
"/fapi/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_v2(
&self,
params: PositionInformationV2Params,
) -> anyhow::Result<RestApiResponse<Vec<models::PositionInformationV2ResponseInner>>> {
let PositionInformationV2Params {
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::PositionInformationV2ResponseInner>>(
&self.configuration,
"/fapi/v2/positionRisk",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn position_information_v3(
&self,
params: PositionInformationV3Params,
) -> anyhow::Result<RestApiResponse<Vec<models::PositionInformationV3ResponseInner>>> {
let PositionInformationV3Params {
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::PositionInformationV3ResponseInner>>(
&self.configuration,
"/fapi/v3/positionRisk",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn query_algo_order(
&self,
params: QueryAlgoOrderParams,
) -> anyhow::Result<RestApiResponse<models::QueryAlgoOrderResponse>> {
let QueryAlgoOrderParams {
algo_id,
client_algo_id,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = algo_id {
query_params.insert("algoId".to_string(), json!(rw));
}
if let Some(rw) = client_algo_id {
query_params.insert("clientAlgoId".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::QueryAlgoOrderResponse>(
&self.configuration,
"/fapi/v1/algoOrder",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn query_all_algo_orders(
&self,
params: QueryAllAlgoOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryAllAlgoOrdersResponseInner>>> {
let QueryAllAlgoOrdersParams {
symbol,
algo_id,
start_time,
end_time,
page,
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) = algo_id {
query_params.insert("algoId".to_string(), json!(rw));
}
if let Some(rw) = start_time {
query_params.insert("startTime".to_string(), json!(rw));
}
if let Some(rw) = end_time {
query_params.insert("endTime".to_string(), json!(rw));
}
if let Some(rw) = page {
query_params.insert("page".to_string(), json!(rw));
}
if let Some(rw) = limit {
query_params.insert("limit".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::QueryAllAlgoOrdersResponseInner>>(
&self.configuration,
"/fapi/v1/allAlgoOrders",
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,
"/fapi/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,
"/fapi/v1/order",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn test_order(
&self,
params: TestOrderParams,
) -> anyhow::Result<RestApiResponse<models::TestOrderResponse>> {
let TestOrderParams {
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,
good_till_date,
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) = good_till_date {
query_params.insert("goodTillDate".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::TestOrderResponse>(
&self.configuration,
"/fapi/v1/order/test",
reqwest::Method::POST,
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,
"/fapi/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_usds_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#"[{"buyer":false,"commission":"-0.07819010","commissionAsset":"USDT","id":698759,"maker":false,"orderId":25851813,"price":"7819.01","qty":"0.002","quoteQty":"15.63802","realizedPnl":"-0.91539999","side":"SELL","positionSide":"SHORT","symbol":"BTCUSDT","time":1569514978020}]"#).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.00000","clientOrderId":"abc","cumQuote":"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":"BTCUSDT","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":0}]"#).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":"BTCUSDT","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_algo_order(
&self,
_params: CancelAlgoOrderParams,
) -> anyhow::Result<RestApiResponse<models::CancelAlgoOrderResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"algoId":2146760,"clientAlgoId":"6B2I9XVcJpCjqPAJ4YoFX7","code":"200","msg":"success"}"#).unwrap();
let dummy_response: models::CancelAlgoOrderResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::CancelAlgoOrderResponse");
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_algo_open_orders(
&self,
_params: CancelAllAlgoOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<models::CancelAllAlgoOpenOrdersResponse>> {
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::CancelAllAlgoOpenOrdersResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::CancelAllAlgoOpenOrdersResponse");
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#"[{"clientOrderId":"myOrder1","cumQty":"0","cumQuote":"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":"BTCUSDT","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1571110484038,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":1693207680000},{"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#"{"clientOrderId":"myOrder1","cumQty":"0","cumQuote":"0","executedQty":"0","orderId":283194212,"origQty":"11","origType":"TRAILING_STOP_MARKET","price":"0","avgPrice":"0.00","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"CANCELED","stopPrice":"9300","closePosition":false,"symbol":"BTCUSDT","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1571110484038,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":1693207680000}"#).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,"maxNotionalValue":"1000000","symbol":"BTCUSDT"}"#,
)
.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_multi_assets_mode(
&self,
_params: ChangeMultiAssetsModeParams,
) -> anyhow::Result<RestApiResponse<models::ChangeMultiAssetsModeResponse>> {
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::ChangeMultiAssetsModeResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::ChangeMultiAssetsModeResponse");
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_algo_open_orders(
&self,
_params: CurrentAllAlgoOpenOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::CurrentAllAlgoOpenOrdersResponseInner>>>
{
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"algoId":2148627,"clientAlgoId":"MRumok0dkhrP4kCm12AHaB","algoType":"CONDITIONAL","orderType":"TAKE_PROFIT","symbol":"BNBUSDT","side":"SELL","positionSide":"BOTH","timeInForce":"GTC","quantity":"0.01","algoStatus":"NEW","actualOrderId":"","actualPrice":"0.00000","triggerPrice":"750.000","price":"750.000","icebergQuantity":null,"tpTriggerPrice":"0.000","tpPrice":"0.000","slTriggerPrice":"0.000","slPrice":"0.000","tpOrderType":"","selfTradePreventionMode":"EXPIRE_MAKER","workingType":"CONTRACT_PRICE","priceMatch":"NONE","closePosition":false,"priceProtect":false,"reduceOnly":false,"createTime":1750514941540,"updateTime":1750514941540,"triggerTime":0,"goodTillDate":0}]"#).unwrap();
let dummy_response: Vec<models::CurrentAllAlgoOpenOrdersResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::CurrentAllAlgoOpenOrdersResponseInner>");
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.00000","clientOrderId":"abc","cumQuote":"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":"BTCUSDT","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":0}]"#).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 futures_tradfi_perps_contract(
&self,
_params: FuturesTradfiPerpsContractParams,
) -> anyhow::Result<RestApiResponse<Value>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let dummy_response = Value::Null;
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn get_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":"BTCUSDT","pair":"BTCUSDT","orderId":20072994037,"clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","time":1629184560899,"amendment":{"price":{"before":"30004","after":"30003.2"},"origQty":{"before":"1","after":"1"},"count":3}},{"amendmentId":5361,"symbol":"BTCUSDT","pair":"BTCUSDT","orderId":20072994037,"clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","time":1629184533946,"amendment":{"price":{"before":"30005","after":"30004"},"origQty":{"before":"1","after":"1"},"count":2}},{"amendmentId":5325,"symbol":"BTCUSDT","pair":"BTCUSDT","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#"[{"symbol":"BTCUSDT","type":1,"deltaType":"USER_ADJUST","amount":"23.36332311","asset":"USDT","time":1578047897183,"positionSide":"BOTH"},{"symbol":"BTCUSDT","type":1,"deltaType":"USER_ADJUST","amount":"100","asset":"USDT","time":1578047900425,"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":"BTCUSDT","pair":"BTCUSDT","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","goodTillDate":0,"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":"BTCUSDT","pair":"BTCUSDT","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","goodTillDate":0,"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_algo_order(
&self,
_params: NewAlgoOrderParams,
) -> anyhow::Result<RestApiResponse<models::NewAlgoOrderResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"algoId":2146760,"clientAlgoId":"6B2I9XVcJpCjqPAJ4YoFX7","algoType":"CONDITIONAL","orderType":"TAKE_PROFIT","symbol":"BNBUSDT","side":"SELL","positionSide":"BOTH","timeInForce":"GTC","quantity":"0.01","algoStatus":"NEW","triggerPrice":"750.000","price":"750.000","icebergQuantity":null,"selfTradePreventionMode":"EXPIRE_MAKER","workingType":"CONTRACT_PRICE","priceMatch":"NONE","closePosition":false,"priceProtect":false,"reduceOnly":false,"activatePrice":"","callbackRate":"","createTime":1750485492076,"updateTime":1750485492076,"triggerTime":0,"goodTillDate":0}"#).unwrap();
let dummy_response: models::NewAlgoOrderResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::NewAlgoOrderResponse");
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","cumQuote":"0","executedQty":"0","orderId":22542179,"avgPrice":"0.00000","origQty":"10","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSDT","timeInForce":"GTD","type":"TRAILING_STOP_MARKET","origType":"TRAILING_STOP_MARKET","updateTime":1566818724722,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":1693207680000}"#).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","cumQuote":"0","executedQty":"0","orderId":22542179,"avgPrice":"0.00000","origQty":"10","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"0","closePosition":false,"symbol":"BTCUSDT","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","origType":"TRAILING_STOP_MARKET","updateTime":1566818724722,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":1693207680000},{"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":"ETHUSDT","adlQuantile":{"LONG":3,"SHORT":3,"HEDGE":0}},{"symbol":"BTCUSDT","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_v2(
&self,
_params: PositionInformationV2Params,
) -> anyhow::Result<RestApiResponse<Vec<models::PositionInformationV2ResponseInner>>>
{
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"entryPrice":"0.00000","breakEvenPrice":"0.0","marginType":"isolated","isAutoAddMargin":"false","isolatedMargin":"0.00000000","leverage":"10","liquidationPrice":"0","markPrice":"6679.50671178","maxNotionalValue":"20000000","positionAmt":"0.000","notional":"0","isolatedWallet":"0","symbol":"BTCUSDT","unRealizedProfit":"0.00000000","positionSide":"BOTH","updateTime":0},{"symbol":"BTCUSDT","positionAmt":"0.001","entryPrice":"22185.2","breakEvenPrice":"0.0","markPrice":"21123.05052574","unRealizedProfit":"-1.06214947","liquidationPrice":"19731.45529116","leverage":"4","maxNotionalValue":"100000000","marginType":"cross","isolatedMargin":"0.00000000","isAutoAddMargin":"false","positionSide":"LONG","notional":"21.12305052","isolatedWallet":"0","updateTime":1655217461579},{"symbol":"BTCUSDT","positionAmt":"0.000","entryPrice":"0.0","breakEvenPrice":"0.0","markPrice":"21123.05052574","unRealizedProfit":"0.00000000","liquidationPrice":"0","leverage":"4","maxNotionalValue":"100000000","marginType":"cross","isolatedMargin":"0.00000000","isAutoAddMargin":"false","positionSide":"SHORT","notional":"0","isolatedWallet":"0","updateTime":0}]"#).unwrap();
let dummy_response: Vec<models::PositionInformationV2ResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::PositionInformationV2ResponseInner>");
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_v3(
&self,
_params: PositionInformationV3Params,
) -> anyhow::Result<RestApiResponse<Vec<models::PositionInformationV3ResponseInner>>>
{
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":"ADAUSDT","positionSide":"BOTH","positionAmt":"30","entryPrice":"0.385","breakEvenPrice":"0.385077","markPrice":"0.41047590","unRealizedProfit":"0.76427700","liquidationPrice":"0","isolatedMargin":"0","notional":"12.31427700","marginAsset":"USDT","isolatedWallet":"0","initialMargin":"0.61571385","maintMargin":"0.08004280","positionInitialMargin":"0.61571385","openOrderInitialMargin":"0","adl":2,"bidNotional":"0","askNotional":"0","updateTime":1720736417660},{"symbol":"ADAUSDT","positionSide":"LONG","positionAmt":"30","entryPrice":"0.385","breakEvenPrice":"0.385077","markPrice":"0.41047590","unRealizedProfit":"0.76427700","liquidationPrice":"0","isolatedMargin":"0","notional":"12.31427700","marginAsset":"USDT","isolatedWallet":"0","initialMargin":"0.61571385","maintMargin":"0.08004280","positionInitialMargin":"0.61571385","openOrderInitialMargin":"0","adl":2,"bidNotional":"0","askNotional":"0","updateTime":1720736417660},{"symbol":"COMPUSDT","positionSide":"SHORT","positionAmt":"-1.000","entryPrice":"70.92841","breakEvenPrice":"70.900038636","markPrice":"49.72023376","unRealizedProfit":"21.20817624","liquidationPrice":"2260.56757210","isolatedMargin":"0","notional":"-49.72023376","marginAsset":"USDT","isolatedWallet":"0","initialMargin":"2.48601168","maintMargin":"0.49720233","positionInitialMargin":"2.48601168","openOrderInitialMargin":"0","adl":2,"bidNotional":"0","askNotional":"0","updateTime":1708943511656}]"#).unwrap();
let dummy_response: Vec<models::PositionInformationV3ResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::PositionInformationV3ResponseInner>");
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_algo_order(
&self,
_params: QueryAlgoOrderParams,
) -> anyhow::Result<RestApiResponse<models::QueryAlgoOrderResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"algoId":2146760,"clientAlgoId":"6B2I9XVcJpCjqPAJ4YoFX7","algoType":"CONDITIONAL","orderType":"TAKE_PROFIT","symbol":"BNBUSDT","side":"SELL","positionSide":"BOTH","timeInForce":"GTC","quantity":"0.01","algoStatus":"CANCELED","actualOrderId":"","actualPrice":"0.00000","triggerPrice":"750.000","price":"750.000","icebergQuantity":null,"tpTriggerPrice":"0.000","tpPrice":"0.000","slTriggerPrice":"0.000","slPrice":"0.000","tpOrderType":"","selfTradePreventionMode":"EXPIRE_MAKER","workingType":"CONTRACT_PRICE","priceMatch":"NONE","closePosition":false,"priceProtect":false,"reduceOnly":false,"createTime":1750485492076,"updateTime":1750514545091,"triggerTime":0,"goodTillDate":0}"#).unwrap();
let dummy_response: models::QueryAlgoOrderResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::QueryAlgoOrderResponse");
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_all_algo_orders(
&self,
_params: QueryAllAlgoOrdersParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryAllAlgoOrdersResponseInner>>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"[{"algoId":2146760,"clientAlgoId":"6B2I9XVcJpCjqPAJ4YoFX7","algoType":"CONDITIONAL","orderType":"TAKE_PROFIT","symbol":"BNBUSDT","side":"SELL","positionSide":"BOTH","timeInForce":"GTC","quantity":"0.01","algoStatus":"CANCELED","actualOrderId":"","actualPrice":"0.00000","triggerPrice":"750.000","price":"750.000","icebergQuantity":null,"tpTriggerPrice":"0.000","tpPrice":"0.000","slTriggerPrice":"0.000","slPrice":"0.000","tpOrderType":"","selfTradePreventionMode":"EXPIRE_MAKER","workingType":"CONTRACT_PRICE","priceMatch":"NONE","closePosition":false,"priceProtect":false,"reduceOnly":false,"createTime":1750485492076,"updateTime":1750514545091,"triggerTime":0,"goodTillDate":0}]"#).unwrap();
let dummy_response: Vec<models::QueryAllAlgoOrdersResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::QueryAllAlgoOrdersResponseInner>");
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.00000","clientOrderId":"abc","cumQuote":"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":"BTCUSDT","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":0}"#).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.00000","clientOrderId":"abc","cumQuote":"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":"BTCUSDT","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false}"#).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 test_order(
&self,
_params: TestOrderParams,
) -> anyhow::Result<RestApiResponse<models::TestOrderResponse>> {
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","cumQuote":"0","executedQty":"0","orderId":22542179,"avgPrice":"0.00000","origQty":"10","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSDT","timeInForce":"GTD","type":"TRAILING_STOP_MARKET","origType":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1566818724722,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":1693207680000}"#).unwrap();
let dummy_response: models::TestOrderResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::TestOrderResponse");
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":6071832819,"symbol":"BTCUSDT","status":"FILLED","clientOrderId":"autoclose-1596107620040000020","price":"10871.09","avgPrice":"10913.21000","origQty":"0.001","executedQty":"0.001","cumQuote":"10.91321","timeInForce":"IOC","type":"LIMIT","reduceOnly":false,"closePosition":false,"side":"SELL","positionSide":"BOTH","stopPrice":"0","workingType":"CONTRACT_PRICE","origType":"LIMIT","time":1596107620044,"updateTime":1596107620087},{"orderId":6072734303,"symbol":"BTCUSDT","status":"FILLED","clientOrderId":"adl_autoclose","price":"11023.14","avgPrice":"10979.82000","origQty":"0.001","executedQty":"0.001","cumQuote":"10.97982","timeInForce":"GTC","type":"LIMIT","reduceOnly":false,"closePosition":false,"side":"BUY","positionSide":"SHORT","stopPrice":"0","workingType":"CONTRACT_PRICE","origType":"LIMIT","time":1596110725059,"updateTime":1596110725071}]"#).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("symbol_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"buyer":false,"commission":"-0.07819010","commissionAsset":"USDT","id":698759,"maker":false,"orderId":25851813,"price":"7819.01","qty":"0.002","quoteQty":"15.63802","realizedPnl":"-0.91539999","side":"SELL","positionSide":"SHORT","symbol":"BTCUSDT","time":1569514978020}]"#).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_example".to_string(),).order_id(1).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#"[{"buyer":false,"commission":"-0.07819010","commissionAsset":"USDT","id":698759,"maker":false,"orderId":25851813,"price":"7819.01","qty":"0.002","quoteQty":"15.63802","realizedPnl":"-0.91539999","side":"SELL","positionSide":"SHORT","symbol":"BTCUSDT","time":1569514978020}]"#).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("symbol_example".to_string())
.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("symbol_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"avgPrice":"0.00000","clientOrderId":"abc","cumQuote":"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":"BTCUSDT","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":0}]"#).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_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.00000","clientOrderId":"abc","cumQuote":"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":"BTCUSDT","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":0}]"#).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("symbol_example".to_string())
.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":"BTCUSDT","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":"BTCUSDT","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_algo_order_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = CancelAlgoOrderParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"algoId":2146760,"clientAlgoId":"6B2I9XVcJpCjqPAJ4YoFX7","code":"200","msg":"success"}"#).unwrap();
let expected_response : models::CancelAlgoOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::CancelAlgoOrderResponse");
let resp = client.cancel_algo_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_algo_order_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = CancelAlgoOrderParams::builder().algo_id(1).client_algo_id("1".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"algoId":2146760,"clientAlgoId":"6B2I9XVcJpCjqPAJ4YoFX7","code":"200","msg":"success"}"#).unwrap();
let expected_response : models::CancelAlgoOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::CancelAlgoOrderResponse");
let resp = client.cancel_algo_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_algo_order_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = CancelAlgoOrderParams::builder().build().unwrap();
match client.cancel_algo_order(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn cancel_all_algo_open_orders_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = CancelAllAlgoOpenOrdersParams::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::CancelAllAlgoOpenOrdersResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::CancelAllAlgoOpenOrdersResponse");
let resp = client
.cancel_all_algo_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_algo_open_orders_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = CancelAllAlgoOpenOrdersParams::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::CancelAllAlgoOpenOrdersResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::CancelAllAlgoOpenOrdersResponse");
let resp = client
.cancel_all_algo_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_algo_open_orders_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = CancelAllAlgoOpenOrdersParams::builder("symbol_example".to_string())
.build()
.unwrap();
match client.cancel_all_algo_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#"[{"clientOrderId":"myOrder1","cumQty":"0","cumQuote":"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":"BTCUSDT","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1571110484038,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":1693207680000},{"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#"[{"clientOrderId":"myOrder1","cumQty":"0","cumQuote":"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":"BTCUSDT","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1571110484038,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":1693207680000},{"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#"{"clientOrderId":"myOrder1","cumQty":"0","cumQuote":"0","executedQty":"0","orderId":283194212,"origQty":"11","origType":"TRAILING_STOP_MARKET","price":"0","avgPrice":"0.00","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"CANCELED","stopPrice":"9300","closePosition":false,"symbol":"BTCUSDT","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1571110484038,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":1693207680000}"#).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#"{"clientOrderId":"myOrder1","cumQty":"0","cumQuote":"0","executedQty":"0","orderId":283194212,"origQty":"11","origType":"TRAILING_STOP_MARKET","price":"0","avgPrice":"0.00","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"CANCELED","stopPrice":"9300","closePosition":false,"symbol":"BTCUSDT","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1571110484038,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":1693207680000}"#).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,"maxNotionalValue":"1000000","symbol":"BTCUSDT"}"#,
)
.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,"maxNotionalValue":"1000000","symbol":"BTCUSDT"}"#,
)
.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_multi_assets_mode_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params =
ChangeMultiAssetsModeParams::builder("multi_assets_margin_example".to_string())
.build()
.unwrap();
let resp_json: Value = serde_json::from_str(r#"{"code":200,"msg":"success"}"#).unwrap();
let expected_response: models::ChangeMultiAssetsModeResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::ChangeMultiAssetsModeResponse");
let resp = client
.change_multi_assets_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_multi_assets_mode_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params =
ChangeMultiAssetsModeParams::builder("multi_assets_margin_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::ChangeMultiAssetsModeResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::ChangeMultiAssetsModeResponse");
let resp = client
.change_multi_assets_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_multi_assets_mode_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params =
ChangeMultiAssetsModeParams::builder("multi_assets_margin_example".to_string())
.build()
.unwrap();
match client.change_multi_assets_mode(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_algo_open_orders_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = CurrentAllAlgoOpenOrdersParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"algoId":2148627,"clientAlgoId":"MRumok0dkhrP4kCm12AHaB","algoType":"CONDITIONAL","orderType":"TAKE_PROFIT","symbol":"BNBUSDT","side":"SELL","positionSide":"BOTH","timeInForce":"GTC","quantity":"0.01","algoStatus":"NEW","actualOrderId":"","actualPrice":"0.00000","triggerPrice":"750.000","price":"750.000","icebergQuantity":null,"tpTriggerPrice":"0.000","tpPrice":"0.000","slTriggerPrice":"0.000","slPrice":"0.000","tpOrderType":"","selfTradePreventionMode":"EXPIRE_MAKER","workingType":"CONTRACT_PRICE","priceMatch":"NONE","closePosition":false,"priceProtect":false,"reduceOnly":false,"createTime":1750514941540,"updateTime":1750514941540,"triggerTime":0,"goodTillDate":0}]"#).unwrap();
let expected_response : Vec<models::CurrentAllAlgoOpenOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::CurrentAllAlgoOpenOrdersResponseInner>");
let resp = client.current_all_algo_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_algo_open_orders_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = CurrentAllAlgoOpenOrdersParams::builder().algo_type("algo_type_example".to_string()).symbol("symbol_example".to_string()).algo_id(1).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"algoId":2148627,"clientAlgoId":"MRumok0dkhrP4kCm12AHaB","algoType":"CONDITIONAL","orderType":"TAKE_PROFIT","symbol":"BNBUSDT","side":"SELL","positionSide":"BOTH","timeInForce":"GTC","quantity":"0.01","algoStatus":"NEW","actualOrderId":"","actualPrice":"0.00000","triggerPrice":"750.000","price":"750.000","icebergQuantity":null,"tpTriggerPrice":"0.000","tpPrice":"0.000","slTriggerPrice":"0.000","slPrice":"0.000","tpOrderType":"","selfTradePreventionMode":"EXPIRE_MAKER","workingType":"CONTRACT_PRICE","priceMatch":"NONE","closePosition":false,"priceProtect":false,"reduceOnly":false,"createTime":1750514941540,"updateTime":1750514941540,"triggerTime":0,"goodTillDate":0}]"#).unwrap();
let expected_response : Vec<models::CurrentAllAlgoOpenOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::CurrentAllAlgoOpenOrdersResponseInner>");
let resp = client.current_all_algo_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_algo_open_orders_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = CurrentAllAlgoOpenOrdersParams::builder().build().unwrap();
match client.current_all_algo_open_orders(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.00000","clientOrderId":"abc","cumQuote":"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":"BTCUSDT","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":0}]"#).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()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"avgPrice":"0.00000","clientOrderId":"abc","cumQuote":"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":"BTCUSDT","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":0}]"#).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 futures_tradfi_perps_contract_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = FuturesTradfiPerpsContractParams::builder().build().unwrap();
let expected_response = Value::Null;
let resp = client
.futures_tradfi_perps_contract(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 futures_tradfi_perps_contract_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = FuturesTradfiPerpsContractParams::builder()
.recv_window(5000)
.build()
.unwrap();
let expected_response = Value::Null;
let resp = client
.futures_tradfi_perps_contract(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 futures_tradfi_perps_contract_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = FuturesTradfiPerpsContractParams::builder().build().unwrap();
match client.futures_tradfi_perps_contract(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":"BTCUSDT","pair":"BTCUSDT","orderId":20072994037,"clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","time":1629184560899,"amendment":{"price":{"before":"30004","after":"30003.2"},"origQty":{"before":"1","after":"1"},"count":3}},{"amendmentId":5361,"symbol":"BTCUSDT","pair":"BTCUSDT","orderId":20072994037,"clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","time":1629184533946,"amendment":{"price":{"before":"30005","after":"30004"},"origQty":{"before":"1","after":"1"},"count":2}},{"amendmentId":5325,"symbol":"BTCUSDT","pair":"BTCUSDT","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":"BTCUSDT","pair":"BTCUSDT","orderId":20072994037,"clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","time":1629184560899,"amendment":{"price":{"before":"30004","after":"30003.2"},"origQty":{"before":"1","after":"1"},"count":3}},{"amendmentId":5361,"symbol":"BTCUSDT","pair":"BTCUSDT","orderId":20072994037,"clientOrderId":"LJ9R4QZDihCaS8UAOOLpgW","time":1629184533946,"amendment":{"price":{"before":"30005","after":"30004"},"origQty":{"before":"1","after":"1"},"count":2}},{"amendmentId":5325,"symbol":"BTCUSDT","pair":"BTCUSDT","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#"[{"symbol":"BTCUSDT","type":1,"deltaType":"USER_ADJUST","amount":"23.36332311","asset":"USDT","time":1578047897183,"positionSide":"BOTH"},{"symbol":"BTCUSDT","type":1,"deltaType":"USER_ADJUST","amount":"100","asset":"USDT","time":1578047900425,"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#"[{"symbol":"BTCUSDT","type":1,"deltaType":"USER_ADJUST","amount":"23.36332311","asset":"USDT","time":1578047897183,"positionSide":"BOTH"},{"symbol":"BTCUSDT","type":1,"deltaType":"USER_ADJUST","amount":"100","asset":"USDT","time":1578047900425,"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),"r#type_example".to_string(),).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),"r#type_example".to_string(),).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),
"r#type_example".to_string(),
)
.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":"BTCUSDT","pair":"BTCUSDT","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","goodTillDate":0,"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":"BTCUSDT","pair":"BTCUSDT","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","goodTillDate":0,"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,dec!(1.0),dec!(1.0),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"orderId":20072994037,"symbol":"BTCUSDT","pair":"BTCUSDT","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","goodTillDate":0,"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,dec!(1.0),dec!(1.0),).order_id(1).orig_client_order_id("1".to_string()).price_match(ModifyOrderPriceMatchEnum::None).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"orderId":20072994037,"symbol":"BTCUSDT","pair":"BTCUSDT","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","goodTillDate":0,"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,
dec!(1.0),
dec!(1.0),
)
.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_algo_order_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = NewAlgoOrderParams::builder("algo_type_example".to_string(),"symbol_example".to_string(),NewAlgoOrderSideEnum::Buy,"r#type_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"algoId":2146760,"clientAlgoId":"6B2I9XVcJpCjqPAJ4YoFX7","algoType":"CONDITIONAL","orderType":"TAKE_PROFIT","symbol":"BNBUSDT","side":"SELL","positionSide":"BOTH","timeInForce":"GTC","quantity":"0.01","algoStatus":"NEW","triggerPrice":"750.000","price":"750.000","icebergQuantity":null,"selfTradePreventionMode":"EXPIRE_MAKER","workingType":"CONTRACT_PRICE","priceMatch":"NONE","closePosition":false,"priceProtect":false,"reduceOnly":false,"activatePrice":"","callbackRate":"","createTime":1750485492076,"updateTime":1750485492076,"triggerTime":0,"goodTillDate":0}"#).unwrap();
let expected_response : models::NewAlgoOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::NewAlgoOrderResponse");
let resp = client.new_algo_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_algo_order_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = NewAlgoOrderParams::builder("algo_type_example".to_string(),"symbol_example".to_string(),NewAlgoOrderSideEnum::Buy,"r#type_example".to_string(),).position_side(NewAlgoOrderPositionSideEnum::Both).time_in_force(NewAlgoOrderTimeInForceEnum::Gtc).quantity(dec!(1.0)).price(dec!(1.0)).trigger_price(dec!(1.0)).working_type(NewAlgoOrderWorkingTypeEnum::MarkPrice).price_match(NewAlgoOrderPriceMatchEnum::None).close_position("close_position_example".to_string()).price_protect("false".to_string()).reduce_only("false".to_string()).activate_price(dec!(1.0)).callback_rate(dec!(1.0)).client_algo_id("1".to_string()).new_order_resp_type(NewAlgoOrderNewOrderRespTypeEnum::Ack).self_trade_prevention_mode(NewAlgoOrderSelfTradePreventionModeEnum::ExpireTaker).good_till_date(789).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"algoId":2146760,"clientAlgoId":"6B2I9XVcJpCjqPAJ4YoFX7","algoType":"CONDITIONAL","orderType":"TAKE_PROFIT","symbol":"BNBUSDT","side":"SELL","positionSide":"BOTH","timeInForce":"GTC","quantity":"0.01","algoStatus":"NEW","triggerPrice":"750.000","price":"750.000","icebergQuantity":null,"selfTradePreventionMode":"EXPIRE_MAKER","workingType":"CONTRACT_PRICE","priceMatch":"NONE","closePosition":false,"priceProtect":false,"reduceOnly":false,"activatePrice":"","callbackRate":"","createTime":1750485492076,"updateTime":1750485492076,"triggerTime":0,"goodTillDate":0}"#).unwrap();
let expected_response : models::NewAlgoOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::NewAlgoOrderResponse");
let resp = client.new_algo_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_algo_order_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = NewAlgoOrderParams::builder(
"algo_type_example".to_string(),
"symbol_example".to_string(),
NewAlgoOrderSideEnum::Buy,
"r#type_example".to_string(),
)
.build()
.unwrap();
match client.new_algo_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,"r#type_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"clientOrderId":"testOrder","cumQty":"0","cumQuote":"0","executedQty":"0","orderId":22542179,"avgPrice":"0.00000","origQty":"10","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSDT","timeInForce":"GTD","type":"TRAILING_STOP_MARKET","origType":"TRAILING_STOP_MARKET","updateTime":1566818724722,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":1693207680000}"#).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,"r#type_example".to_string(),).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()).new_order_resp_type(NewOrderNewOrderRespTypeEnum::Ack).price_match(NewOrderPriceMatchEnum::None).self_trade_prevention_mode(NewOrderSelfTradePreventionModeEnum::ExpireTaker).good_till_date(789).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"clientOrderId":"testOrder","cumQty":"0","cumQuote":"0","executedQty":"0","orderId":22542179,"avgPrice":"0.00000","origQty":"10","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSDT","timeInForce":"GTD","type":"TRAILING_STOP_MARKET","origType":"TRAILING_STOP_MARKET","updateTime":1566818724722,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":1693207680000}"#).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,
"r#type_example".to_string(),
)
.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","cumQuote":"0","executedQty":"0","orderId":22542179,"avgPrice":"0.00000","origQty":"10","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"0","closePosition":false,"symbol":"BTCUSDT","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","origType":"TRAILING_STOP_MARKET","updateTime":1566818724722,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":1693207680000},{"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","cumQuote":"0","executedQty":"0","orderId":22542179,"avgPrice":"0.00000","origQty":"10","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"0","closePosition":false,"symbol":"BTCUSDT","timeInForce":"GTC","type":"TRAILING_STOP_MARKET","origType":"TRAILING_STOP_MARKET","updateTime":1566818724722,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":1693207680000},{"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":"ETHUSDT","adlQuantile":{"LONG":3,"SHORT":3,"HEDGE":0}},{"symbol":"BTCUSDT","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":"ETHUSDT","adlQuantile":{"LONG":3,"SHORT":3,"HEDGE":0}},{"symbol":"BTCUSDT","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_v2_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = PositionInformationV2Params::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"entryPrice":"0.00000","breakEvenPrice":"0.0","marginType":"isolated","isAutoAddMargin":"false","isolatedMargin":"0.00000000","leverage":"10","liquidationPrice":"0","markPrice":"6679.50671178","maxNotionalValue":"20000000","positionAmt":"0.000","notional":"0","isolatedWallet":"0","symbol":"BTCUSDT","unRealizedProfit":"0.00000000","positionSide":"BOTH","updateTime":0},{"symbol":"BTCUSDT","positionAmt":"0.001","entryPrice":"22185.2","breakEvenPrice":"0.0","markPrice":"21123.05052574","unRealizedProfit":"-1.06214947","liquidationPrice":"19731.45529116","leverage":"4","maxNotionalValue":"100000000","marginType":"cross","isolatedMargin":"0.00000000","isAutoAddMargin":"false","positionSide":"LONG","notional":"21.12305052","isolatedWallet":"0","updateTime":1655217461579},{"symbol":"BTCUSDT","positionAmt":"0.000","entryPrice":"0.0","breakEvenPrice":"0.0","markPrice":"21123.05052574","unRealizedProfit":"0.00000000","liquidationPrice":"0","leverage":"4","maxNotionalValue":"100000000","marginType":"cross","isolatedMargin":"0.00000000","isAutoAddMargin":"false","positionSide":"SHORT","notional":"0","isolatedWallet":"0","updateTime":0}]"#).unwrap();
let expected_response : Vec<models::PositionInformationV2ResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::PositionInformationV2ResponseInner>");
let resp = client.position_information_v2(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn position_information_v2_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = PositionInformationV2Params::builder().symbol("symbol_example".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"entryPrice":"0.00000","breakEvenPrice":"0.0","marginType":"isolated","isAutoAddMargin":"false","isolatedMargin":"0.00000000","leverage":"10","liquidationPrice":"0","markPrice":"6679.50671178","maxNotionalValue":"20000000","positionAmt":"0.000","notional":"0","isolatedWallet":"0","symbol":"BTCUSDT","unRealizedProfit":"0.00000000","positionSide":"BOTH","updateTime":0},{"symbol":"BTCUSDT","positionAmt":"0.001","entryPrice":"22185.2","breakEvenPrice":"0.0","markPrice":"21123.05052574","unRealizedProfit":"-1.06214947","liquidationPrice":"19731.45529116","leverage":"4","maxNotionalValue":"100000000","marginType":"cross","isolatedMargin":"0.00000000","isAutoAddMargin":"false","positionSide":"LONG","notional":"21.12305052","isolatedWallet":"0","updateTime":1655217461579},{"symbol":"BTCUSDT","positionAmt":"0.000","entryPrice":"0.0","breakEvenPrice":"0.0","markPrice":"21123.05052574","unRealizedProfit":"0.00000000","liquidationPrice":"0","leverage":"4","maxNotionalValue":"100000000","marginType":"cross","isolatedMargin":"0.00000000","isAutoAddMargin":"false","positionSide":"SHORT","notional":"0","isolatedWallet":"0","updateTime":0}]"#).unwrap();
let expected_response : Vec<models::PositionInformationV2ResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::PositionInformationV2ResponseInner>");
let resp = client.position_information_v2(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn position_information_v2_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = PositionInformationV2Params::builder().build().unwrap();
match client.position_information_v2(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn position_information_v3_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = PositionInformationV3Params::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"symbol":"ADAUSDT","positionSide":"BOTH","positionAmt":"30","entryPrice":"0.385","breakEvenPrice":"0.385077","markPrice":"0.41047590","unRealizedProfit":"0.76427700","liquidationPrice":"0","isolatedMargin":"0","notional":"12.31427700","marginAsset":"USDT","isolatedWallet":"0","initialMargin":"0.61571385","maintMargin":"0.08004280","positionInitialMargin":"0.61571385","openOrderInitialMargin":"0","adl":2,"bidNotional":"0","askNotional":"0","updateTime":1720736417660},{"symbol":"ADAUSDT","positionSide":"LONG","positionAmt":"30","entryPrice":"0.385","breakEvenPrice":"0.385077","markPrice":"0.41047590","unRealizedProfit":"0.76427700","liquidationPrice":"0","isolatedMargin":"0","notional":"12.31427700","marginAsset":"USDT","isolatedWallet":"0","initialMargin":"0.61571385","maintMargin":"0.08004280","positionInitialMargin":"0.61571385","openOrderInitialMargin":"0","adl":2,"bidNotional":"0","askNotional":"0","updateTime":1720736417660},{"symbol":"COMPUSDT","positionSide":"SHORT","positionAmt":"-1.000","entryPrice":"70.92841","breakEvenPrice":"70.900038636","markPrice":"49.72023376","unRealizedProfit":"21.20817624","liquidationPrice":"2260.56757210","isolatedMargin":"0","notional":"-49.72023376","marginAsset":"USDT","isolatedWallet":"0","initialMargin":"2.48601168","maintMargin":"0.49720233","positionInitialMargin":"2.48601168","openOrderInitialMargin":"0","adl":2,"bidNotional":"0","askNotional":"0","updateTime":1708943511656}]"#).unwrap();
let expected_response : Vec<models::PositionInformationV3ResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::PositionInformationV3ResponseInner>");
let resp = client.position_information_v3(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_v3_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = PositionInformationV3Params::builder().symbol("symbol_example".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"symbol":"ADAUSDT","positionSide":"BOTH","positionAmt":"30","entryPrice":"0.385","breakEvenPrice":"0.385077","markPrice":"0.41047590","unRealizedProfit":"0.76427700","liquidationPrice":"0","isolatedMargin":"0","notional":"12.31427700","marginAsset":"USDT","isolatedWallet":"0","initialMargin":"0.61571385","maintMargin":"0.08004280","positionInitialMargin":"0.61571385","openOrderInitialMargin":"0","adl":2,"bidNotional":"0","askNotional":"0","updateTime":1720736417660},{"symbol":"ADAUSDT","positionSide":"LONG","positionAmt":"30","entryPrice":"0.385","breakEvenPrice":"0.385077","markPrice":"0.41047590","unRealizedProfit":"0.76427700","liquidationPrice":"0","isolatedMargin":"0","notional":"12.31427700","marginAsset":"USDT","isolatedWallet":"0","initialMargin":"0.61571385","maintMargin":"0.08004280","positionInitialMargin":"0.61571385","openOrderInitialMargin":"0","adl":2,"bidNotional":"0","askNotional":"0","updateTime":1720736417660},{"symbol":"COMPUSDT","positionSide":"SHORT","positionAmt":"-1.000","entryPrice":"70.92841","breakEvenPrice":"70.900038636","markPrice":"49.72023376","unRealizedProfit":"21.20817624","liquidationPrice":"2260.56757210","isolatedMargin":"0","notional":"-49.72023376","marginAsset":"USDT","isolatedWallet":"0","initialMargin":"2.48601168","maintMargin":"0.49720233","positionInitialMargin":"2.48601168","openOrderInitialMargin":"0","adl":2,"bidNotional":"0","askNotional":"0","updateTime":1708943511656}]"#).unwrap();
let expected_response : Vec<models::PositionInformationV3ResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::PositionInformationV3ResponseInner>");
let resp = client.position_information_v3(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_v3_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = PositionInformationV3Params::builder().build().unwrap();
match client.position_information_v3(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn query_algo_order_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryAlgoOrderParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"algoId":2146760,"clientAlgoId":"6B2I9XVcJpCjqPAJ4YoFX7","algoType":"CONDITIONAL","orderType":"TAKE_PROFIT","symbol":"BNBUSDT","side":"SELL","positionSide":"BOTH","timeInForce":"GTC","quantity":"0.01","algoStatus":"CANCELED","actualOrderId":"","actualPrice":"0.00000","triggerPrice":"750.000","price":"750.000","icebergQuantity":null,"tpTriggerPrice":"0.000","tpPrice":"0.000","slTriggerPrice":"0.000","slPrice":"0.000","tpOrderType":"","selfTradePreventionMode":"EXPIRE_MAKER","workingType":"CONTRACT_PRICE","priceMatch":"NONE","closePosition":false,"priceProtect":false,"reduceOnly":false,"createTime":1750485492076,"updateTime":1750514545091,"triggerTime":0,"goodTillDate":0}"#).unwrap();
let expected_response : models::QueryAlgoOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryAlgoOrderResponse");
let resp = client.query_algo_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_algo_order_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryAlgoOrderParams::builder().algo_id(1).client_algo_id("1".to_string()).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"algoId":2146760,"clientAlgoId":"6B2I9XVcJpCjqPAJ4YoFX7","algoType":"CONDITIONAL","orderType":"TAKE_PROFIT","symbol":"BNBUSDT","side":"SELL","positionSide":"BOTH","timeInForce":"GTC","quantity":"0.01","algoStatus":"CANCELED","actualOrderId":"","actualPrice":"0.00000","triggerPrice":"750.000","price":"750.000","icebergQuantity":null,"tpTriggerPrice":"0.000","tpPrice":"0.000","slTriggerPrice":"0.000","slPrice":"0.000","tpOrderType":"","selfTradePreventionMode":"EXPIRE_MAKER","workingType":"CONTRACT_PRICE","priceMatch":"NONE","closePosition":false,"priceProtect":false,"reduceOnly":false,"createTime":1750485492076,"updateTime":1750514545091,"triggerTime":0,"goodTillDate":0}"#).unwrap();
let expected_response : models::QueryAlgoOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryAlgoOrderResponse");
let resp = client.query_algo_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_algo_order_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = QueryAlgoOrderParams::builder().build().unwrap();
match client.query_algo_order(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn query_all_algo_orders_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryAllAlgoOrdersParams::builder("symbol_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"algoId":2146760,"clientAlgoId":"6B2I9XVcJpCjqPAJ4YoFX7","algoType":"CONDITIONAL","orderType":"TAKE_PROFIT","symbol":"BNBUSDT","side":"SELL","positionSide":"BOTH","timeInForce":"GTC","quantity":"0.01","algoStatus":"CANCELED","actualOrderId":"","actualPrice":"0.00000","triggerPrice":"750.000","price":"750.000","icebergQuantity":null,"tpTriggerPrice":"0.000","tpPrice":"0.000","slTriggerPrice":"0.000","slPrice":"0.000","tpOrderType":"","selfTradePreventionMode":"EXPIRE_MAKER","workingType":"CONTRACT_PRICE","priceMatch":"NONE","closePosition":false,"priceProtect":false,"reduceOnly":false,"createTime":1750485492076,"updateTime":1750514545091,"triggerTime":0,"goodTillDate":0}]"#).unwrap();
let expected_response : Vec<models::QueryAllAlgoOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryAllAlgoOrdersResponseInner>");
let resp = client.query_all_algo_orders(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_all_algo_orders_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = QueryAllAlgoOrdersParams::builder("symbol_example".to_string(),).algo_id(1).start_time(1623319461670).end_time(1641782889000).page(789).limit(100).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"[{"algoId":2146760,"clientAlgoId":"6B2I9XVcJpCjqPAJ4YoFX7","algoType":"CONDITIONAL","orderType":"TAKE_PROFIT","symbol":"BNBUSDT","side":"SELL","positionSide":"BOTH","timeInForce":"GTC","quantity":"0.01","algoStatus":"CANCELED","actualOrderId":"","actualPrice":"0.00000","triggerPrice":"750.000","price":"750.000","icebergQuantity":null,"tpTriggerPrice":"0.000","tpPrice":"0.000","slTriggerPrice":"0.000","slPrice":"0.000","tpOrderType":"","selfTradePreventionMode":"EXPIRE_MAKER","workingType":"CONTRACT_PRICE","priceMatch":"NONE","closePosition":false,"priceProtect":false,"reduceOnly":false,"createTime":1750485492076,"updateTime":1750514545091,"triggerTime":0,"goodTillDate":0}]"#).unwrap();
let expected_response : Vec<models::QueryAllAlgoOrdersResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryAllAlgoOrdersResponseInner>");
let resp = client.query_all_algo_orders(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_all_algo_orders_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = QueryAllAlgoOrdersParams::builder("symbol_example".to_string())
.build()
.unwrap();
match client.query_all_algo_orders(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.00000","clientOrderId":"abc","cumQuote":"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":"BTCUSDT","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":0}"#).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.00000","clientOrderId":"abc","cumQuote":"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":"BTCUSDT","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":0}"#).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.00000","clientOrderId":"abc","cumQuote":"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":"BTCUSDT","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false}"#).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.00000","clientOrderId":"abc","cumQuote":"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":"BTCUSDT","time":1579276756075,"timeInForce":"GTC","type":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1579276756075,"workingType":"CONTRACT_PRICE","priceProtect":false}"#).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 test_order_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = TestOrderParams::builder("symbol_example".to_string(),TestOrderSideEnum::Buy,"r#type_example".to_string(),).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"clientOrderId":"testOrder","cumQty":"0","cumQuote":"0","executedQty":"0","orderId":22542179,"avgPrice":"0.00000","origQty":"10","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSDT","timeInForce":"GTD","type":"TRAILING_STOP_MARKET","origType":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1566818724722,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":1693207680000}"#).unwrap();
let expected_response : models::TestOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::TestOrderResponse");
let resp = client.test_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 test_order_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: false };
let params = TestOrderParams::builder("symbol_example".to_string(),TestOrderSideEnum::Buy,"r#type_example".to_string(),).position_side(TestOrderPositionSideEnum::Both).time_in_force(TestOrderTimeInForceEnum::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(TestOrderWorkingTypeEnum::MarkPrice).price_protect("false".to_string()).new_order_resp_type(TestOrderNewOrderRespTypeEnum::Ack).price_match(TestOrderPriceMatchEnum::None).self_trade_prevention_mode(TestOrderSelfTradePreventionModeEnum::ExpireTaker).good_till_date(789).recv_window(5000).build().unwrap();
let resp_json: Value = serde_json::from_str(r#"{"clientOrderId":"testOrder","cumQty":"0","cumQuote":"0","executedQty":"0","orderId":22542179,"avgPrice":"0.00000","origQty":"10","price":"0","reduceOnly":false,"side":"BUY","positionSide":"SHORT","status":"NEW","stopPrice":"9300","closePosition":false,"symbol":"BTCUSDT","timeInForce":"GTD","type":"TRAILING_STOP_MARKET","origType":"TRAILING_STOP_MARKET","activatePrice":"9020","priceRate":"0.3","updateTime":1566818724722,"workingType":"CONTRACT_PRICE","priceProtect":false,"priceMatch":"NONE","selfTradePreventionMode":"NONE","goodTillDate":1693207680000}"#).unwrap();
let expected_response : models::TestOrderResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::TestOrderResponse");
let resp = client.test_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 test_order_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockTradeApiClient { force_error: true };
let params = TestOrderParams::builder(
"symbol_example".to_string(),
TestOrderSideEnum::Buy,
"r#type_example".to_string(),
)
.build()
.unwrap();
match client.test_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":6071832819,"symbol":"BTCUSDT","status":"FILLED","clientOrderId":"autoclose-1596107620040000020","price":"10871.09","avgPrice":"10913.21000","origQty":"0.001","executedQty":"0.001","cumQuote":"10.91321","timeInForce":"IOC","type":"LIMIT","reduceOnly":false,"closePosition":false,"side":"SELL","positionSide":"BOTH","stopPrice":"0","workingType":"CONTRACT_PRICE","origType":"LIMIT","time":1596107620044,"updateTime":1596107620087},{"orderId":6072734303,"symbol":"BTCUSDT","status":"FILLED","clientOrderId":"adl_autoclose","price":"11023.14","avgPrice":"10979.82000","origQty":"0.001","executedQty":"0.001","cumQuote":"10.97982","timeInForce":"GTC","type":"LIMIT","reduceOnly":false,"closePosition":false,"side":"BUY","positionSide":"SHORT","stopPrice":"0","workingType":"CONTRACT_PRICE","origType":"LIMIT","time":1596110725059,"updateTime":1596110725071}]"#).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":6071832819,"symbol":"BTCUSDT","status":"FILLED","clientOrderId":"autoclose-1596107620040000020","price":"10871.09","avgPrice":"10913.21000","origQty":"0.001","executedQty":"0.001","cumQuote":"10.91321","timeInForce":"IOC","type":"LIMIT","reduceOnly":false,"closePosition":false,"side":"SELL","positionSide":"BOTH","stopPrice":"0","workingType":"CONTRACT_PRICE","origType":"LIMIT","time":1596107620044,"updateTime":1596107620087},{"orderId":6072734303,"symbol":"BTCUSDT","status":"FILLED","clientOrderId":"adl_autoclose","price":"11023.14","avgPrice":"10979.82000","origQty":"0.001","executedQty":"0.001","cumQuote":"10.97982","timeInForce":"GTC","type":"LIMIT","reduceOnly":false,"closePosition":false,"side":"BUY","positionSide":"SHORT","stopPrice":"0","workingType":"CONTRACT_PRICE","origType":"LIMIT","time":1596110725059,"updateTime":1596110725071}]"#).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");
}
}
});
}
}