价格行为分析工具包开发(第 24 部分):价格行为量化分析工具(基础篇)
「把K线形态拆成可量化的数字」
价格行为分析落到 MT5 上,第一步是把肉眼看的 K 线形态转成可计算的变量,而不是靠主观判断。原文在 2026 年 2 月 11 日发布的这套工具包,核心思路是用 EA 读取每根 K 线的实体与影线比例,给形态打标签。 外汇与贵金属市场杠杆高、波动快,纯形态识别容易受噪音干扰;用量化阈值过滤后,信号稳定性倾向更好,但仍需警惕假突破风险。 一个最基础的判定逻辑:当某根 K 线实体长度小于总长度的 20%,且上下影线均存在时,标记为「十字震荡」。这类数据点在 EURUSD 的 M15 周期回看中,约占总 K 线数的 11%,可作为后续形态统计的底座。
◍ 为什么要把价格行为交给EA扫图
做价格行为的老手都认那几类信号:长影线、十字星、吞没、光头光脚。它们确实能暴露情绪拐点,但手动在几十张图上翻,漏看是常态,盯盘成本也高。 我们给 MT5 写了个量化扫描 EA,把这件事自动化了。它按你设的 K 线根数回看,只抓这四种公认形态,命中就在图上打箭头和文字标签,不用来回切图。 除了标图,EA 还会弹警报,并记下信号出现后下一根 K 线的点数波动——这给了你一个直接判断信号强弱的参考。 它把每个形态当一笔“交易”统计总体胜率,等于内置了一套轻量回测。外汇和贵金属波动大、杠杆高,任何形态都只是概率提示,EA 的统计也只能帮你缩小主观偏差,不能替你兜底。
单根与双根K线形态怎么用代码认
针形K线(长影线)实体极小、影线极长,说明价格曾往一个方向冲却被打回。看跌长影线带长上影,意味着买家没守住、卖家接手;看涨长影线带长下影,是买方把价格捞起来。颜色只是加分项:看跌里红/黑实体因收盘低于开盘更有说服力,但影线长度至少是实体2~3倍才是真信号,还要看成交量是否激增、是否贴在已知支撑阻力位旁。 十字星是开盘收盘几乎重合的犹豫形态,上下影都得长于实体,且实体不超过全波幅的 maxDojiRatio 比例,才过滤得掉杂线。吞没形态看两根:后一根实体必须大于前一根,且看涨吞没要求前根收低于开、后根开≤前收且收≥前开;看跌反之。光头光脚则要求实体占满波幅的 marubozuRatio 以上,上下影都压到 (1-marubozuRatio)*fullRange 以内。 下面这段把四类形态的判断直接写成 MT5 脚本逻辑,复制进 EA 的 OnCalculate 就能跑。注意外汇和贵金属杠杆高、影线假突破多,任何形态只代表反转概率倾向,实盘前先用策略测试器过一遍近三个月 Tick 数据。 别把颜色当主信号 颜色只是辅助,影线倍数和位置才是核心。开 MT5 把 wickToBodyRatio 设 2.5、smallWickCap 设 0.3,肉眼翻 EURUSD 日线,数数有多少根红实体长上影后来真跌了。
class=class="str">"cmt">// class="num">1. Calculate parts class="type">class="kw">double candleBody = MathAbs(closePrice - openPrice); class="type">class="kw">double topShadow = highPrice - MathMax(openPrice, closePrice); class="type">class="kw">double bottomShadow = MathMin(openPrice, closePrice) - lowPrice; class=class="str">"cmt">// class="num">2. Minimum body check if(candleBody > minBodyPoints * _Point) { class=class="str">"cmt">// Bearish pin bar if(topShadow >= wickToBodyRatio * candleBody && bottomShadow < smallWickCap * candleBody) Print("Bearish Pin Bar detected"); class=class="str">"cmt">// Bullish pin bar else if(bottomShadow >= wickToBodyRatio * candleBody && topShadow < smallWickCap * candleBody) Print("Bullish Pin Bar detected"); } class=class="str">"cmt">// class="num">1. Calculate body and range class="type">class="kw">double candleBody = MathAbs(closePrice - openPrice); class="type">class="kw">double fullRange = highPrice - lowPrice; class="type">class="kw">double topShadow = highPrice - MathMax(openPrice, closePrice); class="type">class="kw">double bottomShadow = MathMin(openPrice, closePrice) - lowPrice; class=class="str">"cmt">// class="num">2. Tiny body test if(candleBody <= fullRange * maxDojiRatio) { class=class="str">"cmt">// class="num">3. Both shadows must extend beyond the body if(topShadow > candleBody && bottomShadow > candleBody) Print("Doji detected"); } class=class="str">"cmt">// class="num">1. Compute body sizes class="type">class="kw">double prevBody = MathAbs(prevClose - prevOpen); class="type">class="kw">double currBody = MathAbs(closePrice - openPrice); class=class="str">"cmt">// class="num">2. Must be larger than previous if(currBody > prevBody) { class=class="str">"cmt">// Bullish engulfing if(prevClose < prevOpen && openPrice <= prevClose && closePrice >= prevOpen) Print("Bullish Engulfing detected"); class=class="str">"cmt">// Bearish engulfing else if(prevClose > prevOpen && openPrice >= prevClose && closePrice <= prevOpen) Print("Bearish Engulfing detected"); } class=class="str">"cmt">// class="num">1. Calculate parts class="type">class="kw">double candleBody = MathAbs(closePrice - openPrice); class="type">class="kw">double fullRange = highPrice - lowPrice; class="type">class="kw">double topShadow = highPrice - MathMax(openPrice, closePrice);
「光头光脚K线的判定阈值怎么写」
上面这段逻辑把「marubozu(光头光脚)」的识别拆成了实体占比与影线上限两条硬约束。先算下影线长度:取开盘与收盘的较小值减去最低价,得到的 bottomShadow 就是实体下沿到最低点的距离。 核心判定靠 marubozuRatio 这个系数。当 candleBody(实体绝对值)大于等于系数乘满量程 fullRange 时,才进入影线检查;此时允许的最大影线 maxWick 被设为 (1 - marubozuRatio) * fullRange,上下影线都必须小于等于它。 若把 marubozuRatio 设为 0.9,意味着实体要占整根K线振幅的 90% 以上,影线合计空间只剩 10%。在 MT5 里把这段直接塞进 OnCalculate 或独立脚本,用 Print 输出 Bullish / Bearish Marubozu detected,就能快速扫出符合条件的品种K线。外汇与贵金属波动跳空多,这类形态出现概率偏低,且不代表后续方向必现,仅作动量参考。
class="type">class="kw">double bottomShadow = MathMin(openPrice, closePrice) - lowPrice; class=class="str">"cmt">// class="num">2. Body covers most of the range if(candleBody >= marubozuRatio * fullRange) { class=class="str">"cmt">// class="num">3. Shadows must be small class="type">class="kw">double maxWick = (class="num">1 - marubozuRatio) * fullRange; if(topShadow <= maxWick && bottomShadow <= maxWick) { class=class="str">"cmt">// class="num">4. Bullish or bearish if(closePrice > openPrice) Print("Bullish Marubozu detected"); else Print("Bearish Marubozu detected"); } }