# A股量化工具 **Repository Path**: ascano9/a-stock-quant ## Basic Information - **Project Name**: A股量化工具 - **Description**: A股量化交易全栈工具:实时行情 · 趋势诊断 · 回测 · 模拟交易(Node+TS+Vue3) - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-07-28 - **Last Updated**: 2026-08-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # A股量化交易工具 一套基于 **Node.js + TypeScript + Vue3** 的 A 股量化交易全栈方案,专为前端开发者设计,无需 Python 基础。 ## 技术架构 ``` +------------------------------------------+ | 前端监控面板 (Vue3) | | Element Plus + WebSocket 实时推送 | +------------------------------------------+ | +------------------------------------------+ | 后端服务 (Node.js + Express) | | REST API + WebSocket + 策略引擎 + 交易引擎 | +------------------------------------------+ | +------------------------------------------+ | 数据源 (免费公开 API) | | 腾讯财经(实时行情) + 东方财富(K线数据) | | 东财为主源,失败自动切腾讯备用源 | +------------------------------------------+ ``` ## 项目结构 ``` a-stock-quant/ ├── src/ │ ├── types/ # 核心类型定义 │ ├── config/ # 策略权重配置 │ │ └── coreWeights.ts # 核心票因子权重(可针对单票覆盖默认权重) │ ├── data/ # 数据采集模块 │ │ ├── fetcher.ts # 腾讯财经 / 东方财富 API(双源容错) │ │ └── adapters.ts # 数据缓存适配器(QuoteCache, 5s TTL) │ ├── strategy/ # 策略引擎 │ │ ├── base.ts # 技术指标计算 (SMA/EMA/MACD/RSI/BOLL) + BaseStrategy │ │ ├── maStrategy.ts # 双均线策略(金叉/死叉) │ │ ├── macdStrategy.ts # MACD 策略(含零轴分级) │ │ ├── closePickStrategy.ts# 尾盘选股(多因子打分 A/B/C/D 评级) │ │ └── trendAssistant.ts # 趋势 + 波段助手(趋势/支撑压力/高低点/背离诊断) │ ├── trade/ # 交易引擎 │ │ ├── engine.ts # 撮合与资金管理 │ │ ├── order.ts # 订单管理(状态机) │ │ └── position.ts # 持仓管理(成本/盈亏/冻结资金核算) │ ├── backtest/ # 回测引擎 │ │ ├── engine.ts # 尾盘选股回测(次日开盘卖出,胜率/回撤/年化) │ │ ├── trendSignalBacktest.ts# 组合信号回测(加仓摊薄/止损/最大持有天数) │ │ └── factorAnalysis.ts # 单因子信号未来收益分析 │ ├── server/ # 后端服务 │ │ ├── index.ts # Express + WebSocket 入口(5s cron 拉数据并广播) │ │ └── routes.ts # REST API 路由 │ └── utils/ # 工具函数 │ ├── stockCode.ts # 股票代码规范化(自动补 sh/sz 前缀) │ └── logger.ts # 日志模块 ├── web/ # 前端监控面板 (Vue3 + Vue Router + Element Plus) │ └── src/ │ ├── components/ # 业务组件 │ │ ├── MarketMonitor.vue # 实时行情表格(红涨绿跌,原 AccountSummary) │ │ ├── TrendAssistant.vue # 趋势助手面板(趋势/支撑压力/信号源/历史回测) │ │ ├── FactorAnalysis.vue # 单因子信号测试面板 │ │ ├── FactorTable.vue # 单因子结果表格 │ │ ├── WatchListManager.vue # 自选列表管理(localStorage + WS 同步) │ │ ├── WeightCell.vue # 因子权重单元格 │ │ └── PeriodCell.vue # 周期/信号展示子组件 │ ├── views/ # 页面视图 │ │ └── Home.vue # 主监控页(监控 + 趋势助手 + 单因子分析) │ ├── router/ # 前端路由 │ │ └── index.ts │ ├── api/ # API 封装 │ │ ├── index.ts # REST 请求封装 │ │ └── ws.ts # WebSocket 单例助手(setSocket / sendWS) │ ├── composables/ # 组合式函数 │ │ └── useWatchList.ts # 自选列表本地存储 + 首次同步逻辑 │ ├── types/ # 前端类型 │ ├── App.vue # 主布局(含 WS 连接与消息分发) │ └── main.ts # 入口 ├── scripts/ │ ├── test-fetch.ts # 数据抓取测试脚本 │ └── optimizeWeights.ts # 因子权重自动优化脚本(基于组合回测随机搜索) ├── package.json ├── tsconfig.json └── .env.example ``` ## 核心功能 ### 数据采集 - **实时行情**: 腾讯财经免费 API,支持沪深全市场(GBK 编码,`iconv-lite` 解码) - **历史K线**: 东方财富 API 为主源(支持日/周/月及分钟级别),失败时自动切换到腾讯备用源 - **数据缓存**: 实时行情 5 秒本地缓存,减少重复请求 ### 技术指标 - SMA(简单移动平均线) - EMA(指数移动平均线) - MACD(异同移动平均线) - RSI(相对强弱指数) - BOLL(布林带) ### 内置策略 - **双均线策略 (MA)**: 5日/20日均线金叉买入、死叉卖出 - **MACD策略**: DIF/DEA金叉买入、死叉卖出,零轴上方金叉置信度更高 - **尾盘选股 (ClosePick)**: 收盘前对监控列表做 5 因子打分(涨幅 / 量能 / 趋势 / RSI / 均价),输出 A/B/C/D 评级、参考买卖价与文字理由,权重可配。结果通过 REST API(`/api/close-pick`、`/api/backtest/close-pick`)获取 - **趋势助手 (TrendAssistant)**: 判定中/短期趋势、支撑压力位(MA/BOLL/近20日高低点)、高低点分数(RSI+BOLL+MACD背离),并给出文字波段建议——项目内"智能感"最强的一块。 - **背离优先级**:底/顶背离形成即对应买卖决策(背离优先于评分)。 - **超买抑制**:当短期已明显偏高(`state==='strong'`,即 RSI>65 或股价触及 BOLL 上轨)时,**已兑现的旧底背离不再作为低吸信号**,避免"涨停+多头排列仍报底背离"这类误报,此时交由后续逻辑改判持有 / 卖出。 > 说明:以上策略均为**规则 / 专家系统**(技术指标 + 多因子打分 + 启发式诊断),代码内不含机器学习或 LLM 调用。"AI" 体现在策略的工程化与自动化,而非模型训练。 ### 交易引擎 - **模拟交易**: 默认模式,虚拟资金自动撮合(立即按市价成交) - **实盘交易**: 预留接口,可对接券商 API(如中泰XTP、恒生PTrade等);`TRADE_MODE=real` 时只产生信号、不自动下单 - **持仓管理**: 自动计算成本、盈亏、市值 - **资金管理**: 冻结资金 = 当前持仓总成本(占用资金),由持仓成本统一核算,避免累计误差 - 手动下单与策略开关通过 REST API(`/api/orders`、`/api/strategies/:id/toggle`)提供,可由脚本或前端按需调用 ### 回测引擎 - **尾盘选股回测** (`/api/backtest/close-pick`): 以尾盘选股结果次日开盘价卖出,统计胜率、盈亏比、最大回撤、年化收益 - **趋势信号回测** (`/api/backtest/trend-signal`): 组合级回测,支持**加仓摊薄成本 / 止损 / 最大持有天数**三种离场,按组合总资金核算收益率与回撤,并记录每笔加仓明细 - **单因子信号分析** (`/api/backtest/factor-analysis`): 把趋势助手的每个信号来源拆开,统计未来 1/3/5/10/20 日的平均收益、方向胜率、最大可获利/最大可亏损,用于判断各因子可信度 ### 权重配置与优化 - **核心票权重** (`src/config/coreWeights.ts`): 可为单只股票覆盖默认因子权重,精细化控制 RSI/BOLL/背离/高低分等因子在趋势诊断中的贡献 - **权重自动优化** (`scripts/optimizeWeights.ts`): 基于组合回测做随机搜索,输出可直接复制到 `CORE_STOCK_WEIGHTS` 的权重对象。建议用 2023-2024 优化,2024-2025 样本外验证 ### 前端面板 当前前端为「监控 + 诊断 + 分析」三块式布局(单页 `Home.vue` 纵向堆叠): - **实时行情表格**(`MarketMonitor.vue`):监控列表内股票的代码/名称/现价/涨跌/量/高低开/昨收,红涨绿跌 - **趋势助手面板**(`TrendAssistant.vue`):趋势方向、支撑压力位、短期强弱、背离信号与文字建议,并内嵌趋势信号历史回测 - **单因子信号测试面板**(`FactorAnalysis.vue` + `FactorTable.vue`):查看各信号来源的未来收益分析 - **自选列表管理**(`WatchListManager.vue`):增删自选代码,即时同步到后端 > 说明:账户资产、持仓盈亏、手动下单、策略开关等能力由后端 REST API 提供(见 API 列表),当前前端面板未单独放置这些入口,可通过 API 或脚本调用。尾盘选股/回测同样经 REST API 使用,不在前端面板内嵌独立页面。 ### 自选列表与实时同步 自选监视列表**不存入数据库**: - **前端**:保存在浏览器 `localStorage`(key `a-stock-quant:watchlist`),仅存 6 位纯数字代码,刷新/重开不丢;由 `useWatchList` 组合式函数管理,含 `seeded` 标记——首次使用(本地无记录)时采纳后端推送的默认列表,一旦本地写过(含手动清空)则持久保留、不被覆盖。 - **后端**:`watchList` 为可变列表;WebSocket 收到 `set_watchlist` 后用 `normalizeStockCodes` 重设并广播;新连接时推送当前列表供前端首次同步。 - 这套机制让"手动加票"只需改本地存储 + WS 通知,无需后端 DB。 ## WebSocket 协议 后端每 5 秒推送一轮数据,并响应前端的列表设置: | 方向 | type | 说明 | |------|------|------| | 后端→前端 | `quote` | 实时行情数组(连接时立即推一次) | | 后端→前端 | `trend` | 趋势助手诊断数组(含 advice / signalSource) | | 后端→前端 | `watchlist` | 当前自选列表(连接时推送;`set_watchlist` 后广播) | | 前端→后端 | `set_watchlist` | `{ codes: string[] }` 覆盖后端监控列表并广播 | 前端通过 `api/ws.ts` 的 `setSocket` / `sendWS` 单例助手收发;断线自动重连(3 秒)。 ## 快速开始 ### 1. 安装后端依赖 ```bash cd a-stock-quant npm install ``` ### 2. 配置环境变量 ```bash cp .env.example .env ``` 编辑 `.env`: ```env # 交易模式: simulation(模拟) | real(实盘) TRADE_MODE=simulation INITIAL_CAPITAL=100000 # 监控股票列表(逗号分隔) WATCH_LIST=sh600519,sz000858,sz002594,sh601318 # 服务器端口 SERVER_PORT=3000 WS_PORT=3001 ``` ### 3. 启动后端服务 ```bash npm run dev ``` 服务启动后: - HTTP API: http://localhost:3000 - WebSocket: ws://localhost:3001 ### 4. 安装并启动前端 ```bash cd web pnpm install pnpm run dev ``` 前端地址: http://localhost:5173 打开浏览器访问即可看到监控面板。 ## API 列表 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/quotes` | 获取实时行情(支持 `?codes=` 批量,默认指数) | | GET | `/api/quotes/:code` | 获取单只股票行情 | | GET | `/api/kline/:code` | 获取K线数据(`?period=day\|week\|month`,`?limit=`) | | GET | `/api/stock-names` | 获取股票名称(`?codes=`) | | GET | `/api/account` | 获取账户信息(含冻结资金) | | GET | `/api/positions` | 获取持仓列表 | | GET | `/api/orders` | 获取订单列表 | | GET | `/api/orders/history` | 获取订单历史 | | POST | `/api/orders` | 手动下单(`code, direction, price, volume`) | | POST | `/api/orders/:id/cancel` | 取消订单 | | GET | `/api/strategies` | 获取策略列表 | | POST | `/api/strategies/:id/toggle` | 切换策略开关 | | GET | `/api/trade-mode` | 获取交易模式 | | POST | `/api/trade-mode` | 切换交易模式 | | POST | `/api/reset` | 重置交易数据 | | GET | `/api/close-pick` | 尾盘选股实时打分(`?topN=`,`?minScore=`,`?codes=`) | | GET | `/api/trend-assistant` | 趋势与波段助手诊断(`?codes=`) | | GET | `/api/backtest/close-pick` | 尾盘选股历史回测(`?startDate=`,`?endDate=`,`?topN=`,`?minScore=`) | | GET | `/api/backtest/trend-signal` | 趋势信号历史回测(`?maxHoldDays=`,`?stopLossPercent=`,`?positionAmount=`,`?initialCapital=`) | | GET | `/api/backtest/factor-analysis` | 单因子信号未来收益分析(`?startDate=`,`?endDate=`,`?codes=`) | | GET | `/api/health` | 健康检查 | ## 权重自动优化 项目提供 `scripts/optimizeWeights.ts`,基于**组合回测**随机搜索较优的因子权重,输出可直接复制到 `src/config/coreWeights.ts` 的 `CORE_STOCK_WEIGHTS`。 ### 基本用法 ```bash npx tsx scripts/optimizeWeights.ts ``` 默认使用 2023-01-01 ~ 2024-12-31、默认监控列表、30 次随机搜索。 ### 常用参数(环境变量) ```bash # 指定股票列表和区间 WATCH_LIST=sh600519,sz000858 START_DATE=2023-01-01 END_DATE=2024-12-31 npx tsx scripts/optimizeWeights.ts # 增加搜索次数(更精细,但更慢) TRIALS=100 npx tsx scripts/optimizeWeights.ts # 只追求收益(默认是收益/回撤综合指标) OPTIMIZE_METRIC=totalReturnPercent npx tsx scripts/optimizeWeights.ts ``` ### 建议流程 1. 用 **2023-2024** 数据跑优化脚本,得到一组权重。 2. 把脚本输出的 `CORE_STOCK_WEIGHTS` 复制到 `src/config/coreWeights.ts`。 3. 用 **2024-2025** 数据跑趋势信号回测 `/api/backtest/trend-signal` 做样本外验证。 4. **只有样本外表现更好时才使用优化权重**;否则保留默认权重(全 1.0)。 > 注意:权重优化本质是在历史数据上搜索,存在过拟合风险。单因子表现好不代表组合表现好,务必做样本外验证。 ## 自定义策略 在 `src/server/index.ts` 中注册你的策略: ```typescript import { MyStrategy } from './strategy/myStrategy'; const strategies: BaseStrategy[] = [ new MAStrategy('ma_5_20', { shortPeriod: 5, longPeriod: 20 }), new MACDStrategy('macd_default', { fastPeriod: 12, slowPeriod: 26, signalPeriod: 9 }), new MyStrategy('my_custom', { param1: 10, param2: 20 }), ]; ``` 策略需继承 `BaseStrategy`,实现 `onData` 方法: ```typescript import { BaseStrategy } from './base'; import type { RealTimeQuote, KLineData, TradeSignal } from '../types'; export class MyStrategy extends BaseStrategy { onData(quote: RealTimeQuote, klines: KLineData[]): TradeSignal | null { // 你的策略逻辑 // 返回 TradeSignal 或 null return this.generateSignal(quote, 'buy', '理由', 0.8, 100); } } ``` ## 实盘交易接入 当前系统预留了实盘交易接口。要接入真实券商,修改 `src/trade/engine.ts` 中的 `executeSimulation` 方法: 1. 接入券商提供的 SDK(如中泰 XTP、恒生 PTrade、东方财富 Choice 等) 2. 将 SDK 封装为 TypeScript 接口 3. 在 `processSignal` 中调用真实下单 API 4. 通过 WebSocket 接收成交回报 > 注意:实盘交易涉及真实资金,请务必充分测试,并自行承担风险。 ## 常见问题 ### 1. 实时行情中文乱码 腾讯财经接口返回的是 **GBK 编码**,本项目已使用 `iconv-lite` 自动解码。如果仍出现乱码,请确认已安装依赖: ```bash pnpm install ``` ### 2. K线数据获取失败,提示 `socket hang up` 这是东方财富服务器主动断开连接,通常是因为请求缺少浏览器头信息被反爬拦截。代码中已经自动添加 `User-Agent`、`Referer` 等浏览器 headers 并启用 3 次重试,**失败后会自动切换到腾讯 K 线备用源**。 如果仍然失败,请检查: 1. 是否开启了代理/VPN,尝试关闭后重试 2. 在 `.env` 中添加 `IGNORE_SSL_CERTIFICATE_ERRORS=true` 后重试 3. 在终端直接测试接口是否可达: ```bash curl -H "User-Agent: Mozilla/5.0" "https://push2his.eastmoney.com/api/qt/stock/kline/get?secid=1.600519&fields1=f1,f2,f3,f4,f5,f6&fields2=f51,f52,f53,f54,f55,f56,f57&klt=101&fqt=0&end=20500101&lmt=5" ``` 4. 东方财富接口偶尔不稳定,可稍后重试 ### 3. K线数据获取失败,提示证书错误 在 macOS 上 Node.js 可能无法识别东方财富的 HTTPS 证书,报错类似: ``` unable to get local issuer certificate ``` 解决方法:在 `.env` 文件中添加: ```env IGNORE_SSL_CERTIFICATE_ERRORS=true ``` 然后重启服务。**注意:仅用于本地开发,生产环境请勿开启。** ### 4. 接口都失败,是不是免费 API 被封了? 免费 API 目前仍可正常使用。如果全部失败,请按以下顺序排查: 1. 检查网络是否能访问 `http://qt.gtimg.cn` 和 `https://push2his.eastmoney.com` 2. 运行测试脚本查看具体错误: ```bash pnpm test:fetch ``` 3. 检查是否设置了代理或防火墙拦截 ## 免责声明 本项目仅供学习和技术交流使用,不构成任何投资建议。股市有风险,投资需谨慎。使用本项目进行实盘交易产生的任何损失,由使用者自行承担。 ## License MIT