初始化 wiki:项目简介/部署配置/数据导入/踩坑记录

2026-08-15 12:38:11 +08:00
parent 6ad4ad8a65
commit 30a9b84c6a
5 changed files with 213 additions and 0 deletions
+24
@@ -0,0 +1,24 @@
# quanxiel 量化项目 Wiki
> 项目用法、配置说明、注意事项、踩坑记录都放这里。
> 仓库:`shellway/quanxiel`(Gitea: http://192.168.27.11:3579/shellway/quanxiel)
## 📑 目录
- [[项目简介]] — 项目是干什么的、目录结构
- [[部署与配置]] — 数据库 / venv / .env 配置全说明
- [[数据导入]] — 全量导入、增量导入、定时任务怎么跑
- [[踩坑记录]] — 所有踩过的坑(必读!)
## 🔥 最重要的一条教训
**Tushare 不是所有接口都有 `_vip` 版本!** `daily_vip`/`adj_factor_vip` 根本不存在(40101)。
改代码前先跑 `quantitative_data/tushare_api_check.py` 自检。
详见 [[踩坑记录]] 和 `quantitative_data/tushare_api_reference.md`。
## 快速入口
- 增量导入:`quantitative_data/incremental_import.py`
- 接口参考:`quantitative_data/tushare_api_reference.md`
- 接口自检:`quantitative_data/tushare_api_check.py`
- 数据导入核心:`quantitative_data/importer.py`
+51
@@ -0,0 +1,51 @@
# 数据导入
## 运行环境
所有命令在小强容器(openclaw-1)里执行:
```bash
sudo docker exec -u node openclaw-1 bash -c 'cd /home/node/quanxiel/quantitative_data && /opt/quant-venv/bin/python xxx.py'
```
## 全量导入(首次/重建)
```python
# 交互式或脚本里
from importer import full_import
full_import(start_date="2010-01-01", end_date="2025-12-31", import_financials=True)
```
注意:财务表很慢(数小时),可先跑行情、再单独补财务。
## 增量导入(日常)
```bash
# 每日行情(trade_cal/stock_basic/daily/daily_basic/adj_factor/index_daily)
/opt/quant-venv/bin/python incremental_import.py
# 每周一次,加财务表
/opt/quant-venv/bin/python incremental_import.py --weekly
# 只看计划不执行
/opt/quant-venv/bin/python incremental_import.py --dry-run
```
逻辑:查各表 MAX(trade_date),只拉「最后日期+1 → 昨天」。幂等(UPSERT)。
## 定时任务(群晖任务计划,推荐)
容器内无 systemd,crontab 重启会丢 → 用群晖「控制面板 → 任务计划」:
**每天 18:30(A股数据 16~18 点齐):**
```bash
docker exec -u node openclaw-1 bash -c 'cd /home/node/quanxiel && git pull --ff-only && cd quantitative_data && /opt/quant-venv/bin/python incremental_import.py >> incr.log 2>&1'
```
**每周日 18:30(财务):** 同上命令加 `--weekly`
## 断点续传工具
```python
from importer import resume_daily_by_date, check_daily_progress, check_table_summary
check_daily_progress() # 查看 daily 缺失日期
resume_daily_by_date() # 自动补缺失日期
check_table_summary() # 各表行数统计
```
## Tushare 接口
- 实测接口清单 + 示例代码:`tushare_api_reference.md`
- 改代码前自检:`/opt/quant-venv/bin/python tushare_api_check.py`
- ⚠️ 普通接口按 trade_date 全市场需 2000 积分;财务 vip 接口需 5000 积分(当前账号 5120 够)
+60
@@ -0,0 +1,60 @@
# 踩坑记录(必读)
## 1. Tushare 接口名不能想当然加 _vip ⚠️⚠️⚠️
- `daily_vip` → **40101 接口名不存在**(Tushare 根本没这个接口)
- `adj_factor_vip` → 40101 不存在
- `daily_basic_vip` → 40203 存在但无权限
- `income_vip` / `cashflow_vip` / `balancesheet_vip` / `fina_indicator_vip` → 真实存在,5000积分可用
- 教训:**写代码前先跑 `tushare_api_check.py` 自检**
- 修复记录:importer.py 7 处 vip 改回普通接口(commit 0b19869)
## 2. 普通接口按 trade_date 拉全市场需要积分门槛
- `daily`/`daily_basic`/`adj_factor` 按 `trade_date` 全市场:需 **2000 积分**
- 按 `ts_code` 单只拉:120 积分即可
- 当前账号 5120 积分,两种方式都可用
## 3. postgres 超级用户是 sally,不是 postgres
- `psql -U postgres` → 报 `role "postgres" does not exist`
- 正确:`psql -U sally`
## 4. 表 owner 问题(must be owner of table/view)
- 现象:importer 跑 DDL(CREATE INDEX)报 `InsufficientPrivilege: must be owner`
- 原因:GRANT ALL 不等于 owner;DDL 必须 owner 执行
- 修复(sally 执行,一次转所有表/视图/序列):
```sql
DO $$
DECLARE r record;
BEGIN
FOR r IN SELECT c.relname, c.relkind
FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'public' AND c.relkind IN ('r','v','m','S')
LOOP
EXECUTE format('ALTER %s public.%I OWNER TO xiaoqiang_w',
CASE r.relkind WHEN 'r' THEN 'TABLE'
WHEN 'v' THEN 'VIEW'
WHEN 'm' THEN 'MATERIALIZED VIEW'
WHEN 'S' THEN 'SEQUENCE' END,
r.relname);
END LOOP;
END $$;
```
## 5. Debian 12 容器 pip 被 PEP 668 拦截
- 现象:`error: externally-managed-environment`
- 解决:建 venv(`python3 -m venv /opt/quant-venv`),或 `--break-system-packages`(不推荐)
- 注意:venv 里的脚本要用 `/opt/quant-venv/bin/python` 跑
## 6. 目录权限导致写日志失败
- 现象:`PermissionError: import_data.log`
- 原因:仓库是 root clone 的,node 用户写不了
- 解决:`chown -R node:node /home/node/quanxiel`
## 7. 终端粘贴带提示符
- 现象:`-sh: sally@NAS-Sally:~$: command not found`
- 原因:复制命令时把前面的提示符也复制了
- 解决:只复制命令本身
## 8. 历史遗留:数据库数据只到 2025-12-31
- 之前全量导入的 END_DATE 默认是 2025 年底
- 2026-08-15 增量导入实际补了 2026-01-01 ~ 08-14 约 149 个交易日
- 教训:检查数据完整性用 `check_daily_progress()`,别假设数据是全的
+42
@@ -0,0 +1,42 @@
# 部署与配置
## 数据库(黑群晖 Docker)
- 容器:`postgres-server`,端口 **5438**(宿主)→ 5432(容器)
- 超级用户:**sally**(不是 postgres!)
- 数据库:`quant_db`,另有默认库 `mydb`
- 进 psql:`sudo docker exec -it postgres-server psql -U sally -d quant_db`
### 账号
| 账号 | 用途 | 权限 |
|---|---|---|
| sally | 超级用户 | 全部 |
| xiaoqiang | 小强只读查询 | quant_db 只读 |
| xiaoqiang_w | importer 写库 | 全部表/视图/序列 owner |
⚠️ 表/视图/序列的 owner 必须转给 xiaoqiang_w,否则 importer 的
DDL(CREATE INDEX 等)会报 `must be owner`。转换 SQL 见 [[踩坑记录]]。
## Python 环境(小强容器 openclaw-1)
- 系统 Python 3.11 受 PEP 668 保护,不能直接 pip install
- 专用 venv:`/opt/quant-venv`(root 创建)
- 跑脚本一律用:`/opt/quant-venv/bin/python`
- 依赖:tushare / pandas / psycopg2-binary / sqlalchemy / python-dotenv
## .env 配置
路径:`/home/node/quanxiel/quantitative_data/.env`(不入 git)
```ini
QUANT_DB_HOST=192.168.27.11
QUANT_DB_PORT=5438
QUANT_DB_NAME=quant_db
QUANT_DB_USER=xiaoqiang_w
QUANT_DB_PASSWORD=***
TUSHARE_TOKEN=***
```
- 密码含特殊字符时写 .env 用 heredoc `<<'EOF'` 防转义
- 改 .env 后无需重启,config.py 每次加载
## 目录权限
仓库目录必须 node 用户可写(importer 要写日志):
```bash
sudo docker exec -u root openclaw-1 bash -c 'chown -R node:node /home/node/quanxiel'
```
+36
@@ -0,0 +1,36 @@
# 项目简介
## 是什么
quanxiel = 量化交易研究项目。从 Tushare 拉取 A 股行情/财务数据存入 PostgreSQL,做因子研究、策略回测。
## 目录结构
```
quantitative_data/ # 数据采集与入库(主要)
├── importer.py # 导入核心:全量导入、按日期/按股票拉取
├── incremental_import.py # 增量导入脚本(每日/每周)
├── config.py # 配置(读 .env)
├── schema.sql # 建表 DDL
├── requirements.txt # 依赖清单
├── tushare_api_reference.md # Tushare 接口参考(实测版)
├── tushare_api_check.py # 接口自检脚本
└── .env # 敏感配置(不入库)
alpha/ # 策略/因子/回测(在开发中)
```
## 数据表
| 表 | 内容 | 更新频率 |
|---|---|---|
| stock_basic | 股票列表(含退市) | 每日 |
| trade_cal | 交易日历 | 每日 |
| daily | 日线行情 | 每日 |
| daily_basic | 每日指标(估值/换手) | 每日 |
| adj_factor | 复权因子 | 每日 |
| moneyflow | 资金流向 | 每日 |
| index_daily | 指数日线 | 每日 |
| income/balancesheet/cashflow | 三大报表 | 每周 |
| fina_indicator | 财务指标 | 每周 |
## 技术栈
- 数据库:PostgreSQL(Docker,黑群晖 192.168.27.11:5438,库名 quant_db)
- 数据源:Tushare Pro(5120 积分,VIP 财务接口可用)
- 运行环境:小强容器(openclaw-1)venv `/opt/quant-venv`