English Русский 中文 Español Deutsch Português
preview
MQL5を使用してローソク足パターンを検出する方法

MQL5を使用してローソク足パターンを検出する方法

MetaTrader 5トレーディング | 30 5月 2023, 09:49
1 340 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

はじめに

ローソク足は、パターンに基づいて潜在的な動きを見つけることができるため、正しく使用すれば非常に役立つテクニカルツールです。ローソク足はチャート上で特定のパターンを形成することがあり、これらのパターンは、単一ローソク足パターンと混合ローソク足(複数のローソク足)パターンの2つのタイプに分類できます。この記事では、MQL5を使用して、MetaTrader 5取引ターミナルでこれらのパターンの一部を自動的に検出する方法を学びます。これについては、次のトピックで説明します。

重要なシグナルを取得するには、他の技術ツールと併用してこれらのパターンを使用することが非常に重要であることには言及する必要があります。取引を容易にして良好な結果を得るには、取引システムの一部としてMQL5によって言及されたパターンを検出するという主な概念を理解する必要があります。

免責条項:すべての情報は「現状有姿」で提供され、情報提供のみを目的としており、取引目的やアドバイスを目的としたものではありません。いかなる結果も保証するものではありません。読者がこれらの資料を自分の取引口座で使用する場合、自己責任でおこなってください。

1本ローソク足パターン

この部分では、チャートに表示される人気の1本ローソク足パターンの2つの例を見ていきます。これらはどの時間枠でも見ることができますが、価格変動と比較して適切な位置に表示されると、より重要になります。見ていくのは同事パターンとハンマー(カラカサ・トンカチ)パターンです。

同事パターン:

ローソク足パターンの中でも非常に人気があります。始値と終値がほぼ同じローソク足です。チャート上で、ローソク足の実体は非常に小さい、または同じ価格の上実体と下実体がラインになります。これらの髭がないこともあります。次の図はこのローソク足を示しています。

同事

この同事ローソクは、買い手と売り手の間にバランスがあり、表示されている期間中に価格を上下させるために市場を支配する人がいないことを示しています。調整局面の前またはトレンドの終わりにチャート上の適切な位置に表示される場合、市場が反転するまたは調整局面に入る合図となる可能性があり、より大きな時間枠で表示される場合はより重要になります。このローソク足には多くの種類とフォーメーションがあり、トンボや足長のように、誰もが取引に有利に使用できる多くの情報を持っています。

私たちがしなければならないことは、最後のローソク足の価格と時間と、プログラムに必要なすべてのティックを定義して、同事パターンを検出するようにコンピューターに通知し、この定義された時間でこれらの値をチェックして比較し、すべてのポジションを決定することです。始値が終値と等しい場合、プログラムはこれが同事ローソクパターンであるというシグナルを返す必要があります。

ここで、このパターンを検出できるプログラムを作成します。これをおこなうメソッドの手順は次のとおりです。

この同事のgetDoji関数を作成し、それをOnTick()で呼び出して、このパターンを検索するすべてのティックをチェックします。

void OnTick()
  {
   getDoji();
  }

integer型のgetDoji関数を作成します。

int getDoji()

この関数は、最後のローソク足の時間、始値、高値、安値、終値を定義することで定義されます。

ローソク足が開いた時間を返すiTime関数、ローソク足の始値を返すiOpen、高値を返すiHigh、安値を返すiLow、終値を返すiCloseを使用します。パラメータはすべて同じです。

  • symbol:現在の銘柄に適用(_Symbolを使用)
  • timeframe:チャートの期間または時間枠(現在の時間枠にPERIOD_CURRENTを使用)
  • shift:戻り値のインデックス(1を使用して最後のローソクを定義)
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);

if文で検出したい同事の条件を設定します。

if(open==close)

この条件がtrueの場合、時間、価格、矢印のコード、色、必要なテキストのパラメータを使用してcreateObj関数を呼び出し、それに基づいてオブジェクトを作成します。次に、1を返して関数を終了します。

   if(open==close)
     {
      createObj(time,low,217, clrBlack,"Doji");
        {
         return 1;
        }
     }

getDoji関数を終了するには0を返します。

   return 0;

time、price、arrowcode、clr、txtをパラメータにしたvoid型のcreateObj関数を作成します。

void createObj(datetime time, double price, int arrawCode, color clr, string txt)

objNameの文字列変数を作成して、""の値を割り当てます。

string objName=" ";

パラメータの文字列を形成し、StringConcatenate関数を使用して結合してobjName変数に割り当てます。この関数は形成された文字列のサイズを返します。パラメータは次の通りです。

  • string_var:結合後に形成される文字列(objNameを使用)
  • 引数1:任意の単純な型のパラメータ(”Signal at”を使用)
  • 引数2:検出されたローソク足の時間(事前に決定された変数の時間を使用)
  • 引数3:”at”を使用
  • 引数4:DoubleToStringを使用してdouble型をstring型に変換することにより、四捨五入された価格のテキストを設定
  • 引数5:”(”を使用
  • 引数6:必要な所定のarrowcode integer変数の値を使用(このコードは、mql5リファレンスでWingdingsを検索すると見つかります)
  • 引数7:”)”を使用
StringConcatenate(objName, "Signal at ",time, " at ",DoubleToString(price,_Digits)," (",arrawCode,")");

if文とObjectCreate関数を式として使用して、評価される条件を設定します。ObjectCreate関数は、事前定義された名前objNameを使用してオブジェクトを作成します。そのパラメータは次のとおりです。

  • chart_id:チャート(0で現在のチャートを指定)
  • name:オブジェクト名(事前定義された名前objNameを使用)
  • type:オブジェクトタイプ(OBJ_ARROWを使用)
  • nwin:チャートのサブウィンドウの番号(メインのチャートウィンドウに0を使用)
  • time1:アンカーの時間(事前定義されたtime変数を使用)
  • price1:アンカーの価格(事前定義されたprice変数を使用)
if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))

オブジェクトを作成してこの条件が満たされたら、オブジェクトプロパティの値を設定するObjectSetInteger関数を使用して矢印コードと色を決定することで、そのプロパティの形状を設定します。パラメータは次の通りです。

  • chart_id:チャート(0で現在のチャートを指定)
  • name:オブジェクト名(objNameを使用)
  • prop_id:オブジェクトのプロパティ(矢印コードにはOBJPROP_ARROWCODE、色にはOBJPROP_COLORを使用(ENUM_OBJECT_PROPERTY_INTEGERの1つ))
  • prop_value:プロパティ値(矢印コードにはarrawCode、色には事前定義変数clrを使用)
ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);

その後、事前定義されたobjName変数とtxt変数を割り当ててcandleName文字列変数を作成し、ローソク足の定義として必要なテキストを定義します。

string candleName=objName+txt;

if文を使用し、式としてObjectCreate関数を使用してテキストオブジェクトを作成および編集します。演算子は、オブジェクトプロパティの文字列値を設定するObjectSetStringと、テキストオブジェクトの色を設定するObjectSetIntegerになります。

      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);

このエキスパートアドバイザー(EA)の完全なコードは次のようになります。

//+------------------------------------------------------------------+
//|                                        Doji pattern detector.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
void OnTick()
  {
   getDoji();
  }
int getDoji()
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
//Doji
   if(open==close)
     {
      createObj(time,low,217, clrBlack,"Doji");
        {
         return 1;
        }
     }
   return 0;
  }
void createObj(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal at ",time, " at ",DoubleToString(price,_Digits)," (",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }

コードがエラーなしでコンパイルされると、ナビゲーターウィンドウにEAが表示されます。ドラッグして実行すると、同事パターンを検出するシグナルを取得できます。以下はテストの例です。

同事の例

前のチャートでわかるように、ローソク足の下に黒い矢印オブジェクトとローソク足のパターンを定義する「Doji」テキストがあります。

ハンマー(カラカサ・トンカチ)パターン:

ハンマー(カラカサ・トンカチ)パターンは、多くの時間枠でチャートに見られる非常に人気のあるローソク足パターンです。名前の由来は、長い髭と小さな実体をした形状で、この小さな実体の位置によりカラカサ(ハンマー)とトンカチ(逆ハンマー)の2種類のパターンがあります。カラカサでは、長い下髭があり、ローソクの実体が上にあります。カラカサは、始値と終値に基づいて強気にも弱気にもなる可能性があります。次の図は、このカラカサパターンの例です。

  • 強気のカラカサ

強気のカラカサ

これは、売り手が価格を下げようとしたが、買い手が市場を支配し、始値よりも高く終了したことを示しており、買い手が強いことを意味します。

  • 弱気のカラカサ

弱気のカラカサ

これは、売り手が価格を下げようとしたが、買い手が始値付近でクローズしたことを示しており、買い手がまだゲームに参加していることを意味します。

トンカチでは、長い上髭があり、ローソクの実体が下にあります。トンカチは、始値と終値に基づいて強気にも弱気にもなる可能性があります。以下の図はこのトンカチの例です。

  • 強気のトンカチ

強気のトンカチ

これは、買い手が価格を上げようとしたが、売り手が始値と安値付近でローソク足を閉じたことを示しています。これは、買い手の強さにもかかわらず売り手がまだゲームに参加していることを意味します。

  • 弱気のトンカチ

弱気のトンカチ

これは、買い手が価格を下げようとしたが、売り手が市場を支配し、始値よりも安くクローズしたことを示しており、売り手が強いことを意味します。

すべてのローソク足パターン同様、このパターンも、他のテクニカルツールと組み合わせると、より有意義で重要になります。 

ここで、この種のパターンを検出するために使用できるプログラムを作成します。このプログラムはローソク足の価格、時間、ローソク足のサイズを見つけて、ローソクの実体と髭と比較します。これらを継続的に確認して、ティックごとに比較して位置を決定する必要があります。カラカサまたはトンカチ(強気または弱気)のいずれかを検出した場合、そのタイプ名と、ローソク足の色(強気または弱気)に基づいて、そのタイプ名。ローソク足の下または上に表示される矢印の色、上下のどちらであるかを返す必要があります。

このタイプのプログラムを作成するための完全なコードは次のとおりです。

//+------------------------------------------------------------------+
//|                                      Hammer pattern detector.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
void OnTick()
  {
   getHammer(0.07,0.7);
  }
int getHammer(double smallShadowRatio, double longShadowRatio)
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double candleSize=high-low;
   if(open<close)
     {
      if(high-close < candleSize*smallShadowRatio)
        {
         if(open-low>candleSize*longShadowRatio)
            createObj(time,low,217, clrGreen,"Hammer");
           {
            return 1;
           }
        }
     }
   if(open>close)
     {
      if(high-open<candleSize*smallShadowRatio)
        {
         if(close-low>candleSize*longShadowRatio)
            createObj(time,high,218,clrRed,"Hammer");
           {
            return 1;
           }
        }
     }
   if(open<close)
     {
      if(open-low < candleSize*smallShadowRatio)
        {
         if(high-close>candleSize*longShadowRatio)
            createObj(time,low,217, clrGreen,"Inverted Hammer");
           {
            return -1;
           }
        }
     }
   if(open>close)
     {
      if(close-low < candleSize*smallShadowRatio)
        {
         if(high-open>candleSize*longShadowRatio)
            createObj(time,high,218, clrRed,"Inverted Hammer");
           {
            return -1;
           }
        }
     }
   return 0;
  }
void createObj(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }

このコードの違いは、次の通りとなります。

smallShadowRatioとlongShadowRatioに必要なパラメータを決定して、OnTick()でgetHammer関数を呼び出します。

void OnTick()
  {
   getHammer(0.07,0.7);
  }

smallShadowRatioとlongShadowRatioの2つのdouble変数パラメータを使用してgetHammer関数を作成します。

int getHammer(double smallShadowRatio, double longShadowRatio)

比率と比較するためのcandleSize double変数を作成します。

double candleSize=high-low;

カラカサローソク足の状態

強気カラカサ(open<close)の場合、最後の強気のローソク足が必要です。ローソク足の上の髭(high-close)は短髭の比率である0.07よりも小さく、下の髭(open-low)は長髭の比率である0.7よりも大きくなります。チャート上で、このカラカサローソク足の安値の下に、緑色の矢印と、Wingdingsのコード(217)を「Hammer」テキストオブジェクトを使用して作成し、関数を終了します。

   if(open<close)
     {
      if(high-close < candleSize*smallShadowRatio)
        {
         if(open-low>candleSize*longShadowRatio)
            createObj(time,low,217, clrGreen,"Hammer");
           {
            return 1;
           }
        }
     }

弱気のカラカサ(open>close)の場合、最後の弱気のローソク足が必要です。ローソク足の上の髭(high-open)は、短髭の比率である0.07より小さく、下の髭(close-low)は、長髭の比率である0.7よりも大きくなります。チャート上で、このカラカサローソク足の高値の上に、赤い矢印と、Wingdingsのコード(218)を「Hammer」テキストオブジェクトを使用して作成し、関数を終了します。

   if(open>close)
     {
      if(high-open<candleSize*smallShadowRatio)
        {
         if(close-low>candleSize*longShadowRatio)
            createObj(time,high,218,clrRed,"Hammer");
           {
            return 1;
           }
        }
     }

強気のトンカチ(open<close)の場合、最後の強気のローソク足が必要です。ローソク足の下の髭(open-low)は短髭の比率である0.07より小さく、上の髭(high-close)は長髭の比率である0.7よりも大きくなります。チャート上で、このカラカサローソク足の安値の下に、緑色の矢印と、Wingdingsのコード(217)を「Inverted Hammer」テキストオブジェクトを使用して作成し、関数を終了します。

   if(open<close)
     {
      if(open-low < candleSize*smallShadowRatio)
        {
         if(high-close>candleSize*longShadowRatio)
            createObj(time,low,217, clrGreen,"Inverted Hammer");
           {
            return -1;
           }
        }
     }

弱気のトンカチ(open>close)の場合、最後の弱気のローソク足が必要です。ローソク足の下の髭(close-low)は短髭の比率である0.07より小さく、上の髭(high-open)は長髭の比率である0.7よりも大きくなります。チャート上で、このカラカサローソク足の高値の上に、赤い矢印と、Wingdingsのコード(218)を「Inverted Hammer」テキストオブジェクトを使用して作成し、関数を終了します。

   if(open>close)
     {
      if(close-low < candleSize*smallShadowRatio)
        {
         if(high-open>candleSize*longShadowRatio)
            createObj(time,high,218, clrRed,"Inverted Hammer");
           {
            return -1;
           }
        }
     }

if文を使用して、ObjectSetInteger関数で色に基づいて矢印の位置を設定します。

緑がローソク足の下にある場合

      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);

赤がローソク足の上にある場合

      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);

このコードをエラーなしでコンパイルして実行すると、シグナルを取得できます。以下はテストの例です。

  • 強気のカラカサ

強気カラカサの例

ご覧のとおり、チャートには、強気のカラカサローソク足の安値の下に緑色の矢印と緑色の「Hammer」テキストオブジェクトがあります。

  • 弱気のカラカサ

弱気カラカサの例

ご覧のとおり、チャートには、弱気のカラカサローソク足の高値の上に赤い矢印と赤い「Hammer」テキストオブジェクトがあります。

  • 強気のトンカチ

強気のトンカチの例

ご覧のとおり、チャートには、強気のトンカチローソク足の安値の下に、緑色の矢印と緑色の「Inverted Hammer」テキストオブジェクトがあります。

  • 弱気のトンカチ:

弱気のトンカチの例

ご覧のとおり、チャートには、弱気のトンカチローソク足の高値の上に、赤い矢印と赤い「Inverted Hammer」テキストオブジェクトがあります。

2本ローソク足パターン

この部分では、2本のローソク足で構成される別のタイプのローソク足パターンを見ていきます。飲み込み(強気と弱気)、強気の切り込み線とその反対の弱気のかぶせ線パターンという2つの人気のあるパターンです。

飲み込みパターン

このローソク足パターンは、チャートやテクニカル分析でも非常に人気のあるパターンで、2本のローソク足の一方が他方を飲み込むことで構成されます。小さなローソク足の後に大きなローソク足が続き、この大きなローソク足が小さなローソク足を完全にカバーします。

飲み込みパターンには、ローソク足の色や種類に応じていくつかのタイプがあります。

  • 強気の飲み込み

小さな弱気のローソク足の後に大きな強気のローソク足があり、この強気のローソク足が小さいローソク足を飲み込みます。次の図はそれを表しています。

強気の飲み込み

その程度に応じて、買い手が市場を支配し、その後も価格が上昇し続ける可能性があることを示します。

  • 弱気の飲み込み

小さな強気のローソク足の後に大きな弱気のローソク足があり、この弱気のローソク足が小さな強気のローソク足を飲み込みます。次の図はそれを表しています。

弱気の飲み込み

その程度に応じて、売り手が市場を支配しており、その後も価格が下落し続ける可能性があることを示します。

ここで、このパターンを自動的に検出するために使用できるプログラムを作成したい場合は、最後のローソク足の時間と最後の2つのローソク足の価格を定義する必要があります。これらの値をティックごとに継続的に確認し、決定するプログラムが必要です。このタイプの飲み込みパターンがあるかどうかを確認するために、その位置が相互に関連しています。この飲み込みパターンを取得したら、そのタイプ(強気または弱気)に基づいて色付きの矢印とテキストオブジェクトである特定のシグナルを返します。

このプログラムを作成するための完全なコードは次のとおりです。

//+------------------------------------------------------------------+
//|                                   Engulfing pattern detector.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
void OnTick()
  {
   getEngulfing();
  }
int getEngulfing()
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);
   if(open<close)
     {
      if(open2>close2)
        {
         if(high>high2&&low<low2)
           {
            if(close>open2&&open<close2)
              {
               createObj(time,low,217, clrGreen,"Bullish Engulfing");
                 {
                  return 1;
                 }
              }
           }
        }
     }
   if(open>close)
     {
      if(open2<close2)
        {
         if(high>high2&&low<low2)
           {
            if(close<open2&&open>close2)
              {
               createObj(time,high,218, clrRed,"Bearish Engulfing");
                 {
                  return -1;
                 }
              }
           }
        }
     }
   return 0;
  }
void createObj(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }

このコードの違いは次の通りです。

getEngulfing関数を作成する際に、最後のローソクの時間と価格のtime、open、high、low、closeのdouble変数と、最後のローソク足の前のローソク足の価格のopen2、high2、low2、close2を作成します。

   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);

このタイプのローソク足パターンを定義する条件

強気飲み込みの場合、最後のローソク足は強気(open<close)、最後のローソク足の前のローソク足は弱気(open2>close2)、high>high2、low<low2、close>open2、open<close2となります。それを特定したら、作成したcreateObj関数に基づいて次のパラメータを使用してオブジェクトを作成します。

  • time:事前定義された変数である最後のローソク足の時間
  • price:その下にオブジェクトが必要になる、最後のローソク足の安値
  • arrowCode:Wingdingsからは217
  • clr:clrGreen
  • txt:「Bullish Engulfing」

その後、関数を終了します。

   if(open<close)
     {
      if(open2>close2)
        {
         if(high>high2&&low<low2)
           {
            if(close>open2&&open<close2)
              {
               createObj(time,low,217, clrGreen,"Bullish Engulfing");
                 {
                  return 1;
                 }
              }
           }
        }
     }

弱気飲み込みの場合、最後のローソク足は弱気(open>close)、最後のローソク足の前のローソク足は強気(open2<close2)、high>high2、low<low2、close<open2、open>close2となります。それを特定したら、作成したcreateObj関数に基づいて次のパラメータを使用してオブジェクトを作成します。

  • time:事前定義された変数である最後のローソク足の時間
  • price:その上にオブジェクトが必要になる、最後のローソク足の高値
  • arrowCode:Wingdingsからは218
  • clr:clrRed
  • txt:「Bearish Engulfing」

その後、関数を終了します。

   if(open>close)
     {
      if(open2<close2)
        {
         if(high>high2&&low<low2)
           {
            if(close<open2&&open>close2)
              {
               createObj(time,high,218, clrRed,"Bearish Engulfing");
                 {
                  return -1;
                 }
              }
           }
        }
     }

このコードをエラーなしでコンパイルし、EAを実行すると、テストから次の例のようにシグナルを取得できます。

  • 強気の飲み込み

強気の飲み込みの例

前のチャートで見られるのと同じように、パターンの最後のローソク足の安値の下に緑色の矢印と「Bullish Engulfing」テキストがあります。

  • 弱気の飲み込み

弱気の飲み込みの例

前のチャートで見られるのと同じように、パターンの最後のローソク足の高値の上に赤い矢印と「Bearish Engulfing」テキストがあります。

切り込み線とかぶせ線のパターン

  • 切り込み線パターン

これは強気のローソク足であり、最初のローソク足が弱気で、続いて強気のローソク足が弱気のローソク足よりも低く開いてから上昇し、最初の弱気のローソク足の中点を超えて閉じるため、2本のローソク足で構成されています。次の図は、それを説明するグラフです。

切り込み線

買い手がより強くなって、売り手の支配に続いて市場を支配するようになることを示します。つまり、開始時にギャップがあったにもかかわらず、買い手が価格を以前の弱気のローソク足の中間点よりも上に押し上げることができたので、これは売りから買いへのシフトを指します。

  • かぶせ線パターン

これは切り込み線パターンとは逆の形で、最初のローソク足が強気で、その後にギャップのある弱気ローソク足が続き、最初の強気ローソク足の中間点を下回って閉じる弱気パターンです。以下はそのグラフです。

かぶせ線

売い手がより強くなって、買り手の支配に続いて市場を支配するようになることを示します。つまり、開始時にギャップがあったにもかかわらず、売り手が価格を以前の強気のローソク足の中間点よりも下に押し下げることができたため、買いから売りへのパワーの移行を指します。

このタイプのパターンを検出するために使用できるプログラムを作成したい場合は、最初のローソク足の時間と価格(time、open、high、 low、close)と2番目のローソク足の価格(open2、high2、 low2、close2)、最初のローソク足のサイズ(candleSize2)、最初のローソク足の中点(candleMidPoint2)を定義する必要があります。これらの値を継続的に確認し、相互に関連する位置を判断し、強気か弱気かに基づいて特定の条件に基づいて特定のシグナルを返すプログラムが必要です。

このプログラムを作成するための完全なコードは次のとおりです。

//+------------------------------------------------------------------+
//|                      Piercing && Dark Cloud pattern detector.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
void OnTick()
  {
   getPiercing();  
  }
int getPiercing()
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);
   double candleSize2=high2-low2;
   double candleMidPoint2=high2-(candleSize2/2);
   if(open<close)
     {
      if(open2>close2)
        {
         if(open<low2)
           {
            if(close>candleMidPoint2&&close<high2)
              {
               createObj(time,low,217, clrGreen,"Piercing");
                 {
                  return 1;
                 }
              }
           }
        }
     }
   if(open>close)
     {
      if(open2<close2)
        {
         if(open>high2)
           {
            if(close<candleMidPoint2&&close>low2)
              {
               createObj(time,high,218, clrRed,"Dark Cloud");
                 {
                  return -1;
                 }
              }
           }
        }
     }
   return 0;
  }
void createObj(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }

このコードの違い

cancelSize2とCandleMidPoint2を定義します。

   double candleSize2=high2-low2;
   double candleMidPoint2=high2-(candleSize2/2);

次は、パターンの条件です。

切り込み線パターンの場合:

最後のローソク足が強気(open<close)で、open2>close2、open<low2、close>candleMidPoint2、close<high2の場合、チャート上でパターンの下に表示される緑色の矢印と「Piercing」テキストを含むオブジェクトを返して、関数を終了します。

   if(open<close)
     {
      if(open2>close2)
        {
         if(open<low2)
           {
            if(close>candleMidPoint2&&close<high2)
              {
               createObj(time,low,217, clrGreen,"Piercing");
                 {
                  return 1;
                 }
              }
           }
        }
     }

かぶせ線パターンの場合:

最後のローソク足が弱気(open>close)で、open2<close2、open>high2、close<candleMidPoint2、close>がlow2の場合、チャート上でパターンの高値の上に表示される赤い矢印と「DarkCloud」テキストを持つオブジェクトを返して、関数を終了します。

   if(open>close)
     {
      if(open2<close2)
        {
         if(open>high2)
           {
            if(close<candleMidPoint2&&close>low2)
              {
               createObj(time,high,218, clrRed,"Dark Cloud");
                 {
                  return -1;
                 }
              }
           }
        }
     }

このコードをコンパイルしてEAを実行すると、次のテスト例と同じように目的のシグナルを取得できます。

  • 切り込み線パターン:

切り込み線の例

前のチャートでわかるように、パターンの安値の下に必要な緑色の矢印と「Piercing」が表示されています。

  • かぶせ線パターン

かぶせ線の例

前のチャートでわかるように、パターンの高値の上に必要な赤い矢印と「Dark Cloud」が表示されています。

3本ローソク足パターン

この部分では、ブレンドパターンから2つのパターンを見ていきます。明星パターン(明けの明星・宵の明星)とスリーインサイドパターン(アップ、ダウン)です。

明星パターン

  • 明けの明星

前述したように、3本ローソク足の構造です。2本のローソク足の間にある小さなローソク足によって形成され、最初のローソク足はロング/弱気で、2番目のローソク足はロング/強気です。以下はそのグラフです。

明けの明星

その程度に基づいて、買い手が市場を支配し、売り手の支配によって下落した後に価格を押し上げるため、売りから買いへの力の移行を示します。

  • 宵の明星パターン
前述したように、3本ローソク足の構造です。2本のローソク足の間にある小さなローソク足によって形成され、最初のローソク足はロング/強気で、2番目のローソク足はロング/弱気です。以下はそのグラフです。

宵の明星

その程度に基づいて、売り手が市場を支配し、買い手の支配によって上昇した後に価格を下げるため、買いから売りへの力の移行を示します。

この種のパターンを検出するために使用できるプログラムを作成したい場合は、最後のローソク足の時間と価格、および最後のローソク足の前の2つのローソク足の価格データ、最後の3つのローソク足のローソク足サイズを定義する必要があります。それらを相互に比較して、相互に関連する位置を決定し、特定の条件に基づいて特定のシグナルを取得します。

このプログラムを作成するための完全なコードは次のとおりです。

//+------------------------------------------------------------------+
//|                                        Star pattern detector.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
void OnTick()
  {
   getStar(0.5);
  }
int getStar(double middleCandleRatio)
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);
   double open3=iOpen(_Symbol,PERIOD_CURRENT,3);
   double high3=iHigh(_Symbol,PERIOD_CURRENT,3);
   double low3=iLow(_Symbol,PERIOD_CURRENT,3);
   double close3=iClose(_Symbol,PERIOD_CURRENT,3);
   double candleSize=high-low;
   double candleSize2=high2-low2;
   double candleSize3=high3-low3;
   if(open<close)
     {
      if(open3>close3)
        {
         if(candleSize2<candleSize*middleCandleRatio && candleSize2<candleSize3*middleCandleRatio)
           {
            createObj(time,low,217, clrGreen,"Morning Star");
              {
               return 1;
              }
           }
        }

     }
   if(open>close)
     {
      if(open3<close3)
        {
         if(candleSize2<candleSize*middleCandleRatio && candleSize2<candleSize3*middleCandleRatio)
           {
            createObj(time,high,218, clrRed,"Evening Star");
              {
               return -1;
              }
           }
        }

     }
   return 0;
  }
void createObj(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }

このコードの違い

middleCandleRatioパラメータを使用してgetStarを作成します。

int getStar(double middleCandleRatio)

最後のローソク足のtime変数、価格データ(open、high、low、close)、最後の3本のローソク足のサイズ(candlesize、candleSize2、candleSize3)を作成します。

   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);
   double open3=iOpen(_Symbol,PERIOD_CURRENT,3);
   double high3=iHigh(_Symbol,PERIOD_CURRENT,3);
   double low3=iLow(_Symbol,PERIOD_CURRENT,3);
   double close3=iClose(_Symbol,PERIOD_CURRENT,3);
   double candleSize=high-low;
   double candleSize2=high2-low2;
   double candleSize3=high3-low3;

次は、パターンの条件です。

明けの明星パターンの場合:

最後のローソク足が強気(open<close)、3番目のローソク足が弱気(open3>close3)、candleSize2はcandleSizeのmiddleCandleRatioである0.5より低く、同時にcandleSize2がCandleSize3のmiddleCandleRatioよりも低い場合、パターンの下に表示される緑色の矢印と「MorningStar」テキストのオブジェクトを返して関数を終了するプログラムが必要です。

   if(open<close)
     {
      if(open3>close3)
        {
         if(candleSize2<candleSize*middleCandleRatio && candleSize2<candleSize3*middleCandleRatio)
           {
            createObj(time,low,217, clrGreen,"Morning Star");
              {
               return 1;
              }
           }
        }
     }

宵の明星の場合:

最後のローソク足が弱気(open>close)、3番目のローソク足が強気(open3<close3)、candleSize2がcandleSizeのmiddleCandleRatio(0.5)より低く、同時にcandleSize2がcandleSize3のmiddleCandleRatioよりも低い場合、パターンの上に表示される赤い矢印と「EveningStar」テキストのオブジェクトを返して関数を終了するプログラムが必要です。

   if(open>close)
     {
      if(open3<close3)
        {
         if(candleSize2<candleSize*middleCandleRatio && candleSize2<candleSize3*middleCandleRatio)
           {
            createObj(time,high,218, clrRed,"Evening Star");
              {
               return -1;
              }
           }
        }
     }

このコードをエラーなしでコンパイルし、EAを実行すると、テストから次の例と同じシグナルを取得できます。

  • 明けの明星

明けの明星の例

ご覧のように、下のチャートで検出されたパターンの下に、必要なオブジェクトの必要なシグナルがあることがわかります。

  • 宵の明星

宵の明星の例

ご覧のように、下のチャートで検出されたパターンの下に、必要なオブジェクトの必要なシグナルがあることがわかります。

明星パターンの注意点は、同じパターンの形成には中央の小さなローソク足とのギャップがあるため、同じパターンを取得したい場合はコードの追加条件として追加できることです。

スリーインサイドパターン

  • スリーインサイドアップ

これも3本ローソク足パターンで、最初のローソク足はロング/弱気のローソク足で、2番目のローソク足は最初のローソク足の内側で取引されている小さな強気のローソク足、3番目のローソク足は最初のローソク足の高値を超えて終了するロング/強気のローソク足です。以下はこのパターンをグラフ化したものです。

スリーインサイドアップ

その程度に基づいて、買い手の支配による潜在的な強気を示します。

  • スリーインサイドダウン

これも3本ローソク足パターンで、最初のローソク足はロング/強気のローソク足で、2番目のローソク足は最初のローソク足の範囲内で取引されている小さな弱気のローソク足で、3番目のローソク足は最初のローソク足の安値を下回って終了するロング/弱気のローソク足です。以下はこのパターンをグラフ化したものです。

スリーインサイドダウン

その程度に基づいて、売り手の支配による潜在的な弱気を示します。このタイプのパターンを検出するために使用できるプログラムを作成したい場合は、最後のローソク足の時間と最後の3つのローソク足の価格データを定義し、ティックごとにこれらの値を相互に関連付けて確認してその位置を決定し、パターンに応じて適切なシグナルをチャート上のオブジェクトとして返します。このプログラムの完全なコードは次のとおりです。
//+------------------------------------------------------------------+
//|                                Three inside pattern detector.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
void OnTick()
  {
   getthreeInside();
  }
int getthreeInside()
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);
   double open3=iOpen(_Symbol,PERIOD_CURRENT,3);
   double high3=iHigh(_Symbol,PERIOD_CURRENT,3);
   double low3=iLow(_Symbol,PERIOD_CURRENT,3);
   double close3=iClose(_Symbol,PERIOD_CURRENT,3);
   if(open3>close3)
     {
      if(open2<close2)
        {
         if(open2>low3&&close2<high3)
           {
            if(open<close&&open>open2&&open<close2)
              {
               if(close>high3)
                 {
                  createObj(time,low,217, clrGreen,"3 Inside Up");
                    {
                     return 1;
                    }
                 }
              }
           }
        }

     }
   if(open3<close3)
     {
      if(open2>close2)
        {
         if(open2<high3&&close2>low3)
           {
            if(open>close&&open<open2&&open>close2)
              {
               if(close<low3)
                 {
                  createObj(time,high,218, clrRed,"3 Inside Down");
                    {
                     return -1;
                    }
                 }
              }
           }
        }
     }
   return 0;
  }
void createObj(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }

このコードの違いはパターンの条件です

スリーインサイドアップの場合

   if(open3>close3)
     {
      if(open2<close2)
        {
         if(open2>low3&&close2<high3)
           {
            if(open<close&&open>open2&&open<close2)
              {
               if(close>high3)
                 {
                  createObj(time,low,217, clrGreen,"3 Inside Up");
                    {
                     return 1;
                    }
                 }
              }
           }
        }

     }

スリーインサイドダウンの場合

   if(open3<close3)
     {
      if(open2>close2)
        {
         if(open2<high3&&close2>low3)
           {
            if(open>close&&open<open2&&open>close2)
              {
               if(close<low3)
                 {
                  createObj(time,high,218, clrRed,"3 Inside Down");
                    {
                     return -1;
                    }
                 }
              }
           }
        }
     }

このコードをエラーなしでコンパイルし、EAを実行すると、次の例と同じシグナルを取得できます。

  • スリーインサイドアップ

スリーインサイドアップの例

チャートからわかるように、スリーインサイドアップの望ましいシグナルがあります。

  • スリーインサイドダウン

スリーインサイドダウンの例

チャートからわかるように、スリーインサイドダウンの望ましいシグナルがあります。

結論

この記事の前のトピックを読んだ後、さまざまなフォーメーション、つまり1本ローソク足、2本ローソク足、および3本ローソク足のパターンを検出するコードの作成方法を理解できたと思います。

  • 1本ローソク足パターン:同事パターンとカラカサパターンを検出する方法を学びました
  • 2本ローソク足パターン:飲み込み、切り込み線、かぶせ線のパターンを検出する方法を学びました
  • 3本ローソク足パターン:明星パターンとスリーインサイドパターンを検出できるプログラムの作成方法を学びました

この記事がより良い洞察を得るのに役立つことを願っています。

MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/12385

MQL5の圏論(第6回):単射的引き戻しと全射的押し出し MQL5の圏論(第6回):単射的引き戻しと全射的押し出し
圏論は、数学の多様かつ拡大を続ける分野であり、最近になってMQL5コミュニティである程度取り上げられるようになりました。この連載では、その概念と原理のいくつかを探索して考察することで、トレーダーの戦略開発におけるこの注目すべき分野の利用を促進することを目的としたオープンなライブラリを確立することを目指しています。
MQL5の圏論(第5回)等化子 MQL5の圏論(第5回)等化子
圏論は、数学の多様かつ拡大を続ける分野であり、最近になってMQL5コミュニティである程度取り上げられるようになりました。この連載では、その概念と原理のいくつかを探索して考察することで、トレーダーの戦略開発におけるこの注目すべき分野の利用を促進することを目的としたオープンなライブラリを確立することを目指しています。
MetaTrader 5をPostgreSQLに接続する方法 MetaTrader 5をPostgreSQLに接続する方法
この記事では、MQL5コードをPostgresデータベースに接続するための4つの方法について説明し、そのうちの1つであるREST APIの開発環境をWindows Subsystem For Linux (WSL)を使用して設定するためのステップバイステップのチュートリアルを提供します。APIのデモアプリが、データを挿入してそれぞれのテーブルにクエリを実行するための対応MQL5コード、このデータを使用するためのデモエキスパートアドバイザー(EA)とともに提供されます。
母集団最適化アルゴリズム:電磁気的アルゴリズム(ЕМ) 母集団最適化アルゴリズム:電磁気的アルゴリズム(ЕМ)
この記事では、様々な最適化問題において、電磁気的アルゴリズム(EM、electroMagnetism-like Algorithm)を使用する原理、方法、可能性について解説しています。EMアルゴリズムは、大量のデータや多次元関数を扱うことができる効率的な最適化ツールです。