优化index的自动刷新,不占用内存了

This commit is contained in:
jackyu66git
2025-10-11 20:46:41 +08:00
parent ea24371930
commit eb6d4dae1e
5 changed files with 118 additions and 9 deletions
Vendored
BIN
View File
Binary file not shown.
+10 -5
View File
@@ -60,7 +60,7 @@ class ChanKLC():
def set_klc_fx_type(self, klc_fx_type):
#print(self.start_time, klc_fx_type, self.get_feature_data()['klu_macd'], self.get_feature_data()['klu_macdhist'], self.get_feature_data()['klu_rsi'])
self.klc_fx_type = klc_fx_type
#self.cal_invisible()
#self.cal_fx()
self.cal_bb_out()
def add_klu(self, klu):
self.klus.append(klu)
@@ -76,12 +76,9 @@ class ChanKLC():
if klu.macd_state != Chan_MACD_STATE.UNKNOWN:
self.state = klu.macd_state
self.cal_indicators()
def cal_invisible(self):
def cal_fx(self):
if self.klc_fx_type == Chan_KLC_FX.TOP1 or self.klc_fx_type == Chan_KLC_FX.TOP2:
#print(self.end_time, self.fx, self.macd, self.macdhist, len(self.klus))
if self.macdhist < 0 and self.macd > 0:
self.klc_fx_type = Chan_KLC_FX.TOP5
return
if self.state == Chan_MACD_STATE.HIGH_EMPTY and self.macd > 0:
#print(self.end_time, self.state, self.macd, self.klc_fx_type)
self.klc_fx_type = Chan_KLC_FX.TOP6
@@ -191,6 +188,14 @@ class ChanKLC():
return False
def set_fx(self, fx: Chan_FX_TYPE):
self.fx = fx
def cal_invisible(self):
if self.fx == Chan_FX_TYPE.TOP:
if self.macdhist < 0 and self.macd > 0:
self.klc_fx_type = Chan_KLC_FX.TOP5
else:
if self.fx == Chan_FX_TYPE.BOTTOM:
if self.macdhist > 0 and self.macd < 0:
self.klc_fx_type = Chan_KLC_FX.BOTTOM5
def set_pre_fx(self):
if self.pre and self.pre.pre:
self.pre.fx = self.check_fx(self.pre.pre, self.pre)
+4
View File
@@ -576,6 +576,8 @@ class ChanLun():
except Exception:
trend = Chan_PRICE_TREND.UNKNOWN
# 写回趋势
if klc.end_time is None:
trend = Chan_PRICE_TREND.FLAT
if hasattr(klc, 'set_trend'):
klc.set_trend(trend)
else:
@@ -640,6 +642,7 @@ class ChanLun():
#klc.set_state("20")
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
#klc.cal_invisible()
#klc.set_klc_fx_type(Chan_KLC_FX.TOP3)
#print(klc.start_time, klc.fx, "二类卖点Sell 1")
else:
@@ -764,6 +767,7 @@ class ChanLun():
#klc.set_state("-20")
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
#klc.cal_invisible()
#klc.set_klc_fx_type(Chan_KLC_FX.BOTTOM3)
#print(last_bottom.start_time, last_bottom.end_time, "--------------------------------1")
#print(klc.start_time, klc.fx, "二类买点Buy 1")
+2 -2
View File
@@ -127,12 +127,12 @@ class TF_DF():
def check_fx(self, klc):
if klc.pre and klc.next:
if klc.high > klc.pre.high and klc.high > klc.next.high:
if klc.macd > 0 and klc.macd > klc.signal and klc.signal > klc.macdhist:
if klc.macd > 0 and klc.signal > klc.macdhist:
klc.set_fx(Chan_FX_TYPE.TOP)
# print(klc.start_time, klc.end_time,klc.next.start_time, klc.next.end_time,klc.fx, "TOP")
return Chan_FX_TYPE.TOP
elif klc.low < klc.pre.low and klc.low < klc.next.low:
if klc.macd < 0 and klc.macd < klc.signal and klc.signal < klc.macdhist:
if klc.macd < 0 and klc.signal < klc.macdhist:
klc.set_fx(Chan_FX_TYPE.BOTTOM)
# print(klc.start_time, klc.end_time,klc.next.start_time, klc.next.end_time,klc.fx, "BOTTOM")
return Chan_FX_TYPE.BOTTOM
+102 -2
View File
@@ -1341,9 +1341,54 @@
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script>
let currentData = null;
let lastRequestId = 0; // 防止过期响应覆盖新数据
const tables = {};
// ======= 趋势筛选(币对) =======
let trendTable = null;
// 限长截断,减少前端长期持有历史数组导致的内存增长
function trimDataInPlace(payload, maxLen = 2000) {
const keepTail = (arr) => (Array.isArray(arr) && arr.length > maxLen) ? arr.slice(-maxLen) : arr;
if (!payload || typeof payload !== 'object') return;
// 主/次周期K线
payload.kline_data = keepTail(payload.kline_data);
payload.element_kline_data = keepTail(payload.element_kline_data);
// MACD
if (payload.macd) {
payload.macd.macd = keepTail(payload.macd.macd);
payload.macd.signal = keepTail(payload.macd.signal);
payload.macd.histogram = keepTail(payload.macd.histogram);
}
if (payload.element_macd) {
payload.element_macd.macd = keepTail(payload.element_macd.macd);
payload.element_macd.signal = keepTail(payload.element_macd.signal);
payload.element_macd.histogram = keepTail(payload.element_macd.histogram);
}
// ATR
payload.atr = keepTail(payload.atr);
payload.element_atr = keepTail(payload.element_atr);
// 分形/线段/中枢/买卖点
payload.bi_list = keepTail(payload.bi_list);
payload.seg_list = keepTail(payload.seg_list);
payload.zs_list = keepTail(payload.zs_list);
payload.uncompleted_zs_list = keepTail(payload.uncompleted_zs_list);
payload.element_bi_list = keepTail(payload.element_bi_list);
payload.element_seg_list = keepTail(payload.element_seg_list);
payload.element_zs_list = keepTail(payload.element_zs_list);
payload.element_uncompleted_zs_list = keepTail(payload.element_uncompleted_zs_list);
payload.trade_points = keepTail(payload.trade_points);
payload.element_trade_points = keepTail(payload.element_trade_points);
// 移除可能保存的旧快照,避免重复持有
delete payload.original_kline_data;
delete payload.original_macd;
}
let trendDetailTable = null;
let trendChart = null;
@@ -2230,6 +2275,7 @@
}
// 发送请求
const requestId = ++lastRequestId; // 标记本次请求
$.ajax({
url: '/api/analyze',
data: {
@@ -2244,8 +2290,21 @@
success: function(data) {
// 隐藏加载图标
$('#refreshLoadingSpinner').hide();
// 忽略过期响应
if (requestId !== lastRequestId) {
return;
}
// 截断数据以限制内存占用
trimDataInPlace(data, 2000);
// 保存当前数据
if (currentData) {
// 覆盖前断开旧引用,帮助GC尽快回收
delete currentData.original_kline_data;
delete currentData.original_macd;
}
currentData = data;
// 检查和记录服务器返回的时区
@@ -2267,6 +2326,34 @@
// 初始化图表
function initTradingView(symbol, timeframe) {
try {
// 在重新初始化前,尝试释放旧图表与系列资源,避免 GPU 内存累积
try {
if (tvWidget && tvWidget.state && tvWidget.state.isInitialized) {
// 主图
if (tvWidget.mainChart && typeof tvWidget.mainChart.remove === 'function') {
tvWidget.mainChart.remove();
}
// 成交量
if (tvWidget.volumeChart && typeof tvWidget.volumeChart.remove === 'function') {
tvWidget.volumeChart.remove();
}
// 旧 MACD(若存在)
if (tvWidget.macdChart && typeof tvWidget.macdChart.remove === 'function') {
tvWidget.macdChart.remove();
}
// 新 ChanMACD(若存在)
if (tvWidget.chanMacdChart && typeof tvWidget.chanMacdChart.remove === 'function') {
tvWidget.chanMacdChart.remove();
}
// ATR
if (tvWidget.atrChart && typeof tvWidget.atrChart.remove === 'function') {
tvWidget.atrChart.remove();
}
}
} catch (e) {
console.warn('释放旧图表资源失败(可忽略):', e);
}
console.log('初始化TradingView图表:', symbol, timeframe);
// 获取当前交易对的配置
@@ -2337,8 +2424,9 @@
console.log(`A股数据过滤: ${originalLength} -> ${candles.length} 条记录`);
}
// 清除图表容器
document.getElementById('tradingview_chart').innerHTML = '';
// 清除图表容器(释放旧 DOM 与 Canvas
const chartRoot = document.getElementById('tradingview_chart');
if (chartRoot) chartRoot.innerHTML = '';
// 重置图表对象
tvWidget = {
@@ -5683,6 +5771,18 @@
tvWidget.macdChart = macdChart;
tvWidget.chanMacdChart = chanMacdChart;
tvWidget.state.isInitialized = true;
// 注册窗口卸载时释放资源,避免GPU内存泄漏
window.onbeforeunload = function() {
try {
if (tvWidget && tvWidget.state && tvWidget.state.isInitialized) {
if (tvWidget.mainChart && typeof tvWidget.mainChart.remove === 'function') tvWidget.mainChart.remove();
if (tvWidget.volumeChart && typeof tvWidget.volumeChart.remove === 'function') tvWidget.volumeChart.remove();
if (tvWidget.macdChart && typeof tvWidget.macdChart.remove === 'function') tvWidget.macdChart.remove();
if (tvWidget.chanMacdChart && typeof tvWidget.chanMacdChart.remove === 'function') tvWidget.chanMacdChart.remove();
if (tvWidget.atrChart && typeof tvWidget.atrChart.remove === 'function') tvWidget.atrChart.remove();
}
} catch (e) {}
};
// 初始化默认EMA配置(仅在首次初始化时)
if (movingAverages.length === 0) {