小型趋势指标、中型趋势指标和主要趋势指标(基础篇)
「三类趋势指标该怎么分清楚」
在 MT5 里看趋势,先得把周期层级掰开:小型趋势指标盯的是分钟级到小时级的毛刺运动,中型趋势指标通常对应日线附近的波段,主要趋势指标则落在周线及以上,用来定大方向。三层混在一起看,才不容易把噪音当信号。 实操上,很多自带指标(比如不同周期的均线或 MACD)都能分别套到这三个层级。外汇和贵金属杠杆高、跳空频繁,小周期指标容易假突破,大周期指标滞后明显,三层对照能压一压误判概率。 一个可验证的现象:同一品种在 H1 上金叉、在 W1 上却还是死叉,这种背离在 2014 年之后主流货币对里每周都能撞上几次,开 MT5 调出双周期叠加就能自己数。
◍ 甘氏三要素为何常被单拆使用
James Hyerczyk 在《形态-价格-时间:甘氏理论在交易系统里的运用》序言里点出一个实盘通病:交易者做分析时太爱只盯形态、价格或时间中的一项,而不是三者并行。他统计自己的期货经验发现,最常见的系统错误是围绕“进场看时间/出场看价格”或反过来“进场看价格/出场看时间”来搭建,用形态的人则常以较差价位或较差时机进出。 这类偏科直接导致信号质量下降。Hyerczyk 的结论是,形态、价格、时间三者组合才是市场生存的必要条件,他的书也是在这个前提下落笔的。 你可以不认同这个前提,但值得在 MT5 里亲自验证:把纯形态EA、纯均线(价格)EA、纯时间周期突破EA 分别跑同一品种,对比权益曲线离散度。本文后续会基于书中理念,聊怎么用指标和 EA 做自动化分析,建议先翻完该书第一部分“模型”再动手,否则参数含义容易看偏。
从相邻K线关系里抠出小型趋势线段
小型趋势不靠指标参数去拟合,只盯相邻两根 K 线的高低价关系。向上走势要求后一根最高价 > 前一根最高价,且后一根最低价 > 前一根最低价,这时把两根最高价连起来就是一段上升线段;向下则反过来,后一根最低价和最高价都分别小于前一根,连最低价得下降线段。 内侧柱和外侧柱会打断这种简单连接:若后一根最低价高于前一根最低价、同时最高价低于前一根最高价,就是内侧柱,不参与图形构建;若后一根最高价和最低价同时突破前一根的上下沿,就是外侧柱,按它本身方向接上对应区段。 方向切换点就是小型顶底。图 1 里左侧红标是小型底、右侧绿标是小型顶。若向上转向下却没跌破前一个底,只是纠正移动,方向未必真反转——下行同理。价格在顶底之间来回即摆动,可能夹杂纠正移动。 这套画线和常见峰谷指标形态接近,但区别在于它不在其他柱收盘后重绘,也没有外部可调参数去影响趋势线构造,等于把规则锁死在价格本身。外汇与贵金属波动大,纯价格规则也可能在毛刺行情里频繁切换,开 MT5 用历史单品种验证比直接信结论更稳妥。
「画一条小型趋势线:GannMicroTrend 的骨架」
做微型趋势指标,核心是把逐根 K 线的高低点按规则串成线段,并在最近顶/底打上价格标签。它依赖标准库里的 CChartObjectTrend 画趋势线,顶部用左侧价签、底部用右侧价签,全部塞进 CList 方便按时间顺序取最新节点。 外部参数先定边界:MaxBars=1000 意味着默认只扫最近 1000 根柱,设 0 才全量计算;IsSaveTrendParams=true 会把当前趋势和最新顶底写进全局变量,ShowInfo=true 则在图上输出坐标。颜色与线宽也全暴露:UpTrendColor 浅绿、DnTrendColor 浅粉、LineWidth=4,顶底标签宽 StopLossWidth=1。 OnInit 里第一件事是 new 出三个列表指针,校验失败直接报错退出——错误码带 # 方便定位。OnCalculate 看 prev_calculated==0 就清盘重算:删图形对象、清列表,再按 MaxBars 与 rates_total 的关系算 start 起点(柱索引从 0 即最新一根起算)。 画线靠 CreateCut,内部用 GetUniqName 生成唯一名避免重名,成功就设色宽并 CList::Add;顶底则用类似的 CreateUpStopLoss / CreateDnStopLoss。算完用 GetLastNode 捞最新顶底对象填表。外汇与贵金属波动剧烈,这类辅助指标仅描述已发生结构,信号失效概率不低,请先在 MT5 策略测试器跑历史段验证。
class="macro">#include <TextDisplay.mqh> input class="type">int MaxBars = class="num">1000; input class="type">bool IsSaveTrendParams = true; class=class="str">"cmt">//--------------------------------------------------------------------- input class="type">bool ShowInfo = true; input class="type">int UpDownInfoShift = class="num">1; input class="type">int LeftRightInfoShift = class="num">1; input class="type">color TitlesColor = LightCyan; input class="type">color TopFieldsColor = Green; input class="type">color LowFieldsColor = Brown; class=class="str">"cmt">//--------------------------------------------------------------------- input class="type">color UpTrendColor = LightGreen; input class="type">color DnTrendColor = LightPink; input class="type">int LineWidth = class="num">4; class=class="str">"cmt">//--------------------------------------------------------------------- input class="type">color UpStopLossColor = Green; input class="type">color DnStopLossColor = Brown; input class="type">int StopLossWidth = class="num">1; class="macro">#include <Arrays\List.mqh> class="macro">#include <ChartObjects\ChartObjectsLines.mqh> class="macro">#include <ChartObjects\ChartObjectsArrows.mqh> CList* trend_list_Ptr = NULL; class=class="str">"cmt">// list of the trend lines CList* up_list_Ptr = NULL; class=class="str">"cmt">// list of the peaks CList* dn_list_Ptr = NULL; class=class="str">"cmt">// list of the bottoms class="type">int OnInit() { trend_list_Ptr = new CList(); if(CheckPointer(trend_list_Ptr) != POINTER_DYNAMIC) {
◍ 指针校验与初始化的坑
在 MT5 自定义指标里用 CList 管理多组趋势线段,第一步就是动态申请三个链表指针:trend_list_Ptr、up_list_Ptr、dn_list_Ptr。每段 new 出来后必须用 CheckPointer 比对 POINTER_DYNAMIC,否则一旦返回 POINTER_INVALID 或 POINTER_STATIC,后面 Clear()、Add() 都会直接崩。 代码里对三个指针分别做了独立判断,失败时 Print 出对应编号的错误串并返回 -1,这种写法能在日志里精确定位是第几个对象申请失败,比统一报错省不少排查时间。 OnCalculate 首次跑(prev_calculated==0)时会先把三个链表 Clear 一遍,再根据 MaxBars 决定 start 位置:若 MaxBars>0 且 rates_total 超过它,就从 rates_total-MaxBars 根 K 线开始算,否则从头扫。这个截断逻辑直接影响图形绘制的计算量。 CreateCut 函数封装了一段趋势线的绘制:用 GetUniqName 生成不重名对象,new 一个 CChartObjectTrend,Create 时传入起止时间价格,再设颜色和线宽,最后挂进 trend_list_Ptr。若 CheckPointer 不等于 POINTER_INVALID 才往里加,避免空指针入列。外汇与贵金属波动剧烈,这类对象若未释放可能在长时间挂 EA 时累积内存,建议定期清理链表。
Print("Error of creating the object CList #class="num">1"); class="kw">return(-class="num">1); } up_list_Ptr = new CList(); if(CheckPointer(up_list_Ptr) != POINTER_DYNAMIC) { Print("Error of creating the obkect CList #class="num">2"); class="kw">return(-class="num">1); } dn_list_Ptr = new CList(); if(CheckPointer(dn_list_Ptr) != POINTER_DYNAMIC) { Print("Error of creating the object CList #class="num">3"); class="kw">return(-class="num">1); } if(InitGraphObjects() != class="num">0) { Print("Error of creating the object TableDisplay"); class="kw">return(-class="num">1); } class="kw">return(class="num">0); } class="type">int index, start = prev_calculated - class="num">1; if(prev_calculated == class="num">0) { if(CheckPointer(trend_list_Ptr) != POINTER_INVALID) { trend_list_Ptr.Clear(); } if(CheckPointer(up_list_Ptr) != POINTER_INVALID) { up_list_Ptr.Clear(); } if(CheckPointer(dn_list_Ptr) != POINTER_INVALID) { dn_list_Ptr.Clear(); } class=class="str">"cmt">// Determine the bar number of the beginning of calculations: if(MaxBars > class="num">0 && rates_total > MaxBars) { start = rates_total - MaxBars; } else { start = class="num">0; } time_prev = class="num">0; trend_prev = class="num">0; } start = rates_total - MaxBars; class=class="str">"cmt">//--------------------------------------------------------------------- class=class="str">"cmt">// Drawing of a section class=class="str">"cmt">//--------------------------------------------------------------------- class="type">void CreateCut(class="type">class="kw">datetime _dt1, class="type">class="kw">double _prc1, class="type">class="kw">datetime _dt2, class="type">class="kw">double _prc2, class="type">color _clr, class="type">int _wd) { class="type">class="kw">string name = GetUniqName(prefix + " "); CChartObjectTrend* trend_obj = new CChartObjectTrend(); if(CheckPointer(trend_obj) != POINTER_INVALID) { trend_obj.Create(class="num">0, name, class="num">0, _dt1, _prc1, _dt2, _prc2); trend_obj.Color(_clr); trend_obj.Width(_wd); trend_list_Ptr.Add(trend_obj); } }
双柱法刻画中型趋势的转向与纠正
中型趋势用连续两根柱的极值关系来定义,即「双柱走势」。向上段要求后一根柱的最高价与最低价同时高于前两根柱对应极值,向下段则同时低于,连点成线就是中型趋势线。 若原向上段里,后一根最高价未超前两柱最高、但最低价却跌破前两柱最低,方向直接翻为向下;反向同理。这段规则里原文重复了一遍同一条件,实际只需记一次。 内侧柱(最低高于前低、最高低于前高)不参与图形构建,外侧柱(最高破前高、最低破前低)则按自身方向续画一段。这两类形态在 MT5 周线或日线叠加手动连线时很容易肉眼漏掉,建议用脚本标出。 中型趋势反向的唯一信号是对应顶部或底部价位的穿越:上升段被中型底部打穿才转空,下降段被中型顶部打穿才转多。若仅出现反向摆动但未吞掉前一极点,那只是纠正,趋势骨架未断。外汇与贵金属杠杆高,这种纠正常伴临时扫损,验证时请用历史数据核对穿越点。