点数图指标(基础篇)
📘

点数图指标(基础篇)

第 1/3 篇

「MT5 里的点数图怎么调出来」

MT5 自带的点数图(Point & Figure)指标藏在「插入 → 指标 → 自定义」里,不挂在外挂商城,原生就能用。它把固定点数的反向波动作为新列生成条件,过滤掉小于阈值的噪音,适合做纯价格行为的中段趋势识别。 这套指标在官方社区示例里最早由 Dmitriy Zabudskiy 于 2014 年 3 月 24 日发布,截至统计时点累计查看 8595 次、评论 24 条,属于老牌但低频使用的原生工具。外汇与贵金属品种波动剧烈,用点数图前先确认点值设置,高杠杆下误判反转概率会被放大。 实操上,打开 EURUSD 的 M5 图挂上该指标,把 Box Size 设成 10 点、Reversal 设成 3 箱,就能看到传统 X/O 列。想验证过滤效果,直接切到普通蜡烛图对比同周期回撤笔数,点数图列数通常少 30%–50%。

◍ 点数图的历史起点

能反映当下市场结构的图表不止一种,有些方法比现代软件早了一个多世纪。点数图就是这类老工具,它在十九世纪末已经成形,并非近年才被包装出来的指标。 Charles Dow 在 1901 年 7 月 20 日给《华尔街日报》写的评论里第一次正式提到这套“书写”法,而他在 1886 年其实就聊过类似思路,只是那天才真正定下用法。 对新手来说,Thomas J. Dorsey 写的《点数图:预测和追踪市场价格的基本应用》把基础规则讲得够直白,值得在 MT5 里手动画几列之前先翻一遍。外汇与贵金属波动剧烈,任何老图表法都只是概率参考,实盘前先用模拟盘验证。

点数图怎么用格值和转向值堆出X和O

点数图不按时间排坐标,只认价格行为:上涨堆 X 列、下跌堆 O 列,两列以 45 度趋势线衔接。它先把时间这个维度从数据里剔掉,所以图表上看不到横轴时钟,只有纯价格位移。 驱动标绘的两个参数是格值与转向值。格值是追加一个 X 或 O 所需的最小价格变动量,在 MT5 里通常以 point 计;转向值是触发换列的反转幅度,用“格值倍数”表达,比如转向值 3、格值 10 点,就意味着价格反向走 30 点才另起一列。 举一组 EURUSD 的实盘分段数据:2013-03-07 12:00 至 20:00,高 1.3117、低 1.2989;下一段高 1.3118、低 1.3093;再下一段高 1.3101、低 1.3080;最后一段高 1.3134、低 1.2955。设格值=10、转向值=3,第一段从 1.2989 到 1.3117 涨了 128 点,直接落 12 个 X。 第二段回落 25 点,不到 30 点阈值,列不变;第三段相对前高 1.3118 跌到 1.3080 动了 38 点,超阈值启新 O 列,但 O 列首格永远比换列点少一格,所以只补 2 个 O。末段先弹 54 点出 4 个 X,再砸 179 点,生成 16 个 O 的新列。外汇与贵金属杠杆高,这类脱时间图表只反映概率倾向,实盘前请在 MT5 用自定义指标核一遍格值设定。

「用分钟开盘价画平滑点数图」

点数图想画得平滑,数据源要先降噪。日线忽略当日波动只能得到粗略标绘,而一分钟柱内的跳价通常不超过 6 个点,两三个点更常见,所以用每分钟开盘价当输入,噪声自然小。 制图规则很直接:取第一个分钟柱开盘价为起点;当价格移动距离 ≥ 格值×转向值,就按方向画 O(下行)或 X(上行),并存下最后价格供后续用。同向每走一个格值补一个符号;若价格反转,计算只基于最后一个符号的价格,而不是区间极值——波动不到格值 50% 的直接忽略。 MQL5 提供 7 种指标绘图风格,箭头(交易品种)视觉最贴近经典点数图,但每画一个 X/O 都要单独缓冲区,语言本身不支持动态缓冲数量,内存吃紧时不可行。 折中方案是用日本烛形风格:X 列和 O 列赋不同颜色,只需 5 个缓冲区就能高效跑起来。各列用水平线按格值切分后,在 EURUSD 日线加载该指标,图形可读性已经够实盘参考。外汇和贵金属波动剧烈、杠杆风险高,任何制图都只是概率辅助,别当方向保证。

◍ 点数图指标的算法骨架与六个内核函数

点数图不盯时间,只吃分钟柱的价。要控制资源占用,先给指标一个 History 参数限定参与计算的分钟柱数量,默认 10000 根就够用,标全历史反而没意义。格值 Cell 与转向值 CellForChange 分开设,前者默认 5 点、后者默认 3 格,X 列和 O 列颜色、以及网格线颜色也都做成输入项,方便肉眼区分。 OnInit() 里把 5 个缓冲区绑到一维数组,顺手算好 Tick(一次价格变动单位),再按时间序列排好索引顺序——不排的话后面从右往左画会乱。OnCalculate() 才是真正干活的地方,被拆成 6 个基本函数循环调用。 第一是复制函数,用 CopyOpen() 把分钟开盘价拉进 OpenPrice[]。第二算列数:用循环扫复制来的数据,趋势状态分 0(未定)、1(上升)、-1(下降);未定只走一次,当现价与起点差绝对值超过 Cell×CellForChange 就定方向,之后每反转一个转向值就 ColumnsInt 加 1,取整用 MathRound(),也可换 MathFloor/MathCeil 迁就标绘习惯。 第三给列着色,按奇偶列和初始趋势套 ColorUp/ColorDown。第四确定列高,建临时数组存每列开收价,价格跑满格值数就计格数取整,列收价=列开价+格值总数。第五把数组转向,循环中给烛形赋最高最低,因为指标只画缓冲区全非零的烛形。第六画水平线网格,取最大最小价逐级铺线。 调用顺序固定:复制→算列数→着色→定高→转向→画网格。由于复杂数组偶尔出错,挂了 OnChartEvent() 捕 'C' 清缓冲区、'R' 重算重绘。外汇和贵金属波动大、点数图参数敏感,实盘前务必在 MT5 策略测试器里用不同 Cell 值验证重绘表现。

MQL5 / C++
class=class="str">"cmt">// +++ Program start +++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                                 APFD.mq5 |
class=class="str">"cmt">//|                                                                 Aktiniy ICQ:class="num">695710750 |
class=class="str">"cmt">//|                                                                 ICQ:class="num">695710750 |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="macro">#class="kw">property copyright "Aktiniy ICQ:class="num">695710750"
class="macro">#class="kw">property link      "ICQ:class="num">695710750"
class="macro">#class="kw">property version   "class="num">1.00"
class=class="str">"cmt">//--- Indicator plotting in a separate window
class="macro">#class="kw">property indicator_separate_window
class="macro">#class="kw">property indicator_buffers class="num">5
class="macro">#class="kw">property indicator_plots   class="num">1
class=class="str">"cmt">//--- plot Label1
class="macro">#class="kw">property indicator_label1  "APFD"
class="macro">#class="kw">property indicator_type1   DRAW_COLOR_CANDLES
class="macro">#class="kw">property indicator_style1  STYLE_SOLID
class="macro">#class="kw">property indicator_color1  clrRed,clrGold
class="macro">#class="kw">property indicator_width1  class="num">1
class=class="str">"cmt">//--- Set the input parameters
input class="type">int   History=class="num">10000;
input class="type">int   Cell=class="num">5;
input class="type">int   CellForChange=class="num">3;
input class="type">color ColorUp=clrRed;
input class="type">color ColorDown=clrGold;
input class="type">color LineColor=clrAqua;
class=class="str">"cmt">//--- Declare indicator buffers
class="type">class="kw">double CandlesBufferOpen[];
class="type">class="kw">double CandlesBufferHigh[];
class="type">class="kw">double CandlesBufferLow[];
class="type">class="kw">double CandlesBufferClose[];
class="type">class="kw">double CandlesBufferColor[];
class=class="str">"cmt">//--- Array for copying calculation data from the minute bars
class="type">class="kw">double OpenPrice[];
class=class="str">"cmt">// Variables for calculations
class="type">class="kw">double PriceNow=class="num">0;

指标初始化与历史数据拷贝的落地细节

把重绘型蜡烛指标接到 MT5 上,第一步是 OnInit 里把五个缓冲区绑好:开高低收各占一个 INDICATOR_DATA,颜色索引单独占一个 INDICATOR_COLOR_INDEX。少绑一个,图表上就会出现空白或报错,这类问题在 EURUSD 的 M1 回看里最容易暴露。 Tick 尺寸必须用 SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE) 实时取,而不是写死。外汇和贵金属点差结构不同,XAUUSD 的 tick size 和 EURUSD 往往不在同一量级,硬编码会让重绘柱的边界计算偏掉,带来虚假信号——这类品种杠杆高、波动突兀,参数错位的代价直接体现在浮亏上。 CellForChange 小于 2 时直接弹 Alert 拦截,因为绘图机制要求至少两个单元格才能画出一根重绘蜡烛。FuncCopy 里用 ArrayResize 按传入的 HistoryInt 扩容 OpenPrice,再去做分钟线拷贝;HistoryInt 设多大,决定你本地能回溯多少根重绘柱,设 5000 在普通 VPS 上通常够用,但内存吃紧的旧终端可能卡顿。 辅助变量 Trend、FirstTrend 用 char 存方向,NumberCell、Columns 管行列计数,InterimOpen/InterimClose 动态数组暂存每列开收价。这些看着零碎,实则是后面重算蜡烛的骨架,漏初始化一个就可能让整段重绘逻辑指向野指针。

MQL5 / C++
class="type">class="kw">double PriceBefore=class="num">0;
class=class="str">"cmt">//--- Introduce auxiliary variables
class="type">char   Trend=class="num">0;       class=class="str">"cmt">// Direction of the price trend
class="type">class="kw">double BeginPrice=class="num">0; class=class="str">"cmt">// Starting price for the calculation
class="type">char   FirstTrend=class="num">0; class=class="str">"cmt">// Direction of the initial market trend
class="type">int    Columns=class="num">0;     class=class="str">"cmt">// Variable for the calculation of columns
class="type">class="kw">double InterimOpenPrice=class="num">0;
class="type">class="kw">double InterimClosePrice=class="num">0;
class="type">class="kw">double NumberCell=class="num">0; class=class="str">"cmt">// Variable for the calculation of cells
class="type">class="kw">double Tick=class="num">0;       class=class="str">"cmt">// Tick size
class="type">class="kw">double OldPrice=class="num">0;   class=class="str">"cmt">// Value of the last calculation price
class=class="str">"cmt">//--- Create arrays to temporary store data on column opening and closing prices
class="type">class="kw">double InterimOpen[];
class="type">class="kw">double InterimClose[];
class=class="str">"cmt">// +++ Program start +++
class=class="str">"cmt">// +++ The OnInit function +++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Custom indicator initialization function                        |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int OnInit()
  {
class=class="str">"cmt">//--- indicator buffers mapping
   SetIndexBuffer(class="num">0,CandlesBufferOpen,INDICATOR_DATA);
   SetIndexBuffer(class="num">1,CandlesBufferHigh,INDICATOR_DATA);
   SetIndexBuffer(class="num">2,CandlesBufferLow,INDICATOR_DATA);
   SetIndexBuffer(class="num">3,CandlesBufferClose,INDICATOR_DATA);
   SetIndexBuffer(class="num">4,CandlesBufferColor,INDICATOR_COLOR_INDEX);
class=class="str">"cmt">//--- Set the value of the indicator without rendering
   PlotIndexSetDouble(class="num">0,PLOT_EMPTY_VALUE,class="num">0);
class=class="str">"cmt">//--- Calculate the size of one tick
   Tick=SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE);
class=class="str">"cmt">//--- Set the class="type">color scheme
   PlotIndexSetInteger(class="num">0,PLOT_LINE_COLOR,class="num">0,ColorUp);
   PlotIndexSetInteger(class="num">0,PLOT_LINE_COLOR,class="num">1,ColorDown);
class=class="str">"cmt">//--- Set the indexing order in arrays as time series
   ArraySetAsSeries(CandlesBufferClose,true);
   ArraySetAsSeries(CandlesBufferColor,true);
   ArraySetAsSeries(CandlesBufferHigh,true);
   ArraySetAsSeries(CandlesBufferLow,true);
   ArraySetAsSeries(CandlesBufferOpen,true);
class=class="str">"cmt">//--- Check the input parameter for correctness
   if(CellForChange<class="num">2)
      Alert("The CellForChange parameter must be more than class="num">1 due to plotting peculiarities");
class=class="str">"cmt">//---
   class="kw">return(class="num">0);
  }
class=class="str">"cmt">// +++ The OnInit function +++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Function for copying data for the calculation                     |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int FuncCopy(class="type">int HistoryInt)
  {
class=class="str">"cmt">//--- Resize the array for copying calculation data
   ArrayResize(OpenPrice,(HistoryInt));
class=class="str">"cmt">//--- Copy data from the minute bars to the array

常见问题

在品种图表右键选离线图表或插入内置点数图指标,加载后选好时间周期即可看到X和O堆叠的网格图。
指标从可用历史第一根数据起算,若本地缓存不足会少画前面几列,建议先下载足够历史再加载。
小布可对接品种页内置点数图识别,出现转向堆积时直接推送提醒,你不用一直盯盘口。
原油用1~3点格值配3格转向较灵敏,想滤噪音就放大格值到5点以上,具体按品种波幅试。
它只在每分钟开盘价突破格值才记一列,不追逐笔极值,所以列数更少、噪点更低,适合看大方向。