基于 Charles Schwab API 的个人量化交易系统。策略与执行解耦:同一套策略代码依次跑回测 → 模拟盘 → 实盘,三个阶段的成本假设和执行口径完全一致。
数据层 策略层 执行层
┌─────────────┐ ┌─────────────┐ ┌──────────────────────┐
│ Schwab API │ │ 双动量轮动 │ │ 风控:仓位/敞口上限 │
│ Yahoo(研究) │ ───▶ │ 行业ETF轮动 │ ───▶ │ SimulatedBroker 模拟盘 │
│ Parquet存储 │ │ 波动率目标层 │ │ SchwabBroker 实盘(待做) │
└─────────────┘ └──────┬──────┘ └──────────┬───────────┘
▼ ▼
vectorbt 回测引擎 每日报告 data/reports/
| 策略 | 一句话解释 | 配置 |
|---|---|---|
| 双动量轮动 | 每月末在 6 只核心 ETF + 8 只头部个股中,按 3/6/12 个月动量排名持有最强 3 只;全部走弱时空仓持现金 | config/dual_momentum.yaml |
| 行业 ETF 轮动 | 同一引擎,标的池换成 11 只 SPDR 行业 ETF + TLT/GLD 防御腿;无个股选择偏差,回测更可信 | config/sector_rotation.yaml |
| 波动率目标层 | 叠加在任意策略上:组合近期波动超过目标(15%)就等比减仓,只减不加杠杆,用于压回撤 | 两个配置中 vol_target: |
2005–2026 真实复权数据回测:行业轮动年化 ~9.5%(SPY 为 10.9%),但最大回撤 -21%(SPY 为 -55%),风险调整后明显占优。个股池动量收益更高但含选择偏差,数字仅供参考。
研究回测(不需要 Schwab 账户):
uv sync
uv run python scripts/fetch_yahoo.py SPY QQQ IWM EFA TLT GLD AAPL MSFT GOOGL AMZN NVDA META TSLA AVGO
uv run python scripts/run_backtest.py模拟盘(需要 developer.schwab.com 应用凭证):
cp .env.example .env # 填入 API key/secret
uv run python scripts/authorize.py # 首次 OAuth 授权
uv run python scripts/backfill.py SPY QQQ AAPL --start 2015-01-01
uv run python scripts/run_daily.py --bootstrap # 之后每个交易日收盘后跑一次(可挂 cron)每日持仓与成交写入 data/reports/,模拟账户状态在 data/sim/。跑行业轮动加 --config config/sector_rotation.yaml。
.env、token、行情数据均被 gitignore,凭证绝不入库- Schwab 无官方模拟盘 API,模拟撮合由本地
SimulatedBroker完成(行情为真实数据) - 回测 ≠ 未来收益,本仓库不构成投资建议;完整设计见 docs/PROJECT_OUTLINE.md