ピンバーと包み足(エンガルフィング)は、
裁量トレードの反転サインとして人気の高いローソク足パターンですが、
どちらも「見た目で判断する」ことが前提のため、
同じチャートを見ても人によって「これはピンバーだ」
「いや違う」と判断が割れやすいという弱点があります。
この記事では、ボディ・値幅・ヒゲの長さという具体的な数値を使って、
2つのパターンを同時に自動検出し、
矢印で知らせるインジケーターの作り方を解説します。
・ピンバーを数値で判定する3つの比率(ボディ・値幅・ヒゲ)
・包み足(エンガルフィング)を数値で判定する実体の包含ロジック
・閾値に唯一の正解はなく、調整が必要な理由
・実際に動く2パターン同時検出インジケーターのコード全体
設計思想: 「見た目の判断」を数値のルールに変換する
まず、ピンバーと包み足をそれぞれ数値でどう定義するかを整理します。
ピンバーの数値的な定義
ピンバーは、ローソク足全体の値幅(高値-安値)に対して、
実体(始値-終値)が小さく、
片側のヒゲだけが極端に長く伸びている形のローソク足です。
・実体が値幅全体に対して小さい
・上下どちらか一方のヒゲだけが極端に長い
・長いヒゲが反対側のヒゲの2倍以上あることが多い
・下ヒゲが長ければ反転上昇、上ヒゲが長ければ反転下落の目安とされる
包み足(エンガルフィング)の数値的な定義
包み足は、2本目のローソク足の実体が、
1本目のローソク足の実体を始値・終値ともに完全に覆ってしまう形です。
本体サイトのローソク足の見方の記事で解説されている基本の考え方を、
この記事では「実体の始値・終値の大小関係」という数値条件に落とし込みます。
| パターン | 必要な本数 | 判定に使う値 |
|---|---|---|
| ピンバー | 1本 | ボディ・値幅・ヒゲの比率 |
| 包み足 | 2本 | 2本の実体の始値・終値の大小関係 |
ピンバーの判定ロジック
実際にどの比率をどう計算するかを見ていきます。
ボディ・値幅・ヒゲの比率を計算する
double range = High[i] - Low[i]; double body = MathAbs(Close[i] - Open[i]); double upperWick = High[i] - MathMax(Open[i], Close[i]); double lowerWick = Low[i] - MathMin(Open[i], Close[i]); // 負の値になるため符号反転して使う
値幅に対する実体の割合と、
上下どちらのヒゲが長いかを、この4つの値から判定します。
閾値パラメーターの考え方
本記事では「実体が値幅の35%以下」「長いヒゲが短いヒゲの2倍以上」
という2つの条件を初期値にしていますが、
これは一般的によく使われる目安であり、唯一の正解ではありません。
・35%・2倍という数字に業界統一の基準は無い
・通貨ペアや時間足によって「普通の形」が変わる
・厳しくしすぎると矢印が全く出なくなる
・緩くしすぎると普通のローソク足まで検出してしまう
実際に使う通貨ペアの過去チャートで矢印の頻度を見ながら、
入力パラメーターとして調整できるようにしておくことが重要です。
包み足の判定ロジック
2本のローソク足の実体を比較する判定を見ていきます。
実体同士の包含判定
bool bull1 = Close[i+1] < Open[i+1]; // 1本前が陰線
bool bull2 = Close[i] > Open[i]; // 今のバーが陽線
bool engulfBull = bull1 && bull2
&& Open[i] <= Close[i+1]
&& Close[i] >= Open[i+1];
1本前が陰線・今のバーが陽線で、
かつ今のバーの実体(始値から終値)が、
1本前の実体を始値・終値ともに覆っていれば、
強気の包み足として判定します。
弱気の包み足は、この条件の陽線・陰線を入れ替えるだけで判定できます。
実際に動くコード全体
実際にMetaEditorでコンパイルできる、
ピンバーと包み足を同時に検出して矢印表示するインジケーターです。
//+------------------------------------------------------------------+
//| PinbarEngulfingArrow.mq4 |
//| Copyright 2026, FX-EA System Project Creator |
//| https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, FX-EA System Project Creator"
#property link "https://creator.fx-ea-system-project.com/"
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Lime
#property indicator_width1 2
#property indicator_color2 Red
#property indicator_width2 2
#property indicator_color3 DodgerBlue
#property indicator_width3 2
#property indicator_color4 Orange
#property indicator_width4 2
input double BodyRatioMax = 0.35; //実体が値幅の何%以下ならピンバー候補とするか
input double WickRatioMin = 2.0; //長いヒゲが短いヒゲの何倍以上ならピンバーとするか
double PinBullArrow[];
double PinBearArrow[];
double EngulfBullArrow[];
double EngulfBearArrow[];
int OnInit()
{
SetIndexBuffer(0, PinBullArrow);
SetIndexStyle(0, DRAW_ARROW);
SetIndexArrow(0, 233);
SetIndexBuffer(1, PinBearArrow);
SetIndexStyle(1, DRAW_ARROW);
SetIndexArrow(1, 234);
SetIndexBuffer(2, EngulfBullArrow);
SetIndexStyle(2, DRAW_ARROW);
SetIndexArrow(2, 159);
SetIndexBuffer(3, EngulfBearArrow);
SetIndexStyle(3, DRAW_ARROW);
SetIndexArrow(3, 159);
IndicatorShortName("Pinbar/Engulfing Arrow");
return(INIT_SUCCEEDED);
}
bool IsPinBar(int i, bool &bullish)
{
double range = High[i] - Low[i];
if(range <= 0)
return(false);
double body = MathAbs(Close[i] - Open[i]);
if(body / range > BodyRatioMax)
return(false);
double upperWick = High[i] - MathMax(Open[i], Close[i]);
double lowerWick = MathMin(Open[i], Close[i]) - Low[i];
if(lowerWick >= upperWick * WickRatioMin && lowerWick > 0)
{
bullish = true; // 下ヒゲが長い=反転上昇の目安
return(true);
}
if(upperWick >= lowerWick * WickRatioMin && upperWick > 0)
{
bullish = false; // 上ヒゲが長い=反転下落の目安
return(true);
}
return(false);
}
bool IsEngulfing(int i, bool &bullish)
{
bool prevBear = Close[i + 1] < Open[i + 1];
bool prevBull = Close[i + 1] > Open[i + 1];
bool nowBull = Close[i] > Open[i];
bool nowBear = Close[i] < Open[i];
if(prevBear && nowBull && Open[i] <= Close[i + 1] && Close[i] >= Open[i + 1])
{
bullish = true;
return(true);
}
if(prevBull && nowBear && Open[i] >= Close[i + 1] && Close[i] <= Open[i + 1])
{
bullish = false;
return(true);
}
return(false);
}
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
int needed = 3;
if(rates_total < needed)
return(0);
int limit = (prev_calculated == 0) ? rates_total - needed : rates_total - prev_calculated + 1;
for(int i = limit; i >= 0; i--)
{
PinBullArrow[i] = EMPTY_VALUE;
PinBearArrow[i] = EMPTY_VALUE;
EngulfBullArrow[i] = EMPTY_VALUE;
EngulfBearArrow[i] = EMPTY_VALUE;
bool pinBullish;
if(IsPinBar(i, pinBullish))
{
if(pinBullish)
PinBullArrow[i] = Low[i] - 10 * Point;
else
PinBearArrow[i] = High[i] + 10 * Point;
}
bool engulfBullish;
if(i + 1 < rates_total && IsEngulfing(i, engulfBullish))
{
if(engulfBullish)
EngulfBullArrow[i] = Low[i] - 20 * Point;
else
EngulfBearArrow[i] = High[i] + 20 * Point;
}
}
return(rates_total);
}
MetaEditorでのコンパイル・実行手順
実際にMT4で動かすまでの手順です。
- MetaEditorで新規インジケーター「PinbarEngulfingArrow」を作成し、上のコードを貼り付けてコンパイルする
- エラー・警告が0件であることを確認する
- チャートに適用し、ピンバーの位置に緑(上昇)・赤(下落)の矢印が出ることを確認する
- 包み足の位置に青・オレンジの矢印が出ることを確認する(ピンバーと矢印の形を変えて区別してある)
- 入力パラメーターのBodyRatioMax・WickRatioMinを変えて、矢印の出方がどう変わるか見比べる
よくあるエラーと注意点
実装でつまずきやすいポイントをまとめます。
閾値を厳しくしすぎて矢印が全く出ない
BodyRatioMaxを極端に小さくしたり、
WickRatioMinを極端に大きくすると、
理想的すぎる形しか検出されず、
何週間も矢印が出ないことがあります。
まずは初期値のまま過去チャートで頻度を確認してください。
ピンバーと包み足が同じバーで同時に成立する
実体が小さく長いヒゲを持つバーが、
同時に包み足の条件も満たすことがあります。
本記事のコードは両方を独立に判定して別の矢印を出すため、
同じバーに複数の矢印が重なって表示される場合があります。
トレンドの無いレンジ相場で誤検知が増える
細かい値動きが続くレンジ相場では、
本来は意味の薄いヒゲの長いバーが、
ピンバーの条件を満たしてしまうことがあります。
既刊の環境認識系インジケーターと組み合わせて、
トレンド方向を確認してから使うことをおすすめします。
既刊テクニカル指標記事との使い分け
似た「価格パターン検出」型の記事が複数あるため、使い分けを整理します。
| 記事 | 検出対象 | 必要な本数 |
|---|---|---|
| 本記事(ピンバー・包み足) | 実体とヒゲの形・2本の実体の包含 | 1本または2本 |
| ifractals記事(既刊) | 5本の高値・安値の形 | 5本 |
| 連続陽線・陰線記事(既刊) | 同じ方向の連続本数 | 可変 |
よくある質問
ピンバー・包み足の自動検出について、よくある疑問に回答します。
このインジケーターだけで売買判断してよいですか?
おすすめしません。
ピンバー・包み足はどちらも単独では精度の高いサインではなく、
サポート・レジスタンスなど他の根拠と組み合わせて使う前提の
パターンとして広く紹介されています。
EAの発注条件に使えますか?
使えます。
本記事のIsPinBar()・IsEngulfing()関数をそのまま流用すれば、
「ピンバーが出たらエントリーを検討する」
といった発注条件に組み込めます。
閾値はどうやって決めればよいですか?
公式な正解はないため、
使う通貨ペア・時間足の過去チャートで、
実際に目で見て「これはピンバーだ」と思うバーに矢印が出るように、
BodyRatioMax・WickRatioMinを調整するのが実用的な方法です。
【MQL4】ピンバーと包み足を自動検出して矢印表示するインジケーターの作り方(数値での見分け方つき):まとめ
ピンバーと包み足は、どちらも「見た目の判断」が前提のパターンですが、
ボディ・値幅・ヒゲの比率、実体同士の包含関係という数値条件に変換すれば、
自動検出が可能です。
本記事の閾値(35%・2倍)は一般的な目安であり唯一の正解ではないため、
実際に使う通貨ペア・時間足で矢印の頻度を見ながら調整してください。
どちらのパターンも単独では精度の高いサインではないため、
他の根拠と組み合わせて使うことをおすすめします。
コメント