研究烛条分析技术(第二部分):自动搜索新形态·综合运用
🔍

研究烛条分析技术(第二部分):自动搜索新形态·综合运用

(3/3)·手工翻形态太慢?让系统从11类基础烛条里自动生成并验证新组合

偏理论 第 3/3 篇
很多交易者把经典形态当万能钥匙,却忽略市场动态早已偏移。用固定形态套所有品种,等于拿旧地图找新路。让算法基于基础烛条类型自动搜新形态,才可能跟上当前盘面的脾气。

形态索引到烛条结构的映射逻辑

这段分支把整数索引直接翻译成烛条语义:index 3~4 对应短烛(多/空),5~6 是尖顶(spin top),7 号只标了多头十字星,8~9 是 Marubozu 实体阳/阴,10~11 为锤子线多空。注意 7 号没有空头分支,若你的样本里出现看跌 doji,这套映射会漏判,实盘前得在 MT5 里补一个 else if(index==12) 的空头十字星。 下面的 m_pattern_size 决定组合维度:1 根就只解 cand1,2 根解 cand1+cand2,3 根再叠 cand3,循环里用 elements[0~2] 当索引喂给 IndexToPatternType。回测 EURUSD M5 时,m_pattern_size=2 的组合数常落在 120~140 种,单根模式仅十一种,维度一升样本稀疏度就陡增。 最后的倒序扫描从 m_range_total2 跑到 i>5 才停,意味着最近 5 根不参与形态回看;若你想抓突破前两烛的异动,这个硬下限要把 5 改成 2 并同步调缓冲区,否则高频贵金属行情里会少算近端信号。外汇与贵金属杠杆高,这类遗漏可能放大滑点风险,改完务必用策略测试器跑一遍样本一致性。

MQL5 / C++
else if(index==class="num">3)
  {
  res.bull=true;      class=class="str">"cmt">// 标记短烛为多头方向
  res.type=CAND_SHORT; class=class="str">"cmt">// 烛条类型赋为短烛
  }
else if(index==class="num">4)
  {
  res.bull=false;     class=class="str">"cmt">// 短烛空头
  res.type=CAND_SHORT;
  }
else if(index==class="num">5)
  {
  res.bull=true;       class=class="str">"cmt">// 尖顶多头
  res.type=CAND_SPIN_TOP;
  }
else if(index==class="num">6)
  {
  res.bull=false;      class=class="str">"cmt">// 尖顶空头
  res.type=CAND_SPIN_TOP;
  }
else if(index==class="num">7)
  {
  res.bull=true;   class=class="str">"cmt">// 十字星仅多头分支
  res.type=CAND_DOJI;
  }
else if(index==class="num">8)
  {
  res.bull=true;        class=class="str">"cmt">// 多头Marubozu
  res.type=CAND_MARIBOZU;
  }
else if(index==class="num">9)
  {
  res.bull=false;       class=class="str">"cmt">// 空头Marubozu
  res.type=CAND_MARIBOZU;
  }
else if(index==class="num">10)
  {
  res.bull=true;     class=class="str">"cmt">// 多头锤子
  res.type=CAND_HAMMER;
  }
else if(index==class="num">11)
  {
  res.bull=false;    class=class="str">"cmt">// 空头锤子
  res.type=CAND_HAMMER;
  }
if(m_pattern_size==class="num">1)
     IndexToPatternType(cand1[i],(class="type">int)total_combination[i]);
     else if(m_pattern_size==class="num">2)
     {
     IndexToPatternType(cand1[i],(class="type">int)elements[class="num">0]);
     IndexToPatternType(cand2[i],(class="type">int)elements[class="num">1]);
     }
     else if(m_pattern_size==class="num">3)
     {
     IndexToPatternType(cand1[i],(class="type">int)elements[class="num">0]);
     IndexToPatternType(cand2[i],(class="type">int)elements[class="num">1]);
     IndexToPatternType(cand3[i],(class="type">int)elements[class="num">2]);
     }
for(class="type">int i=m_range_total2;i>class="num">5;i--)
  {
  if(m_pattern_size==class="num">1)
  {
   GetCandleType(symbol,cur_cand,m_timeframe2,i); class=class="str">"cmt">// 取当前烛条类型
   for(class="type">int j=class="num">0;j<total_patterns;j++)
     {
     if(cur_cand.type==cand1[j].type && cur_cand.bull==cand1[j].bull)

◍ 按组合长度匹配烛条形态并回写统计

这段逻辑按 m_pattern_size 分三档处理:2根、3根或更多根烛条的组合识别。每档都先调用 GetCandleType 把对应偏移位置的烛条类型和牛熊属性取出来,再和预设的 cand1/cand2/cand3 模板逐字段比对。 当 m_pattern_size 为 2 时,代码取 i 位置的前一根(prev_cand)与 i-1 的当前根(cur_cand);匹配成功后 m_pattern_total[j] 自增,并调 GetCategory(symbol,i-4,ratings[j],m_timeframe2) 记录后续分类。3根档位则多取一根 prev_cand2(i 位置),比对条件扩展到三根全中,分类回看偏移到了 i-5。 最后一段与分档无关:遍历 total_patterns,对每张表调 CoefCalculation(m_table2,i,ratings[i],m_pattern_total[i]) 算相关系数。开 MT5 把 m_pattern_size 改成 1 或 4 试一下,会发现此分支直接跳过统计——模板目前只覆盖 2 和 3 根组合。外汇与贵金属杠杆高,这类形态统计只描述历史频率,不代表后续必然重复。

MQL5 / C++
            {
             m_pattern_total[j]++;
             GetCategory(symbol,i-class="num">3,ratings[j],m_timeframe2);
            }
           }
          }
          else if(m_pattern_size==class="num">2)
          {
           class=class="str">"cmt">//--- 获取当前的烛条类型
           GetCandleType(symbol,prev_cand,m_timeframe2,i);                                                                     class=class="str">"cmt">// 前根烛条
           GetCandleType(symbol,cur_cand,m_timeframe2,i-class="num">1);                                                                   class=class="str">"cmt">// 当前烛条
           class=class="str">"cmt">//---
           for(class="type">int j=class="num">0;j<total_patterns;j++)
             {
              if(cur_cand.type==cand1[j].type && cur_cand.bull==cand1[j].bull &&
                  prev_cand.type==cand2[j].type && prev_cand.bull==cand2[j].bull)
               {
                m_pattern_total[j]++;
                GetCategory(symbol,i-class="num">4,ratings[j],m_timeframe2);
               }
             }
          }
          else if(m_pattern_size==class="num">3)
          {
           class=class="str">"cmt">//--- 获取当前的烛条类型
           GetCandleType(symbol,prev_cand2,m_timeframe2,i);                                                                  class=class="str">"cmt">// 前根烛条
           GetCandleType(symbol,prev_cand,m_timeframe2,i-class="num">1);                                                                class=class="str">"cmt">// 前根烛条
           GetCandleType(symbol,cur_cand,m_timeframe2,i-class="num">2);                                                                  class=class="str">"cmt">// 当前烛条
           class=class="str">"cmt">//---
           for(class="type">int j=class="num">0;j<total_patterns;j++)
             {
              if(cur_cand.type==cand1[j].type && cur_cand.bull==cand1[j].bull &&
                  prev_cand.type==cand2[j].type && prev_cand.bull==cand2[j].bull &&
                  prev_cand2.type==cand3[j].type && prev_cand2.bull==cand3[j].bull)
               {
                m_pattern_total[j]++;
                GetCategory(symbol,i-class="num">5,ratings[j],m_timeframe2);
               }
             }
          }
         }
class=class="str">"cmt">//---
   for(class="type">int i=class="num">0;i<total_patterns;i++)
      CoefCalculation(m_table2,i,ratings[i],m_pattern_total[i]);
class=class="str">"cmt">//+------------------------------------------------------------------+

「效率系数怎么落进表格」

评级系统算出三类品种在上涨/下跌趋势里的命中数后,需要把原始计数转成可读指标。这段逻辑干的就是把 sum1、sum2 除以 found 得到百分比 p1、p2,再用权重 m_k1~m_k3 折算出 k1、k2 两个效率系数,保留两位小数或三位小数。 found 是已匹配的样本总量,若它为 0 则所有比率直接置 0,避免除零崩脚本。m_range_total2 是总扫描区间,第二列写的是 found 占全区间的覆盖百分比,能看出这套扫描在行情里实际触发的密度。 表格列序固定:1列样本数、2列覆盖率、3列上行概率、4列下行概率、5列上行系数、6列下行系数。Update(true) 连同横竖滚动条一起刷,是 MT5 自定义 CTable 里防止界面卡旧值的写法。外汇与贵金属波动剧烈,这类系数仅反映历史样本倾向,实盘须以高风险视角看待。 下面把核心函数逐行拆一遍,方便你直接抄进自己的 EA 里改权重。

MQL5 / C++
class="type">bool CProgram::CoefCalculation(CTable &table,const class="type">int row,RATING_SET &rate,class="type">int found)
  {
   class="type">class="kw">double p1,p2,k1,k2;
   class="type">int sum1=class="num">0,sum2=class="num">0;
   sum1=rate.a_uptrend+rate.b_uptrend+rate.c_uptrend;
   sum2=rate.a_dntrend+rate.b_dntrend+rate.c_dntrend;
class=class="str">"cmt">//---
   p1=(found>class="num">0)?NormalizeDouble((class="type">class="kw">double)sum1/found*class="num">100,class="num">2):class="num">0;
   p2=(found>class="num">0)?NormalizeDouble((class="type">class="kw">double)sum2/found*class="num">100,class="num">2):class="num">0;
   k1=(found>class="num">0)?NormalizeDouble((m_k1*rate.a_uptrend+m_k2*rate.b_uptrend+m_k3*rate.c_uptrend)/found,class="num">3):class="num">0;
   k2=(found>class="num">0)?NormalizeDouble((m_k1*rate.a_dntrend+m_k2*rate.b_dntrend+m_k3*rate.c_dntrend)/found,class="num">3):class="num">0;
   table.SetValue(class="num">1,row,(class="type">class="kw">string)found);
   table.SetValue(class="num">2,row,(class="type">class="kw">string)((class="type">class="kw">double)found/m_range_total2*class="num">100),class="num">2);
   table.SetValue(class="num">3,row,(class="type">class="kw">string)p1,class="num">2);
   table.SetValue(class="num">4,row,(class="type">class="kw">string)p2,class="num">2);
   table.SetValue(class="num">5,row,(class="type">class="kw">string)k1,class="num">2);
   table.SetValue(class="num">6,row,(class="type">class="kw">string)k2,class="num">2);
class=class="str">"cmt">//--- 更新表格
   table.Update(true);
   table.GetScrollVPointer().Update(true);
   table.GetScrollHPointer().Update(true);
   class="kw">return(true);
  }

用 GBPUSD 跑一遍单、双、三烛形态

想验证形态生成器的实用性,直接拿 GBPUSD 的 H1 开刀最直观。第一步只勾选全部简单烛条模型,反复模式设“有反复”,形态内烛条数填 1,趋势阈值点数给 200;进 AutoSearch 搜 Major 再点 GBPUSD,最常见的六种单烛按出现频次排是 1、2、5、6、3、4。 双烛测试时回到设置取消 7–11 号模型,反复改“无反复”、烛条数设 2。若阈值偏低,高时间帧里正反走势几乎没差;把阈值加到 400 后条件变严,结果里 [1,4] 与 [2,6] 呈现单向大动、反向小动,后者(长空—尖顶空)出现频率近乎前者的两倍,更值得盯。 三烛只留 1、2、5、6 四种高频类型,阈值维持 400。同样原则下,[2,5,2](长空—尖顶多—长空)与 [2,5,5](长空—尖顶多—尖顶多)效率系数和概率表现突出,前者上型趋势概率高且系数大,后者单向概率好但系数稍低。 全 11 类烛条全开会产生过多组合,最大可能形态数达 1463(不含样本、周期、阈值等维度),实机跑起来很耗时;建议分批勾选类型,外汇与贵金属波动剧烈、杠杆风险高,回测结论仅代表历史概率倾向。

◍ 把工具请下神坛

这套烛条形态分析工具栏的存档包体积 431.36 KB,解压后把 MQL5 文件夹直接丢进终端目录就能跑,核心文件就三个:PatternAnalyzer.mq5 管图形界面,MainWindow.mqh 和 Program.mqh 是两个底层库。 但别以为下载即胜利。评论区里 2020 到 2024 年陆续有人反馈,第二部分、第四部分代码窗口秒关,最近一位用户直说「太多报错无法解决」。编译日志里 MainWindow.mqh 从 164 行到 638 行堆了一串硬伤:AddItem 参数数量错、number 隐式转 string、SelectedRowColor 和 GreenCheckBox 未声明。 外汇和贵金属波动剧烈、杠杆高风险,这类 GUI 工具只是把形态识别从肉眼搬到屏幕,信号失效时该止损还是得止损。下完包先别急着挂真仓,开 MT5 把那几个未声明标识符补进头文件,能编译过再谈验证。

MQL5 / C++
&class="macro">#x27;AddItem&class="macro">#x27;                 - wrong parameters count       MainWindow.mqh   class="num">164    class="num">17
implicit conversion from &class="macro">#x27;number&class="macro">#x27; to &class="macro">#x27;class="type">class="kw">string&class="macro">#x27;        MainWindow.mqh   class="num">164    class="num">25
&class="macro">#x27;AddItem&class="macro">#x27;                 - wrong parameters count       MainWindow.mqh   class="num">165    class="num">17
implicit conversion from &class="macro">#x27;number&class="macro">#x27; to &class="macro">#x27;class="type">class="kw">string&class="macro">#x27;        MainWindow.mqh   class="num">165    class="num">25
&class="macro">#x27;SelectedRowColor&class="macro">#x27;        - undeclared identifier       MainWindow.mqh   class="num">383    class="num">10
&class="macro">#x27;C&class="macro">#x27; class="num">120 , class="num">100 , class="num">225 &class="macro">#x27;&class="macro">#x27;    - some class="kw">operator expected       MainWindow.mqh   class="num">383    class="num">27
&class="macro">#x27;SelectedRowColor&class="macro">#x27;        - undeclared identifier       MainWindow.mqh   class="num">441    class="num">13
&class="macro">#x27;C&class="macro">#x27; class="num">120 , class="num">100 , class="num">225 &class="macro">#x27;&class="macro">#x27;    - some class="kw">operator expected       MainWindow.mqh   class="num">441    class="num">30
&class="macro">#x27;GreenCheckBox&class="macro">#x27;           - undeclared identifier       MainWindow.mqh   class="num">638    class="num">16
&class="macro">#x27;true&class="macro">#x27;                    - some class="kw">operator expected       MainWindow.mqh   class="num">638    class="num">30
把形态巡检交给小布
这些诊断小布盯盘的 AIGC 已内置,打开对应品种页即可看到自动标注的候选形态与出现频率,你只需判断哪些值得跟。

常见问题

过长的组合会急剧放大形态数量并稀释统计意义,1-3根能在覆盖度与可验证性之间保持平衡,便于后续按出现频率和方向概率筛选。
Set列代表系统生成的形态集合且表格行数不固定,原有分析表针对14种预设形态行数写死,新表随搜索结果动态扩展。
小布的品种页已内置类似AIGC诊断,会自动整理基础烛条参与情况与频率,省去自己在MT5里搭选项卡的重复劳动。
十字星多空意图模糊,强行归边会污染形态的方向概率统计,因此算法将其作为无方向类型单独参与组合。
池子完全容纳11种基础烛条,即6种简单类型按多空拆分后除去十字星方向项所得,新形态均从中抽取并允许反复。