|
@@ -1,4 +1,3 @@
|
|
|
-use std::cmp::min;
|
|
|
|
|
use std::collections::{BTreeMap};
|
|
use std::collections::{BTreeMap};
|
|
|
use std::str::FromStr;
|
|
use std::str::FromStr;
|
|
|
use chrono::NaiveDateTime;
|
|
use chrono::NaiveDateTime;
|
|
@@ -6,6 +5,7 @@ use rust_decimal::Decimal;
|
|
|
use rust_decimal_macros::dec;
|
|
use rust_decimal_macros::dec;
|
|
|
use tracing::{error, info};
|
|
use tracing::{error, info};
|
|
|
use crate::{export_template};
|
|
use crate::{export_template};
|
|
|
|
|
+use crate::swap_bybit::bybit_swap_rest_utils::BybitSwapRest;
|
|
|
use crate::swap_gate::gate_swap_rest_utils::GateSwapRest;
|
|
use crate::swap_gate::gate_swap_rest_utils::GateSwapRest;
|
|
|
use crate::utils::utils::BalanceConfigInfo;
|
|
use crate::utils::utils::BalanceConfigInfo;
|
|
|
|
|
|
|
@@ -19,97 +19,195 @@ pub async fn export_balance(config_info: BalanceConfigInfo) {
|
|
|
//获取不同账号的数据
|
|
//获取不同账号的数据
|
|
|
let mut all_account_balance_info: BTreeMap<String, Vec<Vec<String>>> = BTreeMap::new();
|
|
let mut all_account_balance_info: BTreeMap<String, Vec<Vec<String>>> = BTreeMap::new();
|
|
|
let mut account_name_list: Vec<String> = vec![];
|
|
let mut account_name_list: Vec<String> = vec![];
|
|
|
- loop {
|
|
|
|
|
- if config_info_clone.account_list.len() == 0 {
|
|
|
|
|
- info!("没有账号信息");
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if config_info_clone.account_list.len() == 0 {
|
|
|
|
|
+ info!("没有账号信息");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ for exchange in config_info.exchanges.clone() {
|
|
|
|
|
+ let exchange_up = exchange.to_uppercase();
|
|
|
|
|
+ let exchange_result = 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());
|
|
|
|
|
|
|
|
- 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 {
|
|
|
|
|
- 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" => { "转入转出" }
|
|
|
|
|
- "pnl" => { "减仓盈亏" }
|
|
|
|
|
- "fee" => {
|
|
|
|
|
- "交易手续费";
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- "refr" => {
|
|
|
|
|
- "推荐人返佣";
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- "fund" => {
|
|
|
|
|
- "资金费用";
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- "point_dnw" => {
|
|
|
|
|
- "点卡转入转出";
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- "point_fee" => {
|
|
|
|
|
- "点卡交易手续费";
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- "point_refr" => {
|
|
|
|
|
- "点卡推荐人返佣";
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- _ => {
|
|
|
|
|
- "未知-变更类型";
|
|
|
|
|
- continue;
|
|
|
|
|
|
|
+ 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" => { "转入转出" }
|
|
|
|
|
+ "pnl" => { "减仓盈亏" }
|
|
|
|
|
+ "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;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ "BYBIT" => {
|
|
|
|
|
+ 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());
|
|
|
|
|
+ info!("账号:{:?}",account_info);
|
|
|
|
|
+
|
|
|
|
|
+ let mut gate_exc = BybitSwapRest::new(false, account_info.clone());
|
|
|
|
|
+ let data = gate_exc.get_account_transaction_log().await;
|
|
|
|
|
+ // let data = gate_exc.get_position_closed_pnl("BSVUSDT".to_string()).await;
|
|
|
|
|
+ // let data = gate_exc.get_account_wallet_fund_records(0, 0).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();
|
|
|
|
|
+ let ret_code = json_value.get("retCode").unwrap().as_i64().unwrap();
|
|
|
|
|
+ let ret_msg = json_value.get("retMsg").unwrap().as_str().unwrap();
|
|
|
|
|
+ if ret_code == 0 && ret_msg == "OK" {
|
|
|
|
|
+ let result = json_value.get("result").unwrap();
|
|
|
|
|
+ let list = result.get("list").unwrap();
|
|
|
|
|
+ if let serde_json::Value::Array(array) = list {
|
|
|
|
|
+ let mut name_data_all: Vec<Vec<String>> = vec![];
|
|
|
|
|
+
|
|
|
|
|
+ for item in array {
|
|
|
|
|
+ // info!("数据{:?}",item.clone().to_string());
|
|
|
|
|
+
|
|
|
|
|
+ let id = item.get("id").unwrap().as_str().unwrap();
|
|
|
|
|
+ let type_str = item.get("type").unwrap().as_str().unwrap();
|
|
|
|
|
+ let b_symbol = item.get("symbol").unwrap().as_str().unwrap();
|
|
|
|
|
+ let side = item.get("side").unwrap().as_str().unwrap();
|
|
|
|
|
+ let currency = item.get("currency").unwrap().as_str().unwrap();
|
|
|
|
|
+ let tradePrice = item.get("tradePrice").unwrap().as_str().unwrap();
|
|
|
|
|
+ let funding = item.get("funding").unwrap().as_str().unwrap();
|
|
|
|
|
+ let fee = item.get("fee").unwrap().as_str().unwrap();
|
|
|
|
|
+ let cashFlow = item.get("cashFlow").unwrap().as_str().unwrap();
|
|
|
|
|
+ let change = item.get("change").unwrap().as_str().unwrap();
|
|
|
|
|
+ let cashBalance = item.get("cashBalance").unwrap().as_str().unwrap();
|
|
|
|
|
+ let transactionTime = item.get("transactionTime").unwrap().as_str().unwrap();
|
|
|
|
|
+
|
|
|
|
|
+ let type_str = match type_str {
|
|
|
|
|
+ "TRADE" => { "交易" }
|
|
|
|
|
+ _ => {
|
|
|
|
|
+ "其他-变更类型";
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // info!("result 数据\
|
|
|
|
|
+ // transactionTime:{:?} id:{:?},symbol:{:?},side:{:?},currency:{:?},tradePrice:{:?},funding:{:?},fee:{:?},cashFlow:{:?},cashBalance:{:?},change:{:?}"
|
|
|
|
|
+ // ,transactionTime, id,b_symbol,side,currency,tradePrice,funding,fee,cashFlow,cashBalance,change);//change 變更 = cashFlow + funding - fee
|
|
|
|
|
+
|
|
|
|
|
+// "{\"bonusChange\":\"0\",\"cashBalance\":\"97.95598152\",\"cashFlow\":\"0\",\"category\":\"linear\",\"change\":\"-0.01119174\",\"currency\":\"USDT\",\"fee\":\"0.01119174
|
|
|
|
|
+// \",\"feeRate\":\"0.00014\",\"funding\":\"0\",\"id\":\"123105018_INJUSDT_618678386870\",\"orderId\":\"3d3da36b-c803-441a-bb0b-24fdef56d6f3\",\"orderLinkId\":\"t-459097906\",\"qty\":\"2\",\"side\":\"Buy\",\"size\":\"2\",\"symbol\"
|
|
|
|
|
+// :\"INJUSDT\",\"tradeId\":\"ed458708-3de4-5bc8-bc27-f6b4ba7a8921\",\"tradePrice\":\"39.9705\",\"transactionTime\":\"1703224750479\",\"type\":\"TRADE\"}"
|
|
|
|
|
+
|
|
|
|
|
+// "{\"balance\":\"49.051791949878\",\"change\":\"-0.0576\",\"contract\":\"OP_USDT\",\"text\":\"OP_USDT:376554197685\",\"time\":1702110912,\"trade_id\":\"16306596\",\"type
|
|
|
|
|
+// \":\"pnl\"}"
|
|
|
|
|
|
|
|
|
|
+ let time = transactionTime.parse::<i64>().unwrap() / 1000;
|
|
|
|
|
|
|
|
- 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(id.to_string());
|
|
|
|
|
+ name_data_array.push(change.to_string());
|
|
|
|
|
+ name_data_array.push(cashBalance.to_string());
|
|
|
|
|
+ name_data_array.push(type_str.to_string());
|
|
|
|
|
+ name_data_array.push("".to_string());
|
|
|
|
|
+ name_data_array.push("".to_string());
|
|
|
|
|
|
|
|
- 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());
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- name_data_all.push(name_data_array.clone());
|
|
|
|
|
|
|
+ all_account_balance_info.insert(account_name.clone(), name_data_all.clone());
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ info!("解析失败:{:?}",json_value);
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- all_account_balance_info.insert(account_name.clone(), name_data_all.clone());
|
|
|
|
|
- } else {
|
|
|
|
|
- info!("不是数组 检查数据");
|
|
|
|
|
|
|
+ // break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- // break;
|
|
|
|
|
- }
|
|
|
|
|
- break;//这里是为了 代码收纳,用了loop来放置代码
|
|
|
|
|
|
|
+ _ => {
|
|
|
|
|
+ error!("交易所输入错误!");
|
|
|
|
|
+ panic!("交易所输入错误!")
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
}
|
|
}
|
|
|
|
|
+ info!("all_account_balance_info:{:?}",all_account_balance_info);
|
|
|
|
|
+
|
|
|
|
|
|
|
|
// 根据账户变动填充
|
|
// 根据账户变动填充
|
|
|
let mut count_time_list = vec![];
|
|
let mut count_time_list = vec![];
|
|
@@ -139,6 +237,7 @@ pub async fn export_balance(config_info: BalanceConfigInfo) {
|
|
|
hour_time_list.push(end_time);
|
|
hour_time_list.push(end_time);
|
|
|
let all_balance_info: Vec<Vec<String>> = supply_balance(all_account_balance_info.clone(), hour_time_list.clone());
|
|
let all_balance_info: Vec<Vec<String>> = supply_balance(all_account_balance_info.clone(), hour_time_list.clone());
|
|
|
|
|
|
|
|
|
|
+ account_name_list.push("total_balance".to_string());
|
|
|
account_name_list.push("total_balance".to_string());
|
|
account_name_list.push("total_balance".to_string());
|
|
|
match config_info_clone.export_mode {
|
|
match config_info_clone.export_mode {
|
|
|
1 => export_template::template_balance::export_html(config_info, &account_name_list, &hour_time_list, &all_balance_info, statistic_result),
|
|
1 => export_template::template_balance::export_html(config_info, &account_name_list, &hour_time_list, &all_balance_info, statistic_result),
|
|
@@ -160,34 +259,25 @@ pub fn statistic_balance(balance_info: Vec<Vec<String>>, count_start_time: i64,
|
|
|
balance_info_map.insert(info[0].clone(), default_info);
|
|
balance_info_map.insert(info[0].clone(), default_info);
|
|
|
}
|
|
}
|
|
|
for (account_name, balance_info) in balance_info_map.clone() {
|
|
for (account_name, balance_info) in balance_info_map.clone() {
|
|
|
- let mut max_price = dec!(0);
|
|
|
|
|
- let mut min_price = dec!(0);
|
|
|
|
|
- let mut withdrawal = dec!(0);
|
|
|
|
|
for (index, info) in balance_info.iter().enumerate() {
|
|
for (index, info) in balance_info.iter().enumerate() {
|
|
|
- let present_price = Decimal::from_str(&info[4]).unwrap();
|
|
|
|
|
- if index == 0 || max_price < present_price {
|
|
|
|
|
- max_price = present_price;
|
|
|
|
|
- min_price = present_price;
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- let present_withdrawal = ((Decimal::ONE - (min_price / max_price)) * dec!(100)).round_dp(2);
|
|
|
|
|
- if present_withdrawal > withdrawal { withdrawal = present_withdrawal }
|
|
|
|
|
-
|
|
|
|
|
- if max_price > present_price && present_price < min_price {
|
|
|
|
|
- min_price = present_price;
|
|
|
|
|
|
|
+ if index == 0 { continue; }
|
|
|
|
|
+ let present = Decimal::from_str(&info[4]).unwrap();
|
|
|
|
|
+ let past = Decimal::from_str(&balance_info[index - 1][4]).unwrap();
|
|
|
|
|
+ let withdrawal = ((Decimal::ONE - (present / past)) * dec!(100)).round_dp(2);
|
|
|
|
|
+ if account_name != "total_balance" {
|
|
|
|
|
+ if max_withdrawal < withdrawal { max_withdrawal = withdrawal }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if max_total_withdrawal < withdrawal { max_total_withdrawal = withdrawal }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- if account_name != "total_balance" {
|
|
|
|
|
- if max_withdrawal < withdrawal { max_withdrawal = withdrawal }
|
|
|
|
|
- } else {
|
|
|
|
|
- max_total_withdrawal = withdrawal;
|
|
|
|
|
|
|
+ if account_name == "total_balance" {
|
|
|
let present = Decimal::from_str(&balance_info[0][4]).unwrap();
|
|
let present = Decimal::from_str(&balance_info[0][4]).unwrap();
|
|
|
let past = Decimal::from_str(&balance_info[balance_info.len() - 1][4]).unwrap();
|
|
let past = Decimal::from_str(&balance_info[balance_info.len() - 1][4]).unwrap();
|
|
|
total_income = (((past / present) - Decimal::ONE) * dec!(100)).round_dp(2);
|
|
total_income = (((past / present) - Decimal::ONE) * dec!(100)).round_dp(2);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- let start_time = NaiveDateTime::from_timestamp_millis((count_start_time + 8 * 3600) * 1000).unwrap().format("%d日%H点").to_string();
|
|
|
|
|
- let end_time = NaiveDateTime::from_timestamp_millis((end_start_time + 8 * 3600) * 1000).unwrap().format("%d日%H点").to_string();
|
|
|
|
|
|
|
+ let start_time = NaiveDateTime::from_timestamp_millis((count_start_time + 8 * 3600) * 1000).unwrap().format("%Y-%m-%d日%H点").to_string();
|
|
|
|
|
+ let end_time = NaiveDateTime::from_timestamp_millis((end_start_time + 8 * 3600) * 1000).unwrap().format("%Y-%m-%d日%H点").to_string();
|
|
|
format!("{}到{},总收益约为{}%,最大回撤约为{}%,其中单个账号最大回撤约为{}%。", start_time, end_time, total_income, max_total_withdrawal, max_withdrawal)
|
|
format!("{}到{},总收益约为{}%,最大回撤约为{}%,其中单个账号最大回撤约为{}%。", start_time, end_time, total_income, max_total_withdrawal, max_withdrawal)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -225,7 +315,13 @@ pub fn supply_balance(source_balance_info: BTreeMap<String, Vec<Vec<String>>>, t
|
|
|
let balance_info_filter: Vec<Vec<String>> = balance_info.iter().filter(|item| {
|
|
let balance_info_filter: Vec<Vec<String>> = balance_info.iter().filter(|item| {
|
|
|
item[0].parse::<i64>().unwrap() < time
|
|
item[0].parse::<i64>().unwrap() < time
|
|
|
}).cloned().collect();
|
|
}).cloned().collect();
|
|
|
- let mut last_balance_info = balance_info_filter[balance_info_filter.len() - 1].clone();
|
|
|
|
|
|
|
+ info!("balance_info_filter:{:?}",balance_info_filter.clone());
|
|
|
|
|
+ let mut last_balance_info = vec![];
|
|
|
|
|
+ if balance_info_filter.len() == 0{
|
|
|
|
|
+ last_balance_info = balance_info[0].clone();
|
|
|
|
|
+ }else{
|
|
|
|
|
+ last_balance_info = balance_info_filter[balance_info_filter.len() - 1].clone();
|
|
|
|
|
+ }
|
|
|
last_balance_info.insert(0, key.clone());
|
|
last_balance_info.insert(0, key.clone());
|
|
|
total_price += Decimal::from_str(&last_balance_info[4]).unwrap();
|
|
total_price += Decimal::from_str(&last_balance_info[4]).unwrap();
|
|
|
balance_info_list.push(last_balance_info);
|
|
balance_info_list.push(last_balance_info);
|