refactor: 缠论引擎包化与 Web 分层(ECR-001)
将根目录引擎迁入 chanlun/ 并保留兼容 shim;拆分 TF_DF 与 web 服务; 前端模块化;strategies 改用 chanlun 导入;补充 ESS 文档与 golden 回归。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,356 @@
|
||||
/* chart_tables.js — split from chart.js */
|
||||
function updateTables(currentData) {
|
||||
// 检查数据有效性
|
||||
if (!currentData) {
|
||||
console.error('updateTables: 传入的数据为空');
|
||||
return;
|
||||
}
|
||||
|
||||
const data = currentData;
|
||||
|
||||
const useSubSubPeriod = $('#subSubPeriodKline').is(':checked');
|
||||
const useElementPeriod = $('#elementPeriodKline').is(':checked');
|
||||
const periodLabel = useSubSubPeriod ? '次次周期' : (useElementPeriod ? '小周期' : '主周期');
|
||||
console.log('数据表显示周期选择:', periodLabel);
|
||||
|
||||
// 笔数据表更新
|
||||
if (tables.bi) {
|
||||
tables.bi.clear().destroy();
|
||||
}
|
||||
|
||||
let biData, biSource;
|
||||
if (useSubSubPeriod && data.sub_sub_bi_list && data.sub_sub_bi_list.length > 0) {
|
||||
biData = data.sub_sub_bi_list;
|
||||
biSource = '次次周期';
|
||||
} else if (useElementPeriod && data.element_bi_list && data.element_bi_list.length > 0) {
|
||||
biData = data.element_bi_list;
|
||||
biSource = '小周期';
|
||||
} else {
|
||||
biData = data.bi_list;
|
||||
biSource = '主周期';
|
||||
}
|
||||
console.log(`表格显示${biSource}笔数据,共${biData ? biData.length : 0}条`);
|
||||
|
||||
tables.bi = $('#biTable').DataTable({
|
||||
data: biData || [],
|
||||
order: [[0, 'desc']],
|
||||
pageLength: 25,
|
||||
columns: [
|
||||
{ data: 'start_time', render: formatTime },
|
||||
{ data: 'end_time', render: formatTime },
|
||||
{ data: 'sure_time', render: formatConfirmTime },
|
||||
{ data: 'start_price', render: formatPrice },
|
||||
{ data: 'end_price', render: formatPrice },
|
||||
{ data: 'direction', render: formatDirection },
|
||||
{ data: 'macd_div', render: formatMacdValue }
|
||||
]
|
||||
});
|
||||
|
||||
// 线段数据表更新
|
||||
if (tables.seg) {
|
||||
tables.seg.clear().destroy();
|
||||
}
|
||||
|
||||
let segData, segSource, uncompletedSegData;
|
||||
if (useSubSubPeriod && data.sub_sub_seg_list && data.sub_sub_seg_list.length > 0) {
|
||||
segData = data.sub_sub_seg_list;
|
||||
uncompletedSegData = data.sub_sub_uncompleted_seg_list || [];
|
||||
segSource = '次次周期';
|
||||
} else if (useElementPeriod && data.element_seg_list && data.element_seg_list.length > 0) {
|
||||
segData = data.element_seg_list;
|
||||
uncompletedSegData = data.element_uncompleted_seg_list || [];
|
||||
segSource = '小周期';
|
||||
} else {
|
||||
segData = data.seg_list;
|
||||
uncompletedSegData = data.uncompleted_seg_list || [];
|
||||
segSource = '主周期';
|
||||
}
|
||||
|
||||
// 合并已完成和未完成的线段数据
|
||||
let allSegData = [];
|
||||
if (segData && segData.length > 0) {
|
||||
allSegData = allSegData.concat(segData.map(seg => ({...seg, status: '已完成'})));
|
||||
}
|
||||
if (uncompletedSegData && uncompletedSegData.length > 0) {
|
||||
allSegData = allSegData.concat(uncompletedSegData.map(seg => ({...seg, status: '未完成'})));
|
||||
}
|
||||
|
||||
console.log(`表格显示${segSource}线段数据,已完成${segData ? segData.length : 0}条,未完成${uncompletedSegData ? uncompletedSegData.length : 0}条,总计${allSegData.length}条`);
|
||||
|
||||
tables.seg = $('#segTable').DataTable({
|
||||
data: allSegData,
|
||||
order: [[0, 'desc']],
|
||||
pageLength: 25,
|
||||
columns: [
|
||||
{ data: 'start_time', render: formatTime },
|
||||
{ data: 'end_time', render: function(data, type, row) {
|
||||
if (data === null || data === undefined) {
|
||||
return type === 'display' ? '<span style="color: red;">未完成</span>' : '';
|
||||
}
|
||||
return formatTime(data, type, row);
|
||||
}},
|
||||
{ data: 'sure_time', render: formatConfirmTime },
|
||||
{ data: 'start_price', render: formatPrice },
|
||||
{ data: 'end_price', render: function(data, type, row) {
|
||||
if (data === null || data === undefined) {
|
||||
return type === 'display' ? '<span style="color: red;">未完成</span>' : '';
|
||||
}
|
||||
return formatPrice(data, type, row);
|
||||
}},
|
||||
{ data: 'direction', render: formatDirection },
|
||||
{ data: 'status', render: function(data, type, row) {
|
||||
if (type === 'display') {
|
||||
const color = data === '已完成' ? 'green' : 'red';
|
||||
return `<span style="color: ${color}; font-weight: bold;">${data}</span>`;
|
||||
}
|
||||
return data;
|
||||
}}
|
||||
]
|
||||
});
|
||||
|
||||
// 中枢数据表更新
|
||||
if (tables.zs) {
|
||||
tables.zs.clear().destroy();
|
||||
}
|
||||
|
||||
let zsData, zsSource;
|
||||
if (useSubSubPeriod && data.sub_sub_zs_list && data.sub_sub_zs_list.length > 0) {
|
||||
zsData = data.sub_sub_zs_list;
|
||||
zsSource = '次次周期';
|
||||
} else if (useElementPeriod && data.element_zs_list && data.element_zs_list.length > 0) {
|
||||
zsData = data.element_zs_list;
|
||||
zsSource = '小周期';
|
||||
} else {
|
||||
zsData = data.zs_list;
|
||||
zsSource = '主周期';
|
||||
}
|
||||
console.log(`表格显示${zsSource}中枢数据,共${zsData ? zsData.length : 0}条`);
|
||||
|
||||
tables.zs = $('#zsTable').DataTable({
|
||||
data: zsData || [],
|
||||
order: [[0, 'desc']],
|
||||
pageLength: 25,
|
||||
columns: [
|
||||
{ data: 'start_time', render: formatTime },
|
||||
{ data: 'end_time', render: formatTime },
|
||||
{ data: 'zg', render: formatPrice },
|
||||
{ data: 'zd', render: formatPrice }
|
||||
]
|
||||
});
|
||||
|
||||
// 买卖点数据表更新
|
||||
if (tables.tradePoints) {
|
||||
tables.tradePoints.clear().destroy();
|
||||
}
|
||||
|
||||
let tradePointsData, tradePointsSource;
|
||||
if (useSubSubPeriod && data.sub_sub_bsp_list && data.sub_sub_bsp_list.length > 0) {
|
||||
tradePointsData = data.sub_sub_bsp_list;
|
||||
tradePointsSource = '次次周期';
|
||||
} else if (useElementPeriod && (data.element_trade_points && data.element_trade_points.length > 0 || data.element_bsp_list && data.element_bsp_list.length > 0)) {
|
||||
tradePointsData = data.element_trade_points || data.element_bsp_list;
|
||||
tradePointsSource = '小周期';
|
||||
} else {
|
||||
tradePointsData = data.trade_points || data.bsp_list;
|
||||
tradePointsSource = '主周期';
|
||||
}
|
||||
console.log(`表格显示${tradePointsSource}买卖点数据,共${tradePointsData ? tradePointsData.length : 0}条`);
|
||||
|
||||
tables.tradePoints = $('#tradePointsTable').DataTable({
|
||||
data: tradePointsData || [],
|
||||
order: [[0, 'desc']],
|
||||
pageLength: 25,
|
||||
columns: [
|
||||
{ data: 'time', render: formatTime },
|
||||
{ data: 'price', render: formatPrice },
|
||||
{ data: 'type', render: formatTradePointType },
|
||||
{ data: 'desc' }
|
||||
]
|
||||
});
|
||||
|
||||
// 更新数据源信息显示
|
||||
const selectedPeriod = useSubSubPeriod ? '次次周期' : (useElementPeriod ? '小周期' : '主周期');
|
||||
const timeframe = useSubSubPeriod && data.sub_sub_timeframe ? data.sub_sub_timeframe : (useElementPeriod && data.element_timeframe ? data.element_timeframe : $('#timeframe').val());
|
||||
$('#dataSourceText').html(`当前显示的是<strong>${selectedPeriod} (${timeframe})</strong> 数据`);
|
||||
|
||||
// K线数据表更新
|
||||
if (tables.kline) {
|
||||
tables.kline.clear().destroy();
|
||||
}
|
||||
|
||||
// 根据用户选择决定使用哪个周期的K线数据
|
||||
let klineData, klineSource;
|
||||
if (useSubSubPeriod && data.sub_sub_kline_data && data.sub_sub_kline_data.length > 0) {
|
||||
klineData = data.sub_sub_kline_data;
|
||||
klineSource = '次次周期';
|
||||
} else if (useElementPeriod && data.element_kline_data && data.element_kline_data.length > 0) {
|
||||
klineData = data.element_kline_data;
|
||||
klineSource = '小周期';
|
||||
} else {
|
||||
klineData = data.kline_data;
|
||||
klineSource = '主周期';
|
||||
}
|
||||
console.log(`表格显示${klineSource}K线数据,共${klineData ? klineData.length : 0}条`);
|
||||
|
||||
tables.kline = $('#klineTable').DataTable({
|
||||
data: klineData || [],
|
||||
order: [[0, 'desc']],
|
||||
pageLength: 25,
|
||||
columns: [
|
||||
{ data: 'date', render: function(data) { return formatTime(data); } },
|
||||
{ data: 'open', render: formatPrice },
|
||||
{ data: 'high', render: formatPrice },
|
||||
{ data: 'low', render: formatPrice },
|
||||
{ data: 'close', render: formatPrice },
|
||||
{ data: 'volume', render: function(data) { return parseInt(data).toLocaleString(); } }
|
||||
]
|
||||
});
|
||||
|
||||
// 未完成中枢数据表更新
|
||||
if (tables.uncompletedZs) {
|
||||
tables.uncompletedZs.clear().destroy();
|
||||
}
|
||||
|
||||
let uncompletedZsData, uncompletedZsSource;
|
||||
if (useSubSubPeriod && data.sub_sub_uncompleted_zs_list && data.sub_sub_uncompleted_zs_list.length > 0) {
|
||||
uncompletedZsData = data.sub_sub_uncompleted_zs_list;
|
||||
uncompletedZsSource = '次次周期';
|
||||
} else if (useElementPeriod && data.element_uncompleted_zs_list && data.element_uncompleted_zs_list.length > 0) {
|
||||
uncompletedZsData = data.element_uncompleted_zs_list;
|
||||
uncompletedZsSource = '小周期';
|
||||
} else {
|
||||
uncompletedZsData = data.uncompleted_zs_list;
|
||||
uncompletedZsSource = '主周期';
|
||||
}
|
||||
console.log(`表格显示${uncompletedZsSource}未完成中枢数据,共${uncompletedZsData ? uncompletedZsData.length : 0}条`);
|
||||
|
||||
tables.uncompletedZs = $('#uncompletedZsTable').DataTable({
|
||||
data: uncompletedZsData || [],
|
||||
order: [[0, 'desc']],
|
||||
pageLength: 25,
|
||||
columns: [
|
||||
{ data: 'start_time', render: formatTime },
|
||||
{ data: 'zg', render: formatPrice },
|
||||
{ data: 'zd', render: formatPrice }
|
||||
]
|
||||
});
|
||||
|
||||
// MACD数据表更新
|
||||
if (tables.macd) {
|
||||
tables.macd.clear().destroy();
|
||||
}
|
||||
|
||||
// 根据用户选择决定使用哪个周期的MACD数据
|
||||
let macdDisplayData = [];
|
||||
let macdSource;
|
||||
if (useElementPeriod && data.element_kline_data && data.element_macd) {
|
||||
// 使用小周期数据
|
||||
macdSource = '小周期';
|
||||
macdDisplayData = data.element_kline_data.map((item, index) => {
|
||||
return {
|
||||
time: item.date,
|
||||
close: item.close,
|
||||
macd: data.element_macd.macd[index],
|
||||
signal: data.element_macd.signal[index],
|
||||
histogram: data.element_macd.histogram[index]
|
||||
};
|
||||
});
|
||||
} else if (data.kline_data && data.macd) {
|
||||
// 使用主周期数据
|
||||
macdSource = '主周期';
|
||||
macdDisplayData = data.kline_data.map((item, index) => {
|
||||
return {
|
||||
time: item.date,
|
||||
close: item.close,
|
||||
macd: data.macd.macd[index],
|
||||
signal: data.macd.signal[index],
|
||||
histogram: data.macd.histogram[index]
|
||||
};
|
||||
});
|
||||
}
|
||||
console.log(`表格显示${macdSource}MACD数据,共${macdDisplayData.length}条`);
|
||||
|
||||
tables.macd = $('#macdTable').DataTable({
|
||||
data: macdDisplayData,
|
||||
order: [[0, 'desc']],
|
||||
pageLength: 25,
|
||||
columns: [
|
||||
{ data: 'time', render: formatTime },
|
||||
{ data: 'close', render: formatPrice },
|
||||
{ data: 'macd', render: formatMacdValue },
|
||||
{ data: 'signal', render: formatMacdValue },
|
||||
{ data: 'histogram', render: formatMacdValue }
|
||||
]
|
||||
});
|
||||
|
||||
// 更新数据源信息
|
||||
setupDataSourceInfo(data);
|
||||
}
|
||||
// 设置数据源信息显示
|
||||
function setupDataSourceInfo(data) {
|
||||
const useSubSubPeriod = $('#subSubPeriodKline').is(':checked');
|
||||
const useElementPeriod = $('#elementPeriodKline').is(':checked');
|
||||
const mainTimeframe = $('#timeframe').val();
|
||||
const elementTimeframe = data.element_timeframe || mainTimeframe;
|
||||
const subSubTimeframe = data.sub_sub_timeframe || elementTimeframe;
|
||||
|
||||
$('#kline-tab, #macd-tab').off('click').on('click', function() {
|
||||
$('.data-source-info').show();
|
||||
if (useSubSubPeriod && data.sub_sub_kline_data && data.sub_sub_kline_data.length > 0) {
|
||||
$('#dataSourceText').html(`当前显示的是<strong>次次周期 (${subSubTimeframe})</strong> 数据`);
|
||||
} else if (useElementPeriod && data.element_kline_data && data.element_kline_data.length > 0) {
|
||||
$('#dataSourceText').html(`当前显示的是<strong>小周期 (${elementTimeframe})</strong> 数据`);
|
||||
} else {
|
||||
$('#dataSourceText').html(`当前显示的是<strong>主周期 (${mainTimeframe})</strong> 数据`);
|
||||
}
|
||||
});
|
||||
|
||||
$('#bi-tab').off('click').on('click', function() {
|
||||
$('.data-source-info').show();
|
||||
if (useSubSubPeriod && data.sub_sub_bi_list && data.sub_sub_bi_list.length > 0) {
|
||||
$('#dataSourceText').html(`当前显示的是<strong>次次周期 (${subSubTimeframe})</strong> 笔数据`);
|
||||
} else if (useElementPeriod && data.element_bi_list && data.element_bi_list.length > 0) {
|
||||
$('#dataSourceText').html(`当前显示的是<strong>小周期 (${elementTimeframe})</strong> 笔数据`);
|
||||
} else {
|
||||
$('#dataSourceText').html(`当前显示的是<strong>主周期 (${mainTimeframe})</strong> 笔数据`);
|
||||
}
|
||||
});
|
||||
|
||||
$('#seg-tab').off('click').on('click', function() {
|
||||
$('.data-source-info').show();
|
||||
if (useSubSubPeriod && data.sub_sub_seg_list && data.sub_sub_seg_list.length > 0) {
|
||||
$('#dataSourceText').html(`当前显示的是<strong>次次周期 (${subSubTimeframe})</strong> 线段数据`);
|
||||
} else if (useElementPeriod && data.element_seg_list && data.element_seg_list.length > 0) {
|
||||
$('#dataSourceText').html(`当前显示的是<strong>小周期 (${elementTimeframe})</strong> 线段数据`);
|
||||
} else {
|
||||
$('#dataSourceText').html(`当前显示的是<strong>主周期 (${mainTimeframe})</strong> 线段数据`);
|
||||
}
|
||||
});
|
||||
|
||||
$('#zs-tab').off('click').on('click', function() {
|
||||
$('.data-source-info').show();
|
||||
if (useSubSubPeriod && data.sub_sub_zs_list && data.sub_sub_zs_list.length > 0) {
|
||||
$('#dataSourceText').html(`当前显示的是<strong>次次周期 (${subSubTimeframe})</strong> 中枢数据`);
|
||||
} else if (useElementPeriod && data.element_zs_list && data.element_zs_list.length > 0) {
|
||||
$('#dataSourceText').html(`当前显示的是<strong>小周期 (${elementTimeframe})</strong> 中枢数据`);
|
||||
} else {
|
||||
$('#dataSourceText').html(`当前显示的是<strong>主周期 (${mainTimeframe})</strong> 中枢数据`);
|
||||
}
|
||||
});
|
||||
|
||||
$('#trade-points-tab').off('click').on('click', function() {
|
||||
$('.data-source-info').show();
|
||||
if (useSubSubPeriod && data.sub_sub_bsp_list && data.sub_sub_bsp_list.length > 0) {
|
||||
$('#dataSourceText').html(`当前显示的是<strong>次次周期 (${subSubTimeframe})</strong> 买卖点数据`);
|
||||
} else if (useElementPeriod && data.element_trade_points && data.element_trade_points.length > 0) {
|
||||
$('#dataSourceText').html(`当前显示的是<strong>小周期 (${elementTimeframe})</strong> 买卖点数据`);
|
||||
} else {
|
||||
$('#dataSourceText').html(`当前显示的是<strong>主周期 (${mainTimeframe})</strong> 买卖点数据`);
|
||||
}
|
||||
});
|
||||
|
||||
// 初始触发当前标签的点击事件
|
||||
$('.nav-link.active').trigger('click');
|
||||
}
|
||||
|
||||
// 获取可用交易对
|
||||
Reference in New Issue
Block a user