
スマートマネーコンセプト(オーダーブロック)とフィボナッチ指標を組み合わせた最適な取引エントリー方法
はじめに
スマートマネーコンセプト(SMC)とオーダーブロックは、機関投資家が大規模な買い注文や売り注文を執行する際に、チャート上で重要な役割を果たす領域です。これらのゾーンは、大きな価格変動の起点となることが多いため、機関投資家の市場活動に戦略を合わせたいトレーダーにとって極めて重要です。このような重要な水準が価格動向にどのように影響を与えるのかを理解することで、リテールトレーダーは市場の根本的な力学をより深く理解し、高い確率で発生する動きを予測できるようになります。
フィボナッチリトレースメントのようなツールを組み合わせることで、トレーダーはエントリー戦略をさらに精密化できます。フィボナッチリトレースメントは、直近のスイングハイとスイングローの間における潜在的なプルバックレベルを特定し、価格がトレンドを再開する前にどの程度リトレースするかを測定するための手法を提供します。このアプローチは、機関投資家の注文フローを市場の注目領域と一致させることで、トレーダーが最適なエントリーポイントを正確に特定し、取引精度を高めるのに役立ちます。
エキスパートアドバイザー(EA)ロジック
強気オーダーブロック
強気オーダーブロックは、弱気ローソク足の後に続く強気ローソク足が前の弱気ローソク足を包み込み、大きな強気モメンタムの始まりを示す場合にチャート上で識別されます。このパターンが強気オーダーブロックとして成立するためには、弱気ローソク足に続くローソク足が少なくとも2本以上の強気ローソク足、もしくは一連の強気ローソク足で構成されている必要があります。強気オーダーブロックを取引する正しいアプローチは、価格がリトレースして特定された強気オーダーブロックゾーンに再び到達するのを待つことです。このタイミングで買いポジションをエントリーすることが推奨されます。
強気のフィボナッチリトレースメント
強気オーダーブロックを特定した後、最適なトレードエントリーポイントを見つけるために、フィボナッチリトレースメントツールを使用します。強気オーダーブロックを確認したら、トレーダーはそのオーダーブロックに関連する直近のスイングハイとスイングローを特定します。次に、フィボナッチリトレースメントをチャート上のスイングローからスイングハイに向けて描画します。このリトレースメントは、強気オーダーブロックが61.8%レベル以下にあることを確認するのに役立ちます。これは、機関投資家の注文フローと一致する潜在的な買いの機会を示す重要なリトレースメントゾーンです。
弱気オーダーブロック
弱気オーダーブロックは、強気ローソク足の後に弱気ローソク足が続き、その弱気ローソク足が前の強気ローソク足を包み込む形で現れ、弱気モメンタムの始まりを示すときに識別されます。このパターンが弱気オーダーブロックと見なされるためには、少なくとも2本以上の弱気ローソク足、または一連の弱気ローソク足が強気ローソク足の後に続かなければなりません。弱気オーダーブロックを取引する適切な方法は、価格がリトレースして弱気オーダーブロックゾーンを再テストするのを待つことです。このタイミングで売りポジションをエントリーすることが推奨されます。
弱気フィボナッチリトレースメント
弱気オーダーブロックの場合、フィボナッチリトレースメントツールを使用して最適なトレードエントリーポイントを見つけます。弱気オーダーブロックを特定した後、トレーダーはそのオーダーブロックに関連する直近のスイングハイとスイングローを特定します。この場合、フィボナッチリトレースメントはスイングハイからスイングローにかけて描画されます。これは売り注文を狙うためのアプローチです。このリトレースメントにより、弱気オーダーブロックが61.8%レベル以上に位置しているかどうかを確認できます。61.8%レベル以上は、高い確率でショートポジションのエントリーポイントとなる可能性を示す重要なゾーンです。
始めましょう。
//+------------------------------------------------------------------+ //| FIB_OB.mq5 | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include <Trade/Trade.mqh> CTrade trade; #define BullOB clrLime #define BearOB clrRed
# include <Trade/Trade.mqh>:この行は、取引、注文、ポジションを管理するための組み込み関数を提供するMQL5 Tradeライブラリをインクルードします。Trade.mqhファイルには、注文の開始、決済、変更などの取引操作を簡素化する定義済みのクラスと関数が含まれています。CTradeのインスタンス「trade」を作成します。CTradeクラスは取引操作(売買注文の発注、ポジションの決済、取引の変更など)をカプセル化します。このオブジェクトを作成することで、エキスパートアドバイザー(EA)でオブジェクト指向メソッドを使用して簡単に取引を管理することができます。
次に、強気オーダーブロックと弱気オーダーブロックを視覚化するために使用する色の定数を2つ定義します。BullOBには、強気オーダーブロックの色clrLime(緑)が割り当てられ、買い手が市場に参入した可能性のある領域を示します。BearOBには、弱気オーダーブロックに対してclrRed(赤)が割り当てられ、売り手が市場に参入している可能性がある領域を示します。
//+------------------------------------------------------------------+ //| Global vars | //+------------------------------------------------------------------+ double Lots = 0.01; int takeProfit = 170; //int stopLoss = 200; int length = 100; input double stopLoss = 350; input double Mgtn = 00.85; bool isBullishOB = false; bool isBearishOB = false; input int Time1Hstrt = 3; input int Time1Hend = 4;
isBullishOBとisBearishOBは、オーダーブロック(OB)の検出を追跡するために使用するブールフラグです。グローバル変数の中に、時間設定のための入力パラメータTime1HstrtとTime2Hendがあります。Time1Hstrtは特定の取引期間の開始時間を表します。Time1Hendはその取引期間の終了時間を表します。
class COrderBlock : public CObject { public: int direction; datetime time;//[] double high; double low; void draw(datetime tmS, datetime tmE, color clr){ string objOB = " OB REC" + TimeToString(time); ObjectCreate( 0, objOB, OBJ_RECTANGLE, 0, time, low, tmS, high); ObjectSetInteger( 0, objOB, OBJPROP_FILL, true); ObjectSetInteger( 0, objOB, OBJPROP_COLOR, clr); string objtrade = " OB trade" + TimeToString(time); ObjectCreate( 0, objtrade, OBJ_RECTANGLE, 0, tmS, high, tmE, low); // trnary operator ObjectSetInteger( 0, objtrade, OBJPROP_FILL, true); ObjectSetInteger( 0, objtrade, OBJPROP_COLOR, clr); } };
COrderBlockクラスを定義し、取引チャートのオーダーブロック(OB)をモデル化するのに使用します。このクラスには、オーダーブロックの方向、時間、高値、安値のプロパティと、チャート上にオーダーブロックを描画するメソッド(draw)が含まれています。COrderBlockクラスは、MQL5でオブジェクトを作成するための汎用クラスであるCObject基盤クラスを継承しています。これによりCOrderblockはCObjectのメソッドやプロパティにアクセスできるようになります。
メンバー変数(プロパティ)「direction」はオーダーブロックの方向を表すintデータ型で、オーダーブロックが強気(上向きは1)か弱気(下向きは-1)かを示すために使用されます。「time」は、オーダーブロックが形成された、または検出された時間を表し、オーダーブロックイベントのタイムスタンプを保持します。「high」はオーダーブロックの高値(ゾーンの上限)を表し、「low」はオーダーブロックの安値(ゾーンの下限)を表します。これら4つの変数は、オーダーブロック(OB)の主要な属性です。
次に、チャート上のオーダーブロックを表す矩形オブジェクトの一意な名前を保持するための文字列変数「objOB」を作成します。名前は接頭辞「OB REC」とオーダーブロックの時間(TimeToString()を用いて文字列に変換)を連結して生成されます。ObjectCreate():この関数はチャートに矩形オブジェクト(OBJ-RECTANGLE)を作成します。「0」はチャートID(0は現在のチャートを意味する)、objOBは矩形オブジェクトの名前、timeおよびlowは、矩形の左下隅の座標(時間枠上のオーダーブロックの開始位置と安値の価格水準)、tmSおよびhighは、矩形の右上隅の座標(終了時刻と高値の価格レベル)です。
COrderBlock* OB; color OBClr; datetime T1; datetime T2;
- COrderBlock* OB:オーダーブロックを管理し、チャート上に描画するために使用するオーダーブロックオブジェクトへのポインタ
- color OBClr: 強気または弱気のオーダーブロックが検出された場合に、オーダーブロックに使用される色を保持する変数
- datetime T1:オーダーブロックの開始時刻を表す変数
- datetime T2:オーダーブロックの終了時刻を表す変数
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit(){ trade.SetExpertMagicNumber(MagicNumber); return(INIT_SUCCEEDED); }
OnInit()関数は、EAが初めてチャートにロードされたときに呼び出されます。私たちはEAのマジックナンバーを設定するだけです。マジックナンバーは単にEAによっておこなわれた取引のための一意の識別子です。
const int len = 5; int left_bars, right_bars; int bar_Now = len; bool isSwingH = true, isSwingL = true;
- len:バーがスイングポイントかどうかを判断する際に考慮する、左右のバー(ローソク足)の数を設定します。
- left-bars、right-bars:これらの変数は、現在のバー(bar-Now)に対する左右のバーのインデックスを格納するために使用されます。
- bar-Now = len:分析中の現在のバーがlenに設定されます(この場合、5本後ろのバー)。
- isSwingH, isSwingL:これらのブール変数はtrueに初期化され、現在のバーがスイングハイかスイングローかを確認するために使用されます。
for(int i = 1; i <= len; i++){ right_bars = bar_Now - i; left_bars = bar_Now + i;
forループはバーの範囲(len = 5)を繰り返し、現在のバー(bar-Now)の左側と右側の両方を分析します。
- right-bars = bar-Now - i:現在のバーの右側のバー
- left-bars = bar-Now + i:現在のバーの左側のバー
if((getHigh(bar_Now) <= getHigh(right_bars)) ||(getHigh(bar_Now) < getHigh(left_bars))){ isSwingH = false; }
この条件は、現在のバー(bar-Now)の高値が周囲のバー(左右両方)の高値以下であるかどうかを確認します。どちらか一方のバーがより高いか同じ高値を持っている場合、現在のバーはスイングハイではなく、isSwingHはfalseに設定されます。
if((getLow(bar_Now) >= getLow(right_bars)) || getLow(bar_Now) > getLow(left_bars)){ isSwingL = false; }
スイングハイロジックと同様に、この条件は現在のバーの安値が周囲のバーの安値以上であるかどうかを確認します。どちらか一方のバーが安値である場合、現在のバーはスイングローではなく、isSwingLはfalseに設定されます。
if(isSwingH){ Print("We have a swing high at index: ", bar_Now, "at price: ", getHigh(bar_Now)); fib_high = getHigh(bar_Now); fib_t1 = getTime(bar_Now); }
isSwingHがtrueのままである場合、スイングハイが見つかったことが示されます。この関数は、バーインデックスとスイング価格を表示します。fib-highとfib-t1はスイングハイの価格と対応する時間を格納するグローバル変数です。これらの値は、パラメータとしてFIBOオブジェクトに渡されます。
if(isSwingL){ Print("We have a swing low at index: ", bar_Now," at price: ", getLow(bar_Now)); fib_low = getLow(bar_Now); fib_t2 = getTime(bar_Now); }
同様に、スイングローの検出を処理するために、スイングローが検出された場合、変数isSwingLはtrueのままです。この関数は、バーインデックスとスイングローを表示します。fib-lowとfib-t2はスイングローの価格と時間を格納します。これらの値は、パラメータとしてFIBOオブジェクトに渡されます。
//+------------------------------------------------------------------+ //| Function to find OB | //+------------------------------------------------------------------+ void getOrderB(){ static int prevDay = 0; MqlDateTime structTime; TimeCurrent(structTime); structTime.min = 0; structTime.sec = 0; structTime.hour = Time1Hstrt; datetime timestrt = StructToTime(structTime); structTime.hour = Time1Hend; datetime timend = StructToTime(structTime); if(TimeCurrent() >= timestrt && TimeCurrent() < timend){ if(prevDay != structTime.day_of_year){ delete OB; for(int i = 1; i < 100; i++){ if(getOpen(i) < getClose(i)){ // index is i since the loop starts from i which is = 1 "for(int i = 1)..." if(getOpen(i + 2) < getClose(i + 2)){ if(getOpen(i + 3) > getClose(i + 3) && getOpen(i + 3) < getClose(i + 2)){ Print("Bullish Order Block confirmed at: ", TimeToString(getTime(i + 2), TIME_DATE||TIME_MINUTES)); //isBullishOB = true; OB = new COrderBlock(); OB.direction = 1; OB.time = getTime(i + 3); OB.high = getHigh(i + 3); OB.low = getLow(i + 3); isBullishOB = true; OBClr = isBullishOB ? BullOB : BearOB; // specify strt time T1 = OB.time; // reset BULL OB flag isBullishOB = false; prevDay = structTime.day_of_year; break; delete OB; } } } if(getOpen(i) > getClose(i)){ if(getOpen(i + 2) > getClose(i + 2)){ if(getOpen(i + 3) < getClose(i + 3) && getOpen(i + 3) < getClose(i + 2)){ Print("Bearish Order Block confirmed at: ", TimeToString(getTime(i + 2), TIME_DATE||TIME_MINUTES)); //isBearishOB = true; OB = new COrderBlock(); OB.direction = -1; OB.time = getTime(i + 3); OB.high = getHigh(i + 3); OB.low = getLow(i + 3); isBearishOB = true; OBClr = isBearishOB ? BearOB : BullOB; T1 = OB.time; // reset the BEAR OB flag isBearishOB = false; prevDay = structTime.day_of_year; break; delete OB; } } } } } } }
この関数は、特定の時間範囲内(この場合はTime1HstrtからTime1endまで)の価格データから強気と弱気のオーダーブロックを探します。特定されると、方向、時間、高値と安値のような関連する属性を持つオーダーブロックオブジェクト(COrderBlock)が作成されます。その後、可視化と処理のために色とフラグを設定します。prevDayはstatic変数であり、関数呼び出しの間、値を保持します。これにより、オーダーブロックの検出は1日に1回しかおこなわれないようにします。
この関数が既に現在の日(prevDay)を処理している場合、オーダーブロックの再計算を避けるために検出をスキップします。日が変わるとリセットされます。この関数は、プライスアクションを確認し、強気および弱気のオーダーブロックパターンがないかをチェックします。
- 条件:強気パターンを形成する一連のローソク足を探します。最初のローソク足は強気で、始値が終値より低い必要があります。2本目のローソク足も強気であり、確認の役割を果たします。3本目のローソク足は弱気ですが、その始値が2本目のローソク足の終値より低くなければなりません。
- すべての条件が満たされると、強気オーダーブロックが確定します。
- この際、新しい COrderBlock オブジェクトが作成され、方向(強気)、時間、高値、安値といったプロパティが設定されます。
- 弱気パターンにも同様のロジックが適用されます。最初のローソク足は弱気で、始値が終値より高い必要があります。2本目のローソク足も弱気であり、確認をおこないます。3本目のローソク足は強気ですが、その始値が2本目のローソク足の終値より低い必要があります。
- 条件が満たされると、弱気注文のブロックが確定します。
- 処理後、OBオブジェクトはメモリを解放するために削除されます。
- pervDayが更新され、関数が1日に1回だけ実行されるようになった。
bool isNewBar() { // Memorize the time of opening of the last bar in the static variable static datetime last_time = 0; // Get current time datetime lastbar_time = (datetime)SeriesInfoInteger(Symbol(), Period(), SERIES_LASTBAR_DATE); // First call if (last_time == 0) { last_time = lastbar_time; return false; } // If the time differs (new bar) if (last_time != lastbar_time) { last_time = lastbar_time; return true; } // If no new bar, return false return false; }
この関数は、チャートに新しいバーが現れたかどうかを確認し、バーごとにいくつかの関数を実行します。
double getHigh(int index) { return iHigh(_Symbol, _Period, index); } double getLow(int index) { return iLow(_Symbol, _Period, index); } double getOpen(int index){ return iOpen(_Symbol, _Period, index); } double getClose(int index){ return iClose(_Symbol, _Period, index); } datetime getTime(int index) { return iTime(_Symbol, _Period, index); }
このセクションでは、指定されたバー(またはローソク足)の特定の価格データと時間情報を、指定されたindexで取得するための一連のユーティリティ関数を提供します。各関数は、iHigh()、iLow()、iOpen()、iClose()、iTime()などのMQL5組み込み関数を使用して、銘柄と期間のそれぞれの価格または時間値にアクセスします。
void OnTick(){ if(isNewBar()){ getOrderB(); getSwings(); double Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); if(CheckPointer(OB) != POINTER_INVALID && OB.direction > 0 && Ask < OB.high){ double entry = Ask; double tp = getHigh(iHighest(_Symbol, PERIOD_CURRENT, MODE_HIGH, iBarShift(_Symbol, PERIOD_CURRENT, OB.time))); double sl = NormalizeDouble(OB.low - Mgtn, _Digits); // double sl = getLow(iLowest(_Symbol, PERIOD_CURRENT, MODE_LOW, 2,iBarShift(_Symbol, PERIOD_CURRENT, OB.time))); ObjectCreate( 0, FIBO_OBJ, OBJ_FIBO, 0, fib_t1, fib_low, fib_t2, fib_high); double entLvl = fib_high - (fib_high - fib_low) * Fib_Trade_lvls / 100; // check this if non if(OB.high <= entLvl){ T2 = getTime(0); OB.draw(T1, T2, OBClr); trade.Buy(Lots, _Symbol, entry, sl, tp, "OB buy"); delete OB; }else{ delete OB; } } if(CheckPointer(OB) != POINTER_INVALID && OB.direction < 0 && Bid > OB.low){ double entry = Bid; double tp = getLow(iLowest(_Symbol, PERIOD_CURRENT, MODE_LOW, iBarShift(_Symbol, PERIOD_CURRENT, OB.time))); double sl = NormalizeDouble(OB.high + Mgtn, _Digits); // double sl = getHigh(iHighest(_Symbol, PERIOD_CURRENT, MODE_HIGH, iBarShift(_Symbol, PERIOD_CURRENT, OB.time))); ObjectCreate( 0, FIBO_OBJ, OBJ_FIBO, 0, fib_t2, fib_high, fib_t1, fib_low); double entLvl = fib_low + (fib_low - fib_high) * Fib_Trade_lvls / 100; if(OB.low >= entLvl){ T2 = getTime(0); OB.draw(T1, T2, OBClr); trade.Sell(Lots, _Symbol, entry, sl, tp, "OB sell"); delete OB; }else{ delete OB; } } ObjectSetInteger( 0, FIBO_OBJ, OBJPROP_COLOR, clrBlack); for(int i = 0; i < ObjectGetInteger( 0, FIBO_OBJ, OBJPROP_LEVELS); i++){ ObjectSetInteger( 0, FIBO_OBJ, OBJPROP_LEVELCOLOR, i, clrBlack); } } }
OnTick()は新しいティック(価格の更新)が発生するたびに実行されるので、isNewBar()関数を使って新しいバーが形成されているかどうかを確認します。getOrderB()関数は、潜在的な強気または弱気のオーダーブロック(機関トレーダーが大口の買い/売り注文を出すゾーン)を特定します。getSwing()関数は、値動きのスイングポイント(高値と安値)を特定し、フィボナッチリトレースメントレベルを描画するために使用します。
オーダーブロックが検出され、価格がオーダーブロックゾーンに戻ったら、まず現在の価格がこのゾーン内にあるかどうかを確認します。そうであれば、価格がフィボナッチリトレースメント61.8%水準に整合しているかどうかを確認することで、セットアップの検証を進めます。このレベルは、機関投資家の取引戦略において、しばしば強力な反転ポイントを示唆するため、極めて重要です。オーダーブロック内の価格とフィボナッチリトレースメント61.8%との整合性という両方の条件が満たされた場合のみ、ポジションの執行(買いまたは売り)に進みます。そうでなければ、どちらかの条件が不成立になった場合、単にオーダーブロックを削除し、取引に入るのを避けます。
確認次第、強気オーダーブロック
確認次第、弱気オーダーブロック
システムのロジックは、オーダーブロックとフィボナッチリトレースメントレベルの相関関係に基づいて構築されています。オーダーブロックが検出されると、システムはそれがフィボナッチリトレースメントの61.8%レベルと一致しているかどうかを確認します。強気オーダーブロックの場合、価格は61.8%リトレースメントレベルを下回らなければならず、弱気オーダーブロックの場合、価格は61.8%レベルを上回らなければなりません。オーダーブロックがこれらのフィボナッチ条件を満たさない場合、取引ポジションは執行されません。ただし、フィボナッチオブジェクトはチャート上に描画され、リトレースメントレベルを視覚化します。これにより、トレーダーは適切な条件が満たされるまでポジションを取ることなく、潜在的なトレードセットアップを監視できます。
結論
要約すると、オーダーブロック、スイングハイ/スイングロー、フィボナッチリトレースメントといった主要なテクニカル分析の概念を統合し、取引判断を自動化しました。機関投資家が一般的に大規模な買い注文や売り注文を出す領域を示す、強気と弱気のオーダーブロックを検出する関数を作成しました。フィボナッチレベルを組み込むことで、EAは、取引を実行する前に価格のリトレースメントが高確率ゾーンに一致しているかどうかを確認します。OnTick()関数は市場を継続的に監視し、新しいバーが生成されるたびにポジションを建てる条件が満たされているかを評価します。そして、リアルタイムのプライスアクションに基づいてエントリーポイント、ストップロス、テイクプロフィットのレベルを自動的に設定します。
最後に、このEAは、リテールトレーダーが機関投資家の注文フローに合わせた取引をおこなえるよう支援することを目的としています。オーダーブロックや価格リトレースメントといった主要な市場構造を特定し、それに対応することで、EAは大規模な金融機関の戦略的動きを模倣した取引を可能にします。このアプローチにより、取引精度の向上、感情的な判断の削減、そして最終的にはリテールトレーダーの利益率向上が期待されます。
MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/13396





- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索