价格速度测量方法·综合运用
📈

价格速度测量方法·综合运用

(3/3)·把前两篇的速度测量模型真正跑进历史回测与实盘决策,看清哪些参数只是好看

案例拆解新手友好 第 3/3 篇
很多人把价格速度算出来就以为能直接下单,却从没验证过它在震荡市会不会频繁假信号。本篇用具体测试把方法的边界摊开,省得你拿真金白银去交学费。

「卖单触发与幻数仓位筛查的实现细节」

这段逻辑紧接前面的买价突破判断,当最新 tick 的 bid 相对历史 tick 的 bid 差值大于 ExtPoints 时,系统倾向开启 SELL 持仓。SL 与 TP 若输入参数为 0 则直接置 0,否则以历史 bid 为基准做加减后交给 NormalizePrice 对齐报价精度。 m_trade.Sell 传入手数、品种名、进场 bid 以及标准化后的止损止盈,随后把 last_trade_time 更新为当前 tick 的 time_msc,避免同根 K 线内重复发单。外汇与贵金属杠杆高,这类基于 tick 差值的触发在滑点行情中可能连续误触,实盘前务必在 MT5 策略测试器用真实点差回测。 IsOpenedByMagic 用 PositionsTotal 遍历全部持仓,借助 SelectByIndex 与 PositionGetInteger(POSITION_MAGIC) 比对幻数,只要存在同幻数仓位就返回 true。下面这段是 SELL 分支与筛查函数的核心代码,逐行看能少踩不少坑。 SelectByIndex 先读账户保证金模式:零售对冲账户走 PositionGetTicket 按索引取仓,返回 0 说明索引无效;非对冲账户则取 PositionGetSymbol,空串同样判否。两种分支都只为上层遍历提供“可否选中”的布尔闸门,不碰具体持仓字段。

MQL5 / C++
      m_symbol.NormalizePrice(tp));
      last_trade_time=tick_array_curr[tick_count-class="num">1].time_msc;
      }
      else if(tick_array_curr[shift].bid-tick_array_curr[tick_count-class="num">1].bid>ExtPoints)
      {
      class=class="str">"cmt">//--- 开启 SELL
      class="type">class="kw">double sl=(InpStopLoss==class="num">0)?class="num">0.0:tick_array_curr[tick_count-class="num">1].bid-ExtStopLoss;
      class="type">class="kw">double tp=(InpTakeProfit==class="num">0)?class="num">0.0:tick_array_curr[tick_count-class="num">1].bid+ExtTakeProfit;
      m_trade.Sell(InpLots,m_symbol.Name(),tick_array_curr[tick_count-class="num">1].bid,
            m_symbol.NormalizePrice(sl),
            m_symbol.NormalizePrice(tp));
      last_trade_time=tick_array_curr[tick_count-class="num">1].time_msc;
      }
     }
  ArrayCopy(tick_array_prev,tick_array_curr);
class=class="str">"cmt">//---
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| 使用幻数检查开启的仓位                                                            |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">bool IsOpenedByMagic(class="type">int MagicNumber)
  {
   class="type">int pos=class="num">0;
   class="type">uint total=PositionsTotal();
class=class="str">"cmt">//---
   for(class="type">uint i=class="num">0; i<total; i++)
     {
      if(SelectByIndex(i))
        if(PositionGetInteger(POSITION_MAGIC)==MagicNumber)
           pos++;
     }
   class="kw">return((pos>class="num">0)?true:false);
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| 根据索引选择仓位                                                                  |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">bool SelectByIndex(class="kw">const class="type">int index)
  {
   ENUM_ACCOUNT_MARGIN_MODE margin_mode=(ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE);
class=class="str">"cmt">//---
   if(margin_mode==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)
     {
      class="type">class="kw">ulong ticket=PositionGetTicket(index);
      if(ticket==class="num">0)
         class="kw">return(false);
     }
   else
     {
      class="type">class="kw">string name=PositionGetSymbol(index);
      if(name=="")
         class="kw">return(false);
     }
class=class="str">"cmt">//---
   class="kw">return(true);
  }
class=class="str">"cmt">//+------------------------------------------------------------------+

三种测速策略的回测对照

把三种价格速度算法放到同一环境下跑,才能看出哪种处理思路更经得起折腾。测试窗口取近一年(撰文时约为 2019.01.01—05.26),品种锁 EURUSD,M1 级别 OHLC 起步,初始本金 1000 USD,杠杆 1:500,MetaQuotes-Demo 服务器,五位数报价。延迟不纳入变量,因为这几套都不是高频逻辑,滑点扰动相对有限。 策略一用标准价格速度差值直接触发。前 20 组优化里,低周期搭配小止盈止损反而得分最高,说明信号自身的变化潜力被压得很薄。取常数 0.1 的最优组做单遍回放:资金曲线涨了接近 100%,但夏普只有 0.33,Z 值 -0.16,基本指向随机驱动、一致性很差。EURUSD 这类主流货币对外汇杠杆风险本就偏高,这种统计特征绝不能当常态预期。 策略二把数据基底换成「基于真实分时的每一分时」,其余条件不动。优化前 20 的夏普整体比策略一好看,最佳区落在最小节拍数配合适中点数的组合。系统选择性偏尖——成交笔数极少。最优组回测里利润超 30% 只来自 10 笔交易,样本薄,结论要打折扣。 策略三退回 M1 OHLC,改用间接刻画价动与速率的指标。前 20 组长得很像,暗示最后两个优化参数几乎是摆设;平均夏普约 0.2,不算亮眼。最优组回放显示存款近乎翻倍、夏普漂亮,但用了 52 笔才走到该利润,且 Z 评分呈负相关——盈利笔后面挂亏损笔的概率倾向更高,贵金属与外汇品种遇这种序列要警惕来回吐。

◍ 三种测速法的回测分化

把三类价格速度测量思路接上后验优化跑完,第一种方法的最优参数在不同样本上跳得很厉害,缺乏一致性,实盘直接照搬容易踩坑。 剩下两种的回测表现更稳:夏普比率偏高,且单笔交易之间呈负相关——意味着这笔亏、那笔更可能赚,组合回撤被天然摊薄。 当然这次验证没穷尽所有速度算法,只是挑了最直观、好落地的几种。外汇与贵金属杠杆高、滑点跳空频繁,上述负相关只是样本内概率倾向,换周期或品种可能失效,开 MT5 用自有品种复跑再信。

「把附件跑进终端根目录」

随文打包的 MQL5.zip 体积 734.69 KB,里面按文件夹排好了三套 EA(Strategy_1/2/3.mq5)、一个交易函数库 Engine.mqh,以及平均速度、CAM、趋势方向和力度、HMA_color 四个指标。要直接验证文中策略,得先把 MQL5 文件夹塞进终端根目录,而不是随便解压到桌面。 在 MT5 里按 Ctrl+Shift+D,或用数据文件夹的上下文菜单,就能打开终端根目录。根目录下的 MQL5 文件夹若被覆盖正确,重启终端后导航器里就能看到对应的 EA 与指标。 外汇和贵金属杠杆高、滑点随机,哪怕把作者给出的三套策略都加载回测,也只代表历史样本里的特定表现,实盘仍可能偏离。先在一览里挑 Strategy_1 配合平均速度与 CAM 指标做单机验证,比直接挂实盘更稳妥。

让小布替你跑这套回测
这些诊断与小布盯盘的 AIGC 已内置,打开对应品种页即可看到速度阈值与历史表现,把重复劳动交给小布,你专注决策。

常见问题

单根蜡烛只给开盘到收盘的均值,内部加速减速被抹平,低周期切片才能接近真实盘感,但噪音也会变多。
可以,品种页已内置速度偏离提示,不需要自己写指标,打开就能比对当前速率和历史分位。
倾向至少覆盖两种行情 regime,单纯用三个月趋势段回测容易高估胜率,贵金属与外汇高风险需分开验。
可按近期波动率分位设动态线,固定点数在跳空日会失真,概率上动态阈值更稳。