English Русский Deutsch 日本語
preview
价格行为分析工具包开发(第三十三部分):K线区间理论工具

价格行为分析工具包开发(第三十三部分):K线区间理论工具

MetaTrader 5示例 |
31 0
Christian Benjamin
Christian Benjamin

内容



引言

波动率是市场最本质的体现。早在震荡指标转向或大多数趋势滤波器做出反应之前,价格就已经通过单根K线的运行幅度,清晰地表明了市场态度。波幅突然扩张,往往表明大型参与者正在积极介入;波幅长期收缩,则表明流动性正在消退,市场在酝酿下一波行情。同样,完全运行在前一根K线内部的K线,表明市场暂时处于犹豫状态;而吞没前一根K线完整区间的K线,则反映出坚决、明确的订单流向。这些市场行为显而易见,却很少被系统化地整理成一套可靠的且可被程序识别的分析逻辑。

本文介绍了K线区间理论(CRT),这是一个简洁的分析框架,它将每一根已收盘的K线划分为四个互斥类别之一:

  • 大区间K线(LR) —— 当前K线的真实波幅超过近期平均真实波幅(ATR)的可配置倍数。
  • 小区间K线(SR) —— 当前K线的波幅小于ATR的较低倍数,标志着市场压缩(盘整)。
  • 内包K线(IB) —— 整根K线的高低点完全处于前一根K线的高低点边界之内。
  • 外包K线(OB) —— 在K线形成过程中,同时突破了前一根K线的高点和低点,吞没了前序区间。

CRT并没有引入另一个晦涩难懂的指标,而是通过一套精简且可直接用于实盘的MetaTrader 5工具集,来呈现这些定义清晰的分析概念:

  • CRangePattern.mqh —— 纯头文件类,可在常数时间内完成K线分类。它仅需四个价格数组(开盘价、最高价、最低价、收盘价),即可返回每种形态的布尔标识,且不分配任何动态内存。  
  • CRT Indicator.mq5 —— 图表叠加指标,使用半透明矩形和可选箭头高亮标记每一根LR、SR、IB、OB形态K线。颜色、透明度、箭头符号、尺寸均可完全自定义,确保视觉层能干净地整合进任何现有图表模板,且不突破平台8个缓冲区的限制。  
  • CRT Expert Advisor.mq5 —— 警报引擎,仅在K线收盘后运行,确保信号无重绘。可筛选触发弹窗、声音、推送通知的形态,如有需要,还能自动加载配套指标,确保实盘交易与可视化回测时视觉与声音信息完全同步。

所有组件在MetaTrader 5 build 4180及以上版本编译无任何警告,并严格遵循#property strict规范。它们仅复制ATR计算所需的少量历史数据窗口,即使在高频图表上,对CPU资源的占用也极低。由于系统仅在K线收盘时严格处理数据,其输出结果在所有周期、品种、测试模式下均保持稳定。

本文的目标分为四个部分:

  • 提供大区间K线(LR)、小区间K线(SR)、内包K线(IB)、外包K线(OB)四种形态的精确数学定义。
  • 演示如何将CRangePattern类集成到任意指标、EA或脚本中。
  • 讲解设计思路,使配套指标轻量化、无闪烁、兼容复杂图表布局。
  • 展示EA如何提供回测安全的警报,支持在历史与实时环境中全面评估CRT信号。

到本文结束时,您将拥有一套紧凑且可扩展的分析框架,能够将原始波动率转化为清晰、可执行的交易信息 —— 可用于主观分析、自动化交易或深度研究。

K线区间理论工具集优势:

优势 描述 实战价值
定义精准
LR、SR、IB、OB均采用基于ATR与价格关系的明确公式计算。
彻底消除分析歧义;每一根K线有且仅属于一个分类。
信号无重绘
所有计算仅在K线刚收盘时执行,后续不会修改任何数值。
信号在图表刷新、参数优化、实盘交易中始终保持稳定。
极低资源占用
指标仅加载ATR 周期 + 3根K线数据,EA采用相同逻辑。
降低内存占用,大幅加快策略测试器运行速度。
无缓冲区绘图
视觉效果通过图表对象绘制,而非指标缓冲区。
规避MetaTrader 8个缓冲区的限制,完美兼容复杂图表模板。
可完全自定义
颜色、透明度、箭头符号、ATR周期、大小区间倍数均支持用户自定义设置。
可无缝适配任何个人或机构的图表风格规范。
模块化架构
类库、指标、EA 为独立文件,通过规范接口交互。
开发者可将核心类嵌入其他项目,或替换指标,无需重构代码。
严格模式兼容
所有源码在MT54180及以上版本、#property strict严格模式下无警告编译。
确保与未来MT5版本最大程度向前兼容。
ATR标准化自适应 区间阈值会根据品种波动率自动调整。 一套参数可稳定适用于外汇、差价合约、加密货币、指数、期货全市场。


策略概述

K线区间理论(CRT) 将每一根已收盘K线归入四个分类中的一个,且仅一个。真实波幅远高于近期波动率的 K 线,被标记为大区间K线(LR);波幅仅为正常水平一小部分的收缩K线,则标记为小区间K线(SR)。如果当前K线的整个高低点区间完全包含在前一根K线区间内,则为内包K线(IB);反之,若同时突破了前一根K线的高点与低点,则标记为外包K线(OB)。后续章节将阐述识别这四种形态所依据的统计原理与精确规则。

真实波幅(TR)

真实波幅是韦尔斯・怀尔德(Wilder)提出的原始波动率衡量指标。它通过取以下三者中的最大值,完整反映一个周期内的全部价格波动(包括跳空缺口):

  • 当前K线的最高价减去最低价
  • 当前K线的最高价减去前收盘价的绝对值
  • 当前K线的最低价减去前收盘价的绝对值
TR = max(
  Highₜ – Lowₜ,
 │Highₜ – Closeₜ₋₁│,
  │Lowₜ – Closeₜ₋₁│
)

通过使用真实波幅(TR)而非单纯的高低点跨度,隔夜跳空缺口可被完整捕捉,确保波动率计量在所有品种与交易时段内保持一致。

平均真实波幅(ATR)

要让波动率具备可对比意义,仅靠原始真实波幅并无实际参考价值:欧元兑美元(EURUSD)波动25点属于大幅波动,但黄金兑美元(XAUUSD)波动25点则微不足道。K线区间理论(CRT) 通过将每个周期的真实波幅与最近N期均值进行标准化处理,平滑掉原始毛刺脉冲,提供稳定统一的波动率基准。

// Simple arithmetic ATR
double ATR(const int shift,const int period,
           const double &H[],const double &L[],const double &C[])
{
   double sum = 0.0;
   for(int i = shift; i < shift + period; ++i)
      sum += MathMax(H[i]-L[i],
              MathMax(MathAbs(H[i]-C[i+1]),
                      MathAbs(C[i+1]-L[i])));
   return sum / period;
}

在实际应用中,CRT采用的是简单算术平均值,而非怀尔德原版的指数平滑算法,因为这种方式运算更快、逻辑更直观,对于价格行为分类而言也完全足够。默认使用14根K线的计算窗口,与标准ATR参数保持一致。

区间倍数 —— 客观阈值

通过两个用户可自定义的倍数,将ATR转化为分类判定阈值:
  • 大区间倍数(largeMult):默认值=1.5
  • 小区间倍数(smallMult):默认值=0.5
// ---- User-defined ATR multipliers --------------------------------------
input double largeMult = 1.5;   // Bars ≥ 1.5 × ATR are flagged “Large-Range”
input double smallMult = 0.5;   // Bars ≤ 0.5 × ATR are flagged “Small-Range”
这些参数用于明确界定:
  1. 一根K线需要比平均波幅大多少,才能被判定为异常大区间?
  2. 一根K线需要小到何种程度,才能被视为区间压缩?

通过以ATR为单位设定这些临界值,使得CRT理论可以通用适配于不同交易品种、时间周期和波动率环境。

大区间K线(LR)—— 资金积极入场的信号

当某根K线的真实波幅 ≥ 设定倍数(largeMult)× 当前ATR时,该K线即被判定为大区间K线。
// ---- Large-Range (LR) test ---------------------------------------------
bool isLargeRange = (trueRange >= largeMult * atrCurrent);

这种大幅波动通常由财经数据、重磅新闻或大额订单引发,进而形成此类级别波幅的K线。这类大K线往往预示着持续性趋势行情的启动,或是前一段趋势的最后竭尽性抛盘或反扑。无论哪种情况,它们都是信息量极高的市场事件:即便不清楚背后原因(财报、宏观数据、强制平仓等),仅凭 “异常宽幅波动” 这一事实就已足够明确。

小区间K线(SR)—— 波动率压缩

反之,当K线的真实波幅不大于当前ATR的设定比例(smallMult)时,即为小区间K线。持续的波幅收缩表明市场流动性下降、交易商对冲行为,或是买卖盘力量趋于均衡。

// ---- Small-Range (SR) test ---------------------------------------------
bool isSmallRange = (trueRange <= smallMult * atrCurrent);

市场很少会永远保持平静;连续出现SR,往往预示着波动扩张前的休整期,这对突破策略和跨价交易策略极具参考价值。

内包K线(IB)—— 区间收敛与多空犹豫

当一根K线的整个波动区间完全被前一根K线包含时,即被定义为内包K线 —— 也就是说,它的高点低于前一根K线的高点,且低点高于前一根K线的低点。

// Inside-Bar test for the candle at 'shift' (e.g., shift = 1 → just-closed bar)
bool isInsideBar = (High[shift] < High[shift + 1]) &&   // current high is lower than previous high
                   (Low[shift]  > Low[shift + 1]);      // current low  is higher than previous low

这类K线标志着剧烈的订单流冲击 —— 通常是扫损、强制平仓,或是主力资金的激进吸筹与派发行为。由于市场同时击穿了前一根K线的上下边界,外包K线(OB)会在一个周期内压缩多层止损盘,往往会导致两种走势:(a)如果承接盘占主导,则形成持续性反转;(b)如果突破方向的流动性被快速消耗,则原趋势加速延续。

互斥性与层级性

以下四个分类在设计上互斥,一根K线最多只能符合其中一种定义:

  • 如果属于LR或SR,以波幅大小规则为准。
  • 如果既不属于LR也不属于SR,系统再判断是否为IB。
  • 只有当不符合IB时,才会检测是否为OB。

这种层级性消除了逻辑重叠,让后续的警报、图形标记等逻辑保持清晰无歧义。

时序规则 —— 仅处理已收盘K线

CRT只分析最新一根已完成的K线(K线1),忽略正在形成中的当前K线(K线0)。这样保证了信号无重绘:实盘看到的信号,与历史回测中呈现的完全一致。

从原始数据到可执行交易信号

通过将每根K线归类为四种状态之一,CRT提供:

  • 用于自动化策略的二元信号流(每个分类对应true/false标识)
  • 用于主观交易的可视化语言(彩色标记K线与箭头)
  • 用于警报和附加过滤的触发条件(趋势、交易时段、成交量)


代码分解

K线区间理论工具集采用精心设计的模块化架构。每个组件 —— 头文件、指标、智能交易系统(EA)—— 都只执行单一且明确的任务,并通过极简接口相互通信。本章节将按照MetaTrader的实际执行顺序讲解源码,说明每个主要代码块的作用,以及背后的设计实现思路。  

CandleRangeTheory.mqh – the classification engine

头文件以#property strict开头,强制执行现代类型检查,摒弃编译器旧版的宽松规则。紧接着声明CRangePattern类。其公共成员变量 —— atrPeriodlargeMultsmallMult —— 均作为运行时参数使用,而非硬编码常量,确保任何包含该头文件的脚本都能调整行为表现,无需重新编译类本身。四个布尔标识 —— isLargeisSmallisInsideisOutside —— 构成了类的输出接口。一旦Calculate()方法执行完成,这四个标识中有且仅有一个为true;调用程序无需额外的算法,即可直接判断当前K线的分类结果。

#property strict               // enforce modern type checking
#ifndef  __CANDLE_RANGE_THEORY_MQH__
#define  __CANDLE_RANGE_THEORY_MQH__

class CRangePattern
{
public:
   int    atrPeriod;           // ATR length
   double largeMult,smallMult; // LR / SR thresholds

   bool   isLarge,isSmall,
          isInside,isOutside;  // output flags
   double atr,trueRange,bodyRange;

构造函数会设置实用的默认参数:ATR 周期为14,大区间倍数为1.5,小区间倍数为0.5;随后调用一个私有辅助方法Reset(),将所有结果字段重置为初始状态。使用辅助方法可以避免代码冗余;该方法会在对象创建时以及每次计算开始时被统一调用。

private:
   void Reset()
   {
      isLarge=isSmall=isInside=isOutside=false;
      atr=trueRange=bodyRange=0.0;
   }

public:
   CRangePattern()             // default parameters
   {
      Reset();
      atrPeriod=14;
      largeMult=1.5;
      smallMult=0.5;
   }

Calculate()方法本身的设计简洁而精炼。它首先会验证历史数据量是否充足(K线数量 > ATR周期 + sh + 2),因为无论是ATR还是真实波幅的计算,都需要引用当前判断节点至少前一根K线的数据。程序会严格遵循韦尔斯・怀尔德(Wilder)的定义计算真实波幅和实体波幅,确保无论与本脚本还是外部指标的标准ATR读数完全兼容。

bool Calculate(const int sh,
               const double &H[],const double &L[],
               const double &O[],const double &C[],
               const int bars)
{
   Reset();
   if(bars < atrPeriod + sh + 2)   // enough candles?
      return false;

   // true range of target candle
   trueRange = MathMax(H[sh]-L[sh],
               MathMax(MathAbs(H[sh]-C[sh+1]),
                       MathAbs(C[sh+1]-L[sh])));
   bodyRange  = MathAbs(O[sh]-C[sh]);

ATR循环严格迭代atrPeriod次。由于之前的历史数据检查已确保i + 1处于有效索引范围内,因此内部的条件判断&& i+1 < bars就成了冗余代码,可以直接省略。移除这层防护判断简化了代码的执行路径,消除了一个分支,在不牺牲安全性的前提下,提升了高频数据下的运行性能。

   double sum = 0.0;
   for(int i = sh; i < sh + atrPeriod; ++i)      // exactly atrPeriod
   {
      double tr = MathMax(H[i]-L[i],
                  MathMax(MathAbs(H[i]-C[i+1]),
                          MathAbs(C[i+1]-L[i])));
      sum += tr;
   }
   atr = sum / atrPeriod;

计算出平均值后,函数会对当前K线进行分类判定。如果真实波幅大于上限倍数,则设置isLarge为true;如果真实波幅小于下限倍数,则设置isSmall为true。第二层比较会判断当前K线与前一根K线高低点之间的关系,并相应地将isInsideisOutside设置为true。由于四个标识是互斥的,因此无需进行额外的检查,函数直接返回true以确认计算完成。

   if(trueRange >= largeMult*atr)      isLarge   = true;
   else
   if(trueRange <= smallMult*atr)      isSmall   = true;

   if(H[sh] < H[sh+1] && L[sh] > L[sh+1])        isInside  = true;
   else
   if(H[sh] > H[sh+1] && L[sh] < L[sh+1])        isOutside = true;

   return true;
}
#endif

CRT Indicator.mq5 —— 可视化呈现

该指标文件完全不使用指标缓冲区,而是全程依赖图表对象进行绘制。通过避开缓冲区机制,脚本成功绕过了MetaTrader平台的8个缓冲区上限限制,为交易者预留了空间,可将本指标与其他技术指标叠加使用。初始化时,来自MetaTrader输入设置对话框的参数,会直接写入名为pat内部的CRangePattern实例的公共成员变量中。程序不存储任何其他全局变量,确保当MetaTrader中的参数发生修改时,会执行完全重新初始化,而非保留部分旧状态。

#property indicator_chart_window
#include <CandleRangeTheory.mqh>

input int     ATR_Period = 14;
...
CRangePattern pat;

int OnInit()
{
   pat.atrPeriod = ATR_Period;
   pat.largeMult = LargeXATR;
   pat.smallMult = SmallXATR;
   return(INIT_SUCCEEDED);
}

每当MetaTrader判定有新数据到达时,就会调用OnCalculate()函数。该函数首先检查图表K线数量是否至少为atrPeriod + 3根 —— 额外多取2根是因为ATR循环需要引用当前K线的前一根K线,且Calculate()方法本身会引用偏移量为shift + 1的K线。程序仅将此长度的少量历史数据复制到四个本地数组(最高价H、最低价L、开盘价O、收盘价C)中。随后,每个数组都被标记为序列数组,确保索引0始终代表最新的K线。

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
{
   const int need = pat.atrPeriod + 3;
   if(rates_total < need) return rates_total;

   double H[],L[],O[],C[];
   ArrayResize(H,need); ArraySetAsSeries(H,true);
   ArrayResize(L,need); ArraySetAsSeries(L,true);
   ArrayResize(O,need); ArraySetAsSeries(O,true);
   ArrayResize(C,need); ArraySetAsSeries(C,true);

   CopyHigh (_Symbol,_Period,0,need,H);
   CopyLow  (_Symbol,_Period,0,need,L);
   CopyOpen (_Symbol,_Period,0,need,O);
   CopyClose(_Symbol,_Period,0,need,C);

数据准备就绪后,程序会调用pat.Calculate(1, …) 。传入偏移量1,可确保分析仅作用于最新已收盘K线,绝不会分析正在形成中的未收盘K线。如果分类后没有任何有效标记 —— 即该K线既不是大区间、小区间,也不是内包、外包 —— 函数就会立即返回,图表保持不变。当识别到有效形态时,指标会选择对应的显示属性:从ARGB颜色值中提取矩形颜色(支持透明度控制),并使用符合用户偏好的箭头代码与颜色。 

   if(!pat.Calculate(1,H,L,O,C,need)) return rates_total;

   uint  rClr  = 0;         // rectangle colour (ARGB)
   int   aCode = 221;       // ● default arrow
   color aClr  = clrYellow;

   if(pat.isLarge)
   {
      bool bull = (C[1] > O[1]);
      rClr  = ColorToARGB(bull?clrLime:clrRed,Opacity);
      aCode = bull ? 233 /*▲*/ : 234 /*▼*/;
      aClr  = bull ? clrLime     : clrRed;
   }
   else if(pat.isSmall)     { rClr = ColorToARGB(clrYellow,Opacity); }
   else if(pat.isInside)    { rClr = ColorToARGB(clrAqua,Opacity);   }
   else if(pat.isOutside)   { rClr = ColorToARGB(clrMagenta,Opacity);}
   else return rates_total; // nothing to draw

矩形绘制使用两个时间坐标:偏移量2位置的K线开盘价时间与偏移量1位置的K线开盘价时间,这样能完整覆盖目标K线的整个存续周期。目标K线的最高价与最低价定义了矩形的垂直边界。将OBJPROP_FILL设置为 true,因此矩形显示为半透明色块,而非空心边框。接下来,程序会在K线上方或下方,以经ATR缩放的适度偏移量绘制可选箭头,确保在报价单位差异极大的不同交易品种上都能清晰可见。矩形与箭头都会使用K线开盘时间戳作为标识,确保名称唯一,并且允许脚本在绘制新对象前删除旧的重复项。 

   datetime tClosed = iTime(_Symbol,_Period,1);
   string tagR = "CRT_RECT_"+(string)tClosed;
   string tagA = "CRT_ARW_" +(string)tClosed;

   ObjectDelete(0,tagR);                     // avoid duplicates
   ObjectCreate(0,tagR,OBJ_RECTANGLE,0,
                iTime(_Symbol,_Period,2),H[1],
                tClosed,L[1]);
   ObjectSetInteger(0,tagR,OBJPROP_COLOR,rClr);
   ObjectSetInteger(0,tagR,OBJPROP_FILL,true);
   ObjectSetInteger(0,tagR,OBJPROP_BACK,true);

   double y = (aCode==233 ? H[1]+0.2*pat.atr : L[1]-0.2*pat.atr);
   ObjectCreate(0,tagA,OBJ_ARROW,0,tClosed,y);
   ObjectSetInteger(0,tagA,OBJPROP_ARROWCODE,aCode);
   ObjectSetInteger(0,tagA,OBJPROP_COLOR,aClr);
   return rates_total;
}

CandleRangeTheory.mq5 —— 警报生成

EA共用同一个头文件,因此具备完全一致、结果确定的分类逻辑。初始化时,它会复刻指标中执行的参数传递步骤。此外,EA还会检查自身是否运行在策略测试器的非可视化模式下。如果是,则禁用Alert()、PlaySound()等图形界面相关函数,避免批量优化时出现运行时错误。

#include <CandleRangeTheory.mqh>
input bool Push_Alerts = false;
...
CRangePattern pat;
const bool NonVisualTest = (bool)MQLInfoInteger(MQL_TESTER) &&
                           !MQLInfoInteger(MQL_VISUAL_MODE);

int OnInit()
{
   pat.atrPeriod = ATR_Period;
   pat.largeMult = LargeXATR;
   pat.smallMult = SmallXATR;
   return INIT_SUCCEEDED;
}

当EA被加载到实盘图表或可视化回测中时,它会通过iCustom()函数来自动加载指标。加载成功或失败的状态都会记录在experts日志中,方便排查与核对。在反初始化时,需要手动释放所有指标句柄,避免内存泄漏和图表对象冗余混乱。

int indHndl = INVALID_HANDLE;

int OnInit()
{
   ...
   if(!NonVisualTest)
   {
      indHndl = iCustom(_Symbol,_Period,"CRT Indicator",
                        ATR_Period,LargeXATR,SmallXATR);
      if(indHndl != INVALID_HANDLE)
         ChartIndicatorAdd(0,0,indHndl);
   }
   return INIT_SUCCEEDED;
}

void OnDeinit(const int reason)
{
   if(indHndl != INVALID_HANDLE)
      IndicatorRelease(indHndl);
}

核心逻辑位于OnTick()函数内部。EA会记录偏移量1位置的K线开盘时间,并且在该时间值发生变化之前不会重复执行,确保每一根已收盘的K线只执行一次分析,不受行情tick频率影响。程序复制一小段历史数据 —— 此数组会被显式转换为序列数组,以符合CRangePattern类的要求。如果分类结果识别出有效形态,EA会构建一条易懂的文本提示信息,包含交易品种、时间周期和检测到的K线。根据用户设置弹出提示、播放声音、发送推送通知,但仅在当前运行环境允许的情况下执行。 

datetime lastDone = 0;

void OnTick()
{
   datetime tClosed = iTime(_Symbol,_Period,1);
   if(tClosed == lastDone) return;      // already processed
   lastDone = tClosed;

   const int need = pat.atrPeriod + 3;
   double H[],L[],O[],C[];
   ArrayResize(H,need); ArraySetAsSeries(H,true);
   ArrayResize(L,need); ArraySetAsSeries(L,true);
   ArrayResize(O,need); ArraySetAsSeries(O,true);
   ArrayResize(C,need); ArraySetAsSeries(C,true);

   CopyHigh (_Symbol,_Period,0,need,H);
   CopyLow  (_Symbol,_Period,0,need,L);
   CopyOpen (_Symbol,_Period,0,need,O);
   CopyClose(_Symbol,_Period,0,need,C);

   if(!pat.Calculate(1,H,L,O,C,need)) return;

   string sig;
   if(pat.isLarge)   sig="Large-Range bar";
   else if(pat.isSmall)   sig="Small-Range bar";
   else if(pat.isInside)  sig="Inside bar";
   else if(pat.isOutside) sig="Outside bar";
   if(sig=="") return;

   string msg = _Symbol+" "+EnumToString(_Period)+"  "+sig;
   Print("[CRT-EA] ",msg);

   if(!NonVisualTest) Alert(msg);
   if(Push_Alerts)    SendNotification(msg);
}

在整个EA中,可选的调试语句会对各类操作提供简洁的反馈,例如指标加载成功、历史数据不足等。由于这些日志输出受DebugLog标识控制,因此正式实盘运行时可以完全静默不输出日志,而开发或回测研究时可以开启完整日志追踪。 

input bool DebugLog = true;

if(DebugLog)
   PrintFormat("[CRT-EA] Attached on %s %s  (tester=%d)",
               _Symbol,EnumToString(_Period),
               (int)MQLInfoInteger(MQL_TESTER));

该工具集严格避免使用静态变量或全局可变状态,仅保留程序运行必需的对象。在图表上创建的所有动态对象,要么会在父指标被移除时由MetaTrader自动释放,或者会在代码中显式删除。程序中没有会随时间不断膨胀的持久化数组,每一次行情触发都只执行固定大小的数据复制与分类计算,其时间复杂度与图表K线总数无关。因此,该系统无需任何修改,即可适配从周线到秒级的所有时间周期,且不会出现长期运行后的性能逐渐衰减问题。

// inside any function needing history
const int need = pat.atrPeriod + 3;
double  H[need], L[need], O[need], C[need];   // stack allocation in C++17 style
// (or ArrayResize + quick release when the function exits)


测试结果

本章节将对以下展示的实盘测试结果进行分析。

以下Gif动图展示了由CRT_EA驱动的5分钟步进指数(Step-Index)实时行情图表。随着每一根K线收盘,您会看到彩色方框、标记与箭头同步出现,用以指示当前波动率是在收缩、扩张,还是完全吞没了前一根K线的区间。平静、窄幅的“内包”K线密集出现后,往往会突然爆发一根宽幅K线,标志着动量急剧地释放。在后台,每一根K线都会实时与当前ATR对比并重新分类,因此您能看到不间断、带颜色标记的市场动能快照,且历史K线绝不会重绘。这种实时的可视化展示,能让您轻松识别市场何时处于蓄力压缩状态、何时突破爆发,以及每一根K线如何参与到更大级别的波动率周期中。

下表总结了从上述图表中得出的关键观测结果,后续示意图将展示该工具包在其他交易品种和时间周期上的运行表现。

矩形颜色 箭头/标记 含义
大区间K线(LR) 宝蓝色边框 看涨为亮绿色,看跌为红色 异常宽幅波动 — 波幅 ≥ 大区间倍数 × ATR
小区间K线(SR) 黄色边框 黄色小点 压缩波动 — 波幅 ≤ 小区间倍数 × ATR
内包K线(IB) 浅青蓝色边框 浅青蓝色小点 高点<前一根K线高点**且**低点>前一根 K 线低点
外包K线(OB) 品红色边框 品红色小点 高点>前一根K线高点**且**低点<前一根 K 线低点
  • 步进指数图表

  • Crash 1000指数图表

  • Boom 1000指数图表

B



结论

CRT工具集为MetaTrader 5提供了一套完整、模块化的区间分析解决方案。

  • CRangePattern —— 一个精简、自包含的类,可识别大区间、小区间、内包、外包K线,且信号不重绘。
  • CRT_Indicator —— 通过彩色方框与箭头在图表上叠加信号,实现直观的可视化解读。
  • CRT_EA —— 将同一套分类信号转化为警报或自动下单逻辑。

所有参数 —— ATR长度、大小区间倍数、警报规则等 —— 均可完全自定义,使该框架能适配任何交易品种、任何时间周期与任何波动率环境。由于形态识别逻辑与绘图、执行层相互分离,您只需极少的代码修改,即可将其扩展或嵌入到行情扫描器、仪表盘或完整交易系统中。

本工具集仅供教学使用,在实盘部署前务必先在模拟账户充分测试。请将其客观的区间信号与您自身的交易筛选规则、风险管理规则相结合,确保整套方法符合您的整体交易策略。

通过合理使用,CRT能让您快速、清晰、自信地识别波动率变化、可视化市场状态并执行交易决策。





   
图表展示器
分析评论
分析大师
分析预测 
波动率导航仪
均值回归信号收割器
信号脉冲 
指标看板 
外部数据流
VWAP
Heikin Ashi   FibVWAP  
RSI背离
抛物线止损与反转指标 (PSAR) 
四分位绘制脚本
侵入探测器
TrendLoom工具  四分位看板 
ZigZag分析仪  相关性探索  市场结构反转检测工具
关联仪表盘  货币强度计 
PAQ分析工具 
双EMA分形突破器
针形柱、吞噬形态与相对强弱指数(RSI)背离
流动性扫单 开盘区间突破工具 暴涨与暴跌拦截 CCI零线EA
K线形态识别 基于TA-Lib的K线形态识别 K线区间工具      

本文由MetaQuotes Ltd译自英文
原文地址: https://www.mql5.com/en/articles/18911

附加的文件 |
CRT_EA.mq5 (8.11 KB)
MQL5 MVC 范式下表格的视图与控制器组件:容器 MQL5 MVC 范式下表格的视图与控制器组件:容器
在本文中,我们将讨论如何创建一个支持内容滚动的“容器”控件。在此过程中,将对已实现的图形库控件类进行改进。
MQL5交易工具(第六部分):带脉冲动画与控件的动态全息仪表盘 MQL5交易工具(第六部分):带脉冲动画与控件的动态全息仪表盘
在本文中,我们将使用MQL5创建一个动态全息仪表盘,用于监控交易品种与时间周期,集成RSI指标、波动率预警以及排序功能。我们将添加脉冲动画、交互按钮与全息视觉效果,使该工具在视觉上更具吸引力,并具备良好的交互响应性。
新手在交易中的10个基本错误 新手在交易中的10个基本错误
新手在交易中会犯的10个基本错误: 在市场刚开始时交易, 获利时不适当地仓促, 在损失的时候追加投资, 从最好的仓位开始平仓, 翻本心理, 最优越的仓位, 用永远买进的规则进行交易, 在第一天就平掉获利的仓位,当发出建一个相反的仓位警示时平仓, 犹豫。
MQL5 交易策略自动化(第24篇):集成风险管理与移动止损的伦敦时段突破系统 MQL5 交易策略自动化(第24篇):集成风险管理与移动止损的伦敦时段突破系统
本文将搭建一套伦敦时段突破交易系统,可识别伦敦开盘前区间的突破机会,并支持自定义交易类型、风险参数来挂入挂单。系统内置移动止损、盈亏比、最大回撤限制等功能,同时配备控制面板,可实时监控与管理交易。