Sfoglia il codice sorgente

修改图表注释数据
完善图表

gepangpang 1 anno fa
parent
commit
699c44283e

+ 1 - 1
src/binance_swap/binance_swap_standard.rs

@@ -67,11 +67,11 @@ pub async fn standard_trades(symbol: &str, limit: &str, trade_id: &str) -> Resul
             Trades {
                 id: item.id.to_string(),
                 data_type: "ticker_binance".to_string(),
-                classify: "ticker".to_string(),
                 symbol: symbol.to_string(),
                 create_time: item.time.to_string(),
                 size: if item.is_buyer_maker { item.qty.to_string() } else { format!("-{}", item.qty.to_string()) },
                 price: item.price.clone(),
+                side: if item.is_buyer_maker { "BUY".to_string() } else { "SELL".to_string() },
                 is_effect: true,
             }
         }).collect();

+ 46 - 39
src/export/html.rs

@@ -23,6 +23,7 @@ pub struct ExportExchangeTickerInfo {
 #[derive(Debug, Clone, Deserialize, Serialize)]
 pub struct SeriesInfo {
     pub name: String,
+    pub classify: String,
     pub data: Vec<Trades>,
 }
 
@@ -73,23 +74,27 @@ pub fn export_html(export_info: Vec<ExportExchangeTickerInfo>, start_at: &str, e
         if (long_volume_bool && last_bool != "initiative_long") || (short_volume_bool && last_bool != "initiative_short") || (!long_volume_bool && !short_volume_bool && last_bool != "initiative_none") {
             // 新增订单流主动性数据
             let max_price = max_price * dec!(1.005);
+            let mut side = "";
             if long_volume_bool {
                 last_bool = "initiative_long";
+                side = "LONG";
             }
             if short_volume_bool {
                 last_bool = "initiative_short";
+                side = "SHORT";
             }
             if !long_volume_bool && !short_volume_bool {
                 last_bool = "initiative_none";
+                side = "NONE";
             }
             ticker_info.push(Trades {
                 id: Uuid::new_v4().to_string()[0..8].to_string(),
                 data_type: last_bool.to_string(),
-                classify: "initiative".to_string(),
                 symbol: trades.symbol,
                 create_time: trades.create_time,
                 size: volume.to_string(),
                 price: max_price.to_string(),
+                side: side.to_string(),
                 is_effect: true,
             });
         }
@@ -104,6 +109,7 @@ pub fn export_html(export_info: Vec<ExportExchangeTickerInfo>, start_at: &str, e
     }
     let initiative_info = SeriesInfo {
         name: "主动性".to_string(),
+        classify: "initiative".to_string(),
         data: end_ticker_info.clone(),
     };
 
@@ -116,12 +122,13 @@ pub fn export_html(export_info: Vec<ExportExchangeTickerInfo>, start_at: &str, e
     let mut legend_list: Vec<String> = vec![];
     let mut series_info: Vec<SeriesInfo> = vec![];
 
-    let ref_robot_info: Vec<Trades> = robot_info.iter().filter(|trades| trades.data_type == "robot_ref_price").cloned().collect();
+    let ref_robot_info: Vec<Trades> = robot_info.iter().filter(|trades| trades.data_type == "robot_ref_info").cloned().collect();
 
     for item in export_info.clone() {
         name_list.push(format!("'{}'", item.name));
         series_info.push(SeriesInfo {
             name: item.name.clone(),
+            classify: "ticker".to_string(),
             data: item.ticker_info.clone(),
         })
     }
@@ -129,11 +136,13 @@ pub fn export_html(export_info: Vec<ExportExchangeTickerInfo>, start_at: &str, e
 
     series_info.push(SeriesInfo {
         name: "预定价格".to_string(),
+        classify: "robot_ref".to_string(),
         data: ref_robot_info.clone(),
     });
-    let reg_robot_info: Vec<Trades> = robot_info.iter().filter(|trades| trades.data_type == "robot_reg_price").cloned().collect();
+    let reg_robot_info: Vec<Trades> = robot_info.iter().filter(|trades| trades.data_type == "robot_reg_info").cloned().collect();
     series_info.push(SeriesInfo {
         name: "挂单价格".to_string(),
+        classify: "robot_reg".to_string(),
         data: reg_robot_info.clone(),
     });
 
@@ -195,24 +204,13 @@ pub fn export_html(export_info: Vec<ExportExchangeTickerInfo>, start_at: &str, e
                 // trigger: 'axis',
                 showDelay: 0,
                 formatter: function (params) {
-                  if (params.value.length > 1) {
-                    var time = dayjs(params.value[0]).format('YYYY-MM-DD HH:mm:ss.SSS');
-                    var side = params.value[2] > 0 ? "Buy" : "Sell"
-                    return (
-                      params.seriesName +
-                      ' :<br/>' +
-                      '时间: ' +
-                      time +
-                      ' <br/>' +
-                      '价格: ' +
-                      params.value[1] +
-                      ' <br/>' +
-                      '数量: ' +
-                      params.value[2] +
-                      ' <br/>' +
-                      '买卖方向: ' +
-                      side
-                    );
+                  if(params.value.length <= 0) return "";
+                  var time = dayjs(params.value[0]).format('YYYY-MM-DD HH:mm:ss.SSS');
+                  switch (params.value[4]){
+                    case "ticker": return `${params.seriesName}:<br/>时间: ${time}<br/>价格: ${params.value[1]}<br/>数量: ${params.value[2]}<br/>买卖方向: ${params.value[3]}`;
+                    case "initiative": return `${params.seriesName}:<br/>时间: ${time}<br/>数量: ${params.value[2]}<br/>主动方向: ${params.value[3]}`;
+                    case "robot_ref": return `${params.seriesName}:<br/>时间: ${time}<br/>数量: ${params.value[2]}`;
+                    case "robot_reg": return `${params.seriesName}:<br/>时间: ${time}<br/>数量: ${params.value[2]}<br/>仓位方向: ${params.value[3]}`;
                   }
                 },
                 axisPointer: {
@@ -263,27 +261,42 @@ pub fn export_html(export_info: Vec<ExportExchangeTickerInfo>, start_at: &str, e
                 }
               ],
               series: [
-                {{#each series_info}}
+                {{#each series_info as | series |}}
                 {
-                  name: '{{name}}',
+                  name: '{{series.name}}',
                   type: 'scatter',
-                  symbol: function(value){
-                    if (value[3] == 'ticker') return 'triangle';
-                    if (value[3] == 'initiative') return 'circle';
-                    if (value[3] == 'robot') return 'rect';
+                  {{#if (eq series.classify 'ticker')}}symbol: 'triangle',{{/if}}
+                  {{#if (eq series.classify 'initiative')}}symbol: 'circle',{{/if}}
+                  {{#if (eq series.classify 'robot_ref')}}symbol: 'rect',{{/if}}
+                  {{#if (eq series.classify 'robot_reg')}}symbol: 'rect',{{/if}}
+
+                  {{#if (eq series.classify 'ticker')}}color: exchangeColor['{{series.name}}'.toLocaleLowerCase()],{{/if}}
+                  {{#if (eq series.classify 'initiative')}}color: '#D2D2D2',{{/if}}
+                  {{#if (eq series.classify 'robot_reg')}}
+                  color: {
+                    type: 'linear',
+                    x: 0,
+                    y: 0,
+                    x2: 1,
+                    y2: 0,
+                    colorStops: [{offset: 0, color: 'green'},{offset: 0.5, color: 'green'},{offset: 0.5, color: 'red'}, {offset: 1, color: 'red'}],
+                    global: false
                   },
-                  color: exchangeColor['{{name}}'.toLocaleLowerCase()],
+                  {{/if}}
                   emphasis: {
                     focus: 'series'
                   },
                   data:[
-                    {{#each data}}
+                    {{#each data as |value|}}
                       {
-                        value: [{{create_time}},{{price}},{{size}},'{{classify}}'],
-                        symbolRotate: '{{size}}' > 0 ? '0' : '180',
+                        value: [{{value.create_time}}, {{value.price}}, {{value.size}}, '{{value.side}}', '{{series.classify}}', '{{value.data_type}}'],
+                        symbolRotate: {{value.size}} * 1 > 0 && '{{series.classify}}' == 'ticker' ? '0' : '180',
                         itemStyle: {
-                          color: '{{classify}}' != 'initiative' ? exchangeColor['{{name}}'.toLocaleLowerCase()] : 'white',
-                          borderColor: '{{data_type}}' == 'initiative_long' ? 'green' : '{{data_type}}' == 'initiative_short' ? 'red' : '{{data_type}}' == 'initiative_none' ? 'black' : {{size}} > 0 ? 'green' : 'red',
+                          {{#if (eq value.data_type 'robot_reg_info')}}color: {{value.size}} * 1 > 0 ? 'green' : 'red',{{/if}}
+                          {{#if (eq value.data_type 'initiative_long')}}borderColor: 'green',{{/if}}
+                          {{#if (eq value.data_type 'initiative_short')}}borderColor: 'red',{{/if}}
+                          {{#if (eq value.data_type 'initiative_none')}}borderColor: 'black',{{/if}}
+                          {{#if (eq series.classify 'ticker')}}borderColor: {{value.size}} * 1 > 0 ? 'green' : 'red',{{/if}}
                           borderWidth: 1,
                         }
                       },
@@ -309,12 +322,6 @@ pub fn export_html(export_info: Vec<ExportExchangeTickerInfo>, start_at: &str, e
                         }
                       ]
                     ]
-                  },
-                  markPoint: {
-                    data: [
-                      { type: 'max', name: 'Max' },
-                      { type: 'min', name: 'Min' }
-                    ]
                   }
                 },
                 {{/each}}

+ 1 - 1
src/gate_swap/gate_swap_standard.rs

@@ -29,11 +29,11 @@ pub(crate) async fn standard_trades(symbol: &str, start_at: &str, end_at: &str,
             Trades {
                 id: item.id.to_string(),
                 data_type: "ticker_gate".to_string(),
-                classify: "ticker".to_string(),
                 symbol: item.contract.clone(),
                 create_time: (item.create_time_ms * 1000.0).to_string(),
                 size: (item.size * ct_val.unwrap_or(Decimal::ONE)).to_string(),
                 price: item.price.clone(),
+                side: if item.size > Decimal::ZERO { "BUY".to_string() } else { "SELL".to_string() },
                 is_effect: if item.is_internal.is_none() { true } else { false },
             }
         }).collect();

+ 4 - 3
src/handle_ticker.rs

@@ -71,14 +71,15 @@ pub async fn get_binance_ticker_info(symbol: &str, start_at: &str, end_at: &str)
 
     let mut ticker_info_list: Vec<Trades> = vec![];
     for agg_trades in agg_ticker_info_list.clone() {
+        let agg_trades_size = Decimal::from_str(&agg_trades.size).unwrap();
         ticker_info_list.push(Trades {
             id: agg_trades.start_id,
             data_type: "ticker_binance".to_string(),
-            classify: "ticker".to_string(),
             symbol: agg_trades.symbol,
             create_time: agg_trades.create_time,
             size: agg_trades.size,
             price: agg_trades.price,
+            side: if agg_trades_size > Decimal::ZERO { "BUY".to_string() } else { "SELL".to_string() },
             is_effect: true,
         })
         // let id_diff = Decimal::from_str(&agg_trades.end_id).unwrap() - Decimal::from_str(&agg_trades.start_id).unwrap();
@@ -114,7 +115,7 @@ pub async fn get_okx_ticker_info(symbol: &str, start_at: &str, end_at: &str) ->
     info!("当前时间---{:?}---{:?}",start_at,end_at);
 
     let mut list_array: Vec<Trades> = vec![];
-    let ticker_one = okx_swap_standard::standard_history_candles(symbol, "", end_at_d_str.as_str(), &ct_val).await.unwrap();
+    let ticker_one = okx_swap_standard::standard_history_candles(symbol, "", end_at_d_str.as_str(), ct_val).await.unwrap();
     if ticker_one.len() > 0 {
         let ticker_0 = ticker_one.get(0).cloned();
         let ticker_size = ticker_one.get(ticker_one.len() - 1).cloned();
@@ -131,7 +132,7 @@ pub async fn get_okx_ticker_info(symbol: &str, start_at: &str, end_at: &str) ->
                 let start_at_str = format!("{}000", start_at);
                 // info!("比较:{:?}-{:?}",start_at_str , create_time_size);
                 if start_at_str < create_time_size {
-                    let ticker_one2 = okx_swap_standard::standard_history_candles(symbol, "", create_time_size.as_ref(), &ct_val).await.unwrap();
+                    let ticker_one2 = okx_swap_standard::standard_history_candles(symbol, "", create_time_size.as_ref(), ct_val).await.unwrap();
 
                     let ticker_0_2 = ticker_one2.get(0).cloned();
                     let ticker_size_2 = ticker_one2.get(ticker_one.len() - 1).cloned();

+ 9 - 13
src/okx_swap/okx_swap_standard.rs

@@ -1,4 +1,5 @@
 use std::io::{Error, ErrorKind};
+use rust_decimal::Decimal;
 
 use serde::{Deserialize, Serialize};
 
@@ -14,14 +15,14 @@ pub struct SwapTrades {
     //	成交ID
     px: String,
     //	成交价格
-    sz: String,
+    sz: Decimal,
     //成交数量
     side: String,
     //成交方向buy:,//买sell:,//卖
     ts: String,//成交时间,Unix时间戳的毫秒数格式, 如1597026383085
 }
 
-pub(crate) async fn standard_history_candles(symbol: &str, start_at: &str, end_at: &str, ct_val: &i64) -> Result<Vec<Trades>, Error> {
+pub(crate) async fn standard_history_candles(symbol: &str, start_at: &str, end_at: &str, ct_val: Decimal) -> Result<Vec<Trades>, Error> {
     let mut symbol_fmt = format!("{}-SWAP", symbol.replace("_", "-").clone());
     symbol_fmt = symbol_fmt.to_uppercase();
 
@@ -38,7 +39,7 @@ pub(crate) async fn standard_history_candles(symbol: &str, start_at: &str, end_a
 
             let ticker_list: Vec<SwapTrades> = serde_json::from_str(data.to_string().as_str()).unwrap();
             ticker_list.iter().map(|item| {
-                let mut size_i: i64 = item.sz.clone().parse().expect("Not a valid number");
+                let mut size_i = item.sz;
                 if item.side.as_str() == "sell" {
                     size_i = -size_i;
                 } else if item.side.as_str() == "buy" {
@@ -48,11 +49,11 @@ pub(crate) async fn standard_history_candles(symbol: &str, start_at: &str, end_a
                 Trades {
                     id: item.trade_id.to_string(),
                     data_type: "ticker_okx".to_string(),
-                    classify: "ticker".to_string(),
                     symbol: symbol.to_string(),
                     create_time: item.ts.to_string(),
                     size: (size_i * ct_val).to_string(),
                     price: item.px.clone(),
+                    side: if size_i > Decimal::ZERO { "BUY".to_string() } else { "SELL".to_string() },
                     is_effect: true,
                 }
             }).collect()
@@ -85,7 +86,7 @@ pub struct SwapSymbolDateils {
     //   计价货币币种,如 BTC-USDT 中的USDT ,仅适用于币币/币币杠杆
     settleCcy: String,
     //   盈亏结算和保证金币种,如 BTC 仅适用于交割/永续/期权
-    ctVal: String,
+    ctVal: Decimal,
     //  合约面值,仅适用于交割/永续/期权
     ctMult: String,
     //   合约乘数,仅适用于交割/永续/期权
@@ -171,15 +172,10 @@ pub(crate) async fn standard_symbol_details(symbol: &str) -> Result<Option<SwapS
     }
 }
 
-pub async fn standard_ct_val(symbol: &str) -> i64 {
+pub async fn standard_ct_val(symbol: &str) -> Decimal {
     match standard_symbol_details(symbol).await.unwrap() {
-        None => {
-            1
-        }
-        Some(d) => {
-            let num: i64 = d.ctVal.parse().expect("Not a valid number");
-            num
-        }
+        None => Decimal::ONE,
+        Some(d) => d.ctVal
     }
 }
 

+ 8 - 6
src/robot_data/robot_data_standard.rs

@@ -40,26 +40,28 @@ pub async fn standard_robot_info(symbol: &str, robot_name: &str, start_at: &str,
         let robot_info: RobotInfo = serde_json::from_str(&res_data.data).unwrap();
 
         let ref_price_list: Vec<Trades> = robot_info.ref_price.iter().map(|item| {
+            let size = if item.side.as_str() == "kk" || item.side.as_str() == "pd" { format!("-{}", item.num.clone()) } else { item.num.clone() };
             Trades {
                 id: item.id.to_string(),
-                data_type: "robot_ref_price".to_string(),
-                classify: "robot".to_string(),
+                data_type: "robot_ref_info".to_string(),
                 symbol: symbol.to_string(),
                 create_time: item.trigger_time.to_string(),
-                size: item.num.clone(),
+                size,
                 price: item.ref_price.clone(),
+                side: item.side.to_uppercase(),
                 is_effect: true,
             }
         }).collect();
         let reg_price_list: Vec<Trades> = robot_info.reg_price.iter().map(|item| {
+            let size = if item.side.as_str() == "kk" || item.side.as_str() == "pd" { format!("-{}", item.num.clone()) } else { item.num.clone() };
             Trades {
                 id: item.id.to_string(),
-                data_type: "robot_reg_price".to_string(),
-                classify: "robot".to_string(),
+                data_type: "robot_reg_info".to_string(),
                 symbol: symbol.to_string(),
                 create_time: item.trigger_time.to_string(),
-                size: item.num.clone(),
+                size,
                 price: item.reg_price.clone(),
+                side: item.side.to_uppercase(),
                 is_effect: true,
             }
         }).collect();

+ 1 - 1
src/struct_standard.rs

@@ -5,11 +5,11 @@ use serde::{Deserialize, Serialize};
 pub struct Trades {
     pub id: String,
     pub data_type: String,
-    pub classify: String,
     pub symbol: String,
     pub create_time: String,
     pub size: String,
     pub price: String,
+    pub side: String,
     pub is_effect: bool,
 }