use std::collections::{BTreeMap, HashSet}; use chrono::{DateTime, FixedOffset, NaiveDateTime, TimeZone, Utc}; use tracing::{trace}; use exchanges::gate_swap_rest::GateSwapRest; use exchanges::xlsx_utils::creation_xlsx; //ws-订阅公共频道信息 #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn test_gate_creation_xlsx() { global::log_utils::init_log_with_trace(); //获取不同账号的数据 let mut acc_array: Vec> = vec![]; let mut acc_all_data: BTreeMap>> = BTreeMap::new(); let mut acc_all_data_clone: BTreeMap>> = BTreeMap::new(); let mut data_array_all: Vec> = vec![]; let mut time_all: Vec = vec![]; loop { let mut gate60: BTreeMap = BTreeMap::new(); gate60.insert("acc_name".to_string(), String::from("gate60")); gate60.insert("access_key".to_string(), String::from("61e3a1b12c44c8ccfce1f32782b9922f")); gate60.insert("secret_key".to_string(), String::from("f3f533fa685cbae44b3017f73b71e90eaa9aa8d4922a39426744721e4824a527")); acc_array.push(gate60); let mut gate59: BTreeMap = BTreeMap::new(); gate59.insert("acc_name".to_string(), String::from("gate59")); gate59.insert("access_key".to_string(), String::from("c691d4fcc5a5a98af459f993a3a0c653")); gate59.insert("secret_key".to_string(), String::from("05e7f8640bffeacc146b6f9f08512955d00d89bbdb051c9427f31adf96adeb2f")); acc_array.push(gate59); let mut gate58: BTreeMap = BTreeMap::new(); gate58.insert("acc_name".to_string(), String::from("gate58")); gate58.insert("access_key".to_string(), String::from("dfdc30687ac71daefa2fb39c706b8afa")); gate58.insert("secret_key".to_string(), String::from("31e8999f85d38f5dd174f8919d9a1611c24d4e35b4d6319d6b160005871bf8b6")); acc_array.push(gate58); let mut gate57: BTreeMap = BTreeMap::new(); gate57.insert("acc_name".to_string(), String::from("gate57")); gate57.insert("access_key".to_string(), String::from("ba11ea511f343763db7c92c685f20c12")); gate57.insert("secret_key".to_string(), String::from("272d1d38ac4f0af3e6ed96e6a9a2c59dd905c3d7ad730507008604bba14edb3d")); acc_array.push(gate57); let mut gate56: BTreeMap = BTreeMap::new(); gate56.insert("acc_name".to_string(), String::from("gate56")); gate56.insert("access_key".to_string(), String::from("72f0c351a83b04808baad625f6085599")); gate56.insert("secret_key".to_string(), String::from("8a8d482bcc31f184cce350531cb40ca70564f9c466698d025e16d8943257dc0f")); acc_array.push(gate56); let mut gate55: BTreeMap = BTreeMap::new(); gate55.insert("acc_name".to_string(), String::from("gate55")); gate55.insert("access_key".to_string(), String::from("036408d5cbd8ddf1c6e0baab61ee641a")); gate55.insert("secret_key".to_string(), String::from("940414a37711e59848011e99e223fa11b0e69f8badd35347301e3f8e41957a60")); acc_array.push(gate55); let mut gate54: BTreeMap = BTreeMap::new(); gate54.insert("acc_name".to_string(), String::from("gate54")); gate54.insert("access_key".to_string(), String::from("fbe564e8bd4efaa0c3c023ca8c057b36")); gate54.insert("secret_key".to_string(), String::from("0be3c0223fd021fdacacc03f183f467e988ceee6eb1b0e09ca96bb1eebd45f39")); acc_array.push(gate54); let mut gate53: BTreeMap = BTreeMap::new(); gate53.insert("acc_name".to_string(), String::from("gate53")); gate53.insert("access_key".to_string(), String::from("16d91ba0a3d79a2925d16ea01a615fa1")); gate53.insert("secret_key".to_string(), String::from("607b07cf240466656c00beb0c6fff252839467583fd3f8b14782eb007b3d99ce")); acc_array.push(gate53); let mut gate52: BTreeMap = BTreeMap::new(); gate52.insert("acc_name".to_string(), String::from("gate52")); gate52.insert("access_key".to_string(), String::from("31054006c457a80a027e961cf3e5e3a4")); gate52.insert("secret_key".to_string(), String::from("a43f8f5672b49bfcc304d0731100610de1c55e7d2b6c00199b267993f0b189d1")); acc_array.push(gate52); let mut gate51: BTreeMap = BTreeMap::new(); gate51.insert("acc_name".to_string(), String::from("gate51")); gate51.insert("access_key".to_string(), String::from("edcedefe7830dd5722c2c37704ae700f")); gate51.insert("secret_key".to_string(), String::from("41db86a8463ac7c66023a8505e5fddd3448e551a11a52141bf57ca8478e2149b")); acc_array.push(gate51); for acc in acc_array { let mut gate_exc = GateSwapRest::new(false, acc.clone()); let data = gate_exc.account_book("usdt".to_string()).await; // trace!("data???????:{:?}",data.clone()); if data.code.as_str() == "200" { let acc_name = acc.get("acc_name").clone(); //账号 let json_value: serde_json::Value = serde_json::from_str(&data.data).unwrap(); if let serde_json::Value::Array(array) = json_value { let mut name_data_all: Vec> = vec![]; let mut name_data_all_clone: Vec> = vec![]; for item in array { let time = item["time"].as_i64().unwrap();//秒级 // 使用秒构建一个DateTime对象 // let datetime: DateTime = Utc.timestamp(time, 0); //2023-12-10 00:00:00 if 1702051200 > time { continue; } time_all.push(time); let time_str = NaiveDateTime::from_timestamp_millis((time + 8 * 3600) * 1000).unwrap().format("%Y-%m-%d %H:%M:%S%.3f").to_string(); trace!("数据时间解析:{:?}---{:?}",time,time_str); let change = item["change"].as_str().unwrap(); let balance = item["balance"].as_str().unwrap(); let type_str = match item["type"].as_str().unwrap() { "dnw" => { "转入转出" } "pnl" => { "减仓盈亏" } "fee" => { "交易手续费" } "refr" => { "推荐人返佣" } "fund" => { "资金费用" } "point_dnw" => { "点卡转入转出" } "point_fee" => { "点卡交易手续费" } "point_refr" => { "点卡推荐人返佣" } _ => { "未知-变更类型" } }; let text = item["text"].as_str().unwrap(); let contract = item["contract"].as_str().unwrap(); let trade_id = item["trade_id"].as_str().unwrap(); let mut name_data_array: Vec = vec![]; name_data_array.push(time_str.to_string()); name_data_array.push(trade_id.to_string()); name_data_array.push(change.to_string()); name_data_array.push(balance.to_string()); name_data_array.push(type_str.to_string()); name_data_array.push(contract.to_string()); name_data_array.push(text.to_string()); let mut name_data_array_clone: Vec = vec![]; name_data_array_clone.push(time.to_string()); name_data_array_clone.push(trade_id.to_string()); name_data_array_clone.push(change.to_string()); name_data_array_clone.push(balance.to_string()); name_data_array_clone.push(type_str.to_string()); name_data_array_clone.push(contract.to_string()); name_data_array_clone.push(text.to_string()); name_data_all.push(name_data_array.clone()); name_data_all_clone.push(name_data_array_clone.clone()); let mut cp = name_data_array.clone(); cp.push(acc_name.clone().unwrap().to_string()); data_array_all.push(cp); } acc_all_data.insert(acc_name.clone().unwrap().to_string(), name_data_all.clone()); acc_all_data_clone.insert(acc_name.clone().unwrap().to_string(), name_data_all_clone.clone()); } else { trace!("不是数组 检查数据"); } } // break; } break;//这里是为了 代码收纳,用了loop来放置代码 } trace!("数据如下:{:?}",acc_all_data); //汇总 //1. 生成时间片 let mut unique = HashSet::new(); time_all.retain(|e| unique.insert(*e)); trace!("时间片:{:?}",time_all); //2. 根据时间片 去求每个时间片的 总余额, let mut sum_data_array_all: Vec> = vec![]; for time in time_all.clone() { let mut sum_data_array: Vec = vec![]; let mut sum_balance: f64 = 0 as f64; for (key, value) in acc_all_data_clone.clone() { let acc_key = key; trace!("读取value:{:?}",value); let filter_arrya: Vec> = value.clone().into_iter().filter(|s| { trace!("读取time:{:?}",s); let time_v = s[0].clone(); time_v < (time - 1).to_string() }).collect(); let balance: f64 = if filter_arrya.len() > 0 { let row = filter_arrya[filter_arrya.len() - 1].clone(); trace!("读取balance:{:?}",row); let balance_clone = row[3].clone(); balance_clone.parse::().unwrap() } else { 0 as f64 }; sum_balance = balance + sum_balance; } // 使用秒构建一个DateTime对象 let time_str = NaiveDateTime::from_timestamp_millis((time + 8 * 3600) * 1000).unwrap().format("%Y-%m-%d %H:%M:%S%.3f").to_string(); sum_data_array.push(time_str.to_string()); sum_data_array.push("".to_string()); sum_data_array.push("".to_string()); sum_data_array.push(sum_balance.to_string()); sum_data_array.push("".to_string()); sum_data_array.push("".to_string()); sum_data_array.push("".to_string()); sum_data_array_all.push(sum_data_array); } if sum_data_array_all.len() > 0 { acc_all_data.insert("total".to_string(), sum_data_array_all); } if data_array_all.len() > 0{ acc_all_data.insert("gather".to_string(), data_array_all); } //数据组装. let noe_row_name = vec!["时间", "成交Id", "变更金额", "变更后余额", "变更类型", "合约标识", "注释"]; //创建表格 //提示。涉及到 需要转换的数据,请提前自行转换,工具只负责写入生成 // after - 之后的,时间戳> after 才是有效数据 match creation_xlsx(&noe_row_name, &acc_all_data, "okx".to_string(), ) { Ok(d) => { trace!("完成"); } Err(z) => { eprint!("{:?}", z); trace!("失败"); } } }