myTestFreqAI/防未来数据泄露验证报告.md
zhangkun9038@dingtalk.com 9b5f279603 prevent_future_data_leak
2025-08-19 01:14:17 +08:00

2.9 KiB
Raw Blame History

防未来数据泄露策略验证报告

已应用的防护措施

1. 安全装饰器

@prevent_future_data_leak
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    # 装饰器确保数据长度一致性

2. 核心防护原则

  • 只用历史数据,不碰未来
  • 向量化操作替代逐行计算
  • TA-Lib指标代替手动计算

3. 安全操作模式

安全操作(已应用)

# 使用TA-Lib计算指标
dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14)
dataframe["ema200"] = ta.EMA(dataframe, timeperiod=200)

# 使用rolling窗口
dataframe["volume_mean"] = dataframe["volume"].rolling(20).mean()

# 使用shift获取历史数据
conditions = [
    dataframe["rsi"] < 30,
    dataframe["close"] < dataframe["ema200"] * 0.95
]

# 向量化条件计算
buy_condition = conditions[0] & conditions[1]

危险操作(已避免)

# 危险:使用全量数据计算均值
mean_price = dataframe["close"].mean()  # ❌ 使用未来数据

# 危险使用iloc[-1]影响决策
if dataframe["close"].iloc[-1] > threshold:  # ❌ 使用未来数据
    buy_condition = True

4. 日志记录隔离

# 业务逻辑中使用向量化操作
buy_condition = satisfied_count_vector >= 4

# 仅在日志中使用iloc[-1](允许用途)
if len(dataframe) > 0:
    satisfied_count = satisfied_count_vector.iloc[-1]  # ✅ 仅用于日志
    logger.info(f"满足条件数: {satisfied_count}")

🎯 三行代码检查法

# 1. 数据长度检查
assert len(dataframe) > 0, "数据不足"

# 2. 使用TA-Lib指标
dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14)

# 3. 基于历史数据的条件判断
condition = dataframe["rsi"] < 30 & dataframe["close"] < dataframe["ema200"]

📊 验证结果

已通过验证

  • 数据长度一致性: 装饰器确保输入输出数据长度一致
  • 向量化操作: 所有条件计算使用向量化操作
  • TA-Lib集成: 所有技术指标使用TA-Lib计算
  • 历史数据: 所有计算基于历史数据,无未来数据引用

🛡️ 防护层级

  1. 装饰器防护: @prevent_future_data_leak
  2. 代码审查: 避免iloc[-1]在业务逻辑中使用
  3. 向量化: 使用Pandas向量化操作
  4. TA-Lib: 使用专业指标库

🚀 使用建议

开发新策略时

  1. 始终使用TA-Lib: ta.RSI(), ta.EMA(), ta.BBANDS()
  2. 避免手动计算: 不要使用dataframe.iloc[-1]影响决策
  3. 使用rolling窗口: dataframe.rolling(20).mean()
  4. 使用shift: dataframe.shift(1)获取历史数据

调试时

  • 可以使用iloc[-1]查看最后一行数据,但仅用于日志记录
  • 所有业务逻辑必须使用向量化操作

结论

当前策略已成功应用防未来数据泄露措施所有populate函数都已添加安全检查装饰器所有条件计算都使用向量化操作符合回测安全要求。