
Разработка инструментария для анализа движения цен (Часть 8): Панель метрик
Содержание
- Введение
- Обзор системы
- Код MQL5
- Разбор и реализация кода
- Подключение библиотек
- Результаты
- Заключение
Введение
На ранних этапах нашей серии мы опубликовали статью под названием "Советник Analytics Master", в которой рассматривались методы извлечения и визуализации рыночных показателей предыдущего дня. Эта основополагающая работа подготовила почву для разработки более сложных инструментов. Мы рады представить вам советник Metrics Board — инновационное и высококачественное решение, которое кардинально меняет подход к анализу рынка в MetaTrader 5. Этот инструмент функционирует как интегрированное приложение, предлагая оптимизированный и простой интерфейс, оснащенный специальными кнопками для расширенного анализа, включая:
- High/Low Analysis (анализ максимумов/минимумов) - легко определяйте критические уровни цен для оценки рыночных трендов и выявления потенциальных разворотов.
- Volume Analysis (анализ объемов) - анализируйте торговые объемы для оценки активности рынка и условий ликвидности.
- Trend Analysis (анализ трендов) - оценивайте направление и устойчивость с помощью точных показателей.
- Volatility Analysis (анализ волатильности) - количественная оценка рыночных колебаний для разработки стратегий, адаптированных к различным торговым условиям.
- Moving Average Analysis (анализ скользящей средней) - отслеживайте динамические ценовые тренды для более четкого понимания поведения рынка.
- Support/Resistance (анализ поддержки/сопротивления) - определяйте ключевые ценовые уровни для оптимизации стратегий входа, выхода и управления рисками.
Каждая кнопка обеспечивает доставку данных в реальном времени простым нажатием, мгновенно преобразуя сложные рыночные данные в полезную информацию. Советник Metrics Board основан на передовых алгоритмах, обеспечивающих высокую скорость и точность вычислений, отвечающих потребностям профессиональных трейдеров. Используя этот инструмент, трейдеры могут преобразовывать сложные рыночные данные в простые и практичные решения. Советник служит ключевым ресурсом для тех, кто стремится усовершенствовать свои торговые стратегии.
Обзор системы
В этом разделе я представлю краткий обзор логики системы. Подробное объяснение шагов представлено в разделе "Разбор и реализация кода". Необходимые шаги:
- Настройка класса: Класс создает диалоговое окно с кнопками для различной аналитики.
- Обработка событий: Нажатия кнопок запускают соответствующие методы анализа.
- Анализ и отображение: Рыночные данные обрабатываются и отображаются на панели.
- Закрытие: Кнопка Close (закрыть) позволяет пользователю закрыть панель метрик.
Рис 1. Логика советника
Код MQL5
//+------------------------------------------------------------------+ //| Metrics Board.mql5| //| Copyright 2025, Christian Benjamin| //| https://www.mql5.com| //+------------------------------------------------------------------+ #property copyright "2025, MetaQuotes Software Corp." #property link "https://www.mql5.com/en/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/en/users/lynnchris" #property version "1.0" #property strictВ блоке комментариев описывается цель скрипта и указываются авторы, что важно для определения авторства и обеспечения правильной атрибуции для будущих пользователей. Директивы #property служат для определения различных характеристик скрипта, таких как информация об авторских правах, ссылка на автора или документацию, номер версии и установка строгого режима, который помогает выявлять потенциальные проблемы во время компиляции.
- Подключение необходимых библиотек
Далее мы подключаем библиотеки, необходимые для нашего приложения. Эти библиотеки предоставляют предопределенные функции, упрощающие кодирование.
#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 используются для создания и управления компонентами пользовательского интерфейса панели метрик.
- Определение класса
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 необходим для работы диалогового окна.
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 для дальнейшей обработки.
- Аналитические операции
Следующие методы реализуют различные типы анализа рынка, которые может выполнять наша панель метрик. Например, 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); }
В этом методе мы используем встроенные функции для извлечения самых высоких и самых низких цен за последний час. В случае успеха результаты отображаются на подписи. В противном случае выводится сообщение об ошибке.
Аналогичная логика применяется к другим функциям анализа, таким как 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. В случае успеха приступаем к запуску. Ошибки регистрируются соответствующим образом, а функция указывает на успех или неудачу.
Деинициализация обеспечивает корректное высвобождение ресурсов при удалении советника.
void OnDeinit(const int reason) { ExtDialog.Destroy(reason); // Properly call Destroy method }
- Обработка событий графика
Наконец, мы определяем функцию OnChartEvent для управления событиями, связанными с графиками. Это позволяет интегрировать взаимодействие пользователя непосредственно в функционал приложения. Метод фиксирует события диаграммы и передает их в метод ChartEvent нашего экземпляра CMetricsBoard.
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 библиотека include позволяет интегрировать внешний код, функции или классы в программу, расширяя ее функциональность и позволяя повторно использовать код из различных источников. Включая библиотеку, вы получаете доступ к функциям, классам или переменным, определенным в ней, что делает их доступными для использования в вашем скрипте, советнике или индикаторе. Большинство библиотек в MQL5 являются встроенными и предоставляют готовые решения для распространенных задач, таких как торговые функции, технические индикаторы и многое другое.
Результаты
После успешной компиляции советника вы можете перейти в MetaTrader 5 и прикрепить советник к графику. Давайте рассмотрим результаты, полученные в ходе тестирования.
Рис. 3. Результаты
В соответствии с представленным выше графиком очевидно, что советник Metrics Board обеспечивает оптимальную функциональность, эффективно реагируя на каждое нажатие кнопки. Советник предоставляет необходимые показатели в реальном времени, улучшая взаимодействие с пользователем и производительность.
- Журналирование
Мы также можем просмотреть вкладку "Эксперты" в MetaTrader 5, чтобы проследить взаимодействие между нажатыми кнопками и событиями на графике. Поскольку наш советник включает в себя встроенную функцию журналирования, он будет фиксировать эти взаимодействия. Давайте посмотрим, какая информация была зафиксирована.
Рис 4. Записи на вкладке "Эксперты"
Заключение
Советник Metrics Board имеет динамичный и удобный интерфейс панели, встроенный непосредственно в MetaTrader 5, включая функцию рисования объектов. Благодаря плавной интеграции создается впечатление работы с собственными элементами управления MetaTrader 5. На мой взгляд, это знаменует собой значительный прогресс в области торговых инструментов, обеспечивая функциональность и простоту использования, превосходящие возможности некоторых аналитических скриптов, разработанных мной ранее. Позволяя пользователям сосредоточиться на определенной информации одним нажатием кнопки, приложение гарантирует отображение только необходимых данных, оптимизируя процесс анализа. Хотя предыдущие скрипты эффективно выполняли свои задачи, советник выводит анализ рынка на более высокий уровень эффективности и доступности.
Ключевые особенности советника включают в себя:
Свойство | Польза |
---|---|
High/Low Analysis | Быстро определяет значимые уровни рынка. |
Volume Tracking | Предоставляет актуальные данные об объеме торгов для лучшего понимания ситуации на рынке. |
Trend Identification | Упрощает процесс распознавания текущих рыночных тенденций. |
Support/Resistance | Точно определяет ключевые ценовые зоны для стратегической торговли. |
Этот инструмент позволяет трейдерам эффективно анализировать рынки и делать более обоснованный выбор. Его простой дизайн упрощает сложную аналитику, позволяя пользователям сосредоточиться на совершенствовании своих стратегий. Возможности сервиса могут быть расширены за счет добавления новых функций и дальнейшего улучшения интерфейса.
Дата | Название инструмента | Описание | Версия | Обновления | Примечания |
---|---|---|---|---|---|
01/10/24 | Chart Projector | Скрипт для наложения эффекта призрака на движение цены за предыдущий день. | 1.0 | Первоначальная версия | Первый инструмент в Lynnchris Tools Chest |
18/11/24 | Analytical Comment | Предоставляет информацию за предыдущий день в табличном формате, а также прогнозирует будущее направление рынка. | 1.0 | Первоначальная версия | Второй инструмент в Lynnchris Tools Chest |
27/11/24 | Analytics Master | Регулярное обновление рыночных показателей каждые два часа | 1.01 | Вторая версия | Третий инструмент в Lynnchris Tools Chest |
02/12/24 | Analytics Forecaster | Регулярное обновление рыночных показателей каждые два часа с интеграцией с Telegram | 1.1 | Третья версия | Инструмент номер 4 |
09/12/24 | Volatility Navigator | Советник анализирует рыночные условия с помощью полос Боллинджера, RSI и ATR. | 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 | Панель с кнопкfvb для анализа | 1.0 | Первоначальная версия | Инструмент номер 8 |
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/16584
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.




- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования