156 lines
4.9 KiB
Markdown
156 lines
4.9 KiB
Markdown
# 未来数据使用问题修复说明
|
||
|
||
## 问题背景
|
||
|
||
在原始的买卖点计算系统中,存在使用未来数据的问题,这会导致:
|
||
1. **回测结果偏乐观**:历史分析看起来比实际情况更好
|
||
2. **实盘交易失效**:实际交易中无法获得未来信息
|
||
3. **策略不可实施**:违反了时间序列分析的基本原则
|
||
|
||
## 发现的问题
|
||
|
||
### 1. 分型强度评分中的未来数据
|
||
**位置**:`core/trading_signal.py` - `_calculate_fractal_strength_score`
|
||
|
||
**原始问题代码**:
|
||
```python
|
||
# 使用了当前分型之后的2个分型进行比较
|
||
for i in range(max(0, index-2), min(len(all_fractals), index+3)): # ❌ index+3
|
||
if i != index and all_fractals[i].fractal_type == fractal.fractal_type:
|
||
nearby_fractals.append(all_fractals[i])
|
||
```
|
||
|
||
**修复后代码**:
|
||
```python
|
||
# 只使用过去的分型进行比较
|
||
for i in range(max(0, index-5), index): # ✅ 只看过去5个分型
|
||
if i < len(all_fractals) and all_fractals[i].fractal_type == fractal.fractal_type:
|
||
past_fractals.append(all_fractals[i])
|
||
```
|
||
|
||
### 2. 分型位置评分中的未来数据
|
||
**位置**:`core/trading_signal.py` - `_calculate_fractal_position_score`
|
||
|
||
**原始问题代码**:
|
||
```python
|
||
# 使用了分型时间点之后的10个K线
|
||
start_idx = max(0, fractal_index - 10)
|
||
end_idx = min(len(processed_klines), fractal_index + 10) # ❌ +10个未来K线
|
||
```
|
||
|
||
**修复后代码**:
|
||
```python
|
||
# 只使用过去的数据
|
||
start_idx = max(0, fractal_index - 20) # 只看过去20个K线
|
||
end_idx = fractal_index + 1 # ✅ 包含当前K线,但不包含未来K线
|
||
```
|
||
|
||
### 3. 分型基础检测的固有特性
|
||
**位置**:`core/fractal.py` - 分型检测算法
|
||
|
||
**固有问题**:
|
||
```python
|
||
# 分型定义就需要左右确认
|
||
for i in range(1, strength + 1):
|
||
if self.data.iloc[idx + i]['high'] >= center_high: # 需要未来K线确认
|
||
right_valid = False
|
||
break
|
||
```
|
||
|
||
**说明**:这是缠论分型的固有特性,无法避免,但我们增加了确认机制。
|
||
|
||
## 解决方案
|
||
|
||
### 1. 修正评分算法
|
||
- **分型强度比较**:只使用历史分型数据
|
||
- **位置评分**:只基于过去的价格数据
|
||
- **相对强度**:避免使用未来分型进行比较
|
||
|
||
### 2. 增加确认机制
|
||
|
||
**新增方法**:
|
||
```python
|
||
def update_fractal_confirmation(self, current_idx: int):
|
||
"""更新分型确认状态"""
|
||
for fractal in self.all_fractals:
|
||
if not fractal.confirmed:
|
||
required_confirmation = fractal.strength
|
||
time_passed = current_idx - fractal.index
|
||
|
||
if time_passed >= required_confirmation:
|
||
fractal.confirmed = True
|
||
|
||
def detect_real_time_fractals(self, current_idx: int, lookback_periods: int = 50):
|
||
"""实时分型检测(避免使用未来数据)"""
|
||
# 只检测到当前位置之前的分型
|
||
# 且已经经过足够确认期的分型
|
||
```
|
||
|
||
### 3. 实时交易适配
|
||
|
||
**确认延迟**:
|
||
- 强度为1的分型:需要1个周期确认
|
||
- 强度为2的分型:需要2个周期确认
|
||
- 以此类推...
|
||
|
||
**信号生成时机**:
|
||
- 历史分析:可以看到所有分型(用于分析和学习)
|
||
- 实时交易:只能使用已确认的分型(确保策略可实施)
|
||
|
||
## 修复效果
|
||
|
||
### 1. 时间序列正确性
|
||
- ✅ 所有计算只使用当前时间点之前的数据
|
||
- ✅ 评分算法基于历史信息
|
||
- ✅ 确认机制确保信号可靠性
|
||
|
||
### 2. 实盘交易可行性
|
||
- ✅ 信号产生有合理延迟
|
||
- ✅ 避免了"神奇"的前瞻性
|
||
- ✅ 更加贴近真实交易环境
|
||
|
||
### 3. 回测准确性
|
||
- ✅ 回测结果更加保守和真实
|
||
- ✅ 消除了未来数据偏差
|
||
- ✅ 提高了策略评估的可信度
|
||
|
||
## 使用建议
|
||
|
||
### 历史分析模式
|
||
```python
|
||
# 用于学习和研究
|
||
analyzer = ChanAnalyzer(df)
|
||
result = analyzer.run_full_analysis() # 包含所有分型
|
||
```
|
||
|
||
### 实时交易模式
|
||
```python
|
||
# 用于实盘交易
|
||
current_idx = len(df) - 1
|
||
confirmed_fractals = fractal_detector.get_confirmed_fractals(current_idx)
|
||
real_time_signals = trading_signal.detect_real_time_signals(confirmed_fractals)
|
||
```
|
||
|
||
### 参数调整建议
|
||
|
||
**不同交易风格的设置**:
|
||
- **日内短线**:基础强度1-2,确认周期短
|
||
- **中线波段**:基础强度2-3,平衡确认和敏感性
|
||
- **长线趋势**:基础强度3-5,重视确认可靠性
|
||
|
||
## 注意事项
|
||
|
||
1. **信号延迟**:修复后的系统会有合理的信号延迟,这是正确的
|
||
2. **确认机制**:在实盘交易中必须等待分型确认
|
||
3. **参数调整**:可能需要重新优化策略参数
|
||
4. **回测重运行**:建议使用修复后的系统重新进行历史回测
|
||
|
||
## 总结
|
||
|
||
这次修复消除了系统中的"未来数据泄露"问题,使得:
|
||
- 买卖点计算更加严格和可靠
|
||
- 回测结果更加真实
|
||
- 实盘交易策略更具可操作性
|
||
- 符合量化交易的最佳实践
|
||
|
||
虽然可能会降低一些历史回测的表现,但这是为了获得更可靠和可实施的交易策略所必须的改进。 |