缓存看股数据

This commit is contained in:
2026-08-16 21:24:41 +08:00
parent 65d2f54d1b
commit f192a08384
5 changed files with 45 additions and 758 deletions

View File

@@ -129,7 +129,22 @@ const g = (k: string) => (ts: number) => {
};
// 动态 MA按周期组合注册一次figures 的 key 必须静态,故按签名建缓存)
// 前端直接从收盘价计算 MA无需后端重拉数据切换均线周期即时响应
const _maReg = new Set<string>();
/** 滚动均值O(n) 滑动窗口min_periods=1与后端 pandas rolling 行为一致) */
function computeMA(closes: number[], period: number): (number | null)[] {
const n = closes.length;
const result: (number | null)[] = new Array(n);
let sum = 0;
for (let i = 0; i < n; i++) {
sum += closes[i];
if (i >= period) sum -= closes[i - period];
result[i] = sum / Math.min(i + 1, period);
}
return result;
}
function ensureMaIndicator(periods: number[]) {
const sig = [...periods].sort((a, b) => a - b).join('_');
if (_maReg.has(sig)) return `pv-ma-${sig}`;
@@ -140,11 +155,20 @@ function ensureMaIndicator(periods: number[]) {
key: `ma${p}`, title: `MA${p}`, type: 'line',
styles: () => ({ color: MA_COLORS[i % MA_COLORS.length] }),
})),
calc: (d: KLineData[]) => d.map((bar) => {
const row: Record<string, number | undefined> = {};
for (const p of periods) row[`ma${p}`] = g(`ma${p}`)(bar.timestamp);
return row;
}),
calc: (d: KLineData[]) => {
// 前端直接按收盘价计算 MA不从后端 PV 读取
const closes = d.map((b) => b.close);
const maValues: Record<string, (number | null)[]> = {};
for (const p of periods) maValues[`ma${p}`] = computeMA(closes, p);
return d.map((_, i) => {
const row: Record<string, number | undefined> = {};
for (const p of periods) {
const v = maValues[`ma${p}`][i];
if (v != null) row[`ma${p}`] = v;
}
return row;
});
},
});
_maReg.add(sig);
return `pv-ma-${sig}`;

View File

@@ -385,8 +385,7 @@ watch(active, (code) => {
}, { immediate: true });
watch(adjust, () => load(active.value));
watch(timeframe, () => load(active.value));
// MA 周期变化也要重拉后端按 mas 计算指标序列
watch(maPeriods, () => load(active.value));
// MA 周期变化:前端直接从收盘价计算,无需重拉后端数据DetailKLine.vue 的 watch 会触发图表重建
// 切股时同步自选状态
watch(active, (code) => {