外包线形态基础:从库类改造到形态识别概念铺垫(基础篇)
📐

外包线形态基础:从库类改造到形态识别概念铺垫(基础篇)

(1/3)·孕线讲完,镜像形态外包线怎么在MQL5里落地?先补库类再谈识别逻辑

含代码示例偏理论 第 1/3 篇
很多人在孕线脚本里顺手改几行就想去抓外包线,结果方向判断和过滤器全串味。外包线是双向分看涨看跌的镜像结构,不先把库类属性和访问方法理顺,后面测试只会反复踩坑。

◍ 外包线形态怎么进 DoEasy 库

DoEasy 系列把价格行为里的外包线(Outside Bar)单独抽成了一个形态类,目的是让服务函数在扫描 K 线时直接调用,不必每次重写判定逻辑。 原文示例发布于 2025 年 7 月 10 日 08:01,截至统计显示阅读量 611、互动 1,说明这类底层库改造内容在中文交易圈还偏冷门,但实盘里外包线用的人并不少。 外包线形态类的核心动作是:当前 K 线的高低点完全包住前一根 K 线的高低点,即 High[n] > High[n-1] 且 Low[n] < Low[n-1];把它做成库类后,后续文章会接上测试与调用示例,读者可先在 MT5 自建脚本里用这个条件跑一遍 EURUSD 的 H1,看触发频率是否过高。 外汇与贵金属波动受杠杆影响大,外包线只是概率信号,出现后反转或续涨都可能,别单凭这一根 K 线下单。

「外包线:孕线的镜像与方向分化」

上一节我们在 DoEasy 库里跑通了两根 K 线的孕线(Inside Bar)识别与绘制,这一节直接做它的镜像——外包线(Outside Bar)。两者结构相反:孕线是子柱被母柱完全包裹,外包线则是信号柱实体加影线整体吞掉前一根信号柱。 关键差异在交易方向上。孕线是双向形态,突破任一侧都能进场;外包线被拆成看涨与看跌两个独立类型。BUOVB(Bullish Outside Vertical Bar)要求信号柱完全覆盖前柱且收盘高于前柱最高价,突破信号柱最高价再加 5–10 点过滤器才做多。BEOVB(Bearish Outside Vertical Bar)则收盘低于前柱最低价,突破信号柱最低价减 5–10 点后做空。外汇与贵金属杠杆高,这类形态失败率不低,触发后只是概率倾向,不是必然反转。 动手前得先改库。原先形态访问类里每种形态都写了独立方法,属于概念验证期的直筒实现,代码又长又冗余。现在收敛成单一访问方法,具体形态靠变量指定,动作各自成函数,类文件能砍掉一大截。 另外库停更期间 MQL5 语法有变动,部分已公布的改动还没进编译器,我们手动补进库里,顺手修掉测试期攒下的几个 bug。改完再挂外包线类,MT5 里加载就能看到 BUOVB/BEOVB 标线。

给形态类补上尺寸比率与位图重绘

确定形态时,相邻烛形尺寸的比例关系往往比单根 K 线绝对值更有判别力。这里在抽象形态类里新增了真实属性,把属性总数从 10 扩到 12,并让每个形态对象持有「搜索烛形比率」字段,后续 Pin Bar、Inside Bar 的识别可直接读该值而非现场算。 MT5 测试版 4540 起,ENUM_SYMBOL_SWAP_MODE 多了 SYMBOL_SWAP_MODE_CURRENCY_PROFIT,代表库存费以盈利货币计。库里 Data.mqh 补了对应索引与运行时错误消息(4306、4307),Symbol.mqh 里也加了按该模式返回小数位的方法,避免跨服务器切换时显示错乱。 内存侧修了几处实坑:BaseObj.mqh 中对象加入列表失败时用 new 分配的实例原先不释放,会漏内存;现在添加失败即删对象并返回 false。Order.mqh 计算点数对小于 1 的实数转 int 会得 0,已加四舍五入。Event.mqh 里长整型订单号超 INT_MAX 会溢出成负数,现改为安全返回。 形态渲染从「点阵」切到位图对象。抽象类删了 m_draw_dots,改存图表宽度像素变量;CalculatetBitmapWidth/Height 声明为虚方法,SetDrawAsDots 删除、改 Redraw 虚方法。图表缩放时管理类把新宽高一次性写进所有形态对象,不用每个对象反复读图表属性。 Pin Bar 类固定位图 20x40,锚定柱中心:看涨把点画在下半部(中心+6px),看跌在上半部(中心-6px),半径 2px 保证多周期可见。Inside Bar 原先算柱数遇周末会算成 4 而非 2,已修正为始终取正确相邻柱数 2。外汇与贵金属品种波动大、库存费规则随经纪商变,改完建议开 MT5 用多周期图验证位图重绘是否跟随缩放。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Pattern real properties                                            |
class=class="str">"cmt">//+------------------------------------------------------------------+
enum ENUM_PATTERN_PROP_DOUBLE
  {
class=class="str">"cmt">//--- bar data
   PATTERN_PROP_BAR_PRICE_OPEN = PATTERN_PROP_INTEGER_TOTAL,class=class="str">"cmt">// Pattern defining bar Open price
   PATTERN_PROP_BAR_PRICE_HIGH,                             class=class="str">"cmt">// Pattern defining bar High price

◍ 枚举量里的蜡烛比例与交换利率定义

在 MQL5 图形对象与消息枚举中,有一组 PATTERN_PROP_ 开头的双精度属性专门描述单根蜡烛的几何比例:实体占全长百分比、上下影线各自占全长的百分比,以及多根蜡烛之间的尺寸比值。这类属性后面通常跟着同名的 _CRITERION 常量,用来存放图形识别时设定的阈值,例如实体占比判据、最大/最小影线占比判据。 代码里用宏直接固化了属性规模:PATTERN_PROP_DOUBLE_TOTAL 被定义为 12,代表参与排序与识别的实属性总数;PATTERN_PROP_DOUBLE_SKIP 为 0,说明没有属性被排除在排序之外。你在写自定义形态扫描器时,若增删了比例属性,这两个宏必须同步改,否则 CTrade 或图形库读取结构体可能越界。 另一组 MSG_SYM_SWAP_MODE_ 枚举决定了隔夜费的计算币种与基准:可以是保证金币种、入金币种、盈亏币种,也可以按标的现价或开仓价的年息计提。外汇与贵金属杠杆品种 Swap 成本波动大,实盘前应在 MT5 符号规格里核对当前模式,避免拿回测里的零成本假设直接跑实盘。 下面这段是从标准库摘出的相关定义片段,黄色高亮项(蜡烛尺寸比值、以利润币种计 Swap)是图形识别与跨币种掉期里最容易被忽略的两类:

MQL5 / C++
PATTERN_PROP_BAR_PRICE_LOW,                      class=class="str">"cmt">// Pattern defining bar Low price
PATTERN_PROP_BAR_PRICE_CLOSE,                     class=class="str">"cmt">// Pattern defining bar Close price
PATTERN_PROP_RATIO_BODY_TO_CANDLE_SIZE,           class=class="str">"cmt">// Percentage ratio of the candle body to the full size of the candle
PATTERN_PROP_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE,   class=class="str">"cmt">// Percentage ratio of the upper shadow size to the candle size
PATTERN_PROP_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE,   class=class="str">"cmt">// Percentage ratio of the lower shadow size to the candle size
PATTERN_PROP_RATIO_CANDLE_SIZES,                  class=class="str">"cmt">// Ratio of pattern candle sizes

PATTERN_PROP_RATIO_BODY_TO_CANDLE_SIZE_CRITERION, class=class="str">"cmt">// Defined criterion of the ratio of the candle body to the full candle size in %
PATTERN_PROP_RATIO_LARGER_SHADOW_TO_CANDLE_SIZE_CRITERION, class=class="str">"cmt">// Defined criterion of the ratio of the maximum shadow to the candle size in %
PATTERN_PROP_RATIO_SMALLER_SHADOW_TO_CANDLE_SIZE_CRITERION, class=class="str">"cmt">// Defined criterion of the ratio of the minimum shadow to the candle size in %
PATTERN_PROP_RATIO_CANDLE_SIZES_CRITERION,       class=class="str">"cmt">// Defined criterion for the ratio of pattern candle sizes
};
class="macro">#define PATTERN_PROP_DOUBLE_TOTAL(class="num">12)           class=class="str">"cmt">// Total number of real pattern properties
class="macro">#define PATTERN_PROP_DOUBLE_SKIP(class="num">0)            class=class="str">"cmt">// Number of pattern properties not used in sorting
MSG_SYM_SWAP_MODE_CURRENCY_MARGIN,                class=class="str">"cmt">// Swaps charged in money in symbol margin currency
MSG_SYM_SWAP_MODE_CURRENCY_DEPOSIT,               class=class="str">"cmt">// Swaps charged in money in client deposit currency
MSG_SYM_SWAP_MODE_CURRENCY_PROFIT,                class=class="str">"cmt">// Swaps charged in money in profit calculation currency
MSG_SYM_SWAP_MODE_INTEREST_CURRENT,               class=class="str">"cmt">// Swaps charged as specified annual interest from symbol price at calculation of swap
MSG_SYM_SWAP_MODE_INTEREST_OPEN,                  class=class="str">"cmt">// Swaps charged as specified annual interest from position open price
MSG_LIB_TEXT_PATTERN_RATIO_BODY_TO_CANDLE_SIZE,   class=class="str">"cmt">// Percentage ratio of the candle body to the full size of the candle
MSG_LIB_TEXT_PATTERN_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE, class=class="str">"cmt">// Percentage ratio of the upper shadow size to the candle size
MSG_LIB_TEXT_PATTERN_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE, class=class="str">"cmt">// Percentage ratio of the lower shadow size to the candle size
MSG_LIB_TEXT_PATTERN_RATIO_CANDLE_SIZES,          class=class="str">"cmt">// Ratio of pattern candle sizes

MSG_LIB_TEXT_PATTERN_RATIO_BODY_TO_CANDLE_SIZE_CRIT,    class=class="str">"cmt">// Defined criterion of the ratio of the candle body to the full candle size in %
MSG_LIB_TEXT_PATTERN_RATIO_LARGER_SHADOW_TO_CANDLE_SIZE_CRIT, class=class="str">"cmt">// Defined criterion of the ratio of the maximum shadow to the candle size in %
MSG_LIB_TEXT_PATTERN_RATIO_SMALLER_SHADOW_TO_CANDLE_SIZE_CRIT class=class="str">"cmt">// Defined criterion of the ratio of the minimum shadow to the candle size in %

「蜡烛比例与掉期计价的文本常量定义」

在 MQL5 标准库的消息映射表里,蜡烛形态的尺寸比例被拆成了多个可量化字段:上影线占蜡烛总尺寸的百分比、下影线占蜡烛总尺寸的百分比,以及多根形态蜡烛之间的尺寸比值。这些字符串常量直接服务于形态识别模块,把「影线多长、实体多大」转成可比较的数值阈值。 掉期(Swap)的文案定义也并排放在同一张表里,明确写出四种计息方式:以交易品种保证金货币计、以客户入金货币计、以盈亏计算货币计,以及按年化利率对计算时刻价格或开仓价格计提。外汇与贵金属的掉期成本会随经纪商规则浮动,实际持仓过夜费用可能显著侵蚀短线利润,属典型高风险变量。 下方代码片段展示了这部分双语文案(俄语+英语)在源码里的实际写法,其中被标底色的三行正是「形态蜡烛尺寸比值」相关定义,可直接在 MT5 的 stdlib 消息数组里搜到对应位置验证。

MQL5 / C++
MSG_LIB_TEXT_PATTERN_RATIO_CANDLE_SIZES_CRITERION,           class=class="str">"cmt">// Defined criterion for the ratio of pattern candle sizes

MSG_LIB_TEXT_PATTERN_NAME,                                      class=class="str">"cmt">// Name
{"Свопы начисляются в деньгах в маржинальной валюте символа","Swaps charged in money in symbol margin currency"},
{"Свопы начисляются в деньгах в валюте депозита клиента","Swaps charged in money in client deposit currency"},
{"Свопы начисляются в деньгах в валюте расчета прибыли","Swaps are charged in money, in profit calculation currency"},
{
  "Свопы начисляются в годовых процентах от цены инструмента на момент расчета свопа",
  "Swaps are charged as the specified annual interest from the instrument price at calculation of swap"
},
{"Свопы начисляются в годовых процентах от цены открытия позиции по символу","Swaps charged as specified annual interest from open price of position"},
{"Отношение размера верхней тени к размеру свечи в %","Ratio of the size of the upper shadow to the size of the candle in %"},
{"Отношение размера нижней тени к размеру свечи в %","Ratio of the size of the lower shadow to the size of the candle in %"},
{"Отношение размеров свечей паттерна","Ratio of pattern candle sizes"},

{"Установленный критерий отношения тела свечи к полному размеру свечи в %","Criterion for the Ratio of candle body to full candle size in %"},
{"Установленный критерий отношения размера наибольшей тени к размеру свечи в %","Criterion for the Ratio of the size of the larger shadow to the size of the candle in %"},
{"Установленный критерий отношения размера наименьшей тени к размеру свечи в %","Criterion for the Ratio of the size of the smaller shadow to the size of the candle in %"},
{"Установленный критерий отношения размеров свечей паттерна","Criterion for the Ratio of pattern candle sizes"},

{"Наименование","Name"},
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Array of runtime error messages(class="num">4301 - class="num">4307)                   |
class=class="str">"cmt">//| (MarketInfo)                                                    |
class=class="str">"cmt">//| (class="num">1) in user&class="macro">#x27;s country language                                  |
class=class="str">"cmt">//| (class="num">2) in the international language                                |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">class="kw">string messages_runtime_market[][TOTAL_LANG]=
  {
   {"Неизвестный символ","Unknown symbol"},                class=class="str">"cmt">// class="num">4301

掉期算法决定报价小数位

CSymbol 类里有一段按掉期计算方式返回小数位数的逻辑,直接决定后续利息与价格格式化该取几位。SwapMode 返回 SYMBOL_SWAP_MODE_POINTS、REOPEN_CURRENT 或 REOPEN_BID 时,取品种自身 Digits;若是 CURRENCY_SYMBOL、CURRENCY_MARGIN、CURRENCY_PROFIT、CURRENCY_DEPOSIT 这一类货币模式,则取 DigitsCurrency。 前面那串错误码表(4302–4307)也值得在 MT5 里对照看:4302 是品种没在 MarketWatch 选中,4306 是自选品种数超上限,4307 是调 Session 函数时会话索引错。外汇和贵金属杠杆高,这类底层符号状态异常会让你脚本静默取不到 tick,实盘前务必先自查。 把下面这段直接塞进你的 EA 调试,能确认当前品种走的是哪条分支,再决定手算 swap 时用错位数会不会偏。

MQL5 / C++
class="type">int CSymbol::SymbolDigitsBySwap(class="type">void)
  {
   class="kw">return
     (
       this.SwapMode()==SYMBOL_SWAP_MODE_POINTS       ||
       this.SwapMode()==SYMBOL_SWAP_MODE_REOPEN_CURRENT ||
       this.SwapMode()==SYMBOL_SWAP_MODE_REOPEN_BID     ?   this.Digits() :
       this.SwapMode()==SYMBOL_SWAP_MODE_CURRENCY_SYMBOL  ||
       this.SwapMode()==SYMBOL_SWAP_MODE_CURRENCY_MARGIN  ||
       this.SwapMode()==SYMBOL_SWAP_MODE_CURRENCY_PROFIT  ||
       this.SwapMode()==SYMBOL_SWAP_MODE_CURRENCY_DEPOSIT ?   this.DigitsCurrency() :
       class="num">0
     );
  }
交给小布盯盘看形态
这些基础形态的诊断逻辑小布盯盘的AIGC已内置,打开对应品种页即可看到外包线与孕线的实时标注,你不必从零搭库。

常见问题

孕线是双向形态可任一侧入场,外包线分BUOVB看涨与BEOVB看跌,信号柱完全覆盖前柱且收破极值加过滤器才触发。
原访问类方法未优化且MQL5已有语言变更,需先加烛形比率属性、修错误并统一形态访问方法,否则代码冗余易错。
可以,小布盯盘品种页内置了外包线及孕线等价格行为形态的AIGC标注,省去自行编写EA的重复劳动。
原文示例用5-10点突破过滤器,实际受品种点差与波动影响,外汇贵金属属高风险,参数需按品种回测倾向性调整。