update pay ui
This commit is contained in:
@@ -3,6 +3,207 @@
|
||||
* 用于处理异动标注等图表相关逻辑
|
||||
*/
|
||||
|
||||
/**
|
||||
* 异动类型配置 - 科技感配色方案
|
||||
*/
|
||||
export const ALERT_TYPE_CONFIG = {
|
||||
surge_up: {
|
||||
label: '急涨',
|
||||
color: '#ff4d4f',
|
||||
gradient: ['#ff4d4f', '#ff7a45'],
|
||||
icon: 'TrendingUp',
|
||||
bgAlpha: 0.15,
|
||||
description: '概念板块出现快速上涨异动',
|
||||
},
|
||||
surge: {
|
||||
label: '异动',
|
||||
color: '#ff7a45',
|
||||
gradient: ['#ff7a45', '#ffa940'],
|
||||
icon: 'Zap',
|
||||
bgAlpha: 0.12,
|
||||
description: '概念板块出现明显异动信号',
|
||||
},
|
||||
surge_down: {
|
||||
label: '急跌',
|
||||
color: '#52c41a',
|
||||
gradient: ['#52c41a', '#73d13d'],
|
||||
icon: 'TrendingDown',
|
||||
bgAlpha: 0.15,
|
||||
description: '概念板块出现快速下跌异动',
|
||||
},
|
||||
volume_surge_up: {
|
||||
label: '放量急涨',
|
||||
color: '#eb2f96',
|
||||
gradient: ['#eb2f96', '#f759ab'],
|
||||
icon: 'Activity',
|
||||
bgAlpha: 0.15,
|
||||
description: '成交量放大伴随价格急涨,资金关注度高',
|
||||
},
|
||||
shrink_surge_up: {
|
||||
label: '缩量急涨',
|
||||
color: '#722ed1',
|
||||
gradient: ['#722ed1', '#9254de'],
|
||||
icon: 'Rocket',
|
||||
bgAlpha: 0.15,
|
||||
description: '成交量萎缩但价格急涨,筹码锁定良好',
|
||||
},
|
||||
volume_oscillation: {
|
||||
label: '放量震荡',
|
||||
color: '#13c2c2',
|
||||
gradient: ['#13c2c2', '#36cfc9'],
|
||||
icon: 'Waves',
|
||||
bgAlpha: 0.12,
|
||||
description: '成交量放大但价格震荡,多空分歧加大',
|
||||
},
|
||||
limit_up: {
|
||||
label: '涨停潮',
|
||||
color: '#fa541c',
|
||||
gradient: ['#fa541c', '#ff7a45'],
|
||||
icon: 'Flame',
|
||||
bgAlpha: 0.15,
|
||||
description: '板块内多只股票涨停,热度极高',
|
||||
},
|
||||
rank_jump: {
|
||||
label: '排名跃升',
|
||||
color: '#1890ff',
|
||||
gradient: ['#1890ff', '#40a9ff'],
|
||||
icon: 'ArrowUpCircle',
|
||||
bgAlpha: 0.12,
|
||||
description: '概念板块排名快速上升,关注度提升',
|
||||
},
|
||||
volume_spike: {
|
||||
label: '放量异动',
|
||||
color: '#faad14',
|
||||
gradient: ['#faad14', '#ffc53d'],
|
||||
icon: 'BarChart3',
|
||||
bgAlpha: 0.12,
|
||||
description: '成交量出现突发性放大',
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 指标配置 - 包含详细提示说明
|
||||
*/
|
||||
export const METRIC_CONFIG = {
|
||||
final_score: {
|
||||
label: '综合评分',
|
||||
unit: '分',
|
||||
tooltip: '综合规则评分和机器学习评分的最终得分,分数越高表示异动信号越强。60分以上值得关注,80分以上为强信号。',
|
||||
format: (v) => Math.round(v),
|
||||
getColor: (v) => {
|
||||
if (v >= 80) return '#ff4d4f';
|
||||
if (v >= 60) return '#fa8c16';
|
||||
if (v >= 40) return '#faad14';
|
||||
return '#8c8c8c';
|
||||
},
|
||||
},
|
||||
rule_score: {
|
||||
label: '规则评分',
|
||||
unit: '分',
|
||||
tooltip: '基于预设规则计算的评分,包括涨跌幅、成交量、涨停数等多维度指标。',
|
||||
format: (v) => Math.round(v),
|
||||
},
|
||||
ml_score: {
|
||||
label: 'AI评分',
|
||||
unit: '分',
|
||||
tooltip: '机器学习模型预测的评分,基于历史数据训练,预测该异动后续表现概率。',
|
||||
format: (v) => Math.round(v),
|
||||
},
|
||||
confirm_ratio: {
|
||||
label: '确认率',
|
||||
unit: '%',
|
||||
tooltip: '异动信号的确认程度。100%表示信号完全确认,数值越高表示异动越稳定、越可靠。低于60%的信号可能是噪音。',
|
||||
format: (v) => Math.round(v * 100),
|
||||
getColor: (v) => {
|
||||
if (v >= 0.8) return '#52c41a';
|
||||
if (v >= 0.6) return '#faad14';
|
||||
return '#ff4d4f';
|
||||
},
|
||||
},
|
||||
alpha: {
|
||||
label: '超额收益',
|
||||
unit: '%',
|
||||
tooltip: '概念板块相对于大盘的超额涨跌幅(Alpha)。正值表示跑赢大盘,负值表示跑输大盘。该指标反映板块的相对强弱。',
|
||||
format: (v) => v?.toFixed(2),
|
||||
getColor: (v) => v >= 0 ? '#ff4d4f' : '#52c41a',
|
||||
showSign: true,
|
||||
},
|
||||
alpha_zscore: {
|
||||
label: 'Alpha强度',
|
||||
unit: 'σ',
|
||||
tooltip: 'Alpha的Z-Score标准化值,衡量超额收益的统计显著性。|值|>2表示异常强,|值|>1.5表示较强。正值表示异常上涨,负值表示异常下跌。',
|
||||
format: (v) => v?.toFixed(2),
|
||||
getColor: (v) => v >= 0 ? '#ff4d4f' : '#52c41a',
|
||||
showSign: true,
|
||||
},
|
||||
amt_zscore: {
|
||||
label: '成交额强度',
|
||||
unit: 'σ',
|
||||
tooltip: '成交额的Z-Score标准化值,衡量当前成交额相对于历史的异常程度。>2表示成交额异常放大,资金活跃度高。',
|
||||
format: (v) => v?.toFixed(2),
|
||||
getColor: (v) => {
|
||||
if (v >= 2) return '#eb2f96';
|
||||
if (v >= 1) return '#faad14';
|
||||
return '#8c8c8c';
|
||||
},
|
||||
},
|
||||
rank_zscore: {
|
||||
label: '排名变化强度',
|
||||
unit: 'σ',
|
||||
tooltip: '板块排名变化的Z-Score值。正值表示排名上升速度异常,>2表示排名跃升显著。',
|
||||
format: (v) => v?.toFixed(2),
|
||||
showSign: true,
|
||||
},
|
||||
momentum_3m: {
|
||||
label: '3分钟动量',
|
||||
unit: '',
|
||||
tooltip: '过去3分钟的价格动量指标,反映短期趋势强度。正值表示上涨动量,负值表示下跌动量。',
|
||||
format: (v) => v?.toFixed(3),
|
||||
getColor: (v) => v >= 0 ? '#ff4d4f' : '#52c41a',
|
||||
showSign: true,
|
||||
},
|
||||
momentum_5m: {
|
||||
label: '5分钟动量',
|
||||
unit: '',
|
||||
tooltip: '过去5分钟的价格动量指标,比3分钟动量更稳定,过滤掉更多噪音。',
|
||||
format: (v) => v?.toFixed(3),
|
||||
getColor: (v) => v >= 0 ? '#ff4d4f' : '#52c41a',
|
||||
showSign: true,
|
||||
},
|
||||
limit_up_ratio: {
|
||||
label: '涨停占比',
|
||||
unit: '%',
|
||||
tooltip: '板块内涨停股票数量占总股票数的比例。>10%表示板块热度高,>20%表示涨停潮。',
|
||||
format: (v) => Math.round(v * 100),
|
||||
getColor: (v) => {
|
||||
if (v >= 0.2) return '#ff4d4f';
|
||||
if (v >= 0.1) return '#fa8c16';
|
||||
if (v >= 0.05) return '#faad14';
|
||||
return '#8c8c8c';
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 触发规则配置
|
||||
*/
|
||||
export const TRIGGERED_RULES_CONFIG = {
|
||||
alpha_moderate: { label: 'Alpha中等', color: '#ff7a45', description: '超额收益达到中等水平' },
|
||||
alpha_strong: { label: 'Alpha强', color: '#ff4d4f', description: '超额收益达到强势水平' },
|
||||
amt_moderate: { label: '成交额中等', color: '#faad14', description: '成交额异常放大中等' },
|
||||
amt_strong: { label: '成交额强', color: '#fa8c16', description: '成交额异常放大明显' },
|
||||
limit_up_moderate: { label: '涨停中等', color: '#eb2f96', description: '涨停股票数量适中' },
|
||||
limit_up_extreme: { label: '涨停极端', color: '#ff4d4f', description: '涨停股票数量很多' },
|
||||
momentum_3m_moderate: { label: '3分钟动量', color: '#1890ff', description: '短期动量信号触发' },
|
||||
momentum_3m_strong: { label: '3分钟强动量', color: '#096dd9', description: '短期强动量信号' },
|
||||
combo_alpha_amt: { label: 'Alpha+成交额', color: '#722ed1', description: '超额收益和成交额双重确认' },
|
||||
combo_alpha_limitup: { label: 'Alpha+涨停', color: '#eb2f96', description: '超额收益和涨停双重确认' },
|
||||
early_session: { label: '早盘信号', color: '#13c2c2', description: '开盘30分钟内的异动' },
|
||||
'decay:accelerating': { label: '加速中', color: '#52c41a', description: '异动正在加速' },
|
||||
'decay:stable': { label: '稳定', color: '#1890ff', description: '异动保持稳定' },
|
||||
'decay:fading': { label: '衰减中', color: '#8c8c8c', description: '异动正在衰减' },
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取异动标注的配色和符号
|
||||
* @param {string} alertType - 异动类型
|
||||
@@ -10,42 +211,41 @@
|
||||
* @returns {Object} { color, symbol, symbolSize }
|
||||
*/
|
||||
export const getAlertStyle = (alertType, importanceScore = 0.5) => {
|
||||
let color = '#ff6b6b';
|
||||
let symbol = 'pin';
|
||||
let symbolSize = 35;
|
||||
const config = ALERT_TYPE_CONFIG[alertType] || ALERT_TYPE_CONFIG.surge;
|
||||
const baseSize = 30;
|
||||
const sizeBonus = Math.min(importanceScore * 20, 15);
|
||||
|
||||
let symbol = 'pin';
|
||||
switch (alertType) {
|
||||
case 'surge_up':
|
||||
case 'surge':
|
||||
color = '#ff4757';
|
||||
case 'volume_surge_up':
|
||||
case 'shrink_surge_up':
|
||||
symbol = 'triangle';
|
||||
symbolSize = 30 + Math.min(importanceScore * 20, 15);
|
||||
break;
|
||||
case 'surge_down':
|
||||
color = '#2ed573';
|
||||
symbol = 'path://M0,0 L10,0 L5,10 Z'; // 向下三角形
|
||||
symbolSize = 30 + Math.min(importanceScore * 20, 15);
|
||||
symbol = 'path://M0,0 L10,0 L5,10 Z';
|
||||
break;
|
||||
case 'limit_up':
|
||||
color = '#ff6348';
|
||||
symbol = 'diamond';
|
||||
symbolSize = 28;
|
||||
break;
|
||||
case 'rank_jump':
|
||||
color = '#3742fa';
|
||||
symbol = 'circle';
|
||||
symbolSize = 25;
|
||||
break;
|
||||
case 'volume_spike':
|
||||
color = '#ffa502';
|
||||
case 'volume_oscillation':
|
||||
symbol = 'rect';
|
||||
symbolSize = 25;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
symbol = 'pin';
|
||||
}
|
||||
|
||||
return { color, symbol, symbolSize };
|
||||
return {
|
||||
color: config.color,
|
||||
gradient: config.gradient,
|
||||
symbol,
|
||||
symbolSize: baseSize + sizeBonus,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -54,16 +254,30 @@ export const getAlertStyle = (alertType, importanceScore = 0.5) => {
|
||||
* @returns {string} 显示标签
|
||||
*/
|
||||
export const getAlertTypeLabel = (alertType) => {
|
||||
const labels = {
|
||||
surge: '急涨',
|
||||
surge_up: '暴涨',
|
||||
surge_down: '暴跌',
|
||||
limit_up: '涨停增加',
|
||||
rank_jump: '排名跃升',
|
||||
volume_spike: '放量',
|
||||
unknown: '异动',
|
||||
return ALERT_TYPE_CONFIG[alertType]?.label || alertType || '异动';
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取异动类型的详细描述
|
||||
* @param {string} alertType - 异动类型
|
||||
* @returns {string} 描述
|
||||
*/
|
||||
export const getAlertTypeDescription = (alertType) => {
|
||||
return ALERT_TYPE_CONFIG[alertType]?.description || '概念板块出现异动信号';
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取异动类型的配色
|
||||
* @param {string} alertType - 异动类型
|
||||
* @returns {Object} { color, gradient, bgAlpha }
|
||||
*/
|
||||
export const getAlertTypeColor = (alertType) => {
|
||||
const config = ALERT_TYPE_CONFIG[alertType] || ALERT_TYPE_CONFIG.surge;
|
||||
return {
|
||||
color: config.color,
|
||||
gradient: config.gradient,
|
||||
bgAlpha: config.bgAlpha,
|
||||
};
|
||||
return labels[alertType] || alertType;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -88,7 +302,7 @@ export const getAlertMarkPoints = (alerts, times, prices, priceMax, maxCount = 1
|
||||
const timeIndex = times.indexOf(alert.time);
|
||||
const price = timeIndex >= 0 ? prices[timeIndex] : (alert.index_price || priceMax);
|
||||
|
||||
const { color, symbol, symbolSize } = getAlertStyle(
|
||||
const { color, gradient, symbol, symbolSize } = getAlertStyle(
|
||||
alert.alert_type,
|
||||
alert.final_score / 100 || alert.importance_score || 0.5
|
||||
);
|
||||
@@ -113,23 +327,33 @@ export const getAlertMarkPoints = (alerts, times, prices, priceMax, maxCount = 1
|
||||
symbol,
|
||||
symbolSize,
|
||||
itemStyle: {
|
||||
color,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 1,
|
||||
shadowBlur: 3,
|
||||
shadowColor: 'rgba(0,0,0,0.2)',
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0, y: 0, x2: 0, y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: gradient[0] },
|
||||
{ offset: 1, color: gradient[1] },
|
||||
],
|
||||
},
|
||||
borderColor: 'rgba(255,255,255,0.8)',
|
||||
borderWidth: 2,
|
||||
shadowBlur: 8,
|
||||
shadowColor: `${color}66`,
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
position: isDown ? 'bottom' : 'top',
|
||||
formatter: '{b}',
|
||||
fontSize: 9,
|
||||
color: '#333',
|
||||
backgroundColor: isDown ? 'rgba(46, 213, 115, 0.9)' : 'rgba(255,255,255,0.9)',
|
||||
padding: [2, 4],
|
||||
borderRadius: 2,
|
||||
fontSize: 10,
|
||||
fontWeight: 500,
|
||||
color: isDown ? '#52c41a' : '#ff4d4f',
|
||||
backgroundColor: 'rgba(255,255,255,0.95)',
|
||||
padding: [3, 6],
|
||||
borderRadius: 4,
|
||||
borderColor: color,
|
||||
borderWidth: 1,
|
||||
shadowBlur: 4,
|
||||
shadowColor: 'rgba(0,0,0,0.1)',
|
||||
},
|
||||
alertData: alert, // 存储原始数据
|
||||
};
|
||||
@@ -153,8 +377,45 @@ export const formatScore = (score) => {
|
||||
*/
|
||||
export const getScoreColor = (score) => {
|
||||
const s = score || 0;
|
||||
if (s >= 80) return '#ff4757';
|
||||
if (s >= 60) return '#ff6348';
|
||||
if (s >= 40) return '#ffa502';
|
||||
return '#747d8c';
|
||||
if (s >= 80) return '#ff4d4f';
|
||||
if (s >= 60) return '#fa8c16';
|
||||
if (s >= 40) return '#faad14';
|
||||
return '#8c8c8c';
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取分数等级标签
|
||||
* @param {number} score - 分数 (0-100)
|
||||
* @returns {Object} { label, color }
|
||||
*/
|
||||
export const getScoreLevel = (score) => {
|
||||
const s = score || 0;
|
||||
if (s >= 80) return { label: '强信号', color: '#ff4d4f' };
|
||||
if (s >= 60) return { label: '中等', color: '#fa8c16' };
|
||||
if (s >= 40) return { label: '一般', color: '#faad14' };
|
||||
return { label: '弱信号', color: '#8c8c8c' };
|
||||
};
|
||||
|
||||
/**
|
||||
* 格式化指标值
|
||||
* @param {string} metricKey - 指标键名
|
||||
* @param {number} value - 值
|
||||
* @returns {Object} { formatted, color, showSign }
|
||||
*/
|
||||
export const formatMetric = (metricKey, value) => {
|
||||
const config = METRIC_CONFIG[metricKey];
|
||||
if (!config || value === null || value === undefined) {
|
||||
return { formatted: '-', color: '#8c8c8c', showSign: false };
|
||||
}
|
||||
|
||||
const formatted = config.format(value);
|
||||
const color = config.getColor ? config.getColor(value) : '#8c8c8c';
|
||||
|
||||
return {
|
||||
formatted: config.showSign && value > 0 ? `+${formatted}` : formatted,
|
||||
color,
|
||||
unit: config.unit,
|
||||
label: config.label,
|
||||
tooltip: config.tooltip,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user