|
|
@@ -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}}
|