Skip to content

回测中可能忽略的问题

假设交易逻辑以RSI超买超卖开仓,若以当前未走完的K线(i=0,实时浮动指标值)作为判断依据,就会出现信号错误。因为实时K线的指标值是动态变化的,未固定,而回测环境使用的是历史固定K线(i=1及之后,开高低收已确定)。若代码中未统一处理,实盘与回测的交易记录和绩效会相差甚远。

为什么要统一回测与实盘的价位模式?

以MT5为例,实盘与回测的报价处理机制不同:

  1. 实盘环境
    • 平台服务器(MT5 Server)接收实时报价,传递到本地MT5客户端(MT5 Client),再传递给EA,最后到on tick方法。
    • 若前一个报价(Tick1)在on tick中未执行完毕,后续报价(Tick2、Tick3)会被丢弃,EA无法处理——代码运行效率影响报价接收。
  2. 回测环境
    • 本地测试环境直接生成历史报价,传递给EA和on tick方法。
    • 会等待前一个报价执行完毕,再处理后续报价,不会丢弃任何Tick——保证所有历史价格被处理。
    • 如果被丢弃的tick中刚好产生了交易信号, 则会导致回测结果与实盘结果不一致。

结论:实盘可能错过实时报价,回测则“不离不弃”,两者天然存在偏差。若再使用实时K线(i=0)作为判断依据,不统一喂价模式,实盘与回测绩效会严重脱节。

统一喂价模式的解决方案

1. 使用 isNewBar 函数控制执行时机

OnTick 方法前添加 isNewBar 函数,确保仅在新K线生成时处理价格,避免实时报价干扰:

cpp
bool isNewBar(string symbol, ENUM_TIMEFRAMES tf, int &totalBar)
{
   int totalBars = iBars(_Symbol, tf);
   if (totalBars == totalBar)
      return false;
   totalBar = totalBars;
   return true;
}

通过对比当前K线总数与全局变量,仅在新K线产生时执行策略,确保实盘与回测均基于K线第一个价格处理,统一喂价逻辑。

2. 优化回测时间周期设置

  • 避免高频喂价:回测时若选择“每次报价”或“每个点(基于实时点)”,虽看似精确,但会显著降低回测速度(尤其针对小时级以上策略)。
  • 推荐配置
    • 时间周期选择 M1(1分钟),喂价模式选择 “仅使用开盘价”,即每隔1分钟获取一次K线开盘价。
    • 若策略周期为日线或更高,可放宽至5分钟或更长周期,在保证精度的同时大幅提升回测效率。