十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

手把手教你用OpenStock搭建开源股票行情分析系统

手把手教你用OpenStock搭建开源股票行情分析系统 如果你打算自己动手搭一套开源的股票行情分析系统那 OpenStock 这个名字你应该不陌生。它是一个把行情数据采集、K线展示、指标计算、自选股管理集成在一起的开源项目核心价值是让你不依赖商业软件自己掌控数据自己决定功能怎么改。这个项目特别适合三类人一是想沉淀一套私有行情数据库的量化初学者二是想折腾全栈项目练手的开发者三是受够了传统行情软件广告和功能臃肿的个人投资者。这篇博文我就以“手把手教你搭建OpenStock”为主线先把项目的整体结构和设计思路拆开讲清楚再带你从零开始完成环境准备、数据导入、后端启动、前端装配最后把我在实际搭建中踩过的坑和排查方法一并整理出来。跟着走一遍你就能拥有一套完全属于自己的行情分析系统。1. 先把 OpenStock 看明白再动手1.1 这个开源项目到底解决什么问题很多做股票数据分析的朋友都会遇到一个尴尬局面市面上的行情软件功能很全但数据封闭在别人的服务器里想导出来做策略回测、画自定义指标、做数据统计基本没门。而 OpenStock 这类项目走的是另一条路——它把“数据采集、存储、分析、展示”整个链路都放到你自己的环境里。从功能模块上看OpenStock 大致包含四个层次第一层是数据接入层负责从公开数据源拉取日线、分钟线、财务指标等数据第二层是存储层把数据落进本地数据库常见的选型是 PostgreSQL 或 SQLite第三层是业务服务层提供 REST API包括股票列表查询、K线查询、指标计算、自选股管理第四层是前端展示层通过 Web 页面把走势图、指标、持仓信息呈现出来。换句话说搭建好的 OpenStock 相当于你自己维护了一个“私有版行情终端”。你可以在上面批量导入历史行情按自己的逻辑做二次计算甚至改前端样式做成完全定制化的看盘工具。对于量化入门者来说这还是一个很完整的全栈学习样本代码量不大但麻雀虽小五脏俱全。1.2 为什么建议自己动手搭建而不是直接用在线服务如果你只是每天看一眼行情那直接用市面上的免费软件就够了没必要折腾 OpenStock。但如果你有下面任何一条需求自建的价值就体现出来了你希望把几年的历史行情永久保存在本地不受第三方接口下架影响。你想把自己写的选股条件、技术指标公式植入到系统里在线工具做不到这么灵活。你想学习从“数据-接口-页面”这条完整链路搭建过程本身就是最好的项目实战。你的分析数据涉及隐私比如自选股、持仓记录不希望存放在第三方平台。我在搭建 OpenStock 之前也犹豫过数据源用什么数据库选哪个前端要不要单独构建真正把流程跑通之后才发现项目的设计整体是朝着“个人可维护”这个方向走的。它不像企业级系统那么复杂但足够支撑一个人的日常分析需求。1.3 搭建 OpenStock 需要准备哪些基础环境工欲善其事必先利其器。在开始拉代码之前我先列一下我用的环境你可以根据自己的情况调整操作系统Ubuntu 22.04 / macOS / Windows 均可后面命令我会区分说明。内存最低 2GB建议 4GB 以上。如果你把 MySQL 或 PostgreSQL 和服务跑在同一台机器上内存 4GB 是安全线。磁盘预留 5GB 左右空间。如果导入全量 A 股日线数据量大概在几百 MB 到 1GB 之间加上数据库索引和前端构建产物5GB 足够。软件Git、Python 3.9、Node.js 16以及包管理工具 pip 和 npm。数据库OpenStock 默认支持 SQLite 作为轻量选项也支持 PostgreSQL。第一次搭建建议先用 SQLite省去装数据库服务端的步骤跑通后再迁 PostgreSQL 也不迟。网络需要能访问 GitHub 拉取源码同时行情数据源是国内的公开接口网络正常即可。如果你是纯新手建议先在一台 Linux 云服务器或本地虚拟机上练习。用 Windows 也没有问题但要注意后面提到的依赖安装细节因为 Windows 下部分 Python 包需要预编译的 wheel 文件。2. 环境准备与源码获取半小时跑通初始化2.1 从 GitHub 下载源码与分支选择打开终端先找一个合适的目录存放项目然后执行git clone https://github.com/your-fork/openstock.git cd openstock我这里写的是 your-fork 的地址实际使用时建议你先去项目主页把仓库 fork 到自己账号下理由很简单方便你后续记录自己的改动也能避免原仓库更新后本地代码冲突。克隆完成后先看一下项目的目录结构正常情况下你会看到类似这样的布局openstock/ ├── backend/ # 后端服务API 和数据处理 │ ├── app/ # 主逻辑代码 │ ├── migrations/ # 数据库迁移脚本 │ ├── scripts/ # 数据导入等独立脚本 │ └── requirements.txt # Python 依赖清单 ├── frontend/ # 前端页面 │ ├── src/ # Vue 或 React 源码 │ └── package.json # 前端依赖配置 ├── docs/ # 项目文档 └── README.md # 说明第一次拉代码我建议直接使用默认分支。项目一般把稳定版本放在 main 或 master 分支开发分支可能包含未完成的功能不适合新手。你可以通过git tag查看有哪些发布版本选择最新的稳定 tag 来切分支例如git checkout v1.0.0这样能最大程度减少搭建过程中遇到半成品功能导致的怪问题。2.2 后端 Python 依赖安装与虚拟环境隔离后端是 OpenStock 的核心负责数据采集和 API 服务。我强烈建议在 Python 虚拟环境中安装依赖。Python 项目依赖之间的版本冲突有多烦人经历过的人都懂。先创建并激活虚拟环境cd backend python3 -m venv venv source venv/bin/activate # Windows 下是 venv\Scripts\activate然后升级 pip 并安装依赖pip install --upgrade pip pip install -r requirements.txt这里有一个常见问题国内网络环境下默认的 PyPI 源可能很慢导致安装超时。你可以临时切换为国内镜像源实测速度提升明显pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple依赖安装完成后可以顺手验证一下关键包是否正常导入。常见的几个包包括 fastapi、uvicorn、sqlalchemy、pandas、akshare 等。如果某个包导入报错优先检查 Python 版本是否满足要求其次检查是否使用了虚拟环境。2.3 配置文件与数据库初始化后端代码里通常会有一个示例配置文件比如.env.example里面保存了数据库连接串、服务端口、密钥等参数。第一次使用时要把它复制一份并编辑cp .env.example .env vim .env重点看这几个配置项DATABASE_URL如果使用 SQLite值类似sqlite:///./openstock.db如果使用 PostgreSQL则是postgresql://user:passwordlocalhost:5432/openstock。API_PORT后端服务监听端口默认一般是 8000。SECRET_KEY用于会话和 Token 签名的密钥可以随便改成一个随机字符串。配置完成之后执行数据库迁移命令。大部分项目用 Alembic 管理迁移命令一般是alembic upgrade head执行完毕后数据库里应该会出现 users、stocks、kline_daily 等基础表。你可以用 sqlite3 或数据库客户端查看sqlite3 openstock.db .tables看到表结构正常生成说明初始化成功。这个步骤是整个搭建过程中最容易出问题的地方之一尤其是数据库连接串写错会导致迁移一直报错。我的建议是先本地起一个 PostgreSQL 测试环境把连接串搞明白了再决定是否切回 SQLite。3. 数据层让行情数据真正流动起来3.1 行情数据源接入的三种常见方式OpenStock 的数据层设计核心是“统一数据模型 可替换数据源”。也就是说不管是日线还是分钟线入库后都遵循同一套表结构数据源则通过脚本或接口对接。我实际测试下来有三种方式可以把行情数据导入系统官方内置的数据采集脚本。这种方式最省事脚本会根据配置的股票代码列表批量拉取数据解析后直接写入数据库。缺点是速度受限于数据源接口频率第一次导入全量历史数据需要比较长时间。CSV 文件批量导入。如果你手里有从其他渠道导出的历史行情文件可以用项目提供的导入脚本把 CSV 转成数据库记录。这种方式适合已经有现成数据的用户也能用于数据订正。通过 API 接口在线写入。OpenStock 后端暴露了一些写入接口方便你写独立的采集程序把其他数据源拿到的数据推送给 OpenStock。这种方式扩展性最强适合二次开发。对于第一次搭建我建议先用内置脚本跑一批日线数据等流程完全熟悉了再考虑写自己的采集程序。3.2 执行首次全量历史行情导入进入数据采集脚本目录通常会有类似python scripts/fetch_kline.py的入口。核心参数包括股票代码、开始日期、结束日期、K线周期。以下是我使用的一个示例命令cd backend python scripts/fetch_kline.py --symbol 600519.SH --start 20200101 --end 20231231 --freq daily这里的600519.SH是贵州茅台的证券代码格式一般是“代码.交易所后缀”。开始日期和结束日期控制拉取范围频率参数支持 daily、weekly、monthly 还有分钟级别。执行过程中脚本会打印每一只股票的拉取进度。如果中途因为网络问题中断不要慌直接重跑同一条命令OpenStock 一般会做去重处理已经写入的数据不会重复而是继续补充缺失的部分。这也是为什么我建议你拉数据的时候保留一个“起始日期”参数方便随时续传。导入完成后你可以用下面这条命令大致检查一下数据量sqlite3 openstock.db SELECT COUNT(*), MIN(trade_date), MAX(trade_date) FROM kline_daily WHERE symbol600519.SH;如果数量明显少于预期检查一下数据源在该时间区间是否停牌或者接口是否真的返回了数据。3.3 增量更新与定时任务配置历史数据导入只是第一步每天收盘后的增量更新才是常态。OpenStock 项目里一般有独立的增量更新脚本命令类似python scripts/update_daily.py这个脚本会读取数据库里每只股票的最新交易日期然后从那一天的下一个工作日开始增量拉取直到最新交易日。这样做的好处是每次只需要请求少量数据既节省时间也降低触发数据源限频的风险。我建议把增量更新配置成定时任务。Linux 环境下用 crontab例如每个交易日收盘后半小时执行一次30 16 * * 1-5 cd /path/to/openstock/backend /path/to/venv/bin/python scripts/update_daily.py /var/log/openstock_update.log 21Windows 下就用“任务计划程序”设置触发器为工作日指定时间操作指向 venv 里的 python.exe 和脚本路径。千万要记住一个坑不要在工作日盘中频繁跑增量更新很多公开数据源对单 IP 请求频率有限制短时间大量请求会被暂时封禁轻则本次拿不到数据重则影响后续所有更新任务。4. 后端服务启动与前端的完整装配4.1 启动 API 服务并验证接口数据入库之后就可以把后端 API 服务跑起来了。进入 backend 虚拟环境执行uvicorn app.main:app --host 0.0.0.0 --port 8000看到Uvicorn running on http://0.0.0.0:8000的输出说明服务启动成功。这时打开另一个终端用 curl 验证一个公开接口比如查询股票列表curl http://127.0.0.1:8000/api/v1/stocks/list如果返回 JSON 数组说明 API 正常。再验证K线接口curl http://127.0.0.1:8000/api/v1/stocks/600519.SH/kline?days30返回的数据里应该包含日期、开盘、收盘、最高、最低、成交量等字段。这个接口是前后端联调的关键前端图表页展示的数据完全依赖它。如果发现接口返回为空优先回查数据导入是否成功而不是去改前端代码。4.2 前端环境构建与开发模式启动后端就绪后处理前端。打开另一个终端进入 frontend 目录安装依赖cd frontend npm install如果 npm 安装速度慢同样可以临时切换镜像源npm install --registryhttps://registry.npmmirror.com依赖安装完成后有两种运行方式。如果你只想本地调试用开发服务器模式npm run dev默认会在 5173 或 8080 端口启动一个开发服务访问http://127.0.0.1:5173即可看到页面。开发模式的好处是代码改动热更新改完马上在浏览器看到效果。但开发服务器只适合调试如果要做生产部署一定要执行一次构建npm run build构建产物会输出到dist目录里面是纯静态文件。配合 Nginx 部署时把dist作为站点根目录同时把/api请求反向代理到后端的 8000 端口即可。下面是我实际项目中用的一段 Nginx 配置片段server { listen 80; server_name your-domain.com; root /path/to/openstock/frontend/dist; index index.html; location /api/ { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location / { try_files $uri $uri/ /index.html; } }这里try_files是前端路由刷新 404 的关键。如果只配了静态文件的 location 而没加try_files你点击页面内部跳转没问题但一旦手动刷新某个子路由就会遇到 404。4.3 首次打开页面配置自选股与看K线前后端都跑起来后第一次打开页面你会看到简洁的看盘界面。首次使用一般需要注册一个本地账号注册成功后登录。然后去“自选股”页面添加你关注的股票代码。添加成功后回到行情页面搜索该代码应该就能看到 K 线图和基础指标了。这里我建议你做一次完整的验证闭环先手动向数据库插入一条测试股票的记录再通过前端页面添加自选观察数据是否正常展示。如果页面空白或者接口报错就打开浏览器开发者工具看 Network 面板重点检查接口请求是否走到了正确的地址。有一个很常见的坑前端页面访问的是localhost:5173但后端跑在localhost:8000两者端口不同会导致跨域问题。开发模式下项目一般会在 Vite 配置里做代理转发但如果你是用 IP 加端口的方式从局域网另一台设备访问就需要检查后端是否开启了 CORS 允许规则。开发环境图省事可以直接允许所有来源生产环境建议只允许自己的域名。5. 常见问题与排查技巧实录5.1 问题速查表搭建 OpenStock 的过程中新手最容易踩到下面这些坑。我把最常见的几类问题列成了一张速查表排查时可对照检查。症状可能原因解决办法pip 安装依赖超时默认 PyPI 源在国内网络慢换用清华或阿里镜像源加-i参数数据库迁移报连接失败DATABASE_URL 配置错误检查用户名、密码、端口和数据库名确认服务已启动拉取的历史数据为空数据源接口限频或代码格式不对降速重试重新核对证券代码格式如 600519.SH前端页面刷新后 404Nginx 缺少try_files配置添加try_files $uri $uri/ /index.html;前端能打开但接口 500后端服务未启动或 CORS 未配置检查 uvicorn 日志确认 /api 请求能到达后端导入数据时内存占用过高单次导入数据量过大分批导入缩小日期范围或改用流式处理脚本定时任务不生效cron 环境变量或路径错误脚本用绝对路径日志重定向到文件便于排查这个表只是出发点真正排查问题时第一件事永远是看日志。后端日志在运行 uvicorn 的终端窗口里前端日志在浏览器开发者工具的 Console 面板。把报错信息完整复制下来搜一下大部分问题都能找到答案。5.2 三个让我印象最深的坑第一个坑是 Python 版本不匹配。我第一次搭建时服务器默认装的是 Python 3.8结果依赖装到一半就报错有些较新的第三方库已经放弃对 3.8 的支持。当时我以为是包坏了反复重装浪费了一个多小时。换成 Python 3.11 之后所有依赖一次通过。所有 Python 项目都适用这个经验先确认运行时版本再动手装包。第二个坑是日期格式和数据时区问题。行情数据里的日期看起来都是 YYYY-MM-DD 字符串看似人畜无害但如果你直接拿字符串去比较大小在跨年、跨月边界很容易踩坑。项目里用date类型还是datetime类型直接影响增量更新脚本能不能正确判断“最新的交易日”。我建议统一使用 UTC 日期格式虽然本地看盘不需要时区概念但数据库排序和比较会稳定得多。第三个坑是数据源接口的限频策略。我一开始写了一个并发下载脚本10 个线程同时拉取数百只股票的日线不到五分钟接口就返回 403。后来查文档才发现公开接口对单 IP 并发有限制。解决办法是降低并发到 1 到 2 个线程两个请求之间加 1 秒左右的间隔。全量数据拉起来会慢不少但胜在稳定不会拉一半被封。5.3 搭建完成后的几条维护建议当你顺利把 OpenStock 跑起来之后有几点维护建议是从实战中总结出来的供你参考第一数据库定期备份。OpenStock 里最有价值的不是代码而是你积累的历史数据。我习惯用系统自带的备份工具每天把数据库文件复制一份到另一个磁盘目录。SQLite 备份很简单直接复制.db文件就行PostgreSQL 则用pg_dump导出。第二不要在 root 用户下启动 Web 服务。虽然自己搭的私服没那么高并发但养成良好的安全习惯没有坏处。可以创建普通用户并赋予项目目录权限。第三关注依赖的安全更新。开源项目的依赖库会不断修复安全漏洞建议每隔一段时间执行pip list --outdated和npm outdated查看版本情况。但升级依赖之前一定要先备份数据库避免踩到未知兼容问题。我在实际使用中最大的感受是OpenStock 这类自建系统的价值不在“看盘”这一个动作上而在于你对自己数据的掌控力。搭建过程看起来只是敲了几条命令但它逼着你把“数据从哪来、存哪里、怎么用”整条链路都想了一遍。这套思路放到任何数据分析项目里都是通用的。如果后续你想在 OpenStock 上叠加自己的选股策略可以从写一个简单的指标计算脚本开始把结果存入扩展表再在页面上加一个自定义图表模块——方向清楚之后剩下的就是慢慢打磨了。
返回列表