coinex_swap_test.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. use std::collections::BTreeMap;
  2. use std::str::FromStr;
  3. use std::sync::Arc;
  4. use std::sync::atomic::AtomicBool;
  5. use rust_decimal::Decimal;
  6. use serde_json::Value;
  7. use tokio::sync::Mutex;
  8. use tracing::{error, info, trace};
  9. use exchanges::coinex_swap_rest::CoinexSwapRest;
  10. use exchanges::coinex_swap_ws::{CoinexSwapLogin, CoinexSwapSubscribeType, CoinexSwapWs};
  11. use exchanges::response_base::ResponseData;
  12. use global::log_utils::{init_log_with_info, init_log_with_trace};
  13. const ACCESS_KEY: &str = "";
  14. const SECRET_KEY: &str = "";
  15. //ws-订阅公共频道信息
  16. #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
  17. async fn ws_custom_subscribe() {
  18. global::log_utils::init_log_with_trace();
  19. let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
  20. let (_read_tx, mut read_rx) = futures_channel::mpsc::unbounded::<ResponseData>();
  21. // let (write_tx, write_rx) = tokio::sync::broadcast::channel::<Message>(10);
  22. // let (read_tx, mut read_rx) = tokio::sync::broadcast::channel::<ResponseData>(10);
  23. let write_tx_am = Arc::new(Mutex::new(write_tx));
  24. let is_shutdown_arc = Arc::new(AtomicBool::new(true));
  25. //读取
  26. let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
  27. let _tr = tokio::spawn(async move {
  28. trace!("线程-数据读取-开启");
  29. loop {
  30. // 从通道中接收并丢弃所有的消息,直到通道为空
  31. while let Ok(Some(_data)) = read_rx.try_next() {
  32. // 从通道中接收并丢弃所有的消息,直到通道为空
  33. while let Ok(Some(_)) = read_rx.try_next() {
  34. // 消息被忽略
  35. }
  36. }
  37. }
  38. // trace!("线程-数据读取-结束");
  39. });
  40. //写数据
  41. // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
  42. // let write_tx_clone = Arc::clone(&write_tx_am);
  43. // let su = ws.get_subscription();
  44. // let tw = tokio::spawn(async move {
  45. // trace!("线程-数据写入-开始");
  46. // loop {
  47. // tokio::time::sleep(Duration::from_millis(20 * 1000)).await;
  48. // // let close_frame = CloseFrame {
  49. // // code: CloseCode::Normal,
  50. // // reason: Cow::Borrowed("Bye bye"),
  51. // // };
  52. // // let message = Message::Close(Some(close_frame));
  53. //
  54. //
  55. // let message = Message::Text(su.clone());
  56. // AbstractWsMode::send_subscribe(write_tx_clone.clone(), message.clone()).await;
  57. // trace!("发送指令成功");
  58. // }
  59. // trace!("线程-数据写入-结束");
  60. // });
  61. let fun = move |data: ResponseData| {
  62. async move {
  63. println!("{:?}", data);
  64. }
  65. };
  66. let param = CoinexSwapLogin {
  67. api_key: ACCESS_KEY.to_string(),
  68. secret: SECRET_KEY.to_string(),
  69. };
  70. let t1 = tokio::spawn(async move {
  71. let mut ws = get_ws(Option::from(param));
  72. ws.set_symbols(vec!["FTM_USDT".to_string()]);
  73. ws.set_subscribe(vec![
  74. // CoinexSwapSubscribeType::PuFuturesDepth,
  75. CoinexSwapSubscribeType::PrFuturesOrders
  76. ]);
  77. //链接
  78. let bool_v3_clone = Arc::clone(&is_shutdown_arc);
  79. ws.ws_connect_async(bool_v3_clone, fun, &write_tx_am, write_rx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
  80. trace!("test 唯一线程结束--");
  81. });
  82. tokio::try_join!(t1).unwrap();
  83. trace!("当此结束");
  84. trace!("重启!");
  85. trace!("参考交易所关闭");
  86. return;
  87. }
  88. fn get_ws(btree_map: Option<CoinexSwapLogin>) -> CoinexSwapWs {
  89. let coinex_ws = CoinexSwapWs::new(btree_map);
  90. coinex_ws
  91. }
  92. #[tokio::test]
  93. async fn rest_account_book_test() {
  94. let mut ret = get_rest();
  95. let req_data = ret.get_account().await;
  96. let res_data_json: Value = req_data.data;
  97. println!("coinex--查询合约账户--{:?}", res_data_json);
  98. let result = res_data_json.as_array().unwrap().get(0).unwrap();
  99. println!("coinex--查询合约账户--{:?}", result["ccy"]);
  100. }
  101. #[tokio::test]
  102. async fn rest_spot_account_book_test() {
  103. let mut ret = get_rest();
  104. let req_data = ret.get_spot_account().await;
  105. let res_data_json: Value = req_data.data;
  106. println!("coinex--查询现货账户--{:?}", res_data_json);
  107. let result = res_data_json.as_array().unwrap().get(0).unwrap();
  108. println!("coinex--查询现货账户--{:?}", result["ccy"]);
  109. }
  110. #[tokio::test]
  111. async fn rest_position_test() {
  112. let mut ret = get_rest();
  113. let req_data = ret.get_position("BOMEUSDT".to_string()).await;
  114. println!("coinex--查询仓位--{:?}", req_data);
  115. }
  116. #[tokio::test]
  117. async fn rest_positions_test() {
  118. let mut ret = get_rest();
  119. let req_data = ret.get_user_position().await;
  120. println!("coinex--查询用户所有仓位--{:?}", req_data);
  121. }
  122. #[tokio::test]
  123. async fn rest_ticker_test() {
  124. let mut ret = get_rest();
  125. let req_data = ret.get_ticker("BOMEUSDT".to_string()).await;
  126. println!("coinex--查询ticker--{:?}", req_data);
  127. }
  128. #[tokio::test]
  129. async fn rest_market_test() {
  130. let mut ret = get_rest();
  131. let req_data = ret.get_market_details("BOMEUSDT".to_string()).await;
  132. println!("coinex--查询market--{:?}", req_data);
  133. }
  134. #[tokio::test]
  135. async fn rest_market_list_test() {
  136. let symbol = "DOGEUSDT".to_string();
  137. let price = Decimal::from_str("0.15").unwrap();
  138. let custom_id = "436265461";
  139. let order_side;
  140. let position_side;
  141. let amount = Decimal::from_str("1769").unwrap();
  142. let ct_val = Decimal::from_str("1").unwrap();
  143. let origin_side = "kk";
  144. let size = (amount / ct_val).floor();
  145. match origin_side {
  146. "kd" => {
  147. position_side = "long";
  148. order_side = "buy";
  149. }
  150. "pd" => {
  151. position_side = "long";
  152. order_side = "sell";
  153. }
  154. "kk" => {
  155. position_side = "short";
  156. order_side = "sell";
  157. }
  158. "pk" => {
  159. position_side = "short";
  160. order_side = "buy";
  161. }
  162. _ => {
  163. error!("下单参数错误");
  164. position_side = "error";
  165. order_side = "error";
  166. }
  167. };
  168. let mut ret = get_rest();
  169. let req_data = ret.order(symbol, position_side.to_string(), order_side.to_string(), size, price, custom_id.to_string()).await;
  170. println!("coinex--查询swap_order--{:?}", req_data);
  171. }
  172. #[tokio::test]
  173. async fn rest_cancel_order_test() {
  174. let mut ret = get_rest();
  175. let req_data = ret.cancel_order("DOGEUSDT".to_string(), "", "436265461").await;
  176. println!("coinex--查询cancel_order--{} {:?}", req_data.data.is_null(), req_data);
  177. }
  178. #[tokio::test]
  179. async fn rest_cancel_all_order_test() {
  180. let mut ret = get_rest();
  181. let _ct_val = Decimal::ONE;
  182. let orders_res_data = ret.get_pending_orders().await;
  183. let mut result = vec![];
  184. if orders_res_data.code == 200 {
  185. let orders_res_data_json = orders_res_data.data.as_array().unwrap();
  186. for order in orders_res_data_json {
  187. let cancel_res_data = ret.cancel_order_all(order["market"].as_str().unwrap().to_string()).await;
  188. if cancel_res_data.code == 200 {
  189. result.push(order.clone())
  190. }
  191. }
  192. }
  193. println!("coinex--查询cancel_all_order--{:?}", result);
  194. }
  195. #[tokio::test]
  196. async fn rest_finish_order_list_test() {
  197. let mut ret = get_rest();
  198. let req_data = ret.get_finished_orders().await;
  199. println!("coinex--查询finish_order--{:?}", req_data);
  200. }
  201. #[tokio::test]
  202. async fn rest_pending_order_list_test() {
  203. let mut ret = get_rest();
  204. let req_data = ret.get_pending_orders().await;
  205. println!("coinex--查询pending_order--{:?}", req_data);
  206. }
  207. #[tokio::test]
  208. async fn rest_order_status_test() {
  209. let mut ret = get_rest();
  210. let req_data = ret.get_order_details("136925916412".to_string(), "DOGEUSDT".to_string()).await;
  211. println!("coinex--查询pending_order--{:?}", req_data);
  212. }
  213. #[tokio::test]
  214. async fn rest_setting_dual_leverage_test() {
  215. let mut ret = get_rest();
  216. let req_data = ret.setting_dual_leverage("FTMUSDT".to_string(), 10).await;
  217. println!("coinex--查询setting_dual_leverage--{:?}", req_data);
  218. }
  219. #[tokio::test]
  220. async fn rest_time() {
  221. let mut ret = get_rest();
  222. let res_data = ret.get_server_time().await;
  223. let res_data_json: Value = res_data.data;
  224. let result = res_data_json["timestamp"].to_string();
  225. println!("coinex--time--{:?}", result);
  226. }
  227. #[tokio::test]
  228. async fn rest_account_get_test() {
  229. let mut ret = get_rest();
  230. let res_data = ret.account_get().await;
  231. let res_data_json: Value = res_data.data;
  232. if res_data_json.is_array() {
  233. let array = res_data_json.as_array().unwrap();
  234. for z in array {
  235. trace!("coinex--查看子账号列表--{:?}", z);
  236. }
  237. }
  238. }
  239. #[tokio::test]
  240. async fn rest_account_subs_api_test() {
  241. let mut ret = get_rest();
  242. let params = serde_json::json!({
  243. "sub_user_name":"2024050",
  244. "ip_whitelist":[],
  245. "trade_enabled":false,
  246. "remark":"",
  247. });
  248. let res_data = ret.account_subs_api(params).await;
  249. // let res_data_json: Value = res_data.data;
  250. // let result = res_data_json["timestamp"].to_string();
  251. println!("coinex--获取子账号的apikey--{:?}", res_data);
  252. }
  253. // 将主账号下的 子账号 都创建apikey
  254. #[tokio::test]
  255. async fn rest_account_get_and_api_test() {
  256. let mut ret = get_rest();
  257. let res_data = ret.account_get().await;
  258. let res_data_json: Value = res_data.data;
  259. if res_data_json.is_array() {
  260. let array = res_data_json.as_array().unwrap();
  261. for z in array {
  262. let sub_user_name = z["sub_user_name"].as_str().unwrap();
  263. info!("coinex--查看子账号列表--{:?}", z);
  264. // //每个账号创建apiKey
  265. // let params2 = serde_json::json!({
  266. // "sub_user_name":sub_user_name,
  267. // "ip_whitelist":[],
  268. // "trade_enabled":false,
  269. // "remark":"",
  270. // });
  271. // let res_data2 = ret.account_subs_api(params2).await;
  272. // // info!("coinex--创建成功响应--{:?}", res_data2);
  273. // let res_data_json2: Value = res_data2.data;
  274. // let api_id = res_data_json2["api_id"].as_i64().unwrap();
  275. // let access_id = res_data_json2["access_id"].as_str().unwrap();
  276. // let secret_key = res_data_json2["secret_key"].as_str().unwrap();
  277. // info!("sub_user_name:{:?} \tapi_id:{:?} \t access_id:{:?}\t secret_key:{:?}",sub_user_name,api_id,access_id,secret_key);
  278. }
  279. }
  280. }
  281. // 获取子账号 APIKEY 列表
  282. #[tokio::test]
  283. async fn rest_account_get_apikey_test() {
  284. let str = "api_id access_id secret_key";
  285. let mut ret = get_rest();
  286. let res_data = ret.account_get().await;
  287. let res_data_json: Value = res_data.data;
  288. if res_data_json.is_array() {
  289. let array = res_data_json.as_array().unwrap();
  290. for z in array {
  291. let sub_user_name = z["sub_user_name"].as_str().unwrap();
  292. info!("coinex--查看子账号列表--{:?}", sub_user_name);
  293. //每个账号创建apiKey
  294. let params = serde_json::json!({
  295. "sub_user_name":sub_user_name,
  296. });
  297. let res_data2 = ret.account_get_apikey(params).await;
  298. // trace!("coinex--获取子账号的apikey--{:?}", res_data2);
  299. let res_data_json2: Value = res_data2.data;
  300. if res_data_json2.is_array() {
  301. let array2 = res_data_json2.as_array().unwrap();
  302. for z2 in array2 {
  303. let api_id = z2["api_id"].as_i64().unwrap();
  304. let access_id = z2["access_id"].as_str().unwrap();
  305. info!("sub_user_name:{:?} \tapi_id:{:?} \t access_id:{:?}\t ",sub_user_name,api_id,access_id);
  306. //查询详情
  307. let params3 = serde_json::json!({
  308. "api_id":api_id
  309. });
  310. let res_data3 = ret.account_get_detail(params3).await;
  311. info!("coinex--详情--{:?}", res_data3.data);
  312. //编辑子账号 APIKEY
  313. // let params4 = serde_json::json!({
  314. // "sub_user_name":sub_user_name,
  315. // "api_id":api_id,
  316. // "trade_enabled":true
  317. // });
  318. // let res_data4 = ret.account_get_update(params4).await;
  319. // info!("coinex--编辑结果--{:?}", res_data4.data);
  320. //删除
  321. // let params2 = serde_json::json!({
  322. // "api_id":api_id
  323. // });
  324. // let res_data23 = ret.account_del_apikey(params2).await;
  325. // info!("coinex--删除结果--{:?}", res_data23);
  326. }
  327. }
  328. }
  329. }
  330. // info!("sub_user_name:{:?} \tapi_id:{:?} \t access_id:{:?}\t ",sub_user_name,api_id,access_id)
  331. }
  332. fn get_rest() -> CoinexSwapRest {
  333. // init_log_with_trace();
  334. init_log_with_info();
  335. let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
  336. btree_map.insert("access_key".to_string(), ACCESS_KEY.to_string());
  337. btree_map.insert("secret_key".to_string(), SECRET_KEY.to_string());
  338. let ba_exc = CoinexSwapRest::new(btree_map);
  339. ba_exc
  340. }