English Русский 中文 Español Deutsch Português 한국어 Français Italiano Türkçe
preview
単一チャート上の複数インジケータ(第04部): エキスパートアドバイザーに進む

単一チャート上の複数インジケータ(第04部): エキスパートアドバイザーに進む

MetaTrader 5トレーディング | 20 5月 2022, 15:36
513 0
Daniel Jose
Daniel Jose

はじめに

以前の記事では、複数のサブウィンドウでインジケータを作成する方法を説明しました。これは、カスタムインジケータを使用するときに興味深いものになります。これは非常に簡単にできました。ただし、エキスパートアドバイザーではカスタムインジケータで使用したツールがないため、同じ機能を実装しようとすると少し複雑になります。この時点で、プログラミングが不可欠になります。サブウィンドウを作成するための正しいコードを記述できることが最も重要です。このタスクはそれほど簡単ではありませんが、サブウィンドウをEAに配置する方法を知ることには多くのコーディングは必要ではありません。必要なのはMQL5がどのように機能するかについての知識だけです。


計画

カスタムインジケータはすでに機能しています。つまり、オブジェクトクラスはすでに機能しています。これはオブジェクトクラスであるため、他のモデルに簡単に転送できます。ただし、EAでクラスを宣言して使用しようとしてもカスタムインジケータと同じように機能しません。EAにサブウィンドウ機能がないためです。ただし、その後、「すでにコンパイルされ機能しているカスタムインジケータを使用し、iCustomコマンドを使用してEAから呼び出すとどうなるか」という考えを思いつきました。サブウィンドウは不要で、コマンドは次のようになるため、実際に機能する可能性があります。

#property copyright "Daniel Jose"
//+------------------------------------------------------------------+
input string user01 = "";                //Used indicators
input string user02 = "";                //Assets to follow
//+------------------------------------------------------------------+
int OnInit()
{
        int m_handleSub;

//... Expert Advisor code ...

        if ((m_handleSub = iCustom(NULL, 0, "Chart In SubWindows\\Chart In SubWindow.ex5", user01, user02)) == INVALID_HANDLE) return INIT_FAILED;
        if (!ChartIndicatorAdd(ChartID(), 0, m_handleSub)) return INIT_FAILED;
//... Expert Advisor code ...

        ChartRedraw();
        
        return(INIT_SUCCEEDED);
}
//...The rest of the Expert Advisor code ...

この単純なコードスニペットはカスタムインジケータを読み込むことができますが、サブウィンドウがないため正しく機能しません。この場合、コードがEAで実行されると、EAはメインウィンドウに直接インジケータを適用します。つまり、インジケータによってロードされたテンプレートによってチャートが非表示になります。これは、ここで探しているものではありません。

ここで本当の主な問題は、すでに機能しているインジケータを使用できるように使用できるサブウィンドウを作成することです。しかし、なぜインジケータを後で起動するためのサブウィンドウを作成するのでしょうか。意味がありません。EAに直接機能を追加して、発生する可能性のある制限を克服することをお勧めします。

これに基づいて、いくつかのタスクを実行する必要があります。

タスク 目的
1=>汎用インジケータを作成する チャートを汚染することなく、iCustomコマンドを作成して使用できる
2=>このインジケータを何らかの方法でEAに含める  すべての機能を備えたエキスパートアドバイザーを問題なく転送できるようになる
3=>サブウィンドウの一般的なオブジェクトクラスを生成する  EAを介してサブウィンドウを追加できるようにする
4=>ウィンドウクラスにバインドされたC_TemplateChartクラスを取得する すでに実行中のコードを変更することなく、サブウィンドウのコンテンツを管理できるようになる

難しく見えるかもしれませんが、問題は非常に簡単に解決されます。それぞれのポイントに取り組みましょう。


実装: 汎用インジケータの作成

この部分は、完全にクリーンで機能的なカスタムインジケータコードを作成することで解決できます。この場合のコードは次のようになります。

#property copyright "Daniel Jose"
#property version   "1.00"
#property description "This file only enables support of indicators in SubWin."
#property indicator_chart_window
#property indicator_plots 0
//+------------------------------------------------------------------+
int OnInit()
{
        return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
{
        return rates_total;
}
//+------------------------------------------------------------------+

これだけです。このファイルをSubSupport.mq5として保存しましょう。ただし、他のインジケータと一緒に配置せず、代わりに、エキスパートアドバイザーのRESOURCEディレクトリに移動します。ファイル構造は次の図のようになります。


これにはよい理由がありますが、とりあえず脇に置いて、次のタスクに移りましょう。


実装: EAに一般的な指標を含める

これを行うには、EAの先頭に次のコードを追加する必要があります。

//+------------------------------------------------------------------+
#define def_Resource "Resources\\SubSupport.ex5"
//+------------------------------------------------------------------+
#resource def_Resource
//+------------------------------------------------------------------+

一般的なインジケータのコンパイル済みコードがEAに含まれます。これが行われると、一般的なインジケータの.ex5ファイルが不要になるため、削除されます。ここで、EAコードのコンパイル時にSubSupport.ex5ファイルが見つからない場合、コンパイラはSubSupport. mq5汎用インディケータのコードを自動的にコンパイルして、この新しくコンパイルされた実行可能ファイルをエキスパートアドバイザーに追加することに注意してください。万が一SubSupport.mq5ファイルを編集して変更をエキスパートアドバイザーに追加する必要がある場合は、SubSupport.ex5を削除してください。そうしないと、変更は追加されません。

この詳細は重要です。リソースに新しく実装された変更を追加する方法を本当に知る必要がある場合があります。

さて、汎用インジケータがエキスパートアドバイザーの一部になったので、次のタスクに進みましょう。


実装: サブウィンドウオブジェクトクラスの作成

この部分もシンプルです。ここでは、コーディングする前にいくつかのポイントを定義する必要があります。つまり、このクラスで本当に必要な機能は何かということです。当初、私は以下を使用することにしました。

関数 説明
Init EAを介してサブウィンドウを追加できるようにする
Close EAを介してサブウィンドウを追加できるようにする

これらの関数はテストされないため、EAの存続期間中に一度だけ呼び出されると仮定します。ただし、EAが成長するにつれて、将来的にさらに実用的にすることを検討するのは良いことなので、C_Terminalという新しいオブジェクトクラスを作成しましょう。このクラスは、グラフィカルターミナルに関連するいくつかの機能をサポートします。これについては後で詳しく説明します。解決策を部分的に実装する方法がないため、最後のタスクを見てみましょう。


実装: C_TemplateChartクラスの継承

OOP(オブジェクト指向プログラミング)を使用して新しいものを作成することにしたのは、このアプローチを使用するとセキュリティと継承を含む大きなメリットがあることをすでに知っていたからです。ポリモーフィズムもありますが、これは後で両建て注文システムを作成するときに使用します。この特定の場合、OOPのメリットの1つである継承を使用します。C_TemplateChartはすでに完全に機能するクラスです。これを見れば、すべてを再プログラミングする手間をかけたり、クラスが他の場所で使用できなくなるリスクを冒してクラスにコードを追加したくはなくなるでしょう。解決策は、元のコードをまったく変更せずに新しいコードまたは関数を追加できる継承を使用することです。

継承を使用することには、すでにテストされたコードはテストされたままである、コードサイズを均等に増やさずに複雑さを増す、実際にテストする必要があるのは新機能だけである、変わらないものは単に継承されて安定性が得られるといった多くのメリットがあります。言い換えれば、最小限の労力で物事を改善し、最大限のセキュリティを持つことができます。これを理解するために、下の図を見てみましょう。


祖父母クラスは、データ操作のレベルが最も低い最も基本クラスですが、親クラスが祖父母から何かを継承すると、祖父母クラスでpublicとして宣言されたすべてのものを親クラスが表示して使用できます。また、親クラスに新しいものを追加することもできます。これは、継承され、継承によってサポートされるものには影響しません。親クラスがすでに完成して機能しており、下のクラスで何も変更せずに拡張したい場合は、子クラスを作成します。これにより、前のクラスのすべての機能が利用できるようになります。また、動作方法を変更することもできます。これらの変更は他のクラスに影響を与えないため、継承について興味深いことです。ただし、多重継承を許可するC ++とは異なり、ここには制限があります。子供が父側と母側の両方から機能を継承できる場合、これはMQL5では不可能です。それでも継承の恩恵を受けることができます。多重継承の例を以下に示します。

でも、MQL5でそれを行い、継承を宣言してそれを利用できるようにするにはどうすればよいでしょうか。これを理解する最も正確な方法はオブジェクト指向プログラミング(OOP)コンテンツを読むことですが、ここでは要点を簡単に説明します。継承は次の行を使用して行われます。

#include "C_TemplateChart.mqh"
//+------------------------------------------------------------------+
class C_SubWindow : public C_TemplateChart
{
// ... Class code
};

C_SubWindowクラスがC_TemplateChartクラスをpublicに継承することを確認してください。これで、C_SubWindowを使用して、C_TemplateChartクラスの機能にアクセスできるようになります。

上記のコードスニペットでは、1つのことを強調しました。通常のように、山括弧(<>)ではなくて引用符( ")で囲まれています。なぜでしょうか。C ++言語と同様、MQL5にも非常に興味深いものがいくつかありますが、プログラミングの技術を学び始めたばかりの人を混乱させるものもあります。ヘッダーファイルを山括弧(<>)で囲むと絶対パスが意味されます。この場合、コンパイラは指定したパスを正確にたどります。ただし、(今回のように)引用符を使用すると、コンパイラは相対パスを使用します。わかりやすく言えば、最初に作業ファイルが配置されている現在のディレクトリから開始します。奇妙に思えるかもしれませんが、内容が異なり、異なるディレクトリに同名のファイルがあるかもしれないが現在のディレクトリを参照したいので、引用符を使用します。

前述した、使用予定の2つの関数(INITとCLOSE)を以下に示します。

//+------------------------------------------------------------------+
bool Init(void)
{
        if (m_handleSub != INVALID_HANDLE) return true;
        if ((m_handleSub = iCustom(NULL, 0, "::" + def_Resource)) == INVALID_HANDLE) return false;
        m_IdSub = (int) ChartGetInteger(Terminal.Get_ID(), CHART_WINDOWS_TOTAL);
        if (!ChartIndicatorAdd(Terminal.Get_ID(), m_IdSub, m_handleSub)) return false;
                
        return true;
}
//+------------------------------------------------------------------+
void Close(void)
{
        ClearTemplateChart();
        if (m_handleSub == INVALID_HANDLE) return;
        IndicatorRelease(m_IdSub);
        ChartIndicatorDelete(Terminal.Get_ID(), m_IdSub, ChartIndicatorName(Terminal.Get_ID(), m_IdSub, 0));
        ChartRedraw();
        m_handleSub = INVALID_HANDLE;
}
//+------------------------------------------------------------------+

コードはとてもシンプルで短いです。ただし、注意しなければならないことがあります。強調表示されている部分に注意してください。この部分を追加するときに間違えないように注意してください。そのままにしないと、EAに追加するように要求したSubSupport.ex5実行可能ファイルがEA内に表示されず、EAの外に表示されるためです。詳細については、リソースをご覧ください。ただし、基本的に(::)を使用する場合、これはEAがその内部で使用可能な内部リソースを使用する必要があることを示します。ただし、リソース名だけを指定すると、EAはMQL5ディレクトリ内で検索し、指定した場所にファイルが存在しない場合は、EAリソースとして追加しても機能しなくなります。

次に、リソースが読み込まれたら、存在するサブウィンドウの数を確認し、そのサブウィンドウにインジケータを追加します。

コードが実際に行っていることを以下に示します。

input string user01 = "";               //Used indicators
input string user02 = "";               //Assets to follows
//+------------------------------------------------------------------+
int OnInit()
{
        int m_handleSub;

//...   

        if ((m_handleSub = iCustom(NULL, 0, "Chart In SubWindows\\Chart In SubWindow.ex5", user01, user02)) == INVALID_HANDLE) return INIT_FAILED;
        if (!ChartIndicatorAdd(ChartID(), (int) ChartGetInteger(ChartID(), CHART_WINDOWS_TOTAL), m_handleSub)) return INIT_FAILED;

//...

        ChartRedraw();
        
   return(INIT_SUCCEEDED);
}
//...The rest of the Expert Advisor code ...

どちらのコードも同じように機能しますが、上記のバージョンは統合バージョンであり、変更されないため、オブジェクトクラスバージョンでは、時間の経過とともにさらに多くのものを追加できます。どちらのバージョンも同じことを行います。EAからサブウィンドウを作成し、以前に作成したすべてのカスタムインジケータをこのサブウィンドウに配置します。記事冒頭のコードと比較して、コードに加えられた変更に注意してください。変更は色で強調表示されています。


終わりに

目標を達成するための道をどのようにたどることを決定するかは非常に興味深いです。困難に直面し、目標を達成するのが困難だと思うこともありますが、少しの忍耐と献身で、最初は乗り越えられなかった障害を克服することができます。この記事では、継承を通じて、クラスを変更せずにクラスの機能を拡張する方法を示します。同時に、チャートにインジケータを追加して、すでにテスト済みのように機能させる方法を示します。ex5プログラムをEA内に追加し、EAをロードするだけで元のex5を移植せずに使用できます。

添付ファイルには、れまでに開発されたすべての改善点が含まれていますが、このコードにはすぐに、さらに興味深いものが含まれる予定です。😁👍


MetaQuotes Ltdによりポルトガル語から翻訳されました。
元の記事: https://www.mql5.com/pt/articles/10241

添付されたファイル |
DoEasyライブラリのグラフィックス(第97部): フォームオブジェクトの移動の独立した処理 DoEasyライブラリのグラフィックス(第97部): フォームオブジェクトの移動の独立した処理
本稿では、マウスを使用したフォームオブジェクトの独立したドラッグの実装について検討します。さらに、以前にターミナルとMQL5に実装されたエラーメッセージと新しい取引プロパティをライブラリに追加します。
エキスパートアドバイザーが失敗する理由の分析 エキスパートアドバイザーが失敗する理由の分析
この記事では、通貨データの分析を示して、エキスパートアドバイザーが特定の時間領域で良好なパフォーマンスを示し他の領域でパフォーマンスが低下する理由をよりよく理解します。
ボリンジャーバンドによる取引システムの設計方法を学ぶ ボリンジャーバンドによる取引システムの設計方法を学ぶ
この記事では、取引の世界で最も人気のある指標の1つであるボリンジャーバンドについて学びます。テクニカル分析を検討し、ボリンジャーバンド指標に基づいてアルゴリズム取引システムを設計する方法を確認します。
MQLアプリケーションでのCCanvasクラスの使用 MQLアプリケーションでのCCanvasクラスの使用
この記事では、MQLアプリケーションでのCCanvasクラスの使用について検討します。理論には、CCanvasの基本を完全に理解するための詳細な説明と例が付属しています。