Разработка инструментария для анализа движения цен (Часть 18): Введение в теорию четвертей (III) — Quarters Board
Содержание
Введение
В нашем введении в теорию четвертей, мы начали со скрипта Quarters Drawer. Скрипт автоматизирует отрисовку уровней по четвертям на графике и содержит логические переключатели для управления видимостью каждого уровня.
input bool DrawLargeQuarters = true; // Draw intermediate large quarter lines. input bool DrawSmallQuarters = false; // Draw small quarter lines. input bool DrawOvershootAreas = true; // Mark overshoot/undershoot areas for large quarter lines.
Например, установка DrawSmallQuarters на true отображает небольшие четвертные линии, установка DrawLargeQuarters на false скрывает крупные четвертные линии. Тот же подход применим и к уровням превышения и понижения. Эта функция позволяет сосредоточиться на определенных уровнях, поддерживая чистоту и порядок на графике. Чтобы просмотреть все уровни, просто включите все переключатели.
Часто ли вам приходится возвращаться к коду, чтобы просто изменить какую-нибудь настройку? В этой статье мы представляем Quarters Board — улучшенный инструмент, позволяющий автоматически включать или выключать логические флаги одним нажатием кнопки на графике в реальном времени. Вместо того чтобы редактировать код для изменения флага DrawSmallQuarters, вы можете вносить корректировки непосредственно на графике, что упрощает процесс. Например, если вам нужно просмотреть только большие четверти, это можно сделать простым нажатием кнопки.
Обзор
Как упоминалось во введении, этот инструмент позволяет переключать отображаемые на графике уровни без необходимости возвращаться к коду для редактирования логического флага. Quarter Board - советник с четырьмя кнопками: Large Quarters (большие четверти), Small Quarters (маленькие четверти), Overshoot/Undershoot (превышение/понижение) и Trend Direction (направление тренда). Нажатие любой кнопки переключает соответствующий уровень: текст кнопки становится зеленым, когда уровень активен, и красным, когда он выключен.
Кнопка Trend Direction — это дополнительная функция, предоставляющая информацию о рынке в реальном времени. Всего одним щелчком мыши программа вычисляет простую скользящую среднюю за 50 периодов и сравнивает ее с текущей рыночной ценой, помогая быстро определить, находится ли рынок в восходящем, нисходящем или боковом тренде. Кнопка меняет цвет, чтобы показать свой активный статус, предоставляя понятный и удобный способ отслеживания трендов непосредственно на графике.
Логика
Советник разработан таким образом, чтобы быть одновременно удобным для пользователя и легко адаптируемым. Настройки позволяют легко персонализировать приложение, интерфейс чист и хорошо организован, а кнопочное управление обеспечивает плавное взаимодействие. Автоматически добавляя и удаляя линии четвертей, советник сохраняет график в аккуратном виде и фокусируется на важных ценовых уровнях. Комментарии в реальном времени добавляют еще один уровень анализа, помогая трейдерам быстро оценить направление рынка, не загромождая экран. Благодаря сочетанию визуальных и аналитических инструментов, советник упрощает принятие торговых решений, сохраняя при этом интуитивно понятный и эффективный интерфейс.
Глобальные настройки и структура
В начале работы советник определяет ключевые параметры, которые влияют на отображение уровней цен и элементов графика. Настройки входных параметров позволяют трейдерам настраивать такие параметры, как расстояние между основными ценовыми уровнями и цвета, используемые для различных линий. Эти настройки обеспечивают гибкость, позволяя пользователям изменять внешний вид советника, не меняя при этом его основную логику. Код также включает в себя несколько глобальных логических переменных, которые действуют как переключатели, включая или отключая определенные функции, такие как большие линии четвертей или комментарии к тренду. Для присвоения согласованных имен объектам графика используются макросы, обеспечивающие единообразное использование каждого элемента во всем скрипте. Организация этих настроек в одном месте упрощает редактирование параметров и устранение неполадок без необходимости поиска информации в нескольких разделах кода.#property copyright "Christian Benjamin" #property link "https://www.mql5.com/en/users/lynnchris" #property version "1.0" #property strict //---- Input parameters for drawing levels ---------------------------- input double MajorStep = 0.1000; // Difference between major whole numbers //---- Color settings --------------------------------------------------- input color MajorColor = 0x2F4F4F; // Dark Slate Gray for major lines. input color LargeQuarterColor = 0x8B0000; // Dark Red for large quarter lines. input color SmallQuarterColor = 0x00008B; // Dark Blue for small quarter lines. input color OvershootColor = clrRed; // Red for overshoot/undershoot lines. //---- Line styles and thickness settings ----------------------------- input ENUM_LINE_STYLE MajorLineStyle = STYLE_SOLID; input int MajorLineWidth = 4; input ENUM_LINE_STYLE LargeQuarterLineStyle = STYLE_DOT; input int LargeQuarterLineWidth = 3; input ENUM_LINE_STYLE OvershootLineStyle = STYLE_DASH; input int OvershootLineWidth = 1; input ENUM_LINE_STYLE SmallQuarterLineStyle = STYLE_SOLID; input int SmallQuarterLineWidth = 1; //---- Panel and button settings -------------------------------------- input int PanelX = 10; input int PanelY = 10; input int PanelWidth = 250; input int ButtonHeight = 30; input int ButtonSpacing= 5; //---- Global toggle variables ---------------------------------------- bool g_DrawLargeQuarters = true; bool g_DrawSmallQuarters = false; bool g_DrawOvershootAreas = true; bool g_DrawTrendDirection = false; //---- Object names for panel and buttons ----------------------------- #define PANEL_NAME "LevelsPanel" #define BUTTON_LARGE "btnLargeQuarters" #define BUTTON_SMALL "btnSmallQuarters" #define BUTTON_OVERSHOOT "btnOvershoot" #define BUTTON_TREND "btnTrendDirection" #define TREND_LABEL "TrendDirectionLabel"
Инициализация панели и кнопок
После настройки параметров советник формирует пользовательский интерфейс. Для группировки всех кнопок создается фоновая панель, обеспечивающая структурированное расположение. Панель имитируется с помощью прямоугольной метки, размеры которой регулируются путем изменения свойств текста. Затем кнопки располагаются относительно панели, обеспечивая правильное расстояние и выравнивание.
Кнопки позволяют трейдерам переключать такие функции, как большие четверти, малые четверти, зоны превышения и комментарии о направлении тренда. Каждой кнопке присвоены необходимые ширина и высота, что создает аккуратный и упорядоченный вид. Такая настройка упрощает взаимодействие пользователей с советником, позволяя включать или отключать определенные элементы одним щелчком мыши. Поддерживая единообразную компоновку, советник обеспечивает легкий доступ ко всем элементам управления и их визуальную различимость.
void CreatePanel() { if(ObjectCreate(0, PANEL_NAME, OBJ_RECTANGLE_LABEL, 0, 0, 0)) { ObjectSetInteger(0, PANEL_NAME, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, PANEL_NAME, OBJPROP_XDISTANCE, PanelX); ObjectSetInteger(0, PANEL_NAME, OBJPROP_YDISTANCE, PanelY); ObjectSetInteger(0, PANEL_NAME, OBJPROP_COLOR, clrDarkGray); ObjectSetString(0, PANEL_NAME, OBJPROP_TEXT, "\n\n\n\n"); ObjectSetInteger(0, PANEL_NAME, OBJPROP_BORDER_TYPE, BORDER_RAISED); } }
Обработка взаимодействия с пользователями
Взаимодействие с пользователем является важнейшим аспектом архитектуры советника и управляется с помощью системы обработки событий. Скрипт отслеживает события, связанные с графиком, в частности, проверяет, была ли нажата кнопка. При нажатии кнопки система определяет, какая функция должна быть активирована, сопоставляя название кнопки. После идентификации соответствующая функция включается или выключается. Например, нажатие кнопки Large Quarters позволяет показать/скрыть эти ценовые уровни.
Для большего удобства цвета кнопок мгновенно обновляются, обеспечивая четкую визуальную обратную связь: активные кнопки могут стать зелеными, а неактивные — остаются красными. Система гарантирует независимую работу каждой функции, предотвращая конфликты и обеспечивая быстрое реагирование инструмента на ввод данных пользователем в реальном времени. Благодаря эффективной организации обработки событий, советник остается стабильным и простым в использовании даже в условиях быстро меняющейся рыночной обстановки.
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id == CHARTEVENT_OBJECT_CLICK) { if(sparam == BUTTON_LARGE) { g_DrawLargeQuarters = !g_DrawLargeQuarters; UpdateButtonColors(); DrawQuarterLines(); } else if(sparam == BUTTON_TREND) { g_DrawTrendDirection = !g_DrawTrendDirection; UpdateButtonColors(); if(g_DrawTrendDirection) UpdateTrendComment(); else DeleteTrendComment(); } // Similar handling for other buttons... } }
Отображение/удаление линий четвертей
Одна из основных функций советника — отображение ценовых уровней на графике. Процесс начинается с определения текущей рыночной цены и расчета ключевых ценовых границ. Основные уровни отображаются всегда, а дополнительные, такие как большие и малые четверти и зоны превышения, отображаются только в том случае, если соответствующие кнопки активированы. Чтобы график выглядел аккуратно, советник сначала удаляет все ранее нарисованные линии, а затем наносит новые.
Это предотвращает загромождение экрана накладывающимися или устаревшими строками. Каждый метод основан на структурированном расчете, обеспечивающем правильное согласование уровней цен. Если функция отключена, скрипт удаляет соответствующие строки, предоставляя трейдерам полный контроль над отображаемой информацией. Такой подход гарантирует, что график останется упорядоченным и будет предоставлять только самую актуальную информацию, исходя из предпочтений пользователя.
void DrawQuarterLines() { DeleteQuarterLines(); double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID); double lowerMajor = MathFloor(currentPrice / MajorStep) * MajorStep; DrawHorizontalLine("MajorLower", lowerMajor, MajorColor, MajorLineWidth, MajorLineStyle); if(g_DrawLargeQuarters) { double LQIncrement = MajorStep / 4.0; for(int i = 1; i < 4; i++) { double level = lowerMajor + i * LQIncrement; DrawHorizontalLine("LargeQuarter_" + IntegerToString(i), level, LargeQuarterColor, LargeQuarterLineWidth, LargeQuarterLineStyle); // Overshoot/Undershoot handling... } } // Additional code for small quarters... }
Отображение комментариев к трендам
Помимо графических элементов, советник также предоставляет трейдерам текстовый анализ рыночных трендов. Он вычисляет простую скользящую среднюю (SMA) за определенный период и сравнивает ее с текущей ценой. Если цена находится выше скользящей средней, тренд считается бычьим; если ниже — медвежьим. Если вокруг скользящей средней практически нет движения, рынок классифицируется как нейтральный. Данный анализ отображается в виде текстовой метки на графике, расположенной непосредственно под кнопкой Trend Direction, чтобы обеспечить его видимость и не мешать другим элементам. Комментарии обновляются динамически, предоставляя информацию в реальном времени по мере изменения рыночной конъюнктуры. Эта функция дополняет графическую систему анализа четвертей, предоставляя трейдерам дополнительный уровень анализа и помогая им принимать более обоснованные решения.
void UpdateTrendComment() { double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID); double smaValue = 0.0; int handle = iMA(_Symbol, PERIOD_CURRENT, 50, 0, MODE_SMA, PRICE_CLOSE); if(handle != INVALID_HANDLE) { double buffer[]; if(CopyBuffer(handle, 0, 1, 1, buffer) > 0) smaValue = buffer[0]; IndicatorRelease(handle); } string trendComment = (currentPrice > smaValue) ? "Uptrend" : (currentPrice < smaValue) ? "Downtrend" : "Sideways"; int trendLabelY = PanelY + 10 + 3 * (ButtonHeight + ButtonSpacing) + ButtonHeight + ButtonSpacing; if(ObjectFind(0, TREND_LABEL) == -1) { ObjectCreate(0, TREND_LABEL, OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, TREND_LABEL, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, TREND_LABEL, OBJPROP_XDISTANCE, PanelX + 10); ObjectSetInteger(0, TREND_LABEL, OBJPROP_YDISTANCE, trendLabelY); ObjectSetInteger(0, TREND_LABEL, OBJPROP_COLOR, clrWhite); ObjectSetInteger(0, TREND_LABEL, OBJPROP_FONTSIZE, 14); } ObjectSetString(0, TREND_LABEL, OBJPROP_TEXT, "Trend Direction: " + trendComment); }
Полный код советника
//+------------------------------------------------------------------+ //| Quarters Board EA.mq5| //| Copyright 2025, Christian Benjamin| //| https://www.mql5.com/en/users/lynnchris| //+------------------------------------------------------------------+ #property copyright "Christian Benjamin" #property link "https://www.mql5.com/en/users/lynnchris" #property version "1.0" #property strict //---- Input parameters for drawing levels ---------------------------- input double MajorStep = 0.1000; // Difference between major whole numbers //---- Color settings --------------------------------------------------- input color MajorColor = 0x2F4F4F; // Dark Slate Gray for major lines. input color LargeQuarterColor = 0x8B0000; // Dark Red for large quarter lines. input color SmallQuarterColor = 0x00008B; // Dark Blue for small quarter lines. input color OvershootColor = clrRed; // Red for overshoot/undershoot lines. //---- Line styles and thickness settings ----------------------------- input ENUM_LINE_STYLE MajorLineStyle = STYLE_SOLID; input int MajorLineWidth = 4; input ENUM_LINE_STYLE LargeQuarterLineStyle = STYLE_DOT; input int LargeQuarterLineWidth = 3; input ENUM_LINE_STYLE OvershootLineStyle = STYLE_DASH; input int OvershootLineWidth = 1; input ENUM_LINE_STYLE SmallQuarterLineStyle = STYLE_SOLID; input int SmallQuarterLineWidth = 1; //---- Panel and button settings -------------------------------------- input int PanelX = 10; input int PanelY = 10; input int PanelWidth = 250; input int ButtonHeight = 30; input int ButtonSpacing= 5; //---- Global toggle variables ---------------------------------------- bool g_DrawLargeQuarters = true; bool g_DrawSmallQuarters = false; bool g_DrawOvershootAreas = true; bool g_DrawTrendDirection = false; //---- Object names for panel and buttons ----------------------------- #define PANEL_NAME "LevelsPanel" #define BUTTON_LARGE "btnLargeQuarters" #define BUTTON_SMALL "btnSmallQuarters" #define BUTTON_OVERSHOOT "btnOvershoot" #define BUTTON_TREND "btnTrendDirection" #define TREND_LABEL "TrendDirectionLabel" //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Create panel background and buttons CreatePanel(); CreateButtons(); // Draw quarter lines initially DrawQuarterLines(); // If trend commentary is toggled on, update it if(g_DrawTrendDirection) UpdateTrendComment(); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Delete panel, buttons, quarter lines, and trend commentary ObjectDelete(0, PANEL_NAME); ObjectDelete(0, BUTTON_LARGE); ObjectDelete(0, BUTTON_SMALL); ObjectDelete(0, BUTTON_OVERSHOOT); ObjectDelete(0, BUTTON_TREND); DeleteQuarterLines(); DeleteTrendComment(); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Redraw quarter lines on every tick DrawQuarterLines(); // Update trend commentary if enabled if(g_DrawTrendDirection) UpdateTrendComment(); } //+------------------------------------------------------------------+ //| Chart event function to catch button clicks | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id == CHARTEVENT_OBJECT_CLICK) { if(sparam == BUTTON_LARGE) { g_DrawLargeQuarters = !g_DrawLargeQuarters; UpdateButtonColors(); DrawQuarterLines(); } else if(sparam == BUTTON_SMALL) { g_DrawSmallQuarters = !g_DrawSmallQuarters; UpdateButtonColors(); DrawQuarterLines(); } else if(sparam == BUTTON_OVERSHOOT) { g_DrawOvershootAreas = !g_DrawOvershootAreas; UpdateButtonColors(); DrawQuarterLines(); } else if(sparam == BUTTON_TREND) { g_DrawTrendDirection = !g_DrawTrendDirection; UpdateButtonColors(); if(g_DrawTrendDirection) UpdateTrendComment(); else DeleteTrendComment(); } } } //+------------------------------------------------------------------+ //| Create panel background | //+------------------------------------------------------------------+ void CreatePanel() { if(ObjectCreate(0, PANEL_NAME, OBJ_RECTANGLE_LABEL, 0, 0, 0)) { ObjectSetInteger(0, PANEL_NAME, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, PANEL_NAME, OBJPROP_XDISTANCE, PanelX); ObjectSetInteger(0, PANEL_NAME, OBJPROP_YDISTANCE, PanelY); ObjectSetInteger(0, PANEL_NAME, OBJPROP_COLOR, clrDarkGray); // Simulate a larger panel using newlines in the text. string panelText = "\n\n\n\n"; ObjectSetString(0, PANEL_NAME, OBJPROP_TEXT, panelText); ObjectSetInteger(0, PANEL_NAME, OBJPROP_BORDER_TYPE, BORDER_RAISED); } } //+------------------------------------------------------------------+ //| Create buttons on the panel | //+------------------------------------------------------------------+ void CreateButtons() { int x = PanelX + 10; int y = PanelY + 10; int btnWidth = PanelWidth - 20; // Button for Large Quarters if(!ObjectCreate(0, BUTTON_LARGE, OBJ_BUTTON, 0, 0, 0)) Print("Failed to create button ", BUTTON_LARGE); else { ObjectSetInteger(0, BUTTON_LARGE, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, BUTTON_LARGE, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, BUTTON_LARGE, OBJPROP_YDISTANCE, y); ObjectSetInteger(0, BUTTON_LARGE, OBJPROP_XSIZE, btnWidth); ObjectSetInteger(0, BUTTON_LARGE, OBJPROP_YSIZE, ButtonHeight); ObjectSetString(0, BUTTON_LARGE, OBJPROP_TEXT, "Large Quarters"); } // Button for Smaller Quarters y += ButtonHeight + ButtonSpacing; if(!ObjectCreate(0, BUTTON_SMALL, OBJ_BUTTON, 0, 0, 0)) Print("Failed to create button ", BUTTON_SMALL); else { ObjectSetInteger(0, BUTTON_SMALL, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, BUTTON_SMALL, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, BUTTON_SMALL, OBJPROP_YDISTANCE, y); ObjectSetInteger(0, BUTTON_SMALL, OBJPROP_XSIZE, btnWidth); ObjectSetInteger(0, BUTTON_SMALL, OBJPROP_YSIZE, ButtonHeight); ObjectSetString(0, BUTTON_SMALL, OBJPROP_TEXT, "Smaller Quarters"); } // Button for Overshoot/Undershoot y += ButtonHeight + ButtonSpacing; if(!ObjectCreate(0, BUTTON_OVERSHOOT, OBJ_BUTTON, 0, 0, 0)) Print("Failed to create button ", BUTTON_OVERSHOOT); else { ObjectSetInteger(0, BUTTON_OVERSHOOT, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, BUTTON_OVERSHOOT, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, BUTTON_OVERSHOOT, OBJPROP_YDISTANCE, y); ObjectSetInteger(0, BUTTON_OVERSHOOT, OBJPROP_XSIZE, btnWidth); ObjectSetInteger(0, BUTTON_OVERSHOOT, OBJPROP_YSIZE, ButtonHeight); ObjectSetString(0, BUTTON_OVERSHOOT, OBJPROP_TEXT, "Overshoot/Undershoot"); } // Button for Trend Direction y += ButtonHeight + ButtonSpacing; if(!ObjectCreate(0, BUTTON_TREND, OBJ_BUTTON, 0, 0, 0)) Print("Failed to create button ", BUTTON_TREND); else { ObjectSetInteger(0, BUTTON_TREND, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, BUTTON_TREND, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, BUTTON_TREND, OBJPROP_YDISTANCE, y); ObjectSetInteger(0, BUTTON_TREND, OBJPROP_XSIZE, btnWidth); ObjectSetInteger(0, BUTTON_TREND, OBJPROP_YSIZE, ButtonHeight); ObjectSetString(0, BUTTON_TREND, OBJPROP_TEXT, "Trend Direction"); } UpdateButtonColors(); } //+------------------------------------------------------------------+ //| Update button colors based on toggle state | //+------------------------------------------------------------------+ void UpdateButtonColors() { color onColor = clrGreen; color offColor = clrRed; ObjectSetInteger(0, BUTTON_LARGE, OBJPROP_COLOR, g_DrawLargeQuarters ? onColor : offColor); ObjectSetInteger(0, BUTTON_SMALL, OBJPROP_COLOR, g_DrawSmallQuarters ? onColor : offColor); ObjectSetInteger(0, BUTTON_OVERSHOOT, OBJPROP_COLOR, g_DrawOvershootAreas ? onColor : offColor); ObjectSetInteger(0, BUTTON_TREND, OBJPROP_COLOR, g_DrawTrendDirection ? onColor : offColor); } //+------------------------------------------------------------------+ //| Delete quarter lines | //+------------------------------------------------------------------+ void DeleteQuarterLines() { ObjectDelete(0, "MajorLower"); ObjectDelete(0, "MajorUpper"); for(int i = 1; i < 4; i++) { ObjectDelete(0, "LargeQuarter_" + IntegerToString(i)); ObjectDelete(0, "Overshoot_" + IntegerToString(i) + "_up"); ObjectDelete(0, "Undershoot_" + IntegerToString(i) + "_down"); } for(int seg = 0; seg < 10; seg++) { for(int j = 1; j < 4; j++) { ObjectDelete(0, "SmallQuarter_" + IntegerToString(seg) + "_" + IntegerToString(j)); } } } //+------------------------------------------------------------------+ //| Delete trend commentary | //+------------------------------------------------------------------+ void DeleteTrendComment() { ObjectDelete(0, TREND_LABEL); } //+------------------------------------------------------------------+ //| Update trend commentary | //+------------------------------------------------------------------+ void UpdateTrendComment() { double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID); if(currentPrice == 0) return; double smaValue = 0.0; double buffer[]; int handle = iMA(_Symbol, PERIOD_CURRENT, 50, 0, MODE_SMA, PRICE_CLOSE); if(handle != INVALID_HANDLE) { if(CopyBuffer(handle, 0, 1, 1, buffer) > 0) smaValue = buffer[0]; IndicatorRelease(handle); } string trendComment; if(currentPrice > smaValue) trendComment = "Uptrend"; else if(currentPrice < smaValue) trendComment = "Downtrend"; else trendComment = "Sideways"; // Calculate the position for the commentary label below the Trend Direction button int trendButtonY = PanelY + 10 + 3 * (ButtonHeight + ButtonSpacing); int trendLabelY = trendButtonY + ButtonHeight + ButtonSpacing; int trendLabelX = PanelX + 10; if(ObjectFind(0, TREND_LABEL) == -1) { ObjectCreate(0, TREND_LABEL, OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, TREND_LABEL, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, TREND_LABEL, OBJPROP_XDISTANCE, trendLabelX); ObjectSetInteger(0, TREND_LABEL, OBJPROP_YDISTANCE, trendLabelY); ObjectSetInteger(0, TREND_LABEL, OBJPROP_COLOR, clrWhite); ObjectSetInteger(0, TREND_LABEL, OBJPROP_FONTSIZE, 14); } string txt = "Trend Direction: " + trendComment; ObjectSetString(0, TREND_LABEL, OBJPROP_TEXT, txt); } //+------------------------------------------------------------------+ //| Draw horizontal line utility | //+------------------------------------------------------------------+ void DrawHorizontalLine(string name, double price, color lineColor, int width, ENUM_LINE_STYLE style) { if(ObjectFind(0, name) != -1) ObjectDelete(0, name); if(!ObjectCreate(0, name, OBJ_HLINE, 0, 0, price)) { Print("Failed to create line: ", name); return; } ObjectSetInteger(0, name, OBJPROP_COLOR, lineColor); ObjectSetInteger(0, name, OBJPROP_STYLE, style); ObjectSetInteger(0, name, OBJPROP_WIDTH, width); ObjectSetInteger(0, name, OBJPROP_RAY_RIGHT, true); } //+------------------------------------------------------------------+ //| Draw quarter lines based on toggle settings | //+------------------------------------------------------------------+ void DrawQuarterLines() { DeleteQuarterLines(); double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID); if(currentPrice == 0) return; double lowerMajor = MathFloor(currentPrice / MajorStep) * MajorStep; double upperMajor = lowerMajor + MajorStep; DrawHorizontalLine("MajorLower", lowerMajor, MajorColor, MajorLineWidth, MajorLineStyle); DrawHorizontalLine("MajorUpper", upperMajor, MajorColor, MajorLineWidth, MajorLineStyle); if(g_DrawLargeQuarters) { double LQIncrement = MajorStep / 4.0; for(int i = 1; i < 4; i++) { double level = lowerMajor + i * LQIncrement; string objName = "LargeQuarter_" + IntegerToString(i); DrawHorizontalLine(objName, level, LargeQuarterColor, LargeQuarterLineWidth, LargeQuarterLineStyle); if(g_DrawOvershootAreas) { double smallQuarter = MajorStep / 40.0; DrawHorizontalLine("Overshoot_" + IntegerToString(i) + "_up", level + smallQuarter, OvershootColor, OvershootLineWidth, OvershootLineStyle); DrawHorizontalLine("Undershoot_" + IntegerToString(i) + "_down", level - smallQuarter, OvershootColor, OvershootLineWidth, OvershootLineStyle); } } } if(g_DrawSmallQuarters) { double segStep = MajorStep / 10.0; double smallQuarter = segStep / 4.0; for(int seg = 0; seg < 10; seg++) { double segStart = lowerMajor + seg * segStep; for(int j = 1; j < 4; j++) { double level = segStart + j * smallQuarter; string objName = "SmallQuarter_" + IntegerToString(seg) + "_" + IntegerToString(j); DrawHorizontalLine(objName, level, SmallQuarterColor, SmallQuarterLineWidth, SmallQuarterLineStyle); } } } } //+------------------------------------------------------------------+
Результаты
В этом разделе мы рассмотрим результаты и эффективность нашего советника. Ниже представлена GIF-диаграмма, иллюстрирующая его поведение. При перетаскивании советника на график EURUSD появляется панель с кнопками. Изначально кнопки Larger Quarter и Overshoot/Undershoot отображают зеленый текст, указывающий на то, что они отключены. В отличие от них кнопки Smaller Quarters и Trend Direction отображают красный текст, что означает, что эти уровни активны. При нажатии каждой кнопки соответствующие уровни появляются на графике, если они активированы, или исчезают, если они отключены. После включения кнопки Trend Direction комментарий к тренду обновляется и отображает Uptrend (восходящий тренд), точно отражая текущую рыночную ситуацию на графике.

Ниже показан график, наглядно демонстрирующий результаты тестирования нашего советника. Мы видим, что крупные уровни четверти, обозначенные сплошными синими линиями, и уровни превышения/понижения, представленные красными пунктирными линиями, активны, о чем свидетельствуют как линии графика, так и цвет текста кнопки. Кроме того, отображается направление тренда, о чем свидетельствуют комментарии на графике. Напротив, кнопка Small Quarters отображается красным цветом, указывая на то, что эти уровни неактивны.

Заключение
Мы создали панель с кнопками, позволяющими одним нажатием переключать необходимые уровни на графике. Это еще один шаг вперед в обработке уровней четвертей в соответствии с требованиями трейдеров. Это усовершенствование обеспечивает удобный пользовательский интерфейс: иногда вам может потребоваться сосредоточиться исключительно на больших четвертях, не отвлекаясь на другие уровни, а в других случаях вы можете предпочесть отображение всех уровней. Кроме того, этот инструмент анализирует направление тренда, помогая вам понять, что на самом деле происходит на рынке, исходя из текущей цены.
| Дата | Название инструмента | Описание | Версия | Обновления | Примечания |
|---|---|---|---|---|---|
| 01/10/24 | Chart Projector | Скрипт для наложения эффекта призрака на движение цены за предыдущий день. | 1.0 | Первоначальная версия | Инструмент номер 1 |
| 18/11/24 | Analytical Comment | Предоставляет информацию за предыдущий день в табличном формате, а также прогнозирует будущее направление рынка. | 1.0 | Первоначальная версия | Инструмент номер 2 |
| 27/11/24 | Analytics Master | Регулярное обновление рыночных показателей каждые два часа | 1.01 | Вторая версия | Инструмент номер 3 |
| 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/25 | Signal Pulse | Анализирует несколько таймфреймов | 1.0 | Первоначальная версия | Инструмент номер 7 |
| 17/01/25 | Metrics Board | Панель с кнопками для анализа | 1.0 | Первоначальная версия | Инструмент номер 8 |
| 21/01/25 | External Flow | Аналитика с помощью внешних библиотек | 1.0 | Первоначальная версия | Инструмент номер 9 |
| 27/01/25 | VWAP | Взвешенная по объему средняя цена | 1.3 | Первоначальная версия | Инструмент номер 10 |
| 02/02/25 | Heikin Ashi | Сглаживание тренда и идентификация сигналов разворота | 1.0 | Первоначальная версия | Инструмент номер 11 |
| 04/02/25 | FibVWAP | Генерация сигнала с помощью анализа Python | 1.0 | Первоначальная версия | Инструмент номер 12 |
| 14/02/25 | RSI DIVERGENCE | Дивергенция цены и RSI | 1.0 | Первоначальная версия | Инструмент номер 13 |
| 17/02/25 | Parabolic Stop and Reverse (PSAR) | Автоматизация стратегии PSAR | 1.0 | Первоначальная версия | Инструмент номер 14 |
| 20/02/25 | Скрипт Quarters Drawer | Нанесение уровней четвертей на график | 1.0 | Первоначальная версия | Инструмент номер 15 |
| 27/02/25 | Intrusion Detector | Обнаружение и оповещение о достижении ценой уровней четвертей | 1.0 | Первоначальная версия | Инструмент номер 16 |
| 27/02/25 | TrendLoom Tool | Панель мультитаймфреймового анализа | 1.0 | Первоначальная версия | Инструмент номер 17 |
| 11/03/25 | Quarters Board | Панель с кнопками для включения/отключения уровней четвертей | 1.0 | Первоначальная версия | Инструмент номер 18 |
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/17442
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Нейросети в трейдинге: Возмущённые модели пространства состояний для анализа рыночной динамики
Возможности Мастера MQL5, которые вам нужно знать (Часть 57): Обучение с учителем совместно со скользящей средней и стохастическим осциллятором
От новичка до эксперта: Развиваем географическую осознанность рынка с помощью визуализации на MQL5
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования