|
|
@@ -1,73 +1,68 @@
|
|
|
-use std::cmp::max;
|
|
|
use std::collections::BTreeMap;
|
|
|
use std::sync::Arc;
|
|
|
use std::sync::atomic::AtomicBool;
|
|
|
+use std::time::Duration;
|
|
|
+use chrono::Utc;
|
|
|
|
|
|
+use futures_util::StreamExt;
|
|
|
+use serde_json::json;
|
|
|
use tokio::sync::Mutex;
|
|
|
-use tracing::{info, trace};
|
|
|
+use tokio_tungstenite::tungstenite::Message;
|
|
|
+use tracing::trace;
|
|
|
|
|
|
use exchanges::binance_swap_rest::BinanceSwapRest;
|
|
|
use exchanges::binance_swap_ws::{BinanceSwapLogin, BinanceSwapSubscribeType, BinanceSwapWs, BinanceSwapWsType};
|
|
|
-use exchanges::response_base::ResponseData;
|
|
|
-use global::trace_stack::TraceStack;
|
|
|
+use exchanges::socket_tool::AbstractWsMode;
|
|
|
|
|
|
const ACCESS_KEY: &str = "";
|
|
|
const SECRET_KEY: &str = "";
|
|
|
|
|
|
|
|
|
//ws-订阅公共频道信息
|
|
|
-#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
|
+#[tokio::test(flavor = "multi_thread", worker_threads = 5)]
|
|
|
async fn ws_custom_subscribe() {
|
|
|
global::log_utils::init_log_with_trace();
|
|
|
|
|
|
|
|
|
let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
|
|
|
- let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded::<ResponseData>();
|
|
|
+ let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
|
|
|
|
|
|
// let (write_tx, write_rx) = tokio::sync::broadcast::channel::<Message>(10);
|
|
|
// let (read_tx, mut read_rx) = tokio::sync::broadcast::channel::<ResponseData>(10);
|
|
|
+ let login_param = BinanceSwapLogin {
|
|
|
+ api_key: ACCESS_KEY.to_string(),
|
|
|
+ api_secret: SECRET_KEY.to_string(),
|
|
|
+ };
|
|
|
|
|
|
-
|
|
|
- let mut ws = get_ws(None);
|
|
|
+ let mut ws = get_ws(Option::from(login_param));
|
|
|
ws.set_symbols(vec!["BTC_USDT".to_string()]);
|
|
|
ws.set_subscribe(vec![
|
|
|
- BinanceSwapSubscribeType::PuBookTicker,
|
|
|
+ // BinanceSwapSubscribeType::PuBookTicker,
|
|
|
// BinanceSwapSubscribeType::PuAggTrade,
|
|
|
+ BinanceSwapSubscribeType::PuMarkPrice,
|
|
|
// BinanceSwapSubscribeType::PuDepth20levels100ms,
|
|
|
+
|
|
|
+ BinanceSwapSubscribeType::PrAccount,
|
|
|
]);
|
|
|
|
|
|
|
|
|
let write_tx_am = Arc::new(Mutex::new(write_tx));
|
|
|
- let is_shutdown_arc = Arc::new(AtomicBool::new(true));
|
|
|
+ let bool_v1 = Arc::new(AtomicBool::new(true));
|
|
|
|
|
|
//读取
|
|
|
- let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
|
|
|
+ let _bool_v1_clone = Arc::clone(&bool_v1);
|
|
|
let _tr = tokio::spawn(async move {
|
|
|
trace!("线程-数据读取-开启");
|
|
|
- let mut max_delay = 0i64;
|
|
|
loop {
|
|
|
- // 从通道中接收并丢弃所有的消息,直到通道为空
|
|
|
- while let Ok(Some(data)) = read_rx.try_next() {
|
|
|
- // 消息被忽略
|
|
|
- let mut trace_stack = TraceStack::new(0, Instant::now());
|
|
|
- trace_stack.on_before_unlock_core();
|
|
|
- trace_stack.on_after_network(data.time);
|
|
|
-
|
|
|
- let delay = trace_stack.before_unlock_core - trace_stack.after_network;
|
|
|
- max_delay = max(max_delay, delay);
|
|
|
- info!("{}us, max={}us", delay, max_delay);
|
|
|
-
|
|
|
- // 从通道中接收并丢弃所有的消息,直到通道为空
|
|
|
- while let Ok(Some(_)) = read_rx.try_next() {
|
|
|
- // 消息被忽略
|
|
|
- }
|
|
|
+ if let Some(data) = read_rx.next().await {
|
|
|
+ trace!("读取数据data:{:?}",data)
|
|
|
}
|
|
|
}
|
|
|
// trace!("线程-数据读取-结束");
|
|
|
});
|
|
|
|
|
|
//写数据
|
|
|
- // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
|
|
|
+ // let bool_v2_clone = Arc::clone(&bool_v1);
|
|
|
// let write_tx_clone = Arc::clone(&write_tx_am);
|
|
|
// let su = ws.get_subscription();
|
|
|
// let tw = tokio::spawn(async move {
|
|
|
@@ -90,7 +85,7 @@ async fn ws_custom_subscribe() {
|
|
|
|
|
|
let t1 = tokio::spawn(async move {
|
|
|
//链接
|
|
|
- let bool_v3_clone = Arc::clone(&is_shutdown_arc);
|
|
|
+ let bool_v3_clone = Arc::clone(&bool_v1);
|
|
|
ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
|
|
|
trace!("test 唯一线程结束--");
|
|
|
});
|
|
|
@@ -99,76 +94,6 @@ async fn ws_custom_subscribe() {
|
|
|
trace!("重启!");
|
|
|
trace!("参考交易所关闭");
|
|
|
return;
|
|
|
-
|
|
|
- //************************************
|
|
|
- //************************************
|
|
|
- //************************************
|
|
|
- //************************************
|
|
|
- //************************************
|
|
|
- //************************************
|
|
|
- //************************************
|
|
|
- //11 点31 分
|
|
|
-
|
|
|
- // let mut is_shutdown_arc = Arc::new(AtomicBool::new(true));
|
|
|
- // //创建读写通道
|
|
|
- // let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
|
|
|
- // let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
|
|
|
- // // 封装 write_tx 到 Arc 和 Mutex
|
|
|
- // let write_tx_am = Arc::new(Mutex::new(write_tx));
|
|
|
- //
|
|
|
- // //对象
|
|
|
- // let mut ws = get_ws(None);
|
|
|
- // // 币对
|
|
|
- // ws.set_symbols(vec!["BTC_USDT".to_string()]);
|
|
|
- // //订阅
|
|
|
- // ws.set_subscribe(vec![
|
|
|
- // BinanceSwapSubscribeType::PuBookTicker,
|
|
|
- // BinanceSwapSubscribeType::PuAggTrade,
|
|
|
- // BinanceSwapSubscribeType::PuDepth20levels100ms,
|
|
|
- // ]);
|
|
|
- //
|
|
|
- //
|
|
|
- // //模拟业务场景 开启链接
|
|
|
- // let is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
|
|
|
- // let write_tx_clone1 = Arc::clone(&write_tx_am);
|
|
|
- // let t1 = tokio::spawn(async move {
|
|
|
- // ws.ws_connect_async(is_shutdown_arc_clone, write_tx_clone1, write_rx, &read_tx).await.unwrap();
|
|
|
- // trace!("ws_connect_async 完成");
|
|
|
- // });
|
|
|
- //
|
|
|
- // //模拟业务场景 一直监听数据
|
|
|
- // let t2 = tokio::spawn(async move {
|
|
|
- // loop {
|
|
|
- // if let Some(data) = read_rx.next().await {
|
|
|
- // trace!("读取数据data:{:?}",data)
|
|
|
- // }
|
|
|
- // }
|
|
|
- // trace!("数据读取退出 完成");
|
|
|
- // });
|
|
|
- //
|
|
|
- //
|
|
|
- // //模拟用户主动写入数据
|
|
|
- // // let write_tx_clone2 = Arc::clone(&write_tx_am);
|
|
|
- // // let t3 = tokio::spawn(async move {
|
|
|
- // // //模拟心跳
|
|
|
- // // loop {
|
|
|
- // // tokio::time::sleep(Duration::from_millis(5000)).await;
|
|
|
- // // let mut write_tx_clone = write_tx_clone2.lock().unwrap();
|
|
|
- // // match write_tx_clone.unbounded_send(Message::Pong(Vec::from("pong"))) {
|
|
|
- // // Ok(_) => {
|
|
|
- // // trace!("发送心跳");
|
|
|
- // // continue;
|
|
|
- // // }
|
|
|
- // // Err(_) => {
|
|
|
- // // break;
|
|
|
- // // }
|
|
|
- // // }
|
|
|
- // // }
|
|
|
- // // trace!("主动推出 完成");
|
|
|
- // // });
|
|
|
- // // tokio::try_join!(y,y1,y2).unwrap();
|
|
|
- // tokio::try_join!(t1,t2).unwrap();
|
|
|
- // trace!("323123213");
|
|
|
}
|
|
|
|
|
|
//rest-获取服务器时间
|
|
|
@@ -201,6 +126,66 @@ async fn rest_get_account_test() {
|
|
|
trace!(?rep_data)
|
|
|
}
|
|
|
|
|
|
+//rest-调整开仓杠杆
|
|
|
+#[tokio::test]
|
|
|
+async fn rest_get_leverage_test() {
|
|
|
+ global::log_utils::init_log_with_trace();
|
|
|
+
|
|
|
+ let mut rest = get_rest();
|
|
|
+ let rep_data = rest.get_leverage("DOGEUSDT".to_string(),1).await;
|
|
|
+ trace!(?rep_data)
|
|
|
+}
|
|
|
+//rest-查询订单
|
|
|
+#[tokio::test]
|
|
|
+async fn rest_get_order_test() {
|
|
|
+ global::log_utils::init_log_with_trace();
|
|
|
+
|
|
|
+ let mut rest = get_rest();
|
|
|
+ let rep_data = rest.get_order("DOGEUSDT".to_string(),-1,"".to_string()).await;
|
|
|
+ trace!(?rep_data)
|
|
|
+}
|
|
|
+
|
|
|
+//rest-查看当前全部挂单
|
|
|
+#[tokio::test]
|
|
|
+async fn rest_get_open_orders_test() {
|
|
|
+ global::log_utils::init_log_with_trace();
|
|
|
+
|
|
|
+ let mut rest = get_rest();
|
|
|
+ let rep_data = rest.get_open_orders("DOGEUSDT".to_string()).await;
|
|
|
+ trace!(?rep_data)
|
|
|
+}
|
|
|
+
|
|
|
+//rest-查询所有订单(包括历史订单)
|
|
|
+#[tokio::test]
|
|
|
+async fn rest_get_all_orders_test() {
|
|
|
+ global::log_utils::init_log_with_trace();
|
|
|
+
|
|
|
+ let mut rest = get_rest();
|
|
|
+ let rep_data = rest.get_all_orders("DOGEUSDT".to_string(),100,0,0).await;
|
|
|
+ trace!(?rep_data)
|
|
|
+}
|
|
|
+
|
|
|
+//rest-当前最优挂单
|
|
|
+#[tokio::test]
|
|
|
+async fn rest_get_book_ticker_test() {
|
|
|
+ global::log_utils::init_log_with_trace();
|
|
|
+
|
|
|
+ let mut rest = get_rest();
|
|
|
+ let rep_data = rest.get_book_ticker("DOGEUSDT".to_string()).await;
|
|
|
+ trace!(?rep_data)
|
|
|
+}
|
|
|
+
|
|
|
+//rest-用户持仓风险V2
|
|
|
+#[tokio::test]
|
|
|
+async fn rest_get_position_risk_test() {
|
|
|
+ global::log_utils::init_log_with_trace();
|
|
|
+
|
|
|
+ let mut rest = get_rest();
|
|
|
+ let rep_data = rest.get_position_risk("DOGEUSDT".to_string()).await;
|
|
|
+ trace!(?rep_data)
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
|
|
|
//rest-根据币对 撤销全部订单
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
|
@@ -228,6 +213,48 @@ async fn rest_get_user_trades_test() {
|
|
|
trace!(?rep_data)
|
|
|
}
|
|
|
|
|
|
+//rest-生成 listenKey
|
|
|
+#[tokio::test]
|
|
|
+async fn rest_get_listenKey_test() {
|
|
|
+ global::log_utils::init_log_with_trace();
|
|
|
+
|
|
|
+ let mut rest = get_rest();
|
|
|
+ let rep_data = rest.get_listen_key().await;
|
|
|
+ trace!(?rep_data)
|
|
|
+}
|
|
|
+
|
|
|
+//杠杆设置
|
|
|
+#[tokio::test]
|
|
|
+async fn rest_change_pos_side_test() {
|
|
|
+ global::log_utils::init_log_with_trace();
|
|
|
+
|
|
|
+ let mut rest = get_rest();
|
|
|
+ let rep_data = rest.change_pos_side(true).await;
|
|
|
+ trace!(?rep_data)
|
|
|
+}
|
|
|
+
|
|
|
+//下单
|
|
|
+#[tokio::test]
|
|
|
+async fn rest_swap_order_test() {
|
|
|
+ global::log_utils::init_log_with_trace();
|
|
|
+
|
|
|
+ let mut rest = get_rest();
|
|
|
+ let timestamp = Utc::now().timestamp_millis() / 1000;
|
|
|
+ let timestamp_600 = (timestamp + 700);
|
|
|
+ trace!("{:?}-==={:?}---{:?}--",timestamp,timestamp_600,(timestamp_600 > (timestamp + 600)));
|
|
|
+ let json_str = json!({
|
|
|
+ "symbol":"XRPUSDT",
|
|
|
+ "side":"BUY",
|
|
|
+ "type":"LIMIT",
|
|
|
+ "quantity":"10",
|
|
|
+ "price":"0.59",
|
|
|
+ "timeInForce":"GTC",
|
|
|
+ "goodTillDate":timestamp_600,
|
|
|
+ });
|
|
|
+ let rep_data = rest.swap_order(json_str).await;
|
|
|
+ trace!(?rep_data)
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
fn get_ws(btree_map: Option<BinanceSwapLogin>) -> BinanceSwapWs {
|
|
|
let binance_ws = BinanceSwapWs::new(false,
|