Files
etf/docs/data_logic_analysis.md
aszerW 4df3ac4e31 chore(docs): reorganize documentation files into docs/ folder
Moved markdown documentation from root to docs/ directory to improve project structure.
2026-04-30 01:06:25 +08:00

136 lines
4.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 跨市场数据时间对齐逻辑分析
## 一、各市场交易时间(北京时间)
| 市场 | 交易时间 | 数据代码 | 数据源 | 数据标记 |
|-----|---------|---------|--------|---------|
| A股 | T日 09:30-15:00 | 000300.SH 等 | Tushare | T日 OHLC |
| 港股 | T日 09:30-16:00 | HSTECH.HK (3033.HK) | YFinance | T日 OHLC |
| 美股 | T日 21:30-次日04:00 | NDX | YFinance | T日 OHLC |
| 加密货币 | T日 08:00-次日08:00 (UTC) | BTC/ETH | CCXT/OKX | T日 OHLC |
| 黄金期货 | T日 09:00-15:30, 21:00-次日02:30 | AU.SHF | Tushare | T日 OHLC |
## 二、数据就绪时间点
假设当前是 **T+1日 09:00**(信号计算时间):
| 市场 | T日数据就绪时间 | T+1日09:00时最新数据 |
|-----|---------------|-------------------|
| A股 | T日 15:00 | T日数据 ✓ |
| 港股 | T日 16:00 | T日数据 ✓ |
| 美股 | T+1日 05:00 | T日数据 ✓ |
| 加密货币 | T+1日 08:00 | T+1日数据 ✓ (UTC 00:00) |
| 黄金期货 | T+1日 02:30 | T+1日数据 ✓ (夜盘结束) |
## 三、关键问题分析
### 问题1数据标记与实际交易时间的不一致
**黄金期货 (AU.SHF)**
- 交易时间T日 09:00-15:30日盘+ T日 21:00-T+1日 02:30夜盘
- Tushare 数据标记T+1日 OHLC因为夜盘结束是T+1日凌晨
- 实际对应T日日盘 + T日夜盘 = 标记为 T+1日
**加密货币 (BTC/ETH)**
- 交易时间T日 08:00UTC 00:00- T+1日 08:00UTC 00:00
- CCXT 数据标记T+1日 OHLCUTC 00:00 为日线分界)
- 实际对应T日08:00到T+1日08:00 = 标记为 T+1日
### 问题2当前代码逻辑
```python
# hybrid_source.py 中的数据对齐逻辑
# 以A股交易日为基准对齐所有数据
a_share_dates = 获取A股交易日历(start_date, end_date)
index_data = index_data.reindex(a_share_dates)
# 非A股标的处理
# 港股/美股ffill() - 使用T日数据
# 加密货币/期货bfill() - 使用T+1日数据
```
### 问题3当前存在的问题
**场景3月26日 00:17 运行代码**
| 期望 | 实际 |
|-----|------|
| 获取3月25日所有市场数据 | 可能只获取到3月24日数据 |
| 信号日期3月26日 | 信号日期3月25日 |
| 数据基准3月25日 | 数据基准3月24日 |
**原因分析**
1. `end_date` 默认是 `datetime.now().strftime('%Y-%m-%d')` = "2026-03-26"
2. 但 A股3月26日还没开盘Tushare 获取不到3月26日数据
3. 数据对齐时使用 `index_data.index.max()` 作为结束日期变成3月25日
4. 导致交易日历只到3月25日3月26日被排除
## 四、正确的数据获取逻辑
### 4.1 运行时间点与数据获取
| 运行时间 | A股状态 | 应获取的最新数据 |
|---------|--------|---------------|
| T+1日 00:00-09:00 | 未开盘 | T日数据所有市场 |
| T+1日 09:30-15:00 | 交易中 | T日数据不应获取盘中数据 |
| T+1日 15:00后 | 已收盘 | T+1日数据A股+ T日数据其他 |
### 4.2 数据对齐策略
**核心原则**以A股交易日为基准T+1日09:00计算信号时
1. **A股/港股**T日数据已收盘使用 ffill() 填充
2. **美股**T日数据已收盘T+1日05:00使用 ffill() 填充
3. **加密货币**T+1日08:00已收盘使用 T+1日数据bfill()
4. **黄金期货**T+1日02:30已收盘使用 T+1日数据bfill()
### 4.3 代码修改建议
**修改1使用配置的 end_date 获取交易日历**
```python
# 原代码(错误)
end_str = index_data.index.max().strftime('%Y%m%d')
# 修改后(正确)
end_str = pd.Timestamp(end_date).strftime('%Y%m%d')
```
**修改2区分不同市场的数据对齐方式**
```python
# 港股/美股ffill() - T日数据
# 加密货币/期货bfill() - T+1日数据
yf_codes = [港股, 美股]
crypto_futures_codes = [BTC, ETH, AU.SHF]
```
**修改3信号日期计算**
```python
# 当前代码(错误)
signal_date = backtest_result.index[-1] # 取数据最后一天
data_base_date = signal_date - 1 # 假设是前一天
# 应该根据当前时间判断
if 当前时间 < T+1日09:00:
signal_date = T日
data_base_date = T-1
else:
signal_date = T+1
data_base_date = T日
```
## 五、当前已做的修改
1.`hybrid_source.py` 使用配置的 `end_date` 获取交易日历
2.`hybrid_source.py` 区分 yf_codes 和 crypto_futures_codes 的不同填充方式
3.`hybrid_source.py` YFinance 添加 `auto_adjust=False``end_date+1天`
4.`rotation.yaml` 黄金改为 AU.SHF恒生科技改为 HSTECH.HK
## 六、仍需确认的问题
1. **信号日期显示**:当前显示 "2026-03-25 (基于 2026-03-24 收盘数据)" 是否正确?
- 如果今天是3月26日00:17应该显示 "2026-03-26 (基于 2026-03-25 收盘数据)"
2. **数据基准日期计算**`report.py` 中的 `data_base_date = signal_date - 1` 逻辑是否需要修改?
3. **加密货币/黄金的数据标记**CCXT/Tushare 返回的数据日期是否已经是 T+1日标记