English Deutsch
preview
アルーン(Aroon)取引システムの構築とテスト

アルーン(Aroon)取引システムの構築とテスト

MetaTrader 5トレーディング | 29 4月 2024, 11:15
305 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

はじめに

取引とテクニカル分析の分野では、使用できるツールはたくさんありますが、間違いなく、それらをすべて使用することはなく、テストして最適化した後に、収益性の高いツールを1つまたは組み合わせて選択します。この記事の目的は、このような状況において役立つ方法を提供すること、あるいは異なる視点や考え方についての洞察を提供することであり、それを応用してどの自動売買システムが自分に適しているかを確認することです。

このタイプの記事は、取引システムの適切な設定を見つけるために自分で作業するよりも短時間で読み終えることができるために非常に役に立ちますが、それでも、自分のやり方にとって興味深いものを見つけた後、さらに詳細を調べ、取引に利益をもたらす最終的な結果に到達するまで最適化する必要があります。ここでは、個別に使用したり他のツールと組み合わせて使用したりすることができる取引ツールを紹介して、読者が集中すべきものを見つけて自分に有利に発展させる時間を節約することを目的としています。また、これらのシステムをストラテジーテスターでテストするためのコーディング方法も提供しています。つまり、手動でテストする代わりにテストプロセスを自動化することで、時間を大幅に節約することができます。

この記事では、アルーンテクニカル指標を使用し、その概念に基づいて複数の戦略をテストし、その結果を見ようと思います。さらに価値があるのは、MQL5から指標をコーディングし、戦略に基づいて取引システムで使用する方法を学ぶということです。これらはすべて、アルーン指標とその計算方法と使い方を学んだ後におこなうことになります。

この記事では以下のトピックを取り上げます。

これらのトピックをカバーした後で、アルーン指標についてとその使用法、取引システムを構築するために必要なもの、アルーンの取引戦略、これらの戦略に基づいた取引システムの構築しとテスト、そしてこれらが取引にどれだけ役立つかを理解することができます。

ここで重要なことは、既存の取引システムに何らかのツールを追加する場合、自分の取引スタイルや取引システムに合った最善でより良い結果を得るために、さまざまな観点からテストをおこなう必要があるということです。なぜなら、人それぞれが異なるため、すべてのトレーダーに適した戦略や取引システムをここで提供することはできませんが、読者の作業時間を短縮するのに役立つ、その一部を紹介することはできるからです。

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


アルーン指標の定義

このセクションでは、アルーンテクニカル指標を確認し、その主な概念を理解できるようにします。この指標がどのように算出されるかを理解することで、このアプローチが指標の主な概念を理解し、言及されていることを利用するだけでなく、適切に利用するためのアプローチを開発できるようになるという目的に役立つことがわかるでしょう。

アルーンは1995年にトゥシャール・S・チャンデによってデザインされました。この指標の主なアイデアは、トレンドの変化を検出し、またトレンドの強さを測定することです。この指標は、一定期間の高値と安値の間にどれだけの時間が経過したかを測定することでこれをおこなうことができます。これを測定することで、強い上昇トレンドとは、定期的に新高値を更新していることが確認できることであり、強い下降トレンドとは、定期的に新安値を更新していることであり、指標はそのシグナルを与えてくれるということができます。

アルーン指標は、上昇トレンドの強さを測るアルーンアップと、下降トレンドの強さを測るアルーンダウンの2本の線で構成されています。この文脈では、アルーンアップがアルーンダウンを上回ると、強気シグナルを示すと言えます。アルーンダウンがアルーンアップを上回れば弱気シグナルです。アルーン指標もまた、0と100のレベルの間を移動または振動します。

以下は、アルーンテクニカル指標の計算方法についてです。

アルーンアップ = 100 * ((n-H)/n)

アルーンダウン = 100 * ((n-L)/n)

ここで、

  • アルーンアップ:直近n期間の高値からの期間数(n期間の総数に対するパーセンテージ)
  • アルーンダウン: 直近n期間の安値からの期間数(n期間の総数に対するパーセンテージ)
  • H:直近n期間の高値からn期間の一定時間内の期間数
  • L:直近n期間の安値からn期間の一定時間内の期間数
  • n:期間


アルーン戦略

このセクションでは、アルーン指標の概念に基づいた2つの簡単な使用法について述べます。これらの戦略をMQL5でコードし、ストラテジーテスターでテストし、それぞれの結果を確認して比較します(「アルーン取引システムのテスト」のトピックで説明します)。

主に以下の2つの戦略を用います。

  • アルーンクロスオーバー戦略
  • アルーンレベル戦略

アルーンクロスオーバー戦略

この戦略では、アルーン指標のアップラインとダウンラインが交差したときに注文を出します。アップラインがダウンラインを上抜いたら買い注文を出し、ダウンラインがアップラインを上抜いたら売り注文を出します。

アップライン>ダウンライン==>買う

ダウンライン>アップライン==>売る

アルーンレベル戦略

この戦略では、アルーン指標のダウンラインがアルーン指標の10レベルと50レベルとクロスオーバーした時に注文を出します。よって、ダウンラインのクロスオーバーが10レベルを下回ったら買い注文を出し、ダウンラインのクロスオーバーが50レベルを上回ったら売り注文を出します。

ダウンライン<10==>買う

ダウンライン>50==>売る


アルーン取引システム

このセクションでは、テスターを使用してテストし、その結果を評価するために、MQL5で前述のアルーン戦略をコードする方法を学びます。まず最初に、以下のようにアルーンカスタム指標をコードし、取引戦略で使用できるようにします。

MQL5のグローバルスコープで、プロパティのプリプロセッサを使用して指標のプロパティを設定します。

//properties of the indicator
#property indicator_separate_window // the place of the indicator
#property indicator_buffers 2 // number of buffers
#property indicator_plots 2 // number of plots

//up line
#property indicator_type1  DRAW_LINE      // type of the up values to be drawn is a line
#property indicator_color1 clrGreen       // up line color
#property indicator_style1 STYLE_DASH     // up line style
#property indicator_width1 2              // up line width
#property indicator_label1 "Up"           // up line label

// down line
#property indicator_type2  DRAW_LINE      // type of the down values to be drawn is a line
#property indicator_color2 clrRed         // down line color
#property indicator_style2 STYLE_DASH     // down line style
#property indicator_width2 2              // down line width
#property indicator_label2 "Down"         // down line label

// drawing some levels to be used later 10 and 50
#property indicator_level1 10.0
#property indicator_level2 50.0
#property indicator_levelcolor clrSilver
#property indicator_levelstyle STYLE_DOT

入力キーワードを使用して、指標の期間と水平シフトの2つの整数入力を作成します。

//inputs
input int                      periodInp = 25; // Period
input int                      shiftInp  = 0;  // horizontal shift

指標のアップとダウンの値用に2つのdouble配列を作成します。

//buffers of the indicator
double                         upBuffer[];
double                         downBuffer[];

OnInit()で、SetIndexBuffer関数を使用して、指標バッファとdouble配列をリンクします。

  • index:バッファのインデックス(0:upBuffer、1:downBuffer)
  • buffer[]:配列(upBuffer配列とdownBuffer配列)
  • data_type:格納するデータ型(ENUM_INDEXBUFFR_TYPEのいずれか:ここでは上下ともにINDICATOR_DATA)
   SetIndexBuffer(0, upBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, downBuffer, INDICATOR_DATA);

以下のパラメータを使用してPlotIndexSetInteger関数を呼び出し、対応するプロパティの値と対応する指標のアップラインとダウンラインの値を設定します。

  • plot_index:プロットスタイルのインデックスを表す整数値(アップ:0、ダウン:1)
  • prop_id:プロパティ識別子を表す整数値(ENUM_PLOT_PROPERTY_INTEGERのいずれかで、アップ値とダウン値:PLOT_SHIFT、アップとダウン:PLOT_DRAW_BEGIN)
  • prop_value:設定される整数値(アップとダウン:shiftInp、アップとダウン:periodInp)
   PlotIndexSetInteger(0, PLOT_SHIFT, shiftInp);
   PlotIndexSetInteger(1, PLOT_SHIFT, shiftInp);
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, periodInp);
   PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, periodInp);

アップ配列とダウン配列にAS_SERIESフラグを設定します。

   ArraySetAsSeries(upBuffer, true);
   ArraySetAsSeries(downBuffer, true);

indicatorNameという文字列変数を宣言し、StringFormat関数を代入して指標ウィンドウに表示する書式を設定した後、指標の文字列名と整数値を設定します。

   string indicatorName = StringFormat("Aroon Indicator (%i,%i) - ", periodInp, shiftInp);
   IndicatorSetString(INDICATOR_SHORTNAME, indicatorName);
   IndicatorSetInteger(INDICATOR_DIGITS, 0);

OnInit()イベントの一部としてINIT_SUCCEEDEDを返します。

return INIT_SUCCEEDED;

以下はOnCalculateイベントです。

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[])

イベント本文では、指標を計算し、十分なデータがない場合は0を返します。

   if(rates_total < periodInp - 1)
      return (0);

整数型のcount変数を作成し、rate_totalからprev_calculatedを引いた結果を計算します。

int count = rates_total - prev_calculated;

prev_calculatedが0より大きい場合、新しいデータがあるので、カウントに1を加えて更新します。

   if(prev_calculated > 0)
      count++;

カウント値を更新する別の条件を作成します。

   if(count > (rates_total - periodInp + 1))
      count = (rates_total - periodInp + 1);

最高値と最低値を計算した後、指標のアップ値とダウン値を計算して更新するためのforループを作成します。

   for(int i = count - 1; i >= 0; i--)
     {
      int highestVal   = iHighest(Symbol(), Period(), MODE_HIGH, periodInp, i);
      int lowestVal    = iLowest(Symbol(), Period(), MODE_LOW, periodInp, i);
      upBuffer[i]   = (periodInp - (highestVal - i)) * 100 / periodInp;
      downBuffer[i] = (periodInp - (lowestVal - i)) * 100 / periodInp;
     }

OnCalculateイベントの一部としてrate_totalを返します。

return (rates_total);

以下は、アルーンカスタム指標を作成するためのコードを1つのブロックにまとめたものです。

//+------------------------------------------------------------------+
//|                                                        Aroon.mq5 |
//+------------------------------------------------------------------+
#property indicator_separate_window // the place of the indicator
#property indicator_buffers 2 // number of buffers
#property indicator_plots 2 // number of plots
#property indicator_type1  DRAW_LINE      // type of the up values to be drawn is a line
#property indicator_color1 clrGreen       // up line color
#property indicator_style1 STYLE_DASH     // up line style
#property indicator_width1 2              // up line width
#property indicator_label1 "Up"           // up line label
#property indicator_type2  DRAW_LINE      // type of the down values to be drawn is a line
#property indicator_color2 clrRed         // down line color
#property indicator_style2 STYLE_DASH     // down line style
#property indicator_width2 2              // down line width
#property indicator_label2 "Down"         // down line label
#property indicator_level1 10.0
#property indicator_level2 50.0
#property indicator_levelcolor clrSilver
#property indicator_levelstyle STYLE_DOT
input int periodInp = 25; // Period
input int shiftInp  = 0;  // horizontal shift
double    upBuffer[];
double    downBuffer[];
int OnInit()
  {
   SetIndexBuffer(0, upBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, downBuffer, INDICATOR_DATA);
   PlotIndexSetInteger(0, PLOT_SHIFT, shiftInp);
   PlotIndexSetInteger(1, PLOT_SHIFT, shiftInp);
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, periodInp);
   PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, periodInp);
   ArraySetAsSeries(upBuffer, true);
   ArraySetAsSeries(downBuffer, true);
   string indicatorName = StringFormat("Aroon Indicator (%i,%i) - ", periodInp, shiftInp);
   IndicatorSetString(INDICATOR_SHORTNAME, indicatorName);
   IndicatorSetInteger(INDICATOR_DIGITS, 0);
   return INIT_SUCCEEDED;
  }
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[])
  {
   if(rates_total < periodInp - 1)
      return (0);
   int count = rates_total - prev_calculated;
   if(prev_calculated > 0)
      count++;
   if(count > (rates_total - periodInp + 1))
      count = (rates_total - periodInp + 1);
   for(int i = count - 1; i >= 0; i--)
     {
      int highestVal   = iHighest(Symbol(), Period(), MODE_HIGH, periodInp, i);
      int lowestVal    = iLowest(Symbol(), Period(), MODE_LOW, periodInp, i);
      upBuffer[i]   = (periodInp - (highestVal - i)) * 100 / periodInp;
      downBuffer[i] = (periodInp - (lowestVal - i)) * 100 / periodInp;
     }
   return (rates_total);
  }
//+------------------------------------------------------------------+

このコードをコンパイルした後、カスタム指標をチャートに挿入すると、以下のグラフのようになります。

 Aroon ind

カスタム指標を作成し、取引戦略を構築する準備が整いました。そこで、まずアルーンクロスオーバーから始め、次にアルーンレベルに移りますが、その前に、アルーンレベルのアップ値とダウン値を表示できる簡単なプログラムを作成します。

まず、グローバルスコープで、inputキーワードを使用して、periodとshiftの2つのユーザー入力を作成します。

input int         periodInp = 25; // Period
input int         shiftInp  = 0; // Shift

後で指標ハンドルを割り当てるために、アルーン用の整数変数を宣言します。

int aroon;

OnInit()では、作成したアルーンカスタム指標のハンドルをEAにアタッチするまたは戻すiCustom関数を代入します。パラメータは次の通りです。

  • symbol:銘柄(現在の銘柄は_Symbol)
  • period:期間(現在の期間は_Period)
  • name:カスタム指標の正確な名前と、Indicatorsフォルダ内の正確なディレクトリとパス
  • ...次に、カスタム指標の入力パラメータのリストを指定します。ここでは、作成した2つの入力(期間とシフト)のみを使用します。
aroon = iCustom(_Symbol,PERIOD_CURRENT,"Aroon",periodInp,shiftInp);

そして、EAの初期化に成功したら(INIT_SUCCEEDED)を返します。

return(INIT_SUCCEEDED);

OnDeinitでは、実行中のMQL5プログラムを初期化解除するDeinitイベントが発生したときに、Print関数を使用して「EA is removed」と表示します。

void OnDeinit(const int reason)
  {
   Print("EA is removed");
  }

OnTick()イベントでは、upBufferとdownBufferの2つのdouble配列を宣言します。

double upBuffer[], downBuffer[];

CopyBuffer関数を使用して、アルーン指標の作成されたバッファデータを取得します。CopyBuffer関数は、最初の位置と必要な要素数で呼び出すことができ、そのパラメータは次のとおりです。

  • indicator_handle:アルーンカスタム指標のハンドル
  • buffer_num:指標のバッファ番号
  • start_pos:カウント開始位置
  • count:start_posからのカウント量
  • buffer[]:対象の配列
   CopyBuffer(aroon,0,0,3,upBuffer);
   CopyBuffer(aroon,1,0,3,downBuffer);

ArraySetAsSeriesを使用して、AS_SERIESフラグを指定された値に設定します。これは、配列のインデックス付けの順序を逆にする場合にtrueになります。

   ArraySetAsSeries(upBuffer,true);
   ArraySetAsSeries(downBuffer,true);

upValueとdownValueの2つのdouble変数を宣言し、配列の[0]インデックスからからアルーン指標の現在値を代入します。

   double upValue = upBuffer[0];
   double downValue = downBuffer[0];

Comment関数を使用して、チャートにアルーン指標の上下値でコメントを出力します。

Comment("upValue: ",upValue,"\ndownValue: ",downValue);

以下は、完全なコードブロックです。

//+------------------------------------------------------------------+
//|                                                AroonValuesEA.mq5 |
//+------------------------------------------------------------------+
input int         periodInp = 25; // Period
input int         shiftInp  = 0; // Shift
int aroon;
int OnInit()
  {
   aroon = iCustom(_Symbol,PERIOD_CURRENT,"Aroon",periodInp,shiftInp);
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   Print("EA is removed");
  }
void OnTick()
  {
   double upBuffer[], downBuffer[];
   CopyBuffer(aroon,0,0,3,upBuffer);
   CopyBuffer(aroon,1,0,3,downBuffer);
   ArraySetAsSeries(upBuffer,true);
   ArraySetAsSeries(downBuffer,true);
   double upValue = upBuffer[0];
   double downValue = downBuffer[0];
   Comment("upValue: ",upValue,"\ndownValue: ",downValue);
  }
//+------------------------------------------------------------------+

エラーなしでコードをコンパイルし、チャート上でEAを実行すると、以下の例のような出力が得られます。

アルーン値

前のチャートでわかるように、アップ値(upValue)とダウン値(downValue)がコメントとして表示されています。また、作成済みカスタム指標がチャートに挿入され、EAが同じ指標値(96 48)を返すこともわかります。

アルーンクロスオーバー戦略

次に、ここで紹介した取引戦略をコードします。まずはアルーンクロスオーバー戦略から始めましょう。

グローバルスコープでは、#includeプリプロセッサを使用してEAに取引関数をインクルードし、戦略に基づいて自動的に注文を発注します。

#include <trade/trade.mqh>

period、horizontalshift、lotSize、slLvl、tpLvlの5つの入力を作成し、それぞれにデフォルト値を割り当てます。

input int         periodInp = 25; // Period
input int         shiftInp  = 0; // Shift
input double      lotSize=1;
input double      slLvl=200;
input double      tpLvl=600;

以下の変数を作成します。

  • aroon:後に指標定義に使用する整数
  • barstotal:各バーの新規注文を制限するために使用する整数
  • trade:発注に使用するCTradeオブジェクト
int aroon;
int barsTotal;
CTrade trade;

OnInit()イベントで、銘柄と期間の履歴内で利用可能なバーを返すiBars関数を使用して、宣言されたbarsTotal変数を定義します。

barsTotal=iBars(_Symbol,PERIOD_CURRENT);

iCustomを使用してaroon変数を定義し、作成したアルーンカスタム指標を含めます。

aroon = iCustom(_Symbol,PERIOD_CURRENT,"Aroon",periodInp,shiftInp);

OnDeinit()イベントで、EAが削除されたことを表示します。

Print("EA is removed");

OnTick()イベントで、ティックごとのバー番号を格納する整数型のbar変数を宣言します。

int bars=iBars(_Symbol,PERIOD_CURRENT);

barsTotalがbarsと等しくないことを確認します。

if(barsTotal != bars)

次に、barsTotalをbarsバッファで更新します。

barsTotal=bars;

アップとダウンの2つのdouble配列を宣言し、指標のバッファのデータを取得し、選択された配列にAS_SERIESフラグを設定し、前と現在のアップ値とダウン値のための4つのdouble変数を宣言し定義します。

      double upBuffer[], downBuffer[];
      CopyBuffer(aroon,0,0,3,upBuffer);
      CopyBuffer(aroon,1,0,3,downBuffer);
      ArraySetAsSeries(upBuffer,true);
      ArraySetAsSeries(downBuffer,true);
      double prevUpValue = upBuffer[1];
      double prevDownValue = downBuffer[1];
      double upValue = upBuffer[0];
      double downValue = downBuffer[0];

そして、prevUpValueがprevDownValueより小さく、同時にupValueがdownValueより大きいという、買い注文の条件を設定します。

if(prevUpValue<prevDownValue && upValue>downValue)

この条件が満たされた場合、double型のask変数を宣言して現在の銘柄のask価格と定義し、double型のslValとtpValを宣言し定義し、現在の銘柄で、現在のask価格で、ユーザーによって事前に定義されたlotSizeで買いポジションを建てます。損切りは同じ事前定義されたslValとなり、利食いは同じ事前定義されたtpValとなります。

         double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         double slVal=ask - slLvl*_Point;
         double tpVal=ask + tpLvl*_Point;
         trade.Buy(lotSize,_Symbol,ask,slVal,tpVal);

そして、prevUpValueがprevDownValueより大きく、同時にupValueがdownValueより小さいという売り注文の条件を設定します。

if(prevUpValue>prevDownValue && upValue<downValue)
この条件が満たされた場合、double型のbid変数を宣言し、それを現在の銘柄の現在のbid価格と定義し、double型のslValとtpValを宣言して定義し、現在の銘柄で、現在のbid価格で、ユーザーによって事前に定義されたlotSizeで売りポジションを建てます。損切りは同じ事前定義されたslValになり、利食いは同じ事前定義されたtpValになります。
         double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         double slVal=bid + slLvl*_Point;
         double tpVal=bid - tpLvl*_Point;
         trade.Sell(lotSize,_Symbol,bid,slVal,tpVal);

以下は、アルーンのクロスオーバー戦略の完全なコードブロックです。

//+------------------------------------------------------------------+
//|                                             AroonCrossoverEA.mq5 |
//+------------------------------------------------------------------+
#include <trade/trade.mqh>
input int         periodInp = 25; // Period
input int         shiftInp  = 0; // Shift
input double      lotSize=1;
input double      slLvl=200;
input double      tpLvl=600;
int aroon;
int barsTotal;
CTrade trade;
int OnInit()
  {
   barsTotal=iBars(_Symbol,PERIOD_CURRENT);
   aroon = iCustom(_Symbol,PERIOD_CURRENT,"Aroon",periodInp,shiftInp);
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   Print("EA is removed");
  }
void OnTick()
  {
   int bars=iBars(_Symbol,PERIOD_CURRENT);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      double upBuffer[], downBuffer[];
      CopyBuffer(aroon,0,0,3,upBuffer);
      CopyBuffer(aroon,1,0,3,downBuffer);
      ArraySetAsSeries(upBuffer,true);
      ArraySetAsSeries(downBuffer,true);
      double prevUpValue = upBuffer[1];
      double prevDownValue = downBuffer[1];
      double upValue = upBuffer[0];
      double downValue = downBuffer[0];
      if(prevUpValue<prevDownValue && upValue>downValue)
        {
         double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         double slVal=ask - slLvl*_Point;
         double tpVal=ask + tpLvl*_Point;
         trade.Buy(lotSize,_Symbol,ask,slVal,tpVal);
        }
      if(prevUpValue>prevDownValue && upValue<downValue)
        {
         double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         double slVal=bid + slLvl*_Point;
         double tpVal=bid - tpLvl*_Point;
         trade.Sell(lotSize,_Symbol,bid,slVal,tpVal);
        }
     }
  }
//+------------------------------------------------------------------+

このコードをエラーなしでコンパイルすると、以下のような、戦略に基づく注文のサンプルを見ることができます。

買い注文の例

買い取引

上の例でわかるように、アップラインがダウンラインとクロスオーバーした後に買い注文を出します。

売り注文の例

売り取引

上の例でわかるように、ダウンラインがアップラインとクロスオーバーした後に売り注文を出します。

アルーンレベル戦略

このセクションでは、アルーン戦略で紹介したアルーンレベル戦略をコードします。この戦略では、EAはアルーン指標自体の10レベルと50レベルのダウンラインのクロスオーバーに基づいて注文を出します。これをMQL5でコードする方法を以下に示します。これは、アルーンクロスオーバーでコードしたものと同じですが、若干の違いがあるため、このコードと以前のアルーンクロスオーバー戦略のコードとの違いについてのみ言及します。全コードを提供します。

以下は、アルーンレベル戦略の完全なコードブロックです。

//+------------------------------------------------------------------+
//|                                                AroonLevelsEA.mq5 |
//+------------------------------------------------------------------+
#include <trade/trade.mqh>
input int         periodInp = 25; // Period
input int         shiftInp  = 0; // Shift
input double      lotSize=1;
input double      slLvl=200;
input double      tpLvl=600;
int aroon;
int barsTotal;
CTrade trade;
int OnInit()
  {
   barsTotal=iBars(_Symbol,PERIOD_CURRENT);
   aroon = iCustom(_Symbol,PERIOD_CURRENT,"Aroon",periodInp,shiftInp);
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   Print("EA is removed");
  }
void OnTick()
  {
   int bars=iBars(_Symbol,PERIOD_CURRENT);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      double upBuffer[], downBuffer[];
      CopyBuffer(aroon,0,0,3,upBuffer);
      CopyBuffer(aroon,1,0,3,downBuffer);
      ArraySetAsSeries(upBuffer,true);
      ArraySetAsSeries(downBuffer,true);
      double prevDownValue = downBuffer[1];
      double downValue = downBuffer[0];
      if(prevDownValue> 10 && downValue<10)
        {
         double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         double slVal=ask - slLvl*_Point;
         double tpVal=ask + tpLvl*_Point;
         trade.Buy(lotSize,_Symbol,ask,slVal,tpVal);
        }
      if(prevDownValue < 50 && downValue>50)
        {
         double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         double slVal=bid + slLvl*_Point;
         double tpVal=bid - tpLvl*_Point;
         trade.Sell(lotSize,_Symbol,bid,slVal,tpVal);
        }
     }
  }

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

前の値と現在の値を定義するだけでいい。

      double prevDownValue = downBuffer[1];
      double downValue = downBuffer[0];

戦略の条件:prevDownValueが10レベルより大きく、同時に現在のdownValueが10レベルより小さい場合、ask、損切り、利食いを定義した後、EAが買い注文を出す必要があります。

      if(prevDownValue> 10 && downValue<10)
        {
         double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         double slVal=ask - slLvl*_Point;
         double tpVal=ask + tpLvl*_Point;
         trade.Buy(lotSize,_Symbol,ask,slVal,tpVal);
        }

prevDownValueが50レベルより小さく、同時に現在のdownValueが50レベルより大きい場合、現在のbid、損切り、利食いを定義した後、EAが売り注文を出す必要があります。

      if(prevDownValue < 50 && downValue>50)
        {
         double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         double slVal=bid + slLvl*_Point;
         double tpVal=bid - tpLvl*_Point;
         trade.Sell(lotSize,_Symbol,bid,slVal,tpVal);
        }

エラーなしでこのコードをコンパイルした後、以下の例のように、EAが注文を出せることがわかります。

買い注文の例

買い取引

売り注文の例

売り取引


アルーン取引システムのテスト

このセクションでは、各戦略をテストしてその結果を確認します。より良い結果を得るためには、これらの戦略に対してさらなる最適化が必要かもしれないことは、いくら確認しても十分ではありません。そのため、何がご自分のやり方に合っているのか、何がより貴重になるのかを確認するために下調べをする必要があります。 

両者を比較するために、以下の主要な測定に焦点を当てます。

  • 純利益:売上総利益から売上総損失を差し引くことで算出。高いほど良い
  • バランスDD(相対):  取引中に口座が経験する最大損失額。低いほど良い
  • プロフィットファクター:  売上総利益と売上総損失の比率。高いほど良い
  • 期待損益:  取引の平均的な利益または損失。高いほど良い
  • リカバリーファクター:  テストされた戦略が損失を経験した後にどの程度回復するかの測定。 高いほど良い
  • シャープレシオ: リスクフリーリターンとリターンを比較することで、テストされた取引システムのリスクと安定性を判断する。 高いほど良い

また、両戦略をテストする際には同じ期間(期間は2023年1月1日から2023年12月31日までの1年間)を使用します。15分と1時間の2つの時間枠をテストします。

アルーンクロスオーバー戦略

ここからは、先に述べた数値から注目する点を踏まえ、15分足と1時間足の2つの時間軸で、アルーンクロスオーバー戦略の結果を見ていきたいと思います。

15分足でのテスト

以下のグラフが結果です。

テスト結果15m

テスト結果3-15m

テスト結果2-15m

これまでの結果を踏まえ、今回のテストでは以下のような数字が出ました。

  • 純利益:14791
  • バランスDD(相対):6.78%
  • プロフィットファクター:1.17
  • 期待損益:24.53
  • リカバリーファクター:1.91
  • シャープレシオ:2.23

1時間足でのテスト

以下のグラフが結果です。

結果1hbr>.

テスト結果3-1時間

試験結果2-1時間

これまでの結果を踏まえ、今回のテストでは以下のような数字が出ました。

  • 純利益: 6242.20
  • バランスDD(相対): 1.80%
  • プロフィットファクター:1.39
  • 期待損益: 53.81
  • リカバリーファクター: 2.43
  • シャープレシオ: 3.23

アルーンレベル戦略

このセクションでは、同じ概念に基づいて、同じ戦略を15分足と1時間足の2つの時間枠でテストし、2つの時間枠で同じ数値を比較します。

15分足でのテスト

以下のグラフはテスト結果です。

テスト結果15m

テスト結果3-15m

テスト結果2-15m

これまでの結果を踏まえ、今回のテストでは以下のような数字が出ました。

  • 純利益: 42417.30
  • バランスDD(相対): 12.91%
  • プロフィットファクター:1.21
  • 期待損益: 29.62
  • リカバリーファクター: 2.27
  • シャープレシオ: 1.88

1時間足でのテスト

以下のグラフはテスト結果です。

テスト結果1時間

テスト結果3-1時間

試験結果2-1時間

これまでの結果を踏まえ、今回のテストでは以下のような数字が出ました。

  • 純利益: 16001.10
  • バランスDD(相対): 5.11%
  • プロフィットファクター:1.30
  • 期待損益: 41.89
  • リカバリーファクター: 2.68
  • シャープレシオ:2.61

以下の図は、比較しやすいようにすべての結果を一箇所にまとめたものです。

数字

以上のことから、テストされた戦略と同じ時間枠に対応する最適な数字は次の通りです。

  • 純利益:  最も高い数値(42417.30 USD)は、15分足でテストした場合のアルーンレベル戦略で示されています。
  • バランスDD(相対): 最も低い数値(1.80%)は、1時間足でテストした場合のアルーンクロスオーバー戦略で示されています。
  • プロフィットファクター: 最も高い数値(1.39)は、1時間足でテストした場合のアルーンクロスオーバー戦略で示されています。
  • 期待損益: より高い数値(53.81)は、1時間足でテストした場合のアルーンクロスオーバー戦略で示されています。
  • リカバリーファクター: より高い数値(2.68)は、1時間足でテストした場合のアルーンレベル戦略で示されています。
  • シャープレシオ: より高い数値(3.23)は、1時間足でテストした場合のアルーンクロスオーバー戦略で示されています。

これまでの数字を使えば、取引目的に基づいて適切な戦略を選択し、どの数字がその目的を達成できるかを考えることができます。


結論

取引システムの構築とテストは、取引に真剣に取り組むトレーダーにとって極めて重要な作業です。この記事では、単独で、あるいは他のツールと組み合わせて、どのような取引システムにも使用できるアルーン指標のアイデアを提供しました。読者の取引に役立つこともあれば、優れた取引システムを構築するためのヒントを読者に与えることもあるでしょう。

アルーン指標の詳細、その主な概念に基づく使用方法、および計算方法を明らかにしました。使用できるシンプルな戦略を2つ特定しました。

  • アルーンクロスオーバー戦略:アルーンアップラインがアールーンダウンラインを上回ったら買いポジションを、アールーンダウンラインがアールーンアップラインを上回ったら売りポジションを自動的に建てます。
  • アルーンレベル戦略:アルーンダウンが指標の10レベルを下回った場合に買いポジションを、アルーンダウンが指標の50レベルを上回った場合に売りポジションを自動的に建てます。

MQL5でアルーンカスタム指標を作成し、指標をチャートに挿入することでチャート上にアルーンアップとアルーンダウンの値を生成できる簡単なプログラムをコードした後で、それぞれのEAを作成することでこれらの戦略をコードし、それらをテストして特定しました。重要な数値は、15分と1時間の2つの時間枠で各戦略をテストした結果に基づいています。これらは、取引目的と各戦略の結果に基づいて使い分けることができます。

また、これらの戦略でより良い結果を得るためには、より多くの最適化と努力が必要であることを理解する必要があります。この記事の主な目的は、より良い取引システムを構築または開発するために目を開くようなさまざまな取引システムに関するいくつかのアイデアを共有することによって、何が可能なのかを共有することです。

もし、この記事に興味を持たれ、様々な戦略や様々なテクニカル指標に基づいた取引システムの構築についてもっとお読みになりたい場合、私の過去の記事をご覧ください。私のパブリケーションページでも、最も人気のあるテクニカル指標に関する多くの記事をご覧になれます。

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

添付されたファイル |
Aroon.mq5 (3.04 KB)
AroonValuesEA.mq5 (0.91 KB)
AroonLevelsEA.mq5 (1.63 KB)
ケルトナーチャネル取引システムの構築とテスト ケルトナーチャネル取引システムの構築とテスト
この記事では、金融市場において非常に重要な概念であるボラティリティを利用した取引システムを紹介します。ケルトナーチャネル指標を理解し、それをどのようにコードし、どのように簡単な取引戦略に基づいて取引システムを作成し、様々な資産でテストすることができるかを理解した上で、ケルトナーチャネル指標に基づく取引システムを提供します。
PythonとMetaTrader5 Pythonパッケージを使用した深層学習による予測と注文とONNXモデルファイル PythonとMetaTrader5 Pythonパッケージを使用した深層学習による予測と注文とONNXモデルファイル
このプロジェクトでは、金融市場における深層学習に基づく予測にPythonを使用します。平均絶対誤差(MAE)、平均二乗誤差(MSE)、R二乗(R2)などの主要なメトリクスを使用してモデルのパフォーマンスをテストする複雑さを探求し、すべてを実行ファイルにまとめる方法を学びます。また、そのEAでONNXモデルファイルを作成します。
MQL5を使ったシンプルな多通貨エキスパートアドバイザーの作り方(第6回):互いのラインを交差する2つのRSI指標 MQL5を使ったシンプルな多通貨エキスパートアドバイザーの作り方(第6回):互いのラインを交差する2つのRSI指標
この記事の多通貨EAは、クロスラインを持つ2つのRSI指標、低速RSIと交差する高速RSIを使用するEA(自動売買ロボット)です。
MetaTrader 5用のMQTTクライアントの開発:TDDアプローチ(第5回) MetaTrader 5用のMQTTクライアントの開発:TDDアプローチ(第5回)
この記事は、MQTT 5.0プロトコルのネイティブMQL5クライアントの開発ステップを説明する連載の第5回です。今回は、PUBLISHパケットの構造、Publishフラグの設定方法、Topic Name文字列のエンコード方法、必要な場合のPacket Identifierの設定方法について説明します。