> 本文为建站前的研究方法说明。当前网站为随后新建的独立展示站点，未修改旧网站或原策略参数。

# QQQ / SPY / GLD / BTC / 美元现金：原ETF轮动逻辑迁移回测

本目录是独立研究副本。研究计算阶段没有修改旧 ETF/BTC 项目、没有发布旧网站、没有下单。参数预先沿用原项目，不对新资产池寻优。历史结果不构成预测。

## 复现

Python 3.10+，`pip install -r requirements.txt`。完整冻结缓存已附，通常不需要再次联网。

```bash
cd /workspace/us_rotation_backtest
python3 backtest.py
python3 fetch_execution_minutes.py   # 首次联网验证，后续使用缓存
python3 postprocess.py
python3 audit.py
```

重新获取公开源：`python3 fetch_data.py`。该脚本冻结行情区间为 2012-01-01 至 2026-11-07（右端不含），不是“自动延长至今天”的脚本。`data_sha256.json` 是下载数据校验值。股票与BTC的原始API响应同时保存。`reference/` 仅保存原项目相应函数的只读提取及原文件SHA256，审计不依赖旧项目存在。

## 实际原逻辑核对

原文件 `/workspace/etf_rotation/backtest.py` 和 `make_dashboard.py` 均只读检查。须区分：

- 原看板 C1 本身也有 BIAS 当日过滤，不是纯动量。本研究单独加入 `Momentum`（完全无BIAS）作为对照；`BIAS_filter_only` 才对应不带持续冷却的过滤逻辑。
- N=25 个美股交易日，以 ln(复权收盘) 回归，得分 `(exp(250*b)-1)*R²`；只在得分严格大于0的合格标的中选第一名。
- BIAS = 收盘/20日均线−1。每个资产用自身历史 BIAS 的扩展分位数，至少250个有效历史 BIAS 后启用；97.5%分位为极端阈值，50%分位为冷却解除线。阈值包含当日，因为信号在当日完整收盘以后才生成；没有用未来日期。
- 所有风险资产如果 BIAS 严格高于自身阈值，当日都不合格。C3/C4 另有持续冷却：前一日选中资产若触发极端阈值，加入冷却名单；只有 BIAS 严格低于自身历史中位数才移出，不是回落到97.5%线就立刻重入。按原代码顺序先解除旧冷却、再检查前一选中资产是否新增冷却，之后排名。
- 没有合格正动量标的即现金；现金不参与价格动量排名；不使用中国国债。
- 控波 `min(1,0.15/近40个美股交易日收益率的年化波动)`，波动率按 sqrt(252) 年化，剩余现金、不加杠杆。严格沿用原实现：**仅选中标的改变时设置目标仓位，持有中随价格漂移，不是每天再平衡**。因此15%不是持续保证的组合波动上限。
- 原研究 `backtest.py` 还含明确标记“全样本、有前视”的 `full` 分支；线上 C3 的 `Sig` 实际使用 expanding（无前视），本次没有调用 full，不能把线上C3说成用了全样本未来阈值。
- 与原版必要的迁移差异：国债/原零息空仓改为计息美元现金；无QDII溢价过滤（直接买美股ETF）；BTC单独成本；包含周末的估值；缺交易活动时不虚构成交；现金起步、以完整历史预热指标而不虚构预热期持仓。

## 数据、复权与时间

来源：
- ETF 原始开/收盘、复权收盘及分红/拆分：Yahoo Finance chart 公共端点（QQQ、SPY、GLD）：
  - https://query1.finance.yahoo.com/v8/finance/chart/QQQ
  - https://query1.finance.yahoo.com/v8/finance/chart/SPY
  - https://query1.finance.yahoo.com/v8/finance/chart/GLD
  - 官方复权说明 https://help.yahoo.com/kb/SLN28256.html
- BTC 是 Bitstamp **BTC/USD现货**真实半小时OHLC，并非USDT，也没有拿UTC日收盘冒充美股收盘：
  - https://www.bitstamp.net/api/v2/ohlc/btcusd/
  - 官方参数说明 https://www.bitstamp.net/api/ （OHLC data）
- 美元现金利率：FRED/美联储 H.15 的 DTB3 历史3月国库券贴现收益率：
  - https://fred.stlouisfed.org/series/DTB3
  - https://fred.stlouisfed.org/graph/fredgraph.csv?id=DTB3
  - https://www.federalreserve.gov/releases/h15/

价格和信号严格分开：
- 每个美股交易日，美西13:00 PT（自动处理冬/夏令时）出信号。ETF用此前已完整结束的该日收盘；BTC用截至此刻已结束的半小时K线收盘。半日市的ETF收盘已经更早完成，仍等到13:00 PT才与BTC统一决策。
- 下一美股交易日美西06:30 PT执行：ETF使用真实日开盘；BTC使用同一开盘时刻开始的K线首笔成交作为开盘代理。另对所有实际BTC交易日抓取06:30 PT起的**1分钟K线**，验证该分钟确有真实成交且开盘价与半小时K线开盘一致，详见 `results/execution_minute_audit.json`。这不是逐笔盘口回放，不能声称秒级保证成交。
- 流动性保护只看执行前已经结束的半小时成交量，无成交活动则整个调仓延迟，不用执行后成交量反过来决定是否下单；每笔BTC实际成交另外事后核验执行K线中确有成交。
- 每个日历日美西13:00 PT估值，含周末BTC涨跌；非美股交易日ETF以前一完整收盘计价，不产生新信号。最大回撤是这个日频估值口径，不是盘中最大回撤。
- 共同数据：ETF 2012-01-03至2026-11-06；BTC半小时 2012-01-01至2026-11-06。250个有效BIAS及40日波动预热完成后，指标最早在2013-01-29预热完成。然而，更早回测的10个实际BTC换仓日没有开盘分钟成交（最后一次为2017-03-23），半小时首笔成交不能当成与ETF开盘严格同步。为不虚构成交时点，**正式结果从2017-03-24开始，首个正式信号2017-03-23**，不以早期近似结果作结论；更早仅作为指标预热。最终统一完整估值为2026-11-06美西13:00 PST。没有引用尚未完整的下一交易日数据。
- ETF开盘乘以 `adjclose/rawclose`，收盘用adjclose，采用Yahoo/CRSP标准等比例分红与拆分调整。本样本QQQ有60次分红、SPY有59次，三只无拆分。逐次验证分红前后复权因子与公告分红一致，最大相对误差低于0.000061%。不重复加股息；基金费率已经体现在价格中。未单独模拟除息日至实际派息日的应收账款结算，这是总回报复权的标准近似。
- BTC为单一交易所而非全球指数，早期流动性和跨所基差明显，不能假设任意资金容量都能按历史价成交。已有Yahoo BTC开盘只用作同一UTC时间的外部交叉检查，不混入主价格序列。

## 现金、成本与指标

- 现金按已滞后**5个自然日**的DTB3报价计息，保守覆盖历史公布滞后；按91天票据把贴现收益率换算为近似投资收益率，ACT/365连续计息。是真实历史利率代理，不是实际滚动短债ETF净值、不包含短债价格波动或管理费，也不是默认任何券商现金都能拿到该收益。
- FRED使用本次下载的历史版本，并非逐日ALFRED实时版本库；保守滞后避免发布日期前视，但无法保证所有历史小修订都已按当时版本重放。这是现金收益代理的剩余限制。
- 基准成本：ETF单边3bp，BTC单边10bp，含佣金/滑点假设；没有杠杆，美元、税前。BTC10bp对早期或小额零售账户偏乐观，因此另测ETF10bp/BTC50bp；未模拟跨平台资金结算、提币、托管、税费、市场冲击或容量。
- 夏普 = 日历日 `(策略收益−历史现金基准收益)` 的均值/标准差 ×sqrt(365.25)；波动率同样日历日年化。即使现金“零利息”敏感性，夏普仍使用同一个历史现金机会成本，避免不同比较基准。
- 年换手“单边” = 每年Σ|目标权重−成交前漂移权重|，完整卖旧买新计2；“双边轮次”=前者/2。交易次数分别给单边成交腿数及调仓日数，不把10%仓位成交误称100%换手。
- 2019及2020起的结果为同一条已运行策略的分段切片，继承期初真实模拟持仓，不重新寻优，也不是严格的上线后样本外业绩。

## 核验

- `audit.py` 对只读提取的原函数做真实行情对照：动量公式数值一致，BIAS标记完全一致；正式区间超过2400个交易日，C3/C4净值相对误差均在1e−12以内。为隔离模型差异，C3比较统一成本/零息；C4因参考代码把防守国债当可交易资产，比较使用零成本合成现金，并对齐参考切片起点的波动历史。生产结果仍用完整40日预热及真实设定的分资产成本。
- 截断到2020年底重算动量/扩展分位，历史值不因后续行情改变；所有仓位非负、无杠杆、现金余额不为负；逐日组合分项对数收益严格加总到组合对数收益。
- `corporate_actions_audit.json` 核对复权；`execution_minute_audit.json` 核对BTC实际执行分钟；`data_sha256.json` 记录冻结数据；原代码SHA保存在reference目录。

## 文件

- `results/summary.csv`：全期所有策略核心指标
- `results/subperiods.csv`：2019、2020起指标（全期在summary.csv）
- `results/yearly_returns.csv`：逐年收益
- `results/sensitivity.csv`：全期零息/高成本/去BTC
- `results/all_subperiod_sensitivities.csv`：上述全部情景的2019/2020子段
- `results/*_daily.csv`：逐日收益、净值、权重、费用、现金基准和分项对数收益
- `results/*_trades.csv`：信号日、执行日、原因、成交前/目标权重、单边换手、费用、复权计价价及真实不复权开盘价（raw_price列）
- `results/*_signals.csv`：每天所选标的及冷却名单
- `results/latest.json`：最后完整信号、仓位、待执行目标
- `results/diagnostics.json`：回撤峰谷、BTC贡献、延迟成交统计
- `nav_drawdown_2020.png`：建议聊天附图；`nav_drawdown.png`为全期图

## 早期行情核验中明确淘汰的结果

`exploratory_30min_2013/` 仅保留研究审计痕迹。2013-01-30、02-05、02-25、03-13、05-22、09-30、10-17，以及2015-10-14、2016-03-02、2017-03-23，存在实际BTC换仓但开盘分钟无成交。正式样本起点只按这项事先定义的数据可执行性要求截断，不根据收益或回撤择优。未删掉其中某些不利交易日，也未把后续半小时的成交回填成早先开盘成交。早期近似净值不作为可执行回测结论；正式报告与图只使用严格核验后的区间。
