- Python 64%
- Vue 23.5%
- CSS 7.5%
- TypeScript 4.5%
- Shell 0.2%
- Other 0.2%
| backend | ||
| config/strategies | ||
| deploy | ||
| docs | ||
| frontend | ||
| .env.example | ||
| .gitattributes | ||
| .gitignore | ||
| A股策略轮动提示盘_系统规划与落地方案.md | ||
| LICENSE | ||
| README.md | ||
A 股策略轮动提示盘
面向个人使用的 A 股策略信号中心、跨资产自选观察盘、数据健康监控盘和人工执行辅助系统。当前版本实现 ETF 日频轮动、银行红利低波、RC-ETF 周频轮动与多列表自选观察,采用 Vue 3 PWA、FastAPI、APScheduler、MySQL 8 和宿主机 Caddy。
本项目只提供策略研究和人工执行提示,不构成投资建议,也不会自动下单。
第一版能力
- ETF 收盘后排名、目标持仓和下一交易日换仓信号;
- 银行股实时 TTM 股息率、红利低波排名和调仓缓冲;
- RC-ETF:价值/成长动量切换后,按权益/黄金/国债 75/24/1 风险贡献预算周频调仓;同页支持多个参数/底层标的实例切换,详见 RC-ETF 策略说明;
- 多个独立自选列表,以及股票、ETF、指数、贵金属、商品和外汇品种管理;
- 自选品种按代码或名称查询,支持多候选选择、基础信息确认和列表内自定义显示名称;
- 自选行按日/周/月标签切换收盘价缩略走势,各周期最多展示最近 60 根 K 线,并展示股票/指数估值和 ETF 跟踪指数口径估值;
- 基于本地行情计算日、周、月 BOLL 上中下轨、位置区间和距中轨比例;
- 新增自选品种后异步补齐约两年日线,并持久化通用指标快照;
- 当前持仓、目标持仓、历史信号和人工确认;
- 历史日期试算与正式结果隔离;
- 数据更新时间、任务状态、失败告警和手动刷新;
- 独立 FastAPI 与 APScheduler 进程;
- Vue 3 响应式页面与 PWA;
- iFinD 主数据源,以及 Tushare、AKShare 后备适配器;
- MySQL 持久化和宿主机 Caddy 自动 HTTPS 入口。
规划原文见 A股策略轮动提示盘_系统规划与落地方案.md,Linux 生产部署见 docs/LINUX_DEPLOYMENT.md。
标准生产架构
Browser
|
+-- HTTPS :443 --> host Caddy
|-- / --> /opt/a-share-rotation-dashboard/frontend
`-- /api/* --> 127.0.0.1:8000
|
`-- host MySQL :3306
systemd
|-- a-share-api.service
`-- a-share-scheduler.service (exactly one instance)
生产项目固定目录:
/home/ubuntu/project/a_share_rotation_dashboard
前端在项目内的 frontend/dist 构建,再通过部署脚本同步到 Caddy 读取的 /opt/a-share-rotation-dashboard/frontend。后端以 backend 为工作目录,使用 Conda 环境中的 Python 运行。这样无需放宽 Caddy 对 /home 的 systemd 安全限制。
Redis 是自选观察聚合接口的可选 15 秒缓存;未配置或暂时不可用时会自动回退到 MySQL 行情计算,不影响功能。MongoDB 仍未启用。两者都不需要向公网开放 6379 或 27017。
数据隔离边界
项目数据库名固定为:
a_share_rotation_dashboard_v1_20260720
应用会把 MYSQL_DSN 中的数据库路径强制替换为 MYSQL_DATABASE_OVERRIDE,并拒绝不属于 a_share_rotation_dashboard 命名空间的目标,避免写入旧的 trade_platform 数据库。
生产环境应由 MySQL 管理员预先创建项目库和专用账号。应用初始化默认不会申请服务器级 CREATE DATABASE 权限;只有显式使用 --create-database 时才会尝试建库。
Linux 快速部署摘要
完整步骤和安全检查请以部署文档为准。下面只展示主流程。
- 将仓库检出到固定目录:
cd /home/ubuntu/project
git clone <repository-url> a_share_rotation_dashboard
cd a_share_rotation_dashboard
- 创建 Python 3.11 环境并安装依赖:
conda create -n a_share_rotation_dashboard python=3.11 -y
conda run -n a_share_rotation_dashboard python -m pip install -r backend/requirements.txt
- 将
.env.example的内容写入服务器的:
/etc/a-share-rotation-dashboard/app.env
真实密码和 Token 不能写入仓库。
- 由 MySQL 管理员创建独立数据库及用户,然后初始化:
cd /home/ubuntu/project/a_share_rotation_dashboard/backend
set -a
source /etc/a-share-rotation-dashboard/app.env
set +a
"$PYTHON_BIN" -m app.cli init-database \
--migrate \
--backfill-history \
--history-days 520
- 编译前端并发布到
/opt:
bash deploy/scripts/deploy-frontend.sh
- 将现有
dashboard.jzhao.tech简单反代块替换为仓库中的完整 Caddy 站点配置,校验后平滑 reload。详细命令见 Linux 部署文档。
日常更新
后端代码更新:
cd /home/ubuntu/project/a_share_rotation_dashboard
git pull --ff-only
sudo systemctl restart a-share-api
sudo journalctl -u a-share-api -n 100 --no-pager
如果修改了调度任务、数据源或策略定时逻辑,同时执行:
sudo systemctl restart a-share-scheduler
如果 backend/requirements.txt 变化:
set -a
source /etc/a-share-rotation-dashboard/app.env
set +a
"$PYTHON_BIN" -m pip install -r backend/requirements.txt
如果包含数据库迁移:
cd backend
set -a
source /etc/a-share-rotation-dashboard/app.env
set +a
"$PYTHON_BIN" -m alembic -c alembic.ini upgrade head
本次升级包含策略池和主数据范围变化,部署旧版本的服务器还需执行:
cd /home/ubuntu/project/a_share_rotation_dashboard/backend
bash ../deploy/scripts/run-admin.sh sync-config --force
bash ../deploy/scripts/run-admin.sh refresh-instruments
bash ../deploy/scripts/run-admin.sh refresh-strategy-data --history-days 520
全量场内 ETF 主数据只用于页面搜索;历史和实时行情仍仅请求启用策略池,不会对全量 ETF 消耗行情额度。完整停机顺序、备份要求和核对项见部署文档第 16.0 节。
前端更新:
cd /home/ubuntu/project/a_share_rotation_dashboard
bash deploy/scripts/deploy-frontend.sh
脚本会重新构建并同步到固定的 /opt 目录,因此不需要重启或 reload Caddy。
健康检查
curl --fail http://127.0.0.1:8000/health
sudo systemctl --no-pager --full status a-share-api a-share-scheduler
sudo journalctl -u a-share-api -u a-share-scheduler -n 200 --no-pager
curl --fail https://dashboard.jzhao.tech/healthz
curl --fail https://dashboard.jzhao.tech/api/health
本地开发
后端:
cd backend
python -m pip install -r requirements.txt
python -m uvicorn app.main:app --reload --host 127.0.0.1 --port 8000
前端:
cd frontend
npm ci
npm run dev
生产环境不要使用 --reload,也不要使用 nohup 或 screen 代替 systemd。
项目目录
backend/ FastAPI、策略、数据适配器、任务和 Alembic
frontend/ Vue 3、Element Plus、ECharts 和 PWA
config/strategies/ 可版本化的策略初始配置
deploy/systemd/ API 与单实例调度器服务模板
deploy/caddy/ 宿主机 Caddy 增量站点模板
deploy/scripts/ 原生服务启动、前端构建和 `/opt` 发布脚本
deploy/mysql/ 项目数据库幂等创建脚本
docs/LINUX_DEPLOYMENT.md 完整 Linux 部署、安全和运维手册
.env.example 无密钥生产环境变量模板
测试
cd backend
python -m pytest
cd ../frontend
npm ci
npm run build
升级
cd /home/ubuntu/project/a_share_rotation_dashboard git pull --ff-only
sudo systemctl stop a-share-scheduler
cd backend bash ../deploy/scripts/run-admin.sh migrate bash ../deploy/scripts/run-admin.sh sync-config --force bash ../deploy/scripts/run-admin.sh refresh-instruments bash ../deploy/scripts/run-admin.sh refresh-strategy-data --history-days 520
cd .. bash deploy/scripts/deploy-frontend.sh
sudo systemctl restart a-share-api a-share-scheduler sudo systemctl --no-pager --full status a-share-api a-share-scheduler