一、 背景 (Background)
在金融二级市场中,投资者面临着海量且瞬息万变的数据。手动追踪多只股票并识别交易机会不仅耗时,且容易受到情绪干扰。为了解决这一痛点,我们决定开发一个轻量级的量化终端。它既能实时监控沪深两市的股票行情,又能通过预设算法(如双均线策略)自动识别买卖信号,将感性投资转化为理性逻辑。
C:\myApp\stock-app
二、 目标 (Goal)
- 多市场兼容:支持输入 6 位代码自动识别沪市(SH)与深市(SZ)行情。
- 数据持久化:利用本地存储(LocalStorage)实现自选股列表的断电记忆。
- 专业可视化:集成 ECharts,绘制符合金融标准的专业 K 线图与均线系统。
- 策略模拟 :实现经典"趋势追踪"策略,通过模拟 100 天数据验证 MA5 与 MA20 交叉信号的有效性。

三、 方法 (Methodology)
我们采用了典型的 全栈前后端分离架构:
- 后端 (Node.js + Express) :作为数据中继站。由于 A 股接口(如新浪财经)存在防盗链和编码(GBK)限制,后端通过
axios伪造Referer并利用iconv-lite进行转码,为前端提供清洁的 JSON 数据。 - 前端 (HTML5 + CSS3 + ECharts):负责 UI 展示与交互。利用浏览器本地存储记录自选股。
- 算法层 (JavaScript):
- 均线算法:滑动窗口平均值计算。
- 策略信号:金叉/死叉判定逻辑(Cross-over detection)。
四、 过程 (Process: 源代码核心解析)
1. 后端:智能市场识别与转码
核心代码片段展示了如何根据代码首位自动补全 sh 或 sz 前缀,并处理繁琐的 GBK 编码:
javascript
// server.js 核心逻辑
app.get('/api/stock/:code', async (req, res) => {
const { code } = req.params;
// 识别逻辑:6开头为沪市,0/3开头为深市
let prefix = (code.startsWith('6')) ? 'sh' : 'sz';
const response = await axios.get(`http://hq.sinajs.cn/list=${prefix}${code}`, {
responseType: 'arraybuffer', // 获取二进制流以处理转码
headers: { 'Referer': 'http://finance.sina.com.cn/' }
});
// 转码 GBK -> UTF-8
const decodedData = iconv.decode(Buffer.from(response.data), 'gbk');
// ...解析字符串并返回 JSON
});
2. 前端:双均线策略算法
系统通过以下逻辑在时间序列中寻找买卖点:
javascript
// 均线计算:滑动平均值
function calcMA(dayCount, data) {
return data.map((_, idx) => {
if (idx < dayCount - 1) return '-'; // 初始点不足
const sum = data.slice(idx - dayCount + 1, idx + 1).reduce((a, b) => a + b);
return (sum / dayCount).toFixed(2);
});
}
// 信号判定
if (ma5[i-1] <= ma20[i-1] && ma5[i] > ma20[i]) {
// 短期均线上穿长期均线 -> 金叉买入
}
3. 可视化渲染
通过 ECharts 的 candlestick (K线) 和 line (均线) 复合渲染,将抽象的数字转化为直观的图表。
五、 结果 (Result)
经过多次迭代,系统实现了以下成果:
- 自动化实时监控:每 5-10 秒自动全量刷新自选股行情,涨跌配色采用 A 股传统的"红涨绿跌"。
- 准确的策略标注:在模拟的 100 天走势图中,系统精准标注出了每一次金叉与死叉。
- 零延迟交互:点击左侧列表即可瞬间切换右侧 K 线主视图,用户体验丝滑。