Explorar o código

代码结构初步整理完毕,明天再写逻辑了。

skyffire hai 1 ano
pai
achega
5ed5b0c3e8
Modificáronse 2 ficheiros con 217 adicións e 234 borrados
  1. 200 217
      src/hl_pr_utile.rs
  2. 17 17
      src/main.rs

+ 200 - 217
src/hl_pr_utile.rs

@@ -1,279 +1,262 @@
-use std::collections::{BTreeMap, HashSet};
+use std::collections::{BTreeMap};
 use std::fs::File;
 use std::io::Write;
-use std::str::FromStr;
 use chrono::{NaiveDateTime, Utc};
 use handlebars::Handlebars;
-use rust_decimal::Decimal;
-use rust_decimal::prelude::ToPrimitive;
 use serde_json::{json, Value};
-use tracing::{error, info};
-use crate::export_template::template_ticker::ExportExchangeTickerInfo;
+use tracing::{info};
 use crate::http::request::get;
-use crate::struct_standard::Trades;
-use crate::swap_okx::okx_swap_standard::SwapTrades;
-use crate::utils::utils::TickerConfigInfo;
 
-pub async fn export_ticker(symbol: &str, exchange: &str, time_str: &str, time_interval: i64) {
-
-    //从今天算起
-    let time_this = Utc::now().timestamp_millis();
-    let mut name_html = "";
-    let mut start_at = time_this - match time_str {
+pub fn parse_str_to_seconds(name_html: &mut String, time_str: &str) -> i64 {
+    match time_str {
+        "5M" => {
+            *name_html = "5分钟".to_string();
+            60 * 5
+        }
         "10M" => {
-            name_html = "10分钟";
-            (1000 * 60 * 10)
+            *name_html = "10分钟".to_string();
+            60 * 10
         }
         "20M" => {
-            name_html = "20分钟";
-            (1000 * 60 * 20)
+            *name_html = "20分钟".to_string();
+            60 * 20
         }
         "30M" => {
-            name_html = "30分钟";
-            (1000 * 60 * 30)
+            *name_html = "30分钟".to_string();
+            60 * 30
         }
         "1H" => {
-            name_html = "1小时";
-            (1000 * 60 * 60 * 1)
+            *name_html = "1小时".to_string();
+            60 * 60 * 1
         }
         "2H" => {
-            name_html = "2小时";
-            (1000 * 60 * 60 * 2)
+            *name_html = "2小时".to_string();
+            60 * 60 * 2
         }
         "3H" => {
-            name_html = "3小时";
-            (1000 * 60 * 60 * 3)
+            *name_html = "3小时".to_string();
+            60 * 60 * 3
         }
         "4H" => {
-            name_html = "4小时";
-            (1000 * 60 * 60 * 4)
+            *name_html = "4小时".to_string();
+            60 * 60 * 4
         }
         "12H" => {
-            name_html = "12小时";
-            (1000 * 60 * 60 * 12)
+            *name_html = "12小时".to_string();
+            60 * 60 * 12
         }
         "1D" => {
-            name_html = "1天";
-            (1000 * 60 * 60 * 24)
+            *name_html = "1天".to_string();
+            60 * 60 * 24
         }
         "2D" => {
-            name_html = "1天";
-            (1000 * 60 * 60 * 24 * 2)
+            *name_html = "1天".to_string();
+            60 * 60 * 24 * 2
         }
         "3D" => {
-            name_html = "3天";
-            (1000 * 60 * 60 * 24 * 3)
+            *name_html = "3天".to_string();
+            60 * 60 * 24 * 3
         }
         "5D" => {
-            name_html = "5天";
-            (1000 * 60 * 60 * 24 * 5)
+            *name_html = "5天".to_string();
+            60 * 60 * 24 * 5
         }
         "1Z" => {
-            name_html = "1周";
-            (1000 * 60 * 60 * 24 * 7)
+            *name_html = "1周".to_string();
+            60 * 60 * 24 * 7
         }
         "2Z" => {
-            name_html = "2周";
-            (1000 * 60 * 60 * 24 * 7 * 2)
+            *name_html = "2周".to_string();
+            60 * 60 * 24 * 7 * 2
         }
         "4Z" => {
-            name_html = "1个月";
-            (1000 * 60 * 60 * 24 * 7 * 4)
+            *name_html = "1个月".to_string();
+            60 * 60 * 24 * 7 * 4
         }
         _ => {
-            info!("错误时间");
-            return;
+            panic!("错误时间");
         }
-    };
-    start_at = start_at / 1000;
-    let end_at = time_this.clone() / 1000;
-    let recall_start_at = start_at;
+    }
+}
 
-    let mut exchange_list: BTreeMap<String, Vec<Value>> = BTreeMap::new();
-    let exchange_up = exchange.to_uppercase();
-    let exchange_result = match exchange_up.as_str() {
-        "GATE" => {
-            let mut start_at_ti = start_at;
-            loop {
-                let end_at_ti = start_at_ti + time_interval;
-                if start_at_ti > end_at {
-                    break;
+pub async fn pull_gate_ticker(ticker_map: &mut BTreeMap<u64, Value>, start_at: i64, end_at: i64, time_interval: i64, symbol: String) {
+    let mut from_time = start_at;
+    loop {
+        let to_time = from_time + time_interval;
+        let time_str_start_view = NaiveDateTime::from_timestamp_millis(((from_time) + 8 * 3600) * 1000).unwrap().format("%Y-%m-%d %H:%M:%S%.3f").to_string();
+        let time_str_end_view = NaiveDateTime::from_timestamp_millis(((to_time) + 8 * 3600) * 1000).unwrap().format("%Y-%m-%d %H:%M:%S%.3f").to_string();
+        info!("----拉取时间:{:?}---{:?}", time_str_start_view, time_str_end_view);
+        //查询数据按照间隔20分钟
+        let url = "https://api.gateio.ws/api/v4/futures/usdt/trades";
+        let params = json!({
+            "contract": symbol,
+            "from": from_time,
+            "to": to_time,
+            "limit": "1000"
+        });
+        let res_data = get(url, params.to_string(), None).await;
+        if res_data.code == "200" {
+            let res_data_str = res_data.data;
+
+            let json_value: Value = serde_json::from_str(&res_data_str).unwrap();
+            if let Some(tickers) = json_value.as_array() {
+                info!("数据数量:{:?}", tickers.len());
+                for ticker in tickers {
+                    let key = ticker["id"].as_u64().unwrap();
+
+                    // key是id,value是json
+                    ticker_map.insert(key, ticker.clone());
                 }
-                let time_str_s = NaiveDateTime::from_timestamp_millis(((start_at_ti) + 8 * 3600) * 1000).unwrap().format("%Y-%m-%d %H:%M:%S%.3f").to_string();
-                let time_str_e = NaiveDateTime::from_timestamp_millis(((end_at_ti) + 8 * 3600) * 1000).unwrap().format("%Y-%m-%d %H:%M:%S%.3f").to_string();
-                info!("----时间:{:?}---{:?}",time_str_s,time_str_e);
-                //查询数据按照间隔20分钟
-                let url = "https://api.gateio.ws/api/v4/futures/usdt/trades";
-                let params = serde_json::json!({
-                    "contract": symbol,
-                    "from": start_at_ti,
-                    "to":  end_at_ti,
-                    "to":  end_at_ti,
-                    "limit": "1000"
-                });
-                let res_data = get(url, params.to_string(), None).await;
-                if res_data.code == "200" {
-                    let res_data_str = res_data.data;
-                    // info!("body:{:?}",res_data_str);
-                    let json_value: serde_json::Value = serde_json::from_str(&res_data_str).unwrap();
-                    for rows in json_value.as_array() {
-                        let rows_c = rows.clone();
-                        info!("数据数量:{:?}",rows_c.len());
-                        for row in rows_c {
-                            // {"contract": String("XRP_USDT"), "create_time": Number(1703146260.4), "create_time_ms": Number(1703146260.4), "id": Number(24663517), "price": String("0.6163"), "size": Number(132)}
-                            // info!("数据:{:?}",row.clone());
-                            let row_c = row.clone();
-                            // let create_time = format!("{:?}", row["create_time"].as_f64().unwrap().to_i64().unwrap_or(0)).clone();
-                            // let k = create_time.as_str();
-
-                            let create_time = format!("{:?}", row["create_time"].as_f64().unwrap_or(0.0)).clone();
-                            let time_ttttt = create_time.clone();
-                            let parts: Vec<&str> = time_ttttt.split('.').collect();
-                            let seconds = parts[0].parse::<i64>().unwrap(); // 获取秒
-                            let milliseconds = if parts.len() > 1 {
-                                parts[1].parse::<u32>().unwrap_or(0) / 100
-                            } else {
-                                0
-                            };
-                            let timestamp_millis_i64 = seconds * 1000 + (milliseconds as i64) *100;
-                            let timestamp_millis_i64_string = timestamp_millis_i64.to_string(); // This is now owned and will live long enough.
-                            let k = timestamp_millis_i64_string.as_str();
-
-
-                            let mut def: Vec<Value> = vec![];
-                            if exchange_list.contains_key(k) {
-                                match exchange_list.get(k) {
-                                    None => {}
-                                    Some(r) => {
-                                        def = r.clone();
-                                    }
-                                }
-                            }
-                            def.push(row_c);
-                            exchange_list.insert(k.parse().unwrap(), def);
-                        }
-                    }
-                } else {
-                    info!("数据请求错误:");
-                    start_at_ti = start_at_ti - time_interval;
-                }
-                start_at_ti = start_at_ti + time_interval ;
             }
 
-            // info!("数据:{:?}",exchange_list);
-            info!("----横向图--交易量:");
-            let mut exchange_list_sss: BTreeMap<String, Vec<Value>> = BTreeMap::new();
-            let mut turnover_data: BTreeMap<String, Vec<Value>> = BTreeMap::new();
-            let mut keys: Vec<String> = exchange_list.keys().cloned().collect();
-            keys.sort_by(|&(ref a), &(ref b)| a.len().cmp(&b.len()));
-            for k in keys.clone() {
-                let time_str = NaiveDateTime::from_timestamp_millis(k.clone().parse::<i64>().unwrap() + 8 * 3600 * 1000).unwrap().format("%Y-%m-%d %H:%M:%S%.3f").to_string();
-                let data = exchange_list.get(k.clone().as_str()).unwrap();
-                let mut str_array = vec![""];
-                let mut ti_str = vec![""];
-                for d in data.clone() {
-                    str_array.push(" - ");
-                    // ti_str.push(d.clone());
-                    // info!("数据: {:?} ",d);
-                }
-
-                // info!("数据总数: {:?}: {:?}",time_str,str_array);
-
-
-                let mut def: Vec<Value> = vec![];
-                let size_k = format!("{:?}", data.len());
-                if exchange_list_sss.contains_key(&size_k) {
-                    match exchange_list_sss.get(&size_k) {
-                        None => {}
-                        Some(r) => {
-                            def = r.clone();
-                        }
-                    }
-                }
-                def.extend(data.clone());
-                exchange_list_sss.insert((str_array.len() - 1).to_string(), def);
-
+            from_time = from_time + time_interval;
+        } else {
+            info!("数据请求错误: {:?},重试。", res_data);
+        }
 
-                let mut def2: Vec<Value> = vec![];
-                let size_k2 = format!("{:?}", time_str);
-                if turnover_data.contains_key(&size_k2) {
-                    match turnover_data.get(&size_k2) {
-                        None => {}
-                        Some(r) => {
-                            def2 = r.clone();
-                        }
-                    }
-                }
-                def2.extend(data.clone());
-                turnover_data.insert(String::from(&size_k2), def2);
-            }
+        if from_time > end_at {
+            break;
+        }
+    }
+}
 
-            //总结 交易量
-            info!("总结:");
-            let mut pancake_data_y: Vec<String> = vec![];   //{ value: 1048, name: 'Search Engine' },
-            let mut pancake_data_x: Vec<usize> = vec![];   //{ value: 1048, name: 'Search Engine' },
-            // let zzz = exchange_list_sss.keys();
-            let mut keys: Vec<String> = exchange_list_sss.keys().cloned().collect();
-            keys.sort_by(|&(ref a), &(ref b)| a.len().cmp(&b.len()));
-            for k in keys {
-                let data = exchange_list_sss.get(k.clone().as_str()).unwrap();
+pub async fn export_gate_ticker(start_at: i64, end_at: i64, time_interval: i64, symbol: String) {
+    let mut ticker_map: BTreeMap<u64, Value> = BTreeMap::new();
 
-                let mut initiative_ticker_info = vec![];
-                for d in data {
-                    let create_time = format!("{:?}", d["create_time"].as_f64().unwrap().to_i64().unwrap_or(0)).clone();
-                    let time_str = NaiveDateTime::from_timestamp_millis(create_time.clone().parse::<i64>().unwrap() * 1000 + 8 * 3600 * 1000).unwrap().format("%Y-%m-%d %H:%M:%S%.3f").to_string();
+    // 获取ticker数据
+    pull_gate_ticker(&mut ticker_map, start_at, end_at, time_interval, symbol).await;
 
-                    initiative_ticker_info.push(time_str);
-                };
-                let mut seen = HashSet::new();
-                initiative_ticker_info.retain(|item| seen.insert(item.clone()));
+    info!(?ticker_map);
+}
 
-                let name = format!(" 交易量:{:?}", k.clone());
-                pancake_data_y.push(name);
-                pancake_data_x.push(initiative_ticker_info.len());
-                info!("交易量:{:?},一共有{:?}个时间点:{:?}",k.clone(),initiative_ticker_info.len(),0);
-            }
+pub async fn export_ticker(symbol: &str, exchange: &str, time_range_str: &str, time_interval: i64) {
+    // 只是显示在网页上,记录选择的时间周期
+    let mut name_html = Default::default();
+    // 从此刻往前算时间
+    let timestamp_seconds_now = Utc::now().timestamp();
+    let time_distance_seconds = parse_str_to_seconds(&mut name_html, time_range_str);
 
+    let start_at = timestamp_seconds_now - time_distance_seconds;
+    let end_at = timestamp_seconds_now;
 
-            //柱形图
-            let mut turnover_data_y: Vec<f64> = vec![];
-            let mut turnover_data_x: Vec<String> = vec![];
-            let mut keys: Vec<String> = turnover_data.keys().cloned().collect();
-            keys.sort_by(|&(ref a), &(ref b)| a.len().cmp(&b.len()));
-            turnover_data_x = keys;
-            for k in turnover_data_x.clone() {
-                let rows = turnover_data.get(k.as_str()).unwrap();
-                let mut val_y = 0.0;
-                if rows.len() > 1 {
-                    let mut max_v = 0.0;
-                    let mut min_v = 0.0;
-                    for row in rows {
-                        let price = row["price"].as_str().unwrap().parse::<f64>().unwrap();
-                        // info!("price:{:?} " ,price);
-                        if max_v == 0.0 {
-                            max_v = price
-                        }
-                        if min_v == 0.0 {
-                            min_v = price
-                        }
+    match exchange.to_uppercase().as_str() {
+        "GATE" => {
+            export_gate_ticker(start_at, end_at, time_interval, symbol.to_uppercase()).await;
 
-                        max_v = if price > max_v { price } else { max_v };
-                        min_v = if price < min_v { price } else { min_v };
-                    }
-                    val_y = format!("{:.5}", (max_v - min_v) / max_v).to_string().parse::<f64>().unwrap();
-                }
-                turnover_data_y.push(val_y);
-            }
+            // info!("数据:{:?}",exchange_list);
+            // info!("----横向图--交易量:");
+            // let mut exchange_list_sss: BTreeMap<String, Vec<Value>> = BTreeMap::new();
+            // let mut turnover_data: BTreeMap<String, Vec<Value>> = BTreeMap::new();
+            // let mut keys: Vec<String> = exchange_list.keys().cloned().collect();
+            // keys.sort_by(|&(ref a), &(ref b)| a.len().cmp(&b.len()));
+            // for k in keys.clone() {
+            //     let time_str = NaiveDateTime::from_timestamp_millis(k.clone().parse::<i64>().unwrap() + 8 * 3600 * 1000).unwrap().format("%Y-%m-%d %H:%M:%S%.3f").to_string();
+            //     let data = exchange_list.get(k.clone().as_str()).unwrap();
+            //     let mut str_array = vec![""];
+            //     let mut ti_str = vec![""];
+            //     for d in data.clone() {
+            //         str_array.push(" - ");
+            //         // ti_str.push(d.clone());
+            //         // info!("数据: {:?} ",d);
+            //     }
+            //
+            //     // info!("数据总数: {:?}: {:?}",time_str,str_array);
+            //
+            //
+            //     let mut def: Vec<Value> = vec![];
+            //     let size_k = format!("{:?}", data.len());
+            //     if exchange_list_sss.contains_key(&size_k) {
+            //         match exchange_list_sss.get(&size_k) {
+            //             None => {}
+            //             Some(r) => {
+            //                 def = r.clone();
+            //             }
+            //         }
+            //     }
+            //     def.extend(data.clone());
+            //     exchange_list_sss.insert((str_array.len() - 1).to_string(), def);
+            //
+            //
+            //     let mut def2: Vec<Value> = vec![];
+            //     let size_k2 = format!("{:?}", time_str);
+            //     if turnover_data.contains_key(&size_k2) {
+            //         match turnover_data.get(&size_k2) {
+            //             None => {}
+            //             Some(r) => {
+            //                 def2 = r.clone();
+            //             }
+            //         }
+            //     }
+            //     def2.extend(data.clone());
+            //     turnover_data.insert(String::from(&size_k2), def2);
+            // }
 
-            export_html(name_html, pancake_data_y, pancake_data_x, turnover_data_y, turnover_data_x)
+            //总结 交易量
+            // info!("总结:");
+            // let mut pancake_data_y: Vec<String> = vec![];   //{ value: 1048, name: 'Search Engine' },
+            // let mut pancake_data_x: Vec<usize> = vec![];   //{ value: 1048, name: 'Search Engine' },
+            // // let zzz = exchange_list_sss.keys();
+            // let mut keys: Vec<String> = exchange_list_sss.keys().cloned().collect();
+            // keys.sort_by(|&(ref a), &(ref b)| a.len().cmp(&b.len()));
+            // for k in keys {
+            //     let data = exchange_list_sss.get(k.clone().as_str()).unwrap();
+            //
+            //     let mut initiative_ticker_info = vec![];
+            //     for d in data {
+            //         let create_time = format!("{:?}", d["create_time"].as_f64().unwrap().to_i64().unwrap_or(0)).clone();
+            //         let time_str = NaiveDateTime::from_timestamp_millis(create_time.clone().parse::<i64>().unwrap() * 1000 + 8 * 3600 * 1000).unwrap().format("%Y-%m-%d %H:%M:%S%.3f").to_string();
+            //
+            //         initiative_ticker_info.push(time_str);
+            //     };
+            //     let mut seen = HashSet::new();
+            //     initiative_ticker_info.retain(|item| seen.insert(item.clone()));
+            //
+            //     let name = format!(" 交易量:{:?}", k.clone());
+            //     pancake_data_y.push(name);
+            //     pancake_data_x.push(initiative_ticker_info.len());
+            //     info!("交易量:{:?},一共有{:?}个时间点:{:?}",k.clone(),initiative_ticker_info.len(),0);
+            // }
+            //
+            //
+            // //柱形图
+            // let mut turnover_data_y: Vec<f64> = vec![];
+            // let mut turnover_data_x: Vec<String> = vec![];
+            // let mut keys: Vec<String> = turnover_data.keys().cloned().collect();
+            // keys.sort_by(|&(ref a), &(ref b)| a.len().cmp(&b.len()));
+            // turnover_data_x = keys;
+            // for k in turnover_data_x.clone() {
+            //     let rows = turnover_data.get(k.as_str()).unwrap();
+            //     let mut val_y = 0.0;
+            //     if rows.len() > 1 {
+            //         let mut max_v = 0.0;
+            //         let mut min_v = 0.0;
+            //         for row in rows {
+            //             let price = row["price"].as_str().unwrap().parse::<f64>().unwrap();
+            //             // info!("price:{:?} " ,price);
+            //             if max_v == 0.0 {
+            //                 max_v = price
+            //             }
+            //             if min_v == 0.0 {
+            //                 min_v = price
+            //             }
+            //
+            //             max_v = if price > max_v { price } else { max_v };
+            //             min_v = if price < min_v { price } else { min_v };
+            //         }
+            //         val_y = format!("{:.5}", (max_v - min_v) / max_v).to_string().parse::<f64>().unwrap();
+            //     }
+            //     turnover_data_y.push(val_y);
+            // }
+            //
+            // export_html(name_html, pancake_data_y, pancake_data_x, turnover_data_y, turnover_data_x)
         }
         _ => {
-            error!("交易所输入错误!");
             panic!("交易所输入错误!")
         }
     };
 }
 
+#[allow(dead_code)]
 //生成html
 pub fn export_html(name_html: &str, pancake_data_y: Vec<String>, pancake_data_x: Vec<usize>, turnover_data_y: Vec<f64>, turnover_data_x: Vec<String>) {
     info!("正在生成网页,请稍后!");

+ 17 - 17
src/main.rs

@@ -29,22 +29,22 @@ async fn main() {
         balance_info: balance_config,
     };
 
-    // if config_obj.ticker_info.is_export {
-    //     info!("----------正在导出Ticker信息----------");
-    //     let config_clone = config_obj.ticker_info.clone();
-    //     if http::proxy::ParsingDetail::http_enable_proxy(config_clone.proxy_address.clone()) {
-    //         info!("检测有代理配置,配置走代理");
-    //     }
-    //     export_ticker::export_ticker(config_clone).await;
-    // }
-    // if config_obj.balance_info.is_export {
-    //     info!("----------正在导出Balance信息----------");
-    //     let config_clone = config_obj.balance_info.clone();
-    //     if http::proxy::ParsingDetail::http_enable_proxy(config_clone.proxy_address.clone()) {
-    //         info!("检测有代理配置,配置走代理");
-    //     }
-    //     export_balance::export_balance(config_clone).await;
-    // }
+    if config_obj.ticker_info.is_export {
+        info!("----------正在导出Ticker信息----------");
+        let config_clone = config_obj.ticker_info.clone();
+        if http::proxy::ParsingDetail::http_enable_proxy(config_clone.proxy_address.clone()) {
+            info!("检测有代理配置,配置走代理");
+        }
+        export_ticker::export_ticker(config_clone).await;
+    }
+    if config_obj.balance_info.is_export {
+        info!("----------正在导出Balance信息----------");
+        let config_clone = config_obj.balance_info.clone();
+        if http::proxy::ParsingDetail::http_enable_proxy(config_clone.proxy_address.clone()) {
+            info!("检测有代理配置,配置走代理");
+        }
+        export_balance::export_balance(config_clone).await;
+    }
 
     if true {
         info!("----------正在导出Ticker信息----------");
@@ -68,6 +68,6 @@ async fn main() {
         // 提示: 1. 代码颗粒度为秒级,100毫秒与999毫秒都归纳于1秒之内,
         //       2. 不同币对成交量可能存在差异,当前查询是1000条已经是最大值,但是有点币对交易量只有几百,但是有的可能好几千,这个需要酌情调整
         //time_interval -数据请求的时间间隔 毫秒级
-        hl_pr_utile::export_ticker("WLD_USDT", "GATE", "10M", (1 * 60)).await;
+        hl_pr_utile::export_ticker("ORDI_USDT", "GATE", "10M", 1 * 30).await;
     }
 }