|
|
@@ -1,261 +1,270 @@
|
|
|
-// use std::collections::{BTreeMap};
|
|
|
-// use std::io::{Error, ErrorKind};
|
|
|
-// use tokio::sync::mpsc::Sender;
|
|
|
-// use async_trait::async_trait;
|
|
|
-// use rust_decimal::{Decimal};
|
|
|
-// use serde_json::{json, Value};
|
|
|
-// use tracing::{error, info};
|
|
|
-// use crate::{Platform, ExchangeEnum, Account, Position, Ticker, Market, Order, utils};
|
|
|
-// use exchanges::mexc_swap_rest::MexcSwapRest;
|
|
|
-// use rust_decimal::prelude::FromPrimitive;
|
|
|
-//
|
|
|
-// #[allow(dead_code)]
|
|
|
-// #[derive(Clone)]
|
|
|
-// pub struct MexcSwap {
|
|
|
-// exchange: ExchangeEnum,
|
|
|
-// symbol: String,
|
|
|
-// is_colo: bool,
|
|
|
-// params: BTreeMap<String, String>,
|
|
|
-// request: MexcSwapRest,
|
|
|
-// market: Market,
|
|
|
-// order_sender: Sender<Order>,
|
|
|
-// error_sender: Sender<Error>,
|
|
|
-// }
|
|
|
-//
|
|
|
-// impl MexcSwap {
|
|
|
-// pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> MexcSwap {
|
|
|
-// let market = Market::new();
|
|
|
-// let mut mexc_swap = MexcSwap {
|
|
|
-// exchange: ExchangeEnum::MexcSwap,
|
|
|
-// symbol: symbol.to_uppercase(),
|
|
|
-// is_colo,
|
|
|
-// params: params.clone(),
|
|
|
-// request: MexcSwapRest::new(is_colo, params.clone()),
|
|
|
-// market,
|
|
|
-// order_sender,
|
|
|
-// error_sender,
|
|
|
-// };
|
|
|
-//
|
|
|
-// // 修改持仓模式
|
|
|
-// let symbol_array: Vec<&str> = symbol.split("_").collect();
|
|
|
-// let mode_result = mexc_swap.set_dual_mode(symbol_array[1], true).await;
|
|
|
-// match mode_result {
|
|
|
-// Ok(ok) => {
|
|
|
-// info!("Mexc:设置持仓模式成功!{:?}", ok);
|
|
|
-// }
|
|
|
-// Err(error) => {
|
|
|
-// error!("Mexc:设置持仓模式失败!mode_result={}", error)
|
|
|
-// }
|
|
|
-// }
|
|
|
-// // 获取市场信息
|
|
|
-// mexc_swap.market = MexcSwap::get_market(&mut mexc_swap).await.unwrap_or(mexc_swap.market);
|
|
|
-// return mexc_swap;
|
|
|
-// }
|
|
|
-// }
|
|
|
-//
|
|
|
-// #[async_trait]
|
|
|
-// impl Platform for MexcSwap {
|
|
|
-// // 克隆方法
|
|
|
-// fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
|
|
|
-// // 获取交易所模式
|
|
|
-// fn get_self_exchange(&self) -> ExchangeEnum {
|
|
|
-// ExchangeEnum::MexcSwap
|
|
|
-// }
|
|
|
-// // 获取交易对
|
|
|
-// fn get_self_symbol(&self) -> String { self.symbol.clone() }
|
|
|
-// // 获取是否使用高速通道
|
|
|
-// fn get_self_is_colo(&self) -> bool {
|
|
|
-// self.is_colo
|
|
|
-// }
|
|
|
-// // 获取params信息
|
|
|
-// fn get_self_params(&self) -> BTreeMap<String, String> {
|
|
|
-// self.params.clone()
|
|
|
-// }
|
|
|
-// // 获取market信息
|
|
|
-// fn get_self_market(&self) -> Market { self.market.clone() }
|
|
|
-// // 获取请求时间
|
|
|
-// fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
|
|
|
-// // 获取请求平均时间
|
|
|
-// fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
|
|
|
-// // 获取请求最大时间
|
|
|
-// fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
|
|
|
-//
|
|
|
-// // 获取服务器时间
|
|
|
-// async fn get_server_time(&mut self) -> Result<String, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-// // 获取账号信息
|
|
|
-// async fn get_account(&mut self) -> Result<Account, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-//
|
|
|
-// async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-//
|
|
|
-// // 获取持仓信息
|
|
|
-// async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-// // 获取所有持仓
|
|
|
-// async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-// // 获取市场行情
|
|
|
-// async fn get_ticker(&mut self) -> Result<Ticker, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-//
|
|
|
-// async fn get_ticker_symbol(&mut self, _symbol: String) -> Result<Ticker, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-//
|
|
|
-// async fn get_market(&mut self) -> Result<Market, Error> {
|
|
|
-// let symbol_format = utils::format_symbol(self.symbol.clone(), "_");
|
|
|
-// let params = json!({});
|
|
|
-// let res_data = self.request.get_market(params).await;
|
|
|
-// if res_data.code == 200 {
|
|
|
-// let res_data_json = res_data.data.as_array().unwrap();
|
|
|
-// let market_info = res_data_json.iter().find(|item| item["symbol"].as_str().unwrap() == symbol_format);
|
|
|
-// match market_info {
|
|
|
-// None => {
|
|
|
-// error!("mexc_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
|
|
|
-// Err(Error::new(ErrorKind::Other, res_data.to_string()))
|
|
|
-// }
|
|
|
-// Some(value) => {
|
|
|
-// let symbol = value["symbol"].as_str().unwrap().to_string();
|
|
|
-// let base_asset = value["baseCoin"].as_str().unwrap().to_string();
|
|
|
-// let quote_asset = value["quoteCoin"].as_str().unwrap().to_string();
|
|
|
-// let tick_size = Decimal::from_i64(value["priceUnit"].as_i64().unwrap()).unwrap();
|
|
|
-// let amount_size = Decimal::from_i64(value["volUnit"].as_i64().unwrap()).unwrap();
|
|
|
-// let price_precision = Decimal::from_i64(value["priceScale"].as_i64().unwrap()).unwrap();
|
|
|
-// let amount_precision = Decimal::from_i64(value["volScale"].as_i64().unwrap()).unwrap();
|
|
|
-// let min_qty = Decimal::from_i64(value["minVol"].as_i64().unwrap()).unwrap();
|
|
|
-// let max_qty = Decimal::from_i64(value["maxVol"].as_i64().unwrap()).unwrap();
|
|
|
-// let ct_val = Decimal::from_i64(value["contractSize"].as_i64().unwrap()).unwrap();
|
|
|
-//
|
|
|
-// let result = Market {
|
|
|
-// symbol,
|
|
|
-// base_asset,
|
|
|
-// quote_asset,
|
|
|
-// tick_size,
|
|
|
-// amount_size,
|
|
|
-// price_precision,
|
|
|
-// amount_precision,
|
|
|
-// min_qty,
|
|
|
-// max_qty,
|
|
|
-// min_notional: min_qty,
|
|
|
-// max_notional: max_qty,
|
|
|
-// ct_val,
|
|
|
-// };
|
|
|
-// Ok(result)
|
|
|
-// }
|
|
|
-// }
|
|
|
-// } else {
|
|
|
-// Err(Error::new(ErrorKind::Other, res_data.to_string()))
|
|
|
-// }
|
|
|
-// }
|
|
|
-//
|
|
|
-// async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
|
|
|
-// let symbol_format = utils::format_symbol(symbol.clone(), "-");
|
|
|
-// let params = json!({
|
|
|
-// "symbol": symbol_format.clone()
|
|
|
-// });
|
|
|
-// let res_data = self.request.get_market(params).await;
|
|
|
-// if res_data.code == 200 {
|
|
|
-// let res_data_json = res_data.data.as_array().unwrap();
|
|
|
-// let market_info = res_data_json.iter().find(|item| item["symbol"].as_str().unwrap() == symbol_format);
|
|
|
-// match market_info {
|
|
|
-// None => {
|
|
|
-// error!("mexc_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
|
|
|
-// Err(Error::new(ErrorKind::Other, res_data.to_string()))
|
|
|
-// }
|
|
|
-// Some(value) => {
|
|
|
-// let symbol = value["symbol"].as_str().unwrap().to_string();
|
|
|
-// let base_asset = value["baseCoin"].as_str().unwrap().to_string();
|
|
|
-// let quote_asset = value["quoteCoin"].as_str().unwrap().to_string();
|
|
|
-// let tick_size = Decimal::from_i64(value["priceUnit"].as_i64().unwrap()).unwrap();
|
|
|
-// let amount_size = Decimal::from_i64(value["volUnit"].as_i64().unwrap()).unwrap();
|
|
|
-// let price_precision = Decimal::from_i64(value["priceScale"].as_i64().unwrap()).unwrap();
|
|
|
-// let amount_precision = Decimal::from_i64(value["volScale"].as_i64().unwrap()).unwrap();
|
|
|
-// let min_qty = Decimal::from_i64(value["minVol"].as_i64().unwrap()).unwrap();
|
|
|
-// let max_qty = Decimal::from_i64(value["maxVol"].as_i64().unwrap()).unwrap();
|
|
|
-// let ct_val = Decimal::from_i64(value["contractSize"].as_i64().unwrap()).unwrap();
|
|
|
-//
|
|
|
-// let result = Market {
|
|
|
-// symbol,
|
|
|
-// base_asset,
|
|
|
-// quote_asset,
|
|
|
-// tick_size,
|
|
|
-// amount_size,
|
|
|
-// price_precision,
|
|
|
-// amount_precision,
|
|
|
-// min_qty,
|
|
|
-// max_qty,
|
|
|
-// min_notional: min_qty,
|
|
|
-// max_notional: max_qty,
|
|
|
-// ct_val,
|
|
|
-// };
|
|
|
-// Ok(result)
|
|
|
-// }
|
|
|
-// }
|
|
|
-// } else {
|
|
|
-// Err(Error::new(ErrorKind::Other, res_data.to_string()))
|
|
|
-// }
|
|
|
-// }
|
|
|
-//
|
|
|
-// // 获取订单详情
|
|
|
-// async fn get_order_detail(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-// // 获取订单列表
|
|
|
-// async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-// // 下单接口
|
|
|
-// async fn take_order(&mut self, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-//
|
|
|
-// async fn take_order_symbol(&mut self, _symbol: String, _ct_val: Decimal, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-//
|
|
|
-// // 撤销订单
|
|
|
-// async fn cancel_order(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-// // 批量撤销订单
|
|
|
-// async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-//
|
|
|
-// async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-//
|
|
|
-// async fn take_stop_loss_order(&mut self, _stop_price: Decimal, _price: Decimal, _side: &str) -> Result<Value, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-//
|
|
|
-// async fn cancel_stop_loss_order(&mut self, _order_id: &str) -> Result<Value, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-//
|
|
|
-// // 设置持仓模式
|
|
|
-// async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-//
|
|
|
-// // 更新双持仓模式下杠杆
|
|
|
-// async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-//
|
|
|
-// async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "mexc:该交易所方法未实现".to_string())) }
|
|
|
-//
|
|
|
-// // 交易账户互转
|
|
|
-// async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> {
|
|
|
-// Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
-// }
|
|
|
-// }
|
|
|
+use std::collections::{BTreeMap};
|
|
|
+use std::io::{Error, ErrorKind};
|
|
|
+use tokio::sync::mpsc::Sender;
|
|
|
+use async_trait::async_trait;
|
|
|
+use rust_decimal::{Decimal};
|
|
|
+use serde_json::{json, Value};
|
|
|
+use tracing::{error, info};
|
|
|
+use crate::{Platform, ExchangeEnum, Account, Position, Ticker, Market, Order, utils, Record, OrderCommand};
|
|
|
+use exchanges::mexc_swap_rest::MexcSwapRest;
|
|
|
+use rust_decimal::prelude::FromPrimitive;
|
|
|
+use global::trace_stack::TraceStack;
|
|
|
+
|
|
|
+#[allow(dead_code)]
|
|
|
+#[derive(Clone)]
|
|
|
+pub struct MexcSwap {
|
|
|
+ exchange: ExchangeEnum,
|
|
|
+ symbol: String,
|
|
|
+ is_colo: bool,
|
|
|
+ params: BTreeMap<String, String>,
|
|
|
+ request: MexcSwapRest,
|
|
|
+ market: Market,
|
|
|
+ order_sender: Sender<Order>,
|
|
|
+ error_sender: Sender<Error>,
|
|
|
+}
|
|
|
+
|
|
|
+impl MexcSwap {
|
|
|
+ pub async fn new(symbol: String, is_colo: bool, params: BTreeMap<String, String>, order_sender: Sender<Order>, error_sender: Sender<Error>) -> MexcSwap {
|
|
|
+ let market = Market::new();
|
|
|
+ let mut mexc_swap = MexcSwap {
|
|
|
+ exchange: ExchangeEnum::MexcSwap,
|
|
|
+ symbol: symbol.to_uppercase(),
|
|
|
+ is_colo,
|
|
|
+ params: params.clone(),
|
|
|
+ request: MexcSwapRest::new(is_colo, params.clone()),
|
|
|
+ market,
|
|
|
+ order_sender,
|
|
|
+ error_sender,
|
|
|
+ };
|
|
|
+
|
|
|
+ // 修改持仓模式
|
|
|
+ let symbol_array: Vec<&str> = symbol.split("_").collect();
|
|
|
+ let mode_result = mexc_swap.set_dual_mode(symbol_array[1], true).await;
|
|
|
+ match mode_result {
|
|
|
+ Ok(ok) => {
|
|
|
+ info!("Mexc:设置持仓模式成功!{:?}", ok);
|
|
|
+ }
|
|
|
+ Err(error) => {
|
|
|
+ error!("Mexc:设置持仓模式失败!mode_result={}", error)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 获取市场信息
|
|
|
+ mexc_swap.market = MexcSwap::get_market(&mut mexc_swap).await.unwrap_or(mexc_swap.market);
|
|
|
+ return mexc_swap;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[async_trait]
|
|
|
+impl Platform for MexcSwap {
|
|
|
+ // 克隆方法
|
|
|
+ fn clone_box(&self) -> Box<dyn Platform + Send + Sync> { Box::new(self.clone()) }
|
|
|
+ // 获取交易所模式
|
|
|
+ fn get_self_exchange(&self) -> ExchangeEnum {
|
|
|
+ ExchangeEnum::MexcSwap
|
|
|
+ }
|
|
|
+ // 获取交易对
|
|
|
+ fn get_self_symbol(&self) -> String { self.symbol.clone() }
|
|
|
+ // 获取是否使用高速通道
|
|
|
+ fn get_self_is_colo(&self) -> bool {
|
|
|
+ self.is_colo
|
|
|
+ }
|
|
|
+ // 获取params信息
|
|
|
+ fn get_self_params(&self) -> BTreeMap<String, String> {
|
|
|
+ self.params.clone()
|
|
|
+ }
|
|
|
+ // 获取market信息
|
|
|
+ fn get_self_market(&self) -> Market { self.market.clone() }
|
|
|
+ // 获取请求时间
|
|
|
+ fn get_request_delays(&self) -> Vec<i64> { self.request.get_delays() }
|
|
|
+ // 获取请求平均时间
|
|
|
+ fn get_request_avg_delay(&self) -> Decimal { self.request.get_avg_delay() }
|
|
|
+ // 获取请求最大时间
|
|
|
+ fn get_request_max_delay(&self) -> i64 { self.request.get_max_delay() }
|
|
|
+
|
|
|
+ // 获取服务器时间
|
|
|
+ async fn get_server_time(&mut self) -> Result<String, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+ // 获取账号信息
|
|
|
+ async fn get_account(&mut self) -> Result<Account, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+
|
|
|
+ async fn get_spot_account(&mut self) -> Result<Vec<Account>, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取持仓信息
|
|
|
+ async fn get_position(&mut self) -> Result<Vec<Position>, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+ // 获取所有持仓
|
|
|
+ async fn get_positions(&mut self) -> Result<Vec<Position>, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+ // 获取市场行情
|
|
|
+ async fn get_ticker(&mut self) -> Result<Ticker, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+
|
|
|
+ async fn get_record(&mut self, _interval: String) -> Result<Vec<Record>, Error> {
|
|
|
+ todo!("还没做呢")
|
|
|
+ }
|
|
|
+
|
|
|
+ async fn get_ticker_symbol(&mut self, _symbol: String) -> Result<Ticker, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+
|
|
|
+ async fn get_market(&mut self) -> Result<Market, Error> {
|
|
|
+ let symbol_format = utils::format_symbol(self.symbol.clone(), "_");
|
|
|
+ let params = json!({});
|
|
|
+ let res_data = self.request.get_market(params).await;
|
|
|
+ if res_data.code == 200 {
|
|
|
+ let res_data_json = res_data.data.as_array().unwrap();
|
|
|
+ let market_info = res_data_json.iter().find(|item| item["symbol"].as_str().unwrap() == symbol_format);
|
|
|
+ match market_info {
|
|
|
+ None => {
|
|
|
+ error!("mexc_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
|
|
|
+ Err(Error::new(ErrorKind::Other, res_data.to_string()))
|
|
|
+ }
|
|
|
+ Some(value) => {
|
|
|
+ let symbol = value["symbol"].as_str().unwrap().to_string();
|
|
|
+ let base_asset = value["baseCoin"].as_str().unwrap().to_string();
|
|
|
+ let quote_asset = value["quoteCoin"].as_str().unwrap().to_string();
|
|
|
+ let tick_size = Decimal::from_i64(value["priceUnit"].as_i64().unwrap()).unwrap();
|
|
|
+ let amount_size = Decimal::from_i64(value["volUnit"].as_i64().unwrap()).unwrap();
|
|
|
+ let price_precision = Decimal::from_i64(value["priceScale"].as_i64().unwrap()).unwrap();
|
|
|
+ let amount_precision = Decimal::from_i64(value["volScale"].as_i64().unwrap()).unwrap();
|
|
|
+ let min_qty = Decimal::from_i64(value["minVol"].as_i64().unwrap()).unwrap();
|
|
|
+ let max_qty = Decimal::from_i64(value["maxVol"].as_i64().unwrap()).unwrap();
|
|
|
+ let multiplier = Decimal::from_i64(value["contractSize"].as_i64().unwrap()).unwrap();
|
|
|
+
|
|
|
+ let result = Market {
|
|
|
+ symbol,
|
|
|
+ base_asset,
|
|
|
+ quote_asset,
|
|
|
+ tick_size,
|
|
|
+ amount_size,
|
|
|
+ price_precision,
|
|
|
+ amount_precision,
|
|
|
+ min_qty,
|
|
|
+ max_qty,
|
|
|
+ min_notional: min_qty,
|
|
|
+ max_notional: max_qty,
|
|
|
+ multiplier,
|
|
|
+ };
|
|
|
+ Ok(result)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ Err(Error::new(ErrorKind::Other, res_data.to_string()))
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
|
|
|
+ let symbol_format = utils::format_symbol(symbol.clone(), "-");
|
|
|
+ let params = json!({
|
|
|
+ "symbol": symbol_format.clone()
|
|
|
+ });
|
|
|
+ let res_data = self.request.get_market(params).await;
|
|
|
+ if res_data.code == 200 {
|
|
|
+ let res_data_json = res_data.data.as_array().unwrap();
|
|
|
+ let market_info = res_data_json.iter().find(|item| item["symbol"].as_str().unwrap() == symbol_format);
|
|
|
+ match market_info {
|
|
|
+ None => {
|
|
|
+ error!("mexc_swap:获取Market信息错误!\nget_market:res_data={:?}", res_data);
|
|
|
+ Err(Error::new(ErrorKind::Other, res_data.to_string()))
|
|
|
+ }
|
|
|
+ Some(value) => {
|
|
|
+ let symbol = value["symbol"].as_str().unwrap().to_string();
|
|
|
+ let base_asset = value["baseCoin"].as_str().unwrap().to_string();
|
|
|
+ let quote_asset = value["quoteCoin"].as_str().unwrap().to_string();
|
|
|
+ let tick_size = Decimal::from_i64(value["priceUnit"].as_i64().unwrap()).unwrap();
|
|
|
+ let amount_size = Decimal::from_i64(value["volUnit"].as_i64().unwrap()).unwrap();
|
|
|
+ let price_precision = Decimal::from_i64(value["priceScale"].as_i64().unwrap()).unwrap();
|
|
|
+ let amount_precision = Decimal::from_i64(value["volScale"].as_i64().unwrap()).unwrap();
|
|
|
+ let min_qty = Decimal::from_i64(value["minVol"].as_i64().unwrap()).unwrap();
|
|
|
+ let max_qty = Decimal::from_i64(value["maxVol"].as_i64().unwrap()).unwrap();
|
|
|
+ let multiplier = Decimal::from_i64(value["contractSize"].as_i64().unwrap()).unwrap();
|
|
|
+
|
|
|
+ let result = Market {
|
|
|
+ symbol,
|
|
|
+ base_asset,
|
|
|
+ quote_asset,
|
|
|
+ tick_size,
|
|
|
+ amount_size,
|
|
|
+ price_precision,
|
|
|
+ amount_precision,
|
|
|
+ min_qty,
|
|
|
+ max_qty,
|
|
|
+ min_notional: min_qty,
|
|
|
+ max_notional: max_qty,
|
|
|
+ multiplier,
|
|
|
+ };
|
|
|
+ Ok(result)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ Err(Error::new(ErrorKind::Other, res_data.to_string()))
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取订单详情
|
|
|
+ async fn get_order_detail(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+ // 获取订单列表
|
|
|
+ async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+ // 下单接口
|
|
|
+ async fn take_order(&mut self, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+
|
|
|
+ async fn take_order_symbol(&mut self, _symbol: String, _ct_val: Decimal, _custom_id: &str, _origin_side: &str, _price: Decimal, _amount: Decimal) -> Result<Order, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+
|
|
|
+ // 撤销订单
|
|
|
+ async fn cancel_order(&mut self, _order_id: &str, _custom_id: &str) -> Result<Order, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+ // 批量撤销订单
|
|
|
+ async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+
|
|
|
+ async fn cancel_orders_all(&mut self) -> Result<Vec<Order>, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+
|
|
|
+ async fn take_stop_loss_order(&mut self, _stop_price: Decimal, _price: Decimal, _side: &str) -> Result<Value, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+
|
|
|
+ async fn cancel_stop_loss_order(&mut self, _order_id: &str) -> Result<Value, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置持仓模式
|
|
|
+ async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新双持仓模式下杠杆
|
|
|
+ async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+
|
|
|
+ async fn set_auto_deposit_status(&mut self, _status: bool) -> Result<String, Error> { Err(Error::new(ErrorKind::NotFound, "mexc:该交易所方法未实现".to_string())) }
|
|
|
+
|
|
|
+ // 交易账户互转
|
|
|
+ async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> {
|
|
|
+ Err(Error::new(ErrorKind::NotFound, "mexc_swap:该交易所方法未实现".to_string()))
|
|
|
+ }
|
|
|
+
|
|
|
+ async fn command_order(&mut self, _order_command: &mut OrderCommand, _trace_stack: &TraceStack) {
|
|
|
+ todo!("还没做呢")
|
|
|
+ }
|
|
|
+}
|