※当サイトはアフィリエイト広告(Amazonアソシエイツ等)を利用しています。
こんにちは。trade-engineer.com 運営者のHです。
今回は、RSIやストキャスといったオシレーター系インジケーターを一切使わず、ロウソク足の形状だけを判定材料にして USDJPY 5分足のバックテストを取った結果をまとめます。具体的には「ヒゲがほぼ存在しない完全坊主のロウソク足が出現した直後に逆張りすると、勝率がどう動くのか」という仮説をMT4のヒストリカルデータで検証しました。完全坊主の判定ロジックはMQL4のシンプルなIF文で書ける一方で、実体サイズや時間帯のフィルタを加えるかどうかで結果が大きくぶれる領域でもあります。検証条件・MQL4側の実装ポイント・結果の数値・運用ロジックへの転用方法まで、エンジニア視点で順に解説していきます。
- 完全坊主ロウソク足の定義とMQL4での判定ロジックを具体コード付きで解説
- USDJPY 5分足・確定足ベースでの逆張りバックテスト結果を数値で公開
- 実体サイズフィルタ・時間帯フィルタを加えたときの勝率改善幅を比較
- 結果をFX逆張りロジックに転用する際の設計指針と次の検証課題を提示
完全坊主ロウソク足の逆張り検証 ― 仮説と条件設計
最初の山では、検証に入る前段としてどんな仮説を立てたのか、そしてMT4のヒストリカルデータをどう切り出してMQL4側で判定するのかをまとめます。完全坊主の定義そのものが甘いとサンプルが膨らみすぎて結果がぶれるので、ここで「何をもって完全坊主とみなすか」を厳密に固めておきます。
検証の目的と「完全坊主+逆張り」という仮説
この検証の目的は、ヒゲがほぼ存在しない極端な実体のロウソク足が出現した直後の値動きに、統計的な偏りがあるかどうかを確認することです。直感的には「上ヒゲも下ヒゲも無く一方向に強く伸びた足は、需給が一気に傾いた結果として出やすい。直後はリバウンドが入りやすいのではないか」という仮説が立てられます。トレーダーの主観では「強い足の後は押し目・戻り目を作る」と語られる場面が多いものの、これを5分足の確定足ベースで数値化したデータは案外少ないです。
そこで今回は、完全坊主が出現した次の5分足の確定値が、完全坊主の方向と逆になっているかどうかをそのまま勝敗とカウントします。陽線完全坊主の次足が陰線確定なら「Low勝ち」、陰線完全坊主の次足が陽線確定なら「High勝ち」とみなす、シンプルな逆張りロジックです。バイナリーオプション時代に組み立てたペイアウト計算の名残が残っていますが、勝率さえ正しく出れば、後段でFXのpips逆張りロジックに置き換えるのは難しくありません。仮説検証の段階では指標を増やしすぎず、まずは「単一条件で勝率がどこに着地するか」を確かめます。なお検証結果が芳しくなくても破棄せず、改善条件への参考データとしてそのまま記録します。
仮説を立てる時点で気をつけているのは、完全坊主のような形状ベースの条件は再現性が高く取り回しやすい一方で、相場環境(トレンド・レンジ・ボラティリティ)の前提を無視しがちな点です。検証段階では条件を最小化したほうが純粋な統計値が見えますが、それを実運用に乗せるときには相場環境の前提を必ず添えること。検証用スクリプトと運用用EAでロジック設計の粒度を分けておくと、後から「あれ、検証ではここまで勝率が出たのに本番ではなぜ違う」という事故が減ります。今回も検証は最小条件で走らせ、考察パートで相場前提の話を改めて取り上げる構成にしてあります。
バックテスト条件(USDJPY 5分足・確定足ベース)
バックテスト条件は次のとおりです。MT4のヒストリカルデータからUSDJPYを5分足で読み込み、すべて確定足ベース、つまりOnTick内でiTime(NULL, PERIOD_M5, 1) != prevTimeのような条件で「足が確定した瞬間」だけ判定する形にしています。確定足ベースを徹底すると、リアルタイム値動き中の判定揺らぎを避けられるので、結果が再現しやすくなります。
| 項目 | 条件 |
|---|---|
| 通貨ペア | USDJPY |
| 時間足 | 5分足(PERIOD_M5) |
| 判定タイプ | シングルタイムフレーム(STF)/確定足ベース |
| 判定時間 | 5分後(次足の確定値) |
| サンプル期間 | MT4内蔵ヒストリカルデータ(数十万本規模) |
| エントリー条件 | 陽線完全坊主→Low / 陰線完全坊主→High |
| 勝敗判定 | 次足の確定値方向で判定 |
STFを選んだ理由は、マルチタイムフレーム(MTF)で時間足を混ぜると「どの足の確定でエントリー判定したのか」が後から追えなくなり、再現性が落ちるからです。MTFが必要かどうかは、まずSTFで勝率を出してから比較するのが筋になります。判定時刻を「5分後」に固定しているのも、ロジックを最小単位で検証するためです。複数バー先まで判定をずらすと、相場のドリフトが乗ってきて純粋なロウソク足効果が見えにくくなります。検証で見ているのは「完全坊主直後の一本だけ」の挙動なので、シンプルさを最優先にしました。
確定足ベース+STFで検証することで「どの判定ロジックがどのバーから生まれたのか」を追跡しやすくなります。MTFや複数バー判定は、STFで勝率の下地が見えてから足していくのが手戻りを減らすコツです。
完全坊主の定義とMQL4での判定ロジック
完全坊主とは、本来「上ヒゲ・下ヒゲともに完全にゼロのロウソク足」を指しますが、為替の場合は1pip未満のヒゲがほぼ常に存在します。そこで今回は「ヒゲの長さがそれぞれ1Point以下」を完全坊主とみなす定義を採用しました。Pointは銘柄の最小値動き単位なので、USDJPY(小数点以下3桁ブローカー)では0.001になります。極端な丸めを避けつつ、現実的に「ヒゲがほぼ無い」と言える水準です。MQL4の関数で書くと、ロジック自体は5行程度に収まります。
// 完全坊主判定(陽線・陰線をbool値で返す)
bool IsBullMarubozu(int shift) {
double op = iOpen(NULL, PERIOD_M5, shift);
double cl = iClose(NULL, PERIOD_M5, shift);
double hi = iHigh(NULL, PERIOD_M5, shift);
double lo = iLow(NULL, PERIOD_M5, shift);
return (cl > op) && (hi - cl <= Point) && (op - lo <= Point);
}
bool IsBearMarubozu(int shift) {
double op = iOpen(NULL, PERIOD_M5, shift);
double cl = iClose(NULL, PERIOD_M5, shift);
double hi = iHigh(NULL, PERIOD_M5, shift);
double lo = iLow(NULL, PERIOD_M5, shift);
return (cl < op) && (hi - op <= Point) && (cl - lo <= Point);
}
陽線陰線の判定そのものはiCloseとiOpenの大小比較で十分ですが、毎回4本値を取りに行くのは可読性が下がるので、関数化しておくと後段の検証条件追加(実体サイズ、時間帯)に拡張しやすくなります。陽線陰線をBool値で受け取って分岐させる流れは、MQL4でiBarType関数を自作する陽線陰線判定の実装手順の考え方と同じです。判定対象が「完全坊主かどうか」に変わるだけで、関数の置き場所や呼び出し方は使い回せます。
ロウソク足実体サイズの計測とPoint換算
実体サイズのフィルタは、検証条件②で勝率を改善するための重要な要素です。実体サイズは単純にMathAbs(iClose(NULL, PERIOD_M5, shift) - iOpen(NULL, PERIOD_M5, shift))で求められますが、結果をpip単位やPoint単位で扱うのか、価格そのままで扱うのかで読みやすさが変わります。今回はPoint単位に揃えて、「実体10Point以上」を境界に設定しました。USDJPYの場合は10Point = 1pipなので、ぱっと見の数字感とも一致します。
Point換算は(cl - op) / Pointで算出できます。ただしブローカーによって小数点以下3桁と5桁が混在するため、5桁ブローカーのEUR/USDなどに転用するときはPoint値が異なる点に注意してください。ロウソク足の実体・ヒゲの構造そのものを丁寧に整理した記事として、MQL学習入門編|ローソク足の種類や実体、ヒゲを確認する方法を読んでおくと、ここの実装で迷う場面が減ります。実体サイズの閾値を変えるだけで、検証はそのまま走らせられるようにパラメータ化しておくのがおすすめです。
実体サイズは固定値で持つだけでなく、ATRやボラティリティに対する相対値で持つ方法もあります。たとえば「直近20本のATRに対して実体が0.5倍以上」という条件にすると、相場の活性度に合わせて閾値が自動調整されます。今回の検証では一旦Pointベースの固定閾値で進めますが、相場環境が大きく変わる時期を跨いで運用するなら、相対値ベースの閾値も後段で試す価値があります。閾値の切り替えだけでロジックを使い回せるよう、判定関数のシグネチャは早めに固めておいてください。
「実体●Point以上」のような条件は、MQL4の外部パラメータ(extern int)で定義しておくと、ストラテジーテスターから自動最適化を回しやすくなります。検証コードを書き換えずに閾値だけ変えて比較できるので、検証の再現性も上がります。
確定足STFで検証するときの注意点
STF+確定足の構成にはいくつか落とし穴があります。第一に、テスターの「コントロールポイント」モードで回すと、5分足の確定タイミング前後で判定が走り、本来出るはずのないシグナルが混ざります。完全坊主の判定は「あらゆるティックで完全坊主が成立する瞬間」が連続的に発生し得るため、確定足ベースの判定を入れていないと、同一バー内で何度も判定が走るというバグになりがちです。iTime(NULL, PERIOD_M5, 0)を保存しておき、変化したタイミングだけ判定する形にしてください。
第二に、MT4のヒストリカルデータは標準ではティックが粗いので、ストラテジーテスターの「すべてのティック」モードを使うと結果が変わる場合があります。ただし今回の検証は確定足の終値だけを参照するシンプルな構造なので、コントロールポイントでも結果は安定します。スプレッドコストは判定の勝敗にカウントしていません。バイナリー検証時代の名残ですが、FX用に転用するときには別途スプレッド・スリッページのコストを引き算する必要があります。第三に、過去データの欠損があるとサンプルが減ります。MT4ナビゲータからヒストリーセンターを開き、対象期間のデータが連続して入っているかを確認してから走らせてください。
確定足ベースで検証ロジックを書くと、テスター上の挙動と実運用EAの挙動を一致させやすくなります。EA化する際に、検証スクリプトでは「確定足のみ判定」と書いていたのに、本番では「あらゆるティックで判定」してしまい、結果が再現しないという事故は本当に多いです。検証コードをそのまま運用に移すのではなく、判定タイミングを管理する関数を一つ用意し、検証時もテスト時も同じ関数を経由する設計にすると、こうしたズレを抑えられます。MQL4のテスター内部の挙動は資料が散らばっているので、迷ったときはMetaQuotes公式のOnTick仕様を確認するのが最短ルートです。
完全坊主ロウソク足のバックテスト結果と運用ロジックへの展開
後半では、実際に走らせたバックテストの数値と、その結果をどう次の検証ステップに繋げるかを整理します。単純条件では勝率が伸び悩む場面でも、フィルタを足すと改善の兆しが見える ― そのプロセスをそのまま記録します。
条件① 完全坊主のみ ― 勝率と内訳
条件①「陽線完全坊主→Low/陰線完全坊主→High」だけで走らせた結果、勝率は50%を下回りました。バイナリーオプション時代であれば、ペイアウト1.85倍の勝率分岐点(54.05%)を大きく下回るためマイナス収支ですが、ここで重要なのは「単独条件では仮説が成立しなかった」事実そのものです。勝率が50%を切るということは、完全坊主の方向にむしろ追従するほうが優位という見方もできます。検証ログを残しておくと、後で「順張りロジック」に転用するときの一次データとして使えるので、捨てずに保管してください。
勝率の内訳を時間帯別に集計すると、東京時間と欧州時間の境目(日本時間16〜18時)で勝率が大きくぶれていました。流動性が低い時間帯では、完全坊主の出現自体が「板の薄さによる単発の一方向飛び」になっており、次足で素直に戻すのではなく、そのまま追従する形が増えていたわけです。「完全坊主=勢いの極み=反転」というイメージが、すべての時間帯に当てはまるわけではないことが、サンプル内訳から明確に見えました。逆に欧州時間後半(日本時間21時以降)になると、勝率がわずかに50%を上回るレンジが現れます。後段の時間帯フィルタの土台になる一次サインです。
勝率を1つの平均値で見るのではなく、時間帯・曜日・経済指標発表前後といった軸でクロス集計しておくと、ロジックを伸ばす余地が見えてきます。MT4のテスター結果はCSVに書き出して別途集計するか、エントリーごとにラベルオブジェクトとしてチャートに残しておくのがおすすめです。条件①が単独で勝率50%を割ったという結果は失敗ではなく、「形状単独では足りない」という前提条件を確定できた成果として扱ってください。検証は仮説を採用するためだけでなく、棄却して別ルートを探すためにも回します。
条件② 完全坊主+実体10Point以上 ― 改善幅
条件②では、実体10Point以上というフィルタを足しました。完全坊主であっても実体が極端に小さいものは、単に板が薄かっただけの可能性が高く、ノイズに近い動きです。これを除外することで、本当に勢いが出ている足だけに絞り込めます。実装上は、先ほどのIsBullMarubozu関数に「(cl - op) / Point >= 10」というBool条件を足すだけで完結します。コードの追加は1行で済み、検証コストはほぼゼロです。
結果、勝率は条件①よりわずかに上昇したものの、依然として50%付近に張り付いたままでした。実体サイズが大きい完全坊主は「強い順張りの起点」にもなり得るため、逆張り条件としては中途半端な絞り込みになってしまったと考えられます。一方で、サンプル数は約4割減少しました。母集団が薄くなったため、確率分布のばらつきも大きくなっています。検証結果は単純な「勝率」だけでなく、サンプル数とともに記録しておかないと、後から見たときに過信してしまう原因になります。バックテストの仕組みそのものを再確認したい場合は、RSI制御でバックテストを読み返すと、同じテンプレで別条件を回したときとの比較ができ、感覚が掴みやすくなります。
もう一つ重要なのは、フィルタを加えるたびに「フィルタによって除外したサンプルがどんな顔つきだったか」を観察することです。条件②で除外された「実体10Point未満の完全坊主」は、ボラティリティが低い時間帯に多発しており、勝率自体も条件①の母集団とほぼ同じでした。つまり、実体サイズフィルタは「無駄打ちを減らす効果」はあっても「勝率を底上げする効果」は限定的だった、と読み解けます。フィルタは目的によって使い分けが必要で、勝率向上を狙うのか、エントリー回数を絞ってドローダウンを抑えるのかを、最初に決めておくのが筋です。
「勝率がわずかに上がった」だけでは運用判断には使えません。サンプル数が減って統計的なばらつきが広がっている可能性があるため、勝率の上昇幅とサンプル減少率を必ずセットで評価してください。
条件③ 時間帯フィルタを加えた追加検証
条件①で得た時間帯別の偏りを使い、条件③として「日本時間21時〜翌2時のみエントリー」というフィルタを足しました。欧州・米国時間が重なるこの帯は、ニュースフローや指標発表で完全坊主が出やすく、かつ反対方向への押し戻しも入りやすい時間帯です。MQL4ではTimeHour(TimeCurrent())で現在の時刻(サーバ時間)を取得し、日本時間との時差を加味して条件分岐するだけで実装できます。サーバ時間と日本時間のズレは特に注意が必要で、MT4の表示時間と内部時間の対応関係を確認しないと、フィルタが期待どおりに効きません。
条件③の結果、勝率は条件①・②と比較して明確に向上しました。完全坊主のみ+実体10Point以上+時間帯フィルタを重ねた状態で、サンプル数は3条件のなかで最も少ないですが、勝率は50%台後半の数字が出ました。バイナリーオプションのペイアウト分岐点に届く水準ではないものの、FXに転用する場合は「逆張りエントリーの母集団を絞る初期フィルタ」として使い物になる手応えがあります。さらに、エントリー時間ごとの勝率分布を見ると、時間帯フィルタは「勝率の押し上げ」だけでなく「連敗確率の低減」にも効いており、ドローダウン管理の観点でも価値がありました。
時間帯フィルタが効いた理由は、欧州・米国時間の重なる時間帯では、ヘッジファンドやマーケットメーカーが両方向の流動性を提供しているため、急騰急落の後に一旦戻る動きが出やすい点に尽きます。逆に、東京時間明けの薄商いゾーンでは、いったん出た方向にそのまま吸い込まれることが多く、逆張りロジックが噛み合いません。形状ロジックを設計するときは、流動性プロファイル(ロンドン・ニューヨーク・東京)の前提を常に頭に入れておくと、的外れな仮説検証に時間を割く頻度が大きく下がります。
結果からわかるUSDJPYの値動き特性
3条件の結果を並べると、USDJPYの5分足には次のような特性が浮かびます。第一に、完全坊主だけを判定材料にする逆張りロジックは、単独では機能しません。マーケットメイカー的なロジックや、複数銘柄を組み合わせた相関ロジックと違い、単一銘柄・単一指標の逆張りは現代的なFXの値動きには相性が悪いことが多いです。第二に、実体サイズだけで絞っても勝率に大きな改善は出ません。「強い足が出たら反転する」という一見もっともらしい直感は、データで裏付けを取ると過大評価でした。第三に、時間帯フィルタは勝率を押し上げる効果が明確にありました。流動性と参加プレイヤーの偏りが結果に直結しています。
この特性は、過去にBO時代のヒゲ判定ロジックを検証していたときの傾向ともよく似ています。「形だけ」で逆張りすると勝率は伸びず、「形+時間」「形+他指標」と複合化したときに、ようやくチャンスが見える。エントリーシグナルの設計を考えるなら、ロウソク足の形状単体ではなく、形状・時間・トレンド方向・ボラティリティの4軸を組み合わせる前提でロジックを設計するほうが、検証も実装も筋がいいと判断しました。完全坊主はそのなかの「形状」軸を担当する一つの部品にすぎず、単独でエースとして使うものではないという結論になります。
この4軸の組み合わせ方は、ロジック設計の自由度が一気に広がるぶん、検証の組み合わせ爆発を引き起こしがちです。何を固定し、何を可変にして比較するのか、検証マトリックスの設計を最初に決めておくと、検証の生産性が落ちません。例えば「形状=完全坊主固定/時間帯=3段階/ボラ=ATR3段階/トレンド=H1のMA上下」のように、軸ごとに段階を切ると、組み合わせ数が見える形になります。検証ログをそのテンプレに沿って保存していけば、後から横断比較するときも迷子になりません。
FX逆張りエントリーに転用する場合のロジック設計
バイナリーオプション仕様で得た勝率データを、FXの逆張りエントリーに転用するときは、次のように設計を組み替えるのが現実的です。第一に、勝敗判定を「次足の方向」ではなく「pipsベースの利確・損切ライン」に置き換えます。たとえば、完全坊主の実体サイズと同じpips幅を利確ターゲット、その半分を損切ラインに設定するなど、リスクリワード比を1:1〜1:2の範囲で設定します。第二に、ポジション保有時間にも上限を設けます。5分足のシグナルなら最長3〜4本(15〜20分)程度を上限として、時間切れで強制決済する形にすると、ダラダラ含み損を抱える事故を防げます。
第三に、複数の判定軸を組み合わせます。完全坊主+時間帯フィルタの土台に、上位足のトレンド方向(PERIOD_H1の移動平均など)と整合する場合にのみエントリーを通すと、勝率と期待値が両方押し上がります。MQL4でEA化する際は、エントリー条件・利確損切条件・ポジション管理を3つの関数にきれいに分けて書くと、後でロジックを差し替えるときに楽です。検証段階のスクリプトをそのままEA化するのではなく、関数単位で再設計するフェーズを1回入れることをおすすめします。
EA化のフェーズで意外と忘れがちなのが、約定処理の堅牢化です。OrderSendのリトライ、スリッページ許容値、ポジション重複の禁止、サーバ切断時の挙動。検証では考えなくて済んだ部分が、本番ではEAを止める要因になります。逆張りエントリーは値動きが反対方向に振れた瞬間に約定が必要になることが多く、約定遅延がパフォーマンスを直撃します。約定ロジックは別関数として独立させ、エラーコードごとの再試行回数や、強制クローズ条件をパラメータで持っておくと、運用上の事故が減ります。
まとめ ― 検証で残った課題と次の一歩
完全坊主ロウソク足の逆張りバックテストをUSDJPY 5分足で取った結果、単独条件では勝率は50%付近、実体サイズフィルタを加えても大きな改善はなく、時間帯フィルタを重ねたときに初めて意味のある勝率向上が見られました。検証データそのものはエッジが薄いものの、「完全坊主=反転のサイン」というよく語られる直感が、すべての時間帯では成立しないことを数値で示せたのは収穫です。今後の検証課題は3つあります。一つ目は、上位足トレンドフィルタとの組み合わせ。二つ目は、複数通貨ペア(EURUSD、GBPUSD)での再検証。三つ目は、完全坊主の前後数本のロウソク足パターンとの複合条件です。
ロウソク足の形状判定はMQL4のなかでも特に書きやすい領域ですが、形状単独でエッジを生むのは難しい、という事実をフラットに受け止めたうえで、判定軸の組み合わせ方を工夫していくのが次の一歩になります。今回のコードは関数単位で切り出してあるので、別条件のバックテストにそのまま流用できる作りです。バックテストのテンプレートとして手元に置いておき、新しい仮説を試すたびに最小コストで回せる状態にしておくと、検証のサイクルがぐっと早くなります。検証結果を再現したい方は、Amazonで MQL4 バックテスト関連書籍を見ると、ストラテジーテスターの使い方や統計処理の基礎をまとめて押さえられます。
仮説検証の世界では、ひとつの結果に固執するより、検証回数を稼げる仕組みを作るほうが結果的に強いロジックに辿り着きます。完全坊主の検証ひとつとっても、今回扱った3条件のほかに「直前のN本トレンド」「ヒゲ条件をPoint数で可変化」「複数通貨ペアでの再現性」といった切り口が無数に存在します。手元の検証テンプレートを一段成熟させて、次の仮説に取り掛かるまでの摩擦を下げておくのが、長期的に最も効きます。次回以降の記事でも、同じテンプレートを軸に別条件のバックテスト結果を共有していきますので、当ブログ内の関連記事も併せて参考にしてください。


コメント