
プライスアクション分析ツールキットの開発(第8回):Metrics Board
内容
はじめに
本連載の初期には、「Analytics Master」という記事を公開し、前日の市場指標を取得して視覚化する手法を取り上げました。この基礎的な取り組みが、より高度なツール開発への土台となりました。今回ご紹介するのは、MetaTrader 5上での市場分析を革新する、革新的かつ高品質なソリューション「Metrics Board EA」です。このツールは、MetaTrader 5へシームレスに統合され、直感的でシンプルなインターフェイスに専用の分析ボタンが配置されたアプリケーションとして機能します。以下のような高度な分析をワンクリックで実行可能です。
- 高値・安値分析:重要な価格帯を瞬時に特定し、市場のトレンドや潜在的な反転ポイントを把握します。
- ボリューム分析:取引量を可視化し、市場の参加度や流動性の状態を評価します。
- トレンド分析:正確な数値指標を用いて、価格の方向性とその持続力を判断します。
- ボラティリティ分析:市場の変動性を定量的に測定し、異なる相場環境に応じた戦略立案を支援します。
- 移動平均分析:価格の動的な推移を追跡し、市場の全体的な流れを把握します。
- サポート・レジスタンス分析:エントリーやエグジット、リスク管理において鍵となる価格帯を特定します。
各ボタンをクリックするだけで、リアルタイムのデータが即座に表示され、複雑な市場情報が一瞬で実用的な知見に変わります。Metrics Board EAには高度なアルゴリズムが搭載されており、プロフェッショナルトレーダーの要求に応える高速かつ高精度な演算処理を実現しています。 このツールを活用することで、トレーダーは複雑な市場データをシンプルかつ明確な知見へと変換し、戦略を洗練し、意思決定を迅速化することができます。Metrics Board EAは、取引戦略の精度と効率性を追求するすべてのトレーダーにとって、欠かせないリソースとなるでしょう。
システムの概要
このセクションでは、システムロジックの概要を簡潔に説明します。手順の詳細な解説は「コードの分解と実装」セクションを参照してください。以下の手順に沿ってシステムが動作します。
- クラスの設定:このクラスは、各種分析用ボタンを備えたダイアログを生成します。
- イベント処理:各ボタンのクリックにより、それぞれの分析メソッドが実行されます。
- 分析と表示:市場データが処理され、分析結果がパネルに表示されます。
- 終了処理:「閉じる」ボタンにより、メトリックボードを閉じることができます。
図1:EAロジックの概要
MQL5コード
//+------------------------------------------------------------------+ //| Metrics Board.mql5| //| Copyright 2025, Christian Benjamin| //| https://www.mql5.com| //+------------------------------------------------------------------+ #property copyright "2025, MetaQuotes Software Corp." #property link "https://www.mql5.com/ja/users/lynnchris" #property version "1.0" #property strict #include <Trade\Trade.mqh> #include <Controls\Dialog.mqh> #include <Controls\Button.mqh> #include <Controls\Label.mqh> #include <Controls\Panel.mqh> // Metrics Board Class class CMetricsBoard : public CAppDialog { private: CButton m_btnClose; // Close Button CButton m_btnHighLowAnalysis; CButton m_btnVolumeAnalysis; CButton m_btnTrendAnalysis; CButton m_btnVolatilityAnalysis; CButton m_btnMovingAverage; CButton m_btnSupportResistance; CPanel m_panelResults; CLabel m_lblResults; public: CMetricsBoard(void); ~CMetricsBoard(void); virtual bool Create(const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2); virtual void Minimize(); virtual bool Run(); // Declaration of Run method virtual bool OnEvent(const int id, const long &lparam, const double &dparam, const string &sparam); virtual bool ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam); virtual void Destroy(const int reason = REASON_PROGRAM); // Override Destroy method private: bool CreateButtons(void); bool CreateResultsPanel(void); void OnClickButtonClose(); // New close button handler void PerformHighLowAnalysis(void); void PerformVolumeAnalysis(void); void PerformTrendAnalysis(void); void PerformVolatilityAnalysis(void); void PerformMovingAverageAnalysis(void); void PerformSupportResistanceAnalysis(void); double CalculateMovingAverage(int period); }; CMetricsBoard::CMetricsBoard(void) {} CMetricsBoard::~CMetricsBoard(void) {} // Override Destroy method void CMetricsBoard::Destroy(const int reason) { // Call base class Destroy method to release resources CAppDialog::Destroy(reason); } //+------------------------------------------------------------------+ //| Create a control dialog | //+------------------------------------------------------------------+ bool CMetricsBoard::Create(const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2) { if(!CAppDialog::Create(chart, name, subwin, x1, y1, x2, y2)) { Print("Failed to create CAppDialog instance."); return false; // Failed to create the dialog } if(!CreateResultsPanel()) { Print("Failed to create results panel."); return false; // Failed to create the results panel } if(!CreateButtons()) { Print("Failed to create buttons."); return false; // Failed to create buttons } Show(); // Show the dialog after creation return true; // Successfully created the dialog } //+------------------------------------------------------------------+ //| Minimize the control window | //+------------------------------------------------------------------+ void CMetricsBoard::Minimize() { CAppDialog::Minimize(); } //+------------------------------------------------------------------+ //| Run the control. | //+------------------------------------------------------------------+ bool CMetricsBoard::Run() { // Assuming Run makes the dialog functional if(!Show()) { Print("Failed to show the control."); return false; // Could not show the control } // Additional initialization or starting logic can be added here return true; // Successfully run the control } //+------------------------------------------------------------------+ //| Create the results panel | //+------------------------------------------------------------------+ bool CMetricsBoard::CreateResultsPanel(void) { if(!m_panelResults.Create(0, "ResultsPanel", 0, 10, 10, 330, 60)) return false; m_panelResults.Color(clrLightGray); Add(m_panelResults); if(!m_lblResults.Create(0, "ResultsLabel", 0, 15, 15, 315, 30)) return false; m_lblResults.Text("Results will be displayed here."); m_lblResults.Color(clrBlack); m_lblResults.FontSize(12); Add(m_lblResults); return true; } //+------------------------------------------------------------------+ //| Create buttons for the panel | //+------------------------------------------------------------------+ bool CMetricsBoard::CreateButtons(void) { int x = 20; int y = 80; int buttonWidth = 300; int buttonHeight = 30; int spacing = 15; // Create Close Button if(!m_btnClose.Create(0, "CloseButton", 0, x, y, x + buttonWidth, y + buttonHeight)) return false; m_btnClose.Text("Close Panel"); Add(m_btnClose); y += buttonHeight + spacing; struct ButtonData { CButton *button; string name; string text; }; ButtonData buttons[] = { {&m_btnHighLowAnalysis, "HighLowButton", "High/Low Analysis"}, {&m_btnVolumeAnalysis, "VolumeButton", "Volume Analysis"}, {&m_btnTrendAnalysis, "TrendButton", "Trend Analysis"}, {&m_btnVolatilityAnalysis, "VolatilityButton", "Volatility Analysis"}, {&m_btnMovingAverage, "MovingAverageButton", "Moving Average"}, {&m_btnSupportResistance, "SupportResistanceButton", "Support/Resistance"} }; for(int i = 0; i < ArraySize(buttons); i++) { if(!buttons[i].button.Create(0, buttons[i].name, 0, x, y, x + buttonWidth, y + buttonHeight)) return false; buttons[i].button.Text(buttons[i].text); Add(buttons[i].button); y += buttonHeight + spacing; } return true; } //+------------------------------------------------------------------+ //| Handle events for button clicks | //+------------------------------------------------------------------+ bool CMetricsBoard::OnEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id == CHARTEVENT_OBJECT_CLICK) { Print("Event ID: ", id, ", Event parameter (sparam): ", sparam); if(sparam == "CloseButton") // Handle close button click { OnClickButtonClose(); // Call to new close button handler return true; // Event processed } else if(sparam == "HighLowButton") { Print("High/Low Analysis Button Clicked"); m_lblResults.Text("Performing High/Low Analysis..."); PerformHighLowAnalysis(); return true; // Event processed } else if(sparam == "VolumeButton") { Print("Volume Analysis Button Clicked"); m_lblResults.Text("Performing Volume Analysis..."); PerformVolumeAnalysis(); return true; // Event processed } else if(sparam == "TrendButton") { Print("Trend Analysis Button Clicked"); m_lblResults.Text("Performing Trend Analysis..."); PerformTrendAnalysis(); return true; // Event processed } else if(sparam == "VolatilityButton") { Print("Volatility Analysis Button Clicked"); m_lblResults.Text("Performing Volatility Analysis..."); PerformVolatilityAnalysis(); return true; // Event processed } else if(sparam == "MovingAverageButton") { Print("Moving Average Analysis Button Clicked"); m_lblResults.Text("Calculating Moving Average..."); PerformMovingAverageAnalysis(); return true; // Event processed } else if(sparam == "SupportResistanceButton") { Print("Support/Resistance Analysis Button Clicked"); m_lblResults.Text("Calculating Support/Resistance..."); PerformSupportResistanceAnalysis(); return true; // Event processed } } return false; // If we reach here, the event was not processed } //+------------------------------------------------------------------+ //| Handle chart events | //+------------------------------------------------------------------+ bool CMetricsBoard::ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { Print("ChartEvent ID: ", id, ", lparam: ", lparam, ", dparam: ", dparam, ", sparam: ", sparam); if(id == CHARTEVENT_OBJECT_CLICK) { return OnEvent(id, lparam, dparam, sparam); } return false; } //+------------------------------------------------------------------+ //| Analysis operations | //+------------------------------------------------------------------+ void CMetricsBoard::PerformHighLowAnalysis(void) { double high = iHigh(Symbol(), PERIOD_H1, 0); double low = iLow(Symbol(), PERIOD_H1, 0); Print("Retrieved High: ", high, ", Low: ", low); if(high == 0 || low == 0) { m_lblResults.Text("Failed to retrieve high/low values."); return; } string result = StringFormat("High: %.5f, Low: %.5f", high, low); m_lblResults.Text(result); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMetricsBoard::PerformVolumeAnalysis(void) { double volume = iVolume(Symbol(), PERIOD_H1, 0); Print("Retrieved Volume: ", volume); if(volume < 0) { m_lblResults.Text("Failed to retrieve volume."); return; } string result = StringFormat("Volume (Last Hour): %.1f", volume); m_lblResults.Text(result); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMetricsBoard::PerformTrendAnalysis(void) { double ma = CalculateMovingAverage(14); Print("Calculated 14-period MA: ", ma); if(ma <= 0) { m_lblResults.Text("Not enough data for moving average calculation."); return; } string result = StringFormat("14-period MA: %.5f", ma); m_lblResults.Text(result); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMetricsBoard::PerformVolatilityAnalysis(void) { int atr_period = 14; int atr_handle = iATR(Symbol(), PERIOD_H1, atr_period); if(atr_handle == INVALID_HANDLE) { m_lblResults.Text("Failed to get ATR handle."); return; } double atr_value[]; if(CopyBuffer(atr_handle, 0, 0, 1, atr_value) < 0) { m_lblResults.Text("Failed to copy ATR value."); IndicatorRelease(atr_handle); return; } string result = StringFormat("ATR (14): %.5f", atr_value[0]); m_lblResults.Text(result); IndicatorRelease(atr_handle); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMetricsBoard::PerformMovingAverageAnalysis(void) { double ma = CalculateMovingAverage(50); Print("Calculated 50-period MA: ", ma); if(ma <= 0) { m_lblResults.Text("Not enough data for moving average calculation."); return; } string result = StringFormat("50-period MA: %.5f", ma); m_lblResults.Text(result); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMetricsBoard::PerformSupportResistanceAnalysis(void) { double support = iLow(Symbol(), PERIOD_H1, 1); double resistance = iHigh(Symbol(), PERIOD_H1, 1); Print("Retrieved Support: ", support, ", Resistance: ", resistance); if(support == 0 || resistance == 0) { m_lblResults.Text("Failed to retrieve support/resistance levels."); return; } string result = StringFormat("Support: %.5f, Resistance: %.5f", support, resistance); m_lblResults.Text(result); } //+------------------------------------------------------------------+ //| Calculate moving average | //+------------------------------------------------------------------+ double CMetricsBoard::CalculateMovingAverage(int period) { if(period <= 0) return 0; double sum = 0.0; int bars = Bars(Symbol(), PERIOD_H1); if(bars < period) { return 0; } for(int i = 0; i < period; i++) { sum += iClose(Symbol(), PERIOD_H1, i); } return sum / period; } // Implementation of OnClickButtonClose void CMetricsBoard::OnClickButtonClose() { Print("Close button clicked. Closing the Metrics Board..."); Destroy(); // This method destroys the panel } CMetricsBoard ExtDialog; //+------------------------------------------------------------------+ //| Initialize the application | //+------------------------------------------------------------------+ int OnInit() { if(!ExtDialog.Create(0, "Metrics Board", 0, 10, 10, 350, 500)) { Print("Failed to create Metrics Board."); return INIT_FAILED; } if(!ExtDialog.Run()) // Call Run to make the dialog functional { Print("Failed to run Metrics Board."); return INIT_FAILED; // Call to Run failed } return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ //| Deinitialize the application | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { ExtDialog.Destroy(reason); // Properly call Destroy method } //+------------------------------------------------------------------+ //| Handle chart events | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { ExtDialog.ChartEvent(id, lparam, dparam, sparam); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+
コードの分解と実装
- ヘッダーとメタデータ
//+------------------------------------------------------------------+ //| Metrics Board.mql5| //| Copyright 2025, Christian Benjamin| //| https://www.mql5.com| //+------------------------------------------------------------------+ #property copyright "2025, MetaQuotes Software Corp." #property link "https://www.mql5.com/ja/users/lynnchris" #property version "1.0" #property strictコメントブロックは、このスクリプトの目的を明示し、著作権表示やクレジットを記載するためのものであり、将来の利用者にとって作者を特定し、適切な帰属を保証する上で重要です。#propertyディレクティブは、スクリプトのさまざまな属性を定義するために使用されます。これには、著作権情報、作者やドキュメントへのリンク、バージョン番号、そしてコンパイル時の潜在的な問題を検出するためのstrictモードの設定が含まれます。
- 必要なライブラリをインクルードする
次に、アプリケーションに必要なライブラリをインクルードします。これらのライブラリは、コーディングを簡素化する定義済みの機能を提供します。
#include <Trade\Trade.mqh> #include <Controls\Dialog.mqh> #include <Controls\Button.mqh> #include <Controls\Label.mqh> #include <Controls\Panel.mqh>
ここでは、取引操作およびユーザーインターフェイス制御に関連するライブラリをインポートしています。たとえば、Trade.mqhは取引関数の実行に不可欠なライブラリであり、Dialog.mqh、Button.mqh、Label.mqh、Panel.mqhは、Metrics Boardのユーザーインターフェイス構成要素を作成・管理するために使用されます。
- クラス定義
class CMetricsBoard : public CAppDialog { private: CButton m_btnClose; CButton m_btnHighLowAnalysis; CButton m_btnVolumeAnalysis; CButton m_btnTrendAnalysis; CButton m_btnVolatilityAnalysis; CButton m_btnMovingAverage; CButton m_btnSupportResistance; CPanel m_panelResults; CLabel m_lblResults;
このクラスにはコンストラクタとデストラクタも含まれています。
public: CMetricsBoard(void); ~CMetricsBoard(void); CMetricsBoard::CMetricsBoard(void) {} CMetricsBoard::~CMetricsBoard(void) {}
コンストラクタはクラスの初期化をおこない、デストラクタは(この場合は空ですが)CMetricsBoardのインスタンスが破棄される際に必要なクリーンアップ処理がおこなわれるよう定義されています。これは、リソースを効率的に管理する上で重要です。
- ダイアログの作成
Createメソッドは、コントロールダイアログ全体を構築する役割を担います。このメソッドでは、まず基底クラス(CAppDialog::Create)を呼び出してダイアログの作成を試みます。もし作成に失敗した場合は、エラーログを出力し、falseを返します。続いて、結果表示用のパネルおよび各種ボタンを作成し、それぞれの処理が正常におこなわれたかを確認します。最後に、すべての手順が成功した場合は、ダイアログを表示し、trueを返します。
bool CMetricsBoard::Create(const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2) { if(!CAppDialog::Create(chart, name, subwin, x1, y1, x2, y2)) { Print("Failed to create CAppDialog instance."); return false; } if(!CreateResultsPanel()) { Print("Failed to create results panel."); return false; } if(!CreateButtons()) { Print("Failed to create buttons."); return false; } Show(); return true; }
ここで、Runダイアログが表示されます。Runメソッドは、このダイアログを機能させるために不可欠な役割を果たします。
bool CMetricsBoard::Run() { if(!Show()) { Print("Failed to show the control."); return false; } return true; }
ここでは、Showメソッドを使用してダイアログを表示します。ダイアログの表示に失敗した場合は、エラーメッセージが出力され、falseが返されます。
- 結果パネルの作成
CreateResultsPanelメソッドは、分析結果を表示するパネルを構築します。 まず結果パネルを作成し、色やサイズなどのプロパティを設定します。続いて、このパネルをダイアログに追加します。さらに、パネル内に結果表示用のラベルを作成し、その外観をカスタマイズしたうえでパネルに追加します。このメソッドは、すべてが正常に作成された場合にtrueを返します。
bool CMetricsBoard::CreateResultsPanel(void) { if(!m_panelResults.Create(0, "ResultsPanel", 0, 10, 10, 330, 60)) return false; m_panelResults.Color(clrLightGray); Add(m_panelResults); if(!m_lblResults.Create(0, "ResultsLabel", 0, 15, 15, 315, 30)) return false; m_lblResults.Text("Results will be displayed here."); m_lblResults.Color(clrBlack); m_lblResults.FontSize(12); Add(m_lblResults); return true; }
- ボタンの作成
CreateButtonsメソッドは、ダイアログ内のインタラクティブなボタンを初期化する役割を担います。
bool CMetricsBoard::CreateButtons(void) { int x = 20; int y = 80; int buttonWidth = 300; int buttonHeight = 30; int spacing = 15; if(!m_btnClose.Create(0, "CloseButton", 0, x, y, x + buttonWidth, y + buttonHeight)) return false; m_btnClose.Text("Close Panel"); Add(m_btnClose); y += buttonHeight + spacing; struct ButtonData { CButton *button; string name; string text; }; ButtonData buttons[] = { {&m_btnHighLowAnalysis, "HighLowButton", "High/Low Analysis"}, {&m_btnVolumeAnalysis, "VolumeButton", "Volume Analysis"}, {&m_btnTrendAnalysis, "TrendButton", "Trend Analysis"}, {&m_btnVolatilityAnalysis, "VolatilityButton", "Volatility Analysis"}, {&m_btnMovingAverage, "MovingAverageButton", "Moving Average"}, {&m_btnSupportResistance, "SupportResistanceButton", "Support/Resistance"} }; for(int i = 0; i < ArraySize(buttons); i++) { if(!buttons[i].button.Create(0, buttons[i].name, 0, x, y, x + buttonWidth, y + buttonHeight)) return false; buttons[i].button.Text(buttons[i].text); Add(buttons[i].button); y += buttonHeight + spacing; } return true; }
この実装では、ボタンの初期座標、サイズ、間隔を定義します。まず、パネルを閉じるためのボタンを作成し、ダイアログに追加します。次に、ButtonData構造体の配列を用いてボタンの定義を効率的にループ処理します。各ボタンには対応するテキストが設定され、ダイアログに追加されます。すべてのボタンが正常に作成された場合に、メソッドはtrueを返して終了します。
- イベントの処理
1. ボタンクリック
OnEventメソッドは、ボタンクリックなどのユーザー操作によって発生するイベントを処理します。
bool CMetricsBoard::OnEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id == CHARTEVENT_OBJECT_CLICK) { Print("Event ID: ", id, ", Event parameter (sparam): ", sparam); if(sparam == "CloseButton") { OnClickButtonClose(); return true; } // ... Handling for other button clicks } return false; }
イベントが発生した際、まずそれがボタンクリックイベントであるかを確認します。デバッグ目的でイベントの詳細を出力し、特定のボタンがクリックされた場合には対応する処理関数を呼び出します。もしクリックされたボタンが閉じるボタンであれば、OnClickButtonCloseメソッドを実行します。
2. チャートイベント
ChartEventメソッドは同様の役割を持ちますが、チャートに関連するイベントを対象としています。
bool CMetricsBoard::ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { Print("ChartEvent ID: ", id, ", lparam: ", lparam, ", dparam: ", dparam, ", sparam: ", sparam); if(id == CHARTEVENT_OBJECT_CLICK) { return OnEvent(id, lparam, dparam, sparam); } return false; }
このメソッドはチャート上のオブジェクトへのクリックを検知し、そのイベントをOnEventメソッドに渡してさらに処理をおこないます。
- 分析操作
以下のメソッドは、Metrics Boardが実行できるさまざまな市場分析の種類を実装しています。たとえば、PerformHighLowAnalysisメソッドは、指定された期間の高値と安値を取得します。
void CMetricsBoard::PerformHighLowAnalysis(void) { double high = iHigh(Symbol(), PERIOD_H1, 0); double low = iLow(Symbol(), PERIOD_H1, 0); Print("Retrieved High: ", high, ", Low: ", low); if(high == 0 || low == 0) { m_lblResults.Text("Failed to retrieve high/low values."); return; } string result = StringFormat("High: %.5f, Low: %.5f", high, low); m_lblResults.Text(result); }
このメソッドでは、組み込み関数を使って直近1時間の最高値と最安値を取得します。取得に成功した場合は、その結果をラベルに表示し、失敗した場合はエラーメッセージを表示します。
同様のロジックが、PerformVolumeAnalysis、PerformTrendAnalysis、PerformVolatilityAnalysis、PerformMovingAverageAnalysis、PerformSupportResistanceAnalysisといった他の分析関数にも適用されます。各メソッドは、分析タイプに固有のデータを取得し、それに応じてユーザーインターフェイスを更新します。
- 移動平均を計算する
ユーティリティメソッドの一つに、指定された期間の移動平均を計算するCalculateMovingAverageがあります。 このメソッドは、指定期間の終値を合計し、その期間数で割ることで平均値を算出します。計算をおこなう前に、入力値の妥当性や十分なデータがあるかどうかを確認します。
double CMetricsBoard::CalculateMovingAverage(int period) { if(period <= 0) return 0; double sum = 0.0; int bars = Bars(Symbol(), PERIOD_H1); if(bars < period) { return 0; } for(int i = 0; i < period; i++) { sum += iClose(Symbol(), PERIOD_H1, i); } return sum / period; }
- グローバルインスタンスと初期化
CMetricsBoardクラスのインスタンスがグローバルに生成され、その後、アプリケーションの初期化および終了処理がおこなわれます。
CMetricsBoard ExtDialog; int OnInit() { if(!ExtDialog.Create(0, "Metrics Board", 0, 10, 10, 350, 500)) { Print("Failed to create Metrics Board."); return INIT_FAILED; } if(!ExtDialog.Run()) { Print("Failed to run Metrics Board."); return INIT_FAILED; } return INIT_SUCCEEDED; }
OnInit関数では、Createメソッドを呼び出してMetrics Boardを初期化します。初期化に成功した場合は、続けてRunメソッドを実行します。エラーが発生した場合はログに記録され、関数は成功・失敗の状態を返します。
終了処理では、EAが削除された際にリソースが正しく解放されるようにします。
void OnDeinit(const int reason) { ExtDialog.Destroy(reason); // Properly call Destroy method }
- チャートイベント処理
最後に、チャート関連のイベントを管理するためにOnChartEvent関数を定義します。これにより、ユーザーの操作がアプリケーションの機能に直接統合されます。 このメソッドはチャートイベントを検知し、それをCMetricsBoardインスタンスのChartEventメソッドに渡します。
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { ExtDialog.ChartEvent(id, lparam, dparam, sparam); }
ライブラリをインクルードする
前のセクションで紹介したライブラリを含めずにコードをコンパイルすると、エラーが発生する可能性があります。これを解決するには、MetaEditorを開き、ナビゲータパネルに移動してください。下にスクロールして「Include」セクションを探すと、必要なライブラリにアクセスできます。該当するサブフォルダを開き、関連ファイルを選んで個別にコンパイルします。また、スクリプトの先頭で#includeディレクティブを使って、コード内でライブラリが正しく参照されていることを必ず確認してください。この手順により、すべての依存関係が正しく読み込まれ、コンパイルエラーを防ぐことができます。以下のGIFは、MetaEditorでライブラリにアクセスして組み込む方法を示しています。
図2:ライブラリをインクルードする
MQL5では、インクルードライブラリを使うことで、外部のコードや関数、クラスをプログラムに統合でき、機能を拡張するとともに、さまざまなソースからのコードを再利用できます。ライブラリを組み込むことで、その中で定義されている関数やクラス、変数にアクセス可能となり、スクリプト、エキスパートアドバイザー(EA)、インジケーターなどで利用できるようになります。MQL5のライブラリの多くは組み込み済みで、取引機能やテクニカル指標など、一般的なタスクにすぐに使える便利なソリューションを提供しています。
結果
EAのコンパイルに成功したら、MetaTrader 5を開いてチャートにEAを適用できます。テスト時に得られた結果を確認してみましょう。
図3:結果
上記の図から、Metrics Board EAは各ボタン操作に的確に反応し、最適な機能を提供していることが明らかです。この機能により、EAは必要な指標をリアルタイムで提供し、ユーザーの操作性とパフォーマンスを向上させます。
- EAログ
また、MetaTrader 5のExpertsログを確認することで、押されたボタンとチャート上のイベントの連携を観察できます。本EAにはログ機能が組み込まれているため、これらの操作が記録されています。ログに記録された情報を見て、内容を分析してみましょう。
図4:EAログ
結論
Metrics Board EAは、MetaTrader 5内に直接組み込まれ、描画オブジェクト機能を活用した動的かつユーザーフレンドリーなパネルインターフェイスを備えています。スムーズな統合により、まるでMetaTrader 5のネイティブコントロールを操作しているかのような使い心地を実現し、組み込みアプリケーションに匹敵する操作体験を提供します。私の見解では、本ツールは取引ツールの大きな飛躍を示しており、以前に開発したいくつかの分析スクリプトを凌駕する機能性と使いやすさを兼ね備えています。ユーザーはボタンを一度クリックするだけで必要な情報に絞って表示できるため、分析プロセスが大幅に効率化されます。過去のスクリプトも目的を十分に果たしていましたが、Metrics Board EAは市場分析の効率性とアクセシビリティをさらに一段階引き上げる存在です。
Metrics Board EAの主な機能は次のとおりです。
機能 | 利点 |
---|---|
高値・安値分析 | 素早く重要な市場レベルを特定し、トレーダーを支援します。 |
ボリュームトラッキング | 最新の取引量情報を提供し、市場状況の把握をサポートします。 |
トレンドの特定 | 現在の市場トレンドの把握を簡素化します。 |
サポート・レジスタンスレベル | 戦略的な取引のための重要な価格帯を正確に特定します。 |
このツールはトレーダーが市場を効果的に分析し、より良い判断を下す力を与えます。シンプルな設計により複雑な分析を簡素化し、ユーザーが戦略の改善に集中できるようにします。今後は、新機能の追加やインターフェイスのさらなる改良によって、さらなる機能拡張の可能性があります。
日付 | ツール名 | 詳細 | バージョン | アップデート | 備考 |
---|---|---|---|---|---|
01/10/24 | ChartProjector | 前日のプライスアクションをゴースト効果でオーバーレイするスクリプト | 1.0 | 初回リリース | Lynnchris Tool Chestの最初のツール |
18/11/24 | Analytical Comment | 前日の情報を表形式で提供し、市場の将来の方向性を予測する | 1.0 | 初回リリース | Lynnchris Tool Chestの2番目のツール |
27/11/24 | Analytics Master | 2時間ごとに市場指標を定期的に更新 | 1.01 | v.2 | Lynnchris Tool Chestの3番目のツール |
02/12/24 | Analytics Forecaster | Telegram統合により、2時間ごとに市場指標を定期的に更新 | 1.1 | v.3 | ツール番号4 |
09/12/24 | Volatility Navigator | ボリンジャーバンド、RSI、ATR指標を使用して市場の状況を分析するEA | 1.0 | 初回リリース | ツール番号5 |
19/12/24 | Mean Reversion Signal Reaper | 平均回帰戦略を用いて市場を分析し、シグナルを提供する | 1.0 | 初回リリース | ツール番号6 |
9/01/2025 | Signal Pulse | 多時間枠分析ツール | 1.0 | 初回リリース | ツール番号7 |
17/01/2025 | Metrics Board | 分析用のボタン付きパネル | 1.0 | 初回リリース | ツール番号8 |
MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/16584





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