|
|
@@ -0,0 +1,214 @@
|
|
|
+use std::collections::BTreeMap;
|
|
|
+use std::fs::File;
|
|
|
+use std::io::BufReader;
|
|
|
+use std::str::FromStr;
|
|
|
+use chrono::NaiveDateTime;
|
|
|
+use rust_decimal::Decimal;
|
|
|
+use tracing::{error, info};
|
|
|
+use crate::swap_bybit::bybit_swap_rest_utils::BybitSwapRest;
|
|
|
+use crate::swap_gate::gate_swap_rest_utils::GateSwapRest;
|
|
|
+use crate::utils::utils;
|
|
|
+use crate::utils::utils::BalanceConfigInfo;
|
|
|
+
|
|
|
+pub async fn export_balance(config_info: BalanceConfigInfo) {
|
|
|
+ let config_info_clone = config_info.clone();
|
|
|
+ let start_time = NaiveDateTime::parse_from_str(&config_info.range_time[0].clone(), "%Y-%m-%d %H:%M:%S").unwrap().timestamp() - 8 * 3600;
|
|
|
+ let end_time = NaiveDateTime::parse_from_str(&config_info.range_time[1].clone(), "%Y-%m-%d %H:%M:%S").unwrap().timestamp() - 8 * 3600;
|
|
|
+ let count_start_time = NaiveDateTime::parse_from_str(&config_info.count_range_time[0].clone(), "%Y-%m-%d %H:%M:%S").unwrap().timestamp() - 8 * 3600;
|
|
|
+ let count_end_time = NaiveDateTime::parse_from_str(&config_info.count_range_time[1].clone(), "%Y-%m-%d %H:%M:%S").unwrap().timestamp() - 8 * 3600;
|
|
|
+
|
|
|
+ //获取不同账号的数据
|
|
|
+ let mut all_account_balance_info: BTreeMap<String, Vec<Vec<String>>> = BTreeMap::new();
|
|
|
+ let mut account_name_list: Vec<String> = vec![];
|
|
|
+ if config_info_clone.account_list.len() == 0 {
|
|
|
+ info!("没有账号信息");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ let mut data: serde_json::Value = utils::get_json_file("./config_history_balance.json");
|
|
|
+
|
|
|
+ for exchange in config_info.exchanges.clone() {
|
|
|
+ let exchange_up = exchange.to_uppercase();
|
|
|
+ match exchange_up.as_str() {
|
|
|
+ "GATE" => {
|
|
|
+ for account in config_info_clone.account_list.clone() {
|
|
|
+ let mut account_info: BTreeMap<String, String> = BTreeMap::new();
|
|
|
+ account_info.insert("account_name".to_string(), account[0].clone());
|
|
|
+ account_info.insert("access_key".to_string(), account[1].clone());
|
|
|
+ account_info.insert("secret_key".to_string(), account[2].clone());
|
|
|
+
|
|
|
+ let mut gate_exc = GateSwapRest::new(false, account_info.clone());
|
|
|
+ let data = gate_exc.account_book("usdt".to_string()).await;
|
|
|
+ // info!("请求完成{:?}",data.clone());
|
|
|
+ if data.code.as_str() == "200" {
|
|
|
+ let account_name = account_info.get("account_name").unwrap();
|
|
|
+ account_name_list.push(account_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<String>> = vec![];
|
|
|
+ let mut times = 0;
|
|
|
+
|
|
|
+ for item in array {
|
|
|
+ // info!("数据{:?}",item.clone().to_string());
|
|
|
+
|
|
|
+ let time = item["time"].as_i64().unwrap();//秒级
|
|
|
+ if time == times { continue; }
|
|
|
+ times = time;
|
|
|
+
|
|
|
+ let change = item["change"].as_str().unwrap();
|
|
|
+
|
|
|
+ let balance = item["balance"].as_str().unwrap();
|
|
|
+ let type_str = match item["type"].as_str().unwrap() {
|
|
|
+ "dnw" => { "transfer" }
|
|
|
+ "pnl" => { "profit" }
|
|
|
+ "fee" => {
|
|
|
+ "交易手续费";
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ "refr" => {
|
|
|
+ "推荐人返佣";
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ "fund" => {
|
|
|
+ "资金费用";
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ "point_dnw" => {
|
|
|
+ "点卡转入转出";
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ "point_fee" => {
|
|
|
+ "点卡交易手续费";
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ "point_refr" => {
|
|
|
+ "点卡推荐人返佣";
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ _ => {
|
|
|
+ "未知-变更类型";
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ 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<String> = vec![];
|
|
|
+ name_data_array.push(time.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());
|
|
|
+
|
|
|
+ name_data_all.push(name_data_array.clone());
|
|
|
+ }
|
|
|
+ all_account_balance_info.insert(account_name.clone(), name_data_all.clone());
|
|
|
+ } else {
|
|
|
+ info!("不是数组 检查数据");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // break;
|
|
|
+ };
|
|
|
+ }
|
|
|
+ _ => {
|
|
|
+ error!("交易所输入错误!");
|
|
|
+ panic!("交易所输入错误!")
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ // 根据账户变动填充
|
|
|
+ let mut count_time_list = vec![];
|
|
|
+ for (_account_name, balance_info) in all_account_balance_info.clone() {
|
|
|
+ for value in balance_info {
|
|
|
+ let time = value[0].clone().parse::<i64>().unwrap();
|
|
|
+ if !count_time_list.contains(&time) && time > count_start_time && time < count_end_time {
|
|
|
+ count_time_list.push(time)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ count_time_list.sort_by(|a, b| a.cmp(&b));
|
|
|
+ count_time_list.insert(0, count_start_time);
|
|
|
+ count_time_list.push(count_end_time);
|
|
|
+ let count_balance_info = supply_balance(all_account_balance_info.clone(), count_time_list.clone());
|
|
|
+ let mut new_data: BTreeMap<String, Vec<Vec<String>>> = BTreeMap::new();
|
|
|
+
|
|
|
+ for entry in count_balance_info {
|
|
|
+ let key = entry[0].clone();
|
|
|
+ let value = new_data.entry(key).or_insert(Vec::new());
|
|
|
+ value.push(entry.clone());
|
|
|
+ }
|
|
|
+ println!("--------------------");
|
|
|
+ println!("{:?}", new_data);
|
|
|
+ // let statistic_result = statistic_balance(count_balance_info.clone(), count_start_time.clone(), count_end_time.clone(), config_info.clone());
|
|
|
+
|
|
|
+ data["balance_list"] = serde_json::to_string(&all_account_balance_info).unwrap().parse().unwrap();
|
|
|
+ utils::set_json_file("./config_history_balance.json", serde_json::to_string(&data).unwrap());
|
|
|
+ // 打印解析后的数据
|
|
|
+ // println!("{:?}", data);
|
|
|
+ if data["last_time"] == 0 {}
|
|
|
+}
|
|
|
+
|
|
|
+pub fn supply_balance(source_balance_info: BTreeMap<String, Vec<Vec<String>>>, time_slicer: Vec<i64>) -> Vec<Vec<String>> {
|
|
|
+ let mut balance_info_list: Vec<Vec<String>> = vec![];
|
|
|
+ for time in time_slicer.clone() {
|
|
|
+ // 根据时间片去拿数据 ,如果有添加没有,手动添加
|
|
|
+ let mut total_price = Decimal::ZERO;
|
|
|
+ for (key, value) in source_balance_info.clone() {
|
|
|
+ let mut balance_info = value.clone();
|
|
|
+ balance_info.sort_by(|a, b| a[0].cmp(&b[0]));
|
|
|
+
|
|
|
+ let mut new_info: Option<Vec<String>> = None;
|
|
|
+ for mut info in balance_info.clone() {
|
|
|
+ let info_time = info[0].parse::<i64>().unwrap();
|
|
|
+ if info_time == time {
|
|
|
+ match new_info {
|
|
|
+ None => {
|
|
|
+ info.insert(0, key.clone());
|
|
|
+ new_info = Option::from(info);//记录当前实际
|
|
|
+ }
|
|
|
+ Some(ref value) => {
|
|
|
+ if value[1] < info[1] {
|
|
|
+ info.insert(0, key.clone());
|
|
|
+ new_info = Option::from(info);//记录当前实际
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ match new_info {
|
|
|
+ None => {
|
|
|
+ let balance_info_filter: Vec<Vec<String>> = balance_info.iter().filter(|item| {
|
|
|
+ item[0].parse::<i64>().unwrap() < time
|
|
|
+ }).cloned().collect();
|
|
|
+
|
|
|
+ let mut last_balance_info = if balance_info_filter.len() == 0 {
|
|
|
+ balance_info[0].clone()
|
|
|
+ } else {
|
|
|
+ balance_info_filter[balance_info_filter.len() - 1].clone()
|
|
|
+ };
|
|
|
+ last_balance_info.insert(0, key.clone());
|
|
|
+ total_price += Decimal::from_str(&last_balance_info[4]).unwrap();
|
|
|
+ balance_info_list.push(last_balance_info);
|
|
|
+ }
|
|
|
+ Some(ref info) => {
|
|
|
+ total_price += Decimal::from_str(&info[4]).unwrap();
|
|
|
+ balance_info_list.push(info.clone());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let sum_row: Vec<String> = vec!["total_balance".to_string(), time.to_string(), "".to_string(), "0".to_string(), total_price.round_dp(2).to_string(), "".to_string(), "".to_string(), "".to_string()];
|
|
|
+ balance_info_list.push(sum_row.clone());
|
|
|
+ };
|
|
|
+ balance_info_list
|
|
|
+}
|