От начального до среднего уровня: Объекты (I)
Введение
В предыдущей статье, «От начального до среднего уровня: Индикатор (V)» было объяснено, как мы можем простым способом адаптировать, пусть даже частично, индикатор к режиму построения графика, используемому в MetaTrader 5. Хотя не было показано, как использовать три модели построения графиков, поскольку для этого требуются знания, которые мы здесь ещё должным образом не объяснили.
В определённых границах мы можем использовать режим свечей или режим баров в одном и том же индикаторе, и это можно сделать без особых проблем. А если мы захотим использовать линейный режим, нам придётся создать отдельный индикатор и разместить его на графике вручную. Несмотря на этот незначительный недостаток, мы покажем, как избежать его в будущем.
Я верю, что вы смогли понять, как мы можем временно справляться с существующими ограничениями, пока не достигнем нужного уровня в этих статьях, чтобы вы понимали, как работать без необходимости объяснять каждую деталь, связанную с реализацией.
Но, несмотря на это, есть вещи, которые мы уже можем начать обсуждать, хотя они могут быть более интересны для одних читателей и менее интересны для других. Я говорю это, потому что многие из вас, возможно, не видят более глубокого смысла в теме, которую мы начнем обсуждать в сегодняшней статье. Однако для других то, что будет показано и объяснено в этой и последующих статьях, действительно представляет большой интерес и может даже преследовать весьма благородную цель.
Итак, начнём с рассмотрения того, что не будет подробно разбираться в этой статье, но послужит отправной точкой для обсуждения данной темы.
Особая предусмотрительность
Есть несколько типов данных, которые многим трейдерам нравится видеть на графике. Некоторые из этих в большей или меньшей степени полезны в зависимости от конкретного момента. Один из них — это счетчики свечей или баров. Для многих людей подобные вещи не несут совершенно никакой пользы, в то время как для других это средство быстрого и эффективного общения с другими трейдерами для обмена мнениями о том, как они оценивают рынок.
Хорошо, вышесказанное относится к тому, что мы разместили на графике, с точки зрения пользователя. Но для нас, программистов, всё развивается несколько иначе.
Это объясняется тем, что можно создавать различные и привлекательные способы отображения информации на графике. Однако в этом скромном примере существует не так много разных способов сделать это, поскольку главная цель — просто разместить текст на изображении, и не более того. Реальная разница, по сути, будет заключаться не в самом тексте, а в том, как мы его разместим в таблице и будем периодически обновлять.
У многих людей, занимающихся программированием в качестве хобби, отсутствует ясное видение, свойственное программистам, которые по-настоящему преданны своему делу и изучают тему. И пожалуйста, не поймите меня неправильно, я не утверждаю, что человек, который создает программы с конкретными целями время от времени, не знает, что делает. Проблема в том, что эти люди не всегда осведомлены о некоторых видах проблем, которые могут возникнуть из-за плохо оптимизированных программ при работе с платформой MetaTrader 5, вызывая постепенное и прогрессирующее ухудшение производительности до такой степени, что платформа становится полностью непригодной для использования со всеми этими приложениями, работающими на графике.
Простой счетчик свечей, предназначенный лишь для отображения текста на графике, при недостаточной оптимизации может потреблять гораздо больше ресурсов, чем необходимо. Даже здесь, где основная цель всегда будет образовательной, мы стараемся показывать коды, которые не окажут существенного негативного влияния на производительность MetaTrader 5. И если такое может случайно произойти, я напоминаю о необходимости проявлять осторожность, чтобы люди, применяющие на практике то, что описано в статьях, избежали лишней головной боли.
Уважаемые читатели, давайте теперь вернемся к нашему вопросу: что можно придумать в качестве счетчика свечей? Можно было бы подумать о каком-нибудь приложении, которое выводило бы числовые значения на шкалу. Но вопрос остается открытым. Какое приложение вы бы использовали? Итак, поскольку мы уже видели, как создавать скрипты и индикаторы, скорее всего, вы окажетесь где-то между этими двумя случаями. Однако из-за некоторых ограничений скриптов в итоге придётся перейти на индикаторы.
И какие именно ограничения существуют в скриптах? Если вы уже поэкспериментировали, вы наверняка заметили, что всякий раз, когда мы добавляем скрипт на график, он удаляется при изменении временного периода графика. Даже если мы используем цикл в скрипте, чтобы предотвратить это. Хорошо, это потребует от нас принятия мер для того, чтобы при изменении временного интервала мы корректировали положение скрипта на графике. Существует способ избежать проблем, связанных с запуском скриптов. Однако, так как это предполагает использование сервисов, а их связь с графиком довольно сложна, такой вариант нам не подходит.
Если вам интересно узнать, насколько сложна подобная структура связей, поищите мои статьи о создании системы репликации/моделирования. Но поскольку эти статьи ориентированы на тех, кто уже имеет хорошие базовые знания в программировании на MQL5 (что на данный момент не относится к данной теме, так как мы только начинаем), я не буду подробно рассказывать о манипулировании графиком с помощью сервисов для этой цели.
Таким образом, остается альтернативный вариант — использование индикаторов. Верно, но, тем не менее, индикаторы в большинстве случаев не подходят для определенных типов задач. Так происходит, потому что индикаторы в MetaTrader 5 выполняются одним блоком, словно это одно приложение, работающее на графике. Это делается для ускорения вычислений, которые MetaTrader 5 выполняет для предоставления нам определенных значений. Указанные значения являются частью набора входных параметров, которые можно выбрать при размещении индикатора на графике. Об этом уже говорилось в предыдущих статьях.
Однако, учитывая, что счетчик баров запускается только тогда, когда на графике появляется новый бар, у нас может возникнуть соблазн использовать таймер для синхронизации. И вот здесь начинаются проблемы. Использование таймера на индикаторе на самом деле не рекомендуется. Это происходит так, потому что в случае сбоя в коде таймера пострадают все остальные индикаторы, и это может даже на несколько мгновений заблокировать MetaTrader 5, при этом данные мгновения могут оказаться решающими.
Но существуют способы работы с системой, цель которой — определить появление новых баров на графике. Использование индикатора — это, по сути, самый простой и практичный способ узнать, когда появилась новая свеча, и, таким образом, иметь возможность подсчитать количество свечей, отображая после этого текст. Чтобы дойти до того момента, когда начнется подсчет свечей, нам нужно откуда-то начать. И начнем с кода, который вы видите ниже.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. int OnInit() 05. { 06. return INIT_SUCCEEDED; 07. }; 08. //+------------------------------------------------------------------+ 09. int OnCalculate(const int rates_total, const int prev_calculated, const datetime &Time[], const double &Open[], const double &High[], const double &Low[], const double &Close[], const long &TickVolume[], const long &Volume[], const int &Spread[]) 10. { 11. return rates_total; 12. }; 13. //+------------------------------------------------------------------+
Код 01
А теперь обратите внимание: каждый раз, когда изменяется цена символа, отображаемого на графике, все индикаторы будут получать событие Calculate от MetaTrader 5. В MetaTrader 5 событие Calculate не запускается на основе активности за определенный период времени. Если использовать график с 10-минутным периодом, то при появлении каждого нового бара примерно через 10 минут событие Calculate не будет происходить, если цена фактически не изменилась. До этого момента ни одно событие Calculate происходить не будет.
Учитывая, что в случае с высоко волатильными символами события Calculate могут происходить за очень короткие промежутки времени (порядка миллисекунд), нам необходимо, чтобы это событие Calculate выполнялось как можно быстрее. Иными словами, не стоит тратить время на вычисления или поиск информации без необходимости, так как это значительно замедлит обработку события.
А это негативно сказывается на всех остальных приложениях, связанных с данным графиком. И помните, мы ещё даже не затронули тему советников. Да, и наличие плохо оптимизированных индикаторов наносит серьезный вред MetaTrader 5. Но скоро всё будет выглядеть лучше.
На данный момент вам необходимо понимать, что скорость выполнения зависит от того, как мы ищем информацию. В коде 01 можно увидеть, что у нас есть массив, предназначенный для предоставления нам значения времени каждого бара. Обратите внимание: здесь, в событии Calculate, мы не знаем, в какой именно момент изменилась котировка. Мы знаем только, когда был создан данный бар. И уже исходя из временного периода, представленного на графике, мы можем оценить, сколько времени потребуется для закрытия сделки. Данная информация важна для создания другого типа приложений, который мы рассмотрим позже.
Но здесь наша цель — создать счетчик свечей или, по крайней мере, знать, есть ли на графике новый бар. Таким образом, всякий раз, когда значение массива Time, показанного в строке 09, изменяется, это означает появление нового бара на графике.
Другой способ, который, на мой взгляд, гораздо проще, — это посмотреть на значения prev_calculated и rates_total. Но почему? Причина в том, что значение в массиве Time имеет тип datetime. В отличие от них, значения prev_calculated и rates_total предоставлены самой платформой MetaTrader 5 и имеют целочисленный тип, что значительно упрощает и ускоряет проверку. А поскольку изменения происходят только при появлении новых баров на графике, всё становится гораздо проще для наблюдения.
Помимо другого вопроса, к которому мы скоро перейдем, вы понимаете, к чему я клоню? Неважно, как мы собираемся что-то реализовать. Важно понимать, какая информация у нас есть в распоряжении для достижения нашей цели. Для проверки мы изменим код 01 на код 02, как можно увидеть ниже.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. int OnInit() 05. { 06. return INIT_SUCCEEDED; 07. }; 08. //+------------------------------------------------------------------+ 09. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) 10. { 11. return rates_total; 12. }; 13. //+------------------------------------------------------------------+
Код 02
Теперь у нас есть отправная точка, чтобы понять, что всё зависит от правильного понимания ситуации и умения использовать имеющуюся в вашем распоряжении информацию. Не существует единственно правильного (или неправильного) способа что-либо сделать, есть лишь более простые способы достижения той же цели и результата. Хорошо, но как определить, появился ли на графике новый бар или нет? Это самая простая часть, уважаемые читатели. Для этого мы изменим код 02, как показано ниже.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. int OnInit() 05. { 06. return INIT_SUCCEEDED; 07. }; 08. //+------------------------------------------------------------------+ 09. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) 10. { 11. if ((prev_calculated > 0) && (prev_calculated != rates_total)) 12. Print("New Bar..."); 13. 14. return rates_total; 15. }; 16. //+------------------------------------------------------------------+
Код 03
Код 03 воплощает в жизнь именно то, что мы хотели показать, и то, что было сказано мгновение назад. Иными словами, здесь мы имеем очень простой способ узнать, когда закрылся текущий бар и когда появился новый. Чтобы убедиться в этом, давайте посмотрим на анимацию ниже.

Анимация 01
Поскольку код 03 очень прост, как и сама анимация, мы можем обойтись без каких-либо объяснений и начать самую интересную часть статьи. Но для этого мы должны начать новую тему.
Объекты и график
Вопреки распространенному мнению, всё, что присутствует на графике, является объектом. Конечно, эти объекты могут иметь совершенно разное назначение, в зависимости от того, что мы пытаемся создать, но это не меняет того факта, что они по-прежнему являются объектами. И ещё один момент: объекты, о которых мы говорим, не имеют никакого отношения к объектно-ориентированному программированию (ООП). Сейчас подходим к сложной части. Существует два типа объектов, или, точнее, два способа размещения объектов на графике котировок. Такова ситуация с графиками, созданными и поддерживаемыми MetaTrader 5.
Первый тип — это объекты, система координат которых основана на экранных координатах, а второй тип — это объекты с экранными координатами. Между этими объектами существуют различия как в способе их отображения на экране, так и в способе взаимодействия с ними. Однако между некоторыми типами существует определённая взаимосвязь. Умение правильно выбрать тип значительно упрощает реализацию и, естественно, ускоряет выполнение кода.
Итак, поскольку мы впервые сталкиваемся с подобным, давайте ненадолго отвлечемся от счетчика свечей, так как сначала нам нужно понять, как обращаться с этими объектами.
В качестве отправной точки следует обратиться к документации MQL5, к разделу «Типы объектов». Там можно увидеть список различных объектов. Хотя вы можете предположить, что у нас там недостаточно объектов и что некоторые отсутствуют, это не так. На мой взгляд, MQL5 предоставляет нам более чем достаточно объектов для использования на графике. Честно говоря, нам все эти элементы не понадобятся. Но если они уже внедрены и доступны нам, то не вижу никаких проблем в их эффективном использовании. Кроме того, многие из них можно использовать очень интересным образом, что значительно сэкономит нам время.
Чтобы это продемонстрировать, мы напишем небольшой фрагмент кода, чтобы показать, как можно работать с объектами на графике. Код, о котором идёт речь, находится ниже.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #define def_NameChannel "Demo" 05. //+------------------------------------------------------------------+ 06. int OnInit() 07. { 08. ObjectCreate(0, def_NameChannel, OBJ_REGRESSION, 0, 0, 0); 09. 10. return INIT_SUCCEEDED; 11. }; 12. //+------------------------------------------------------------------+ 13. int OnCalculate(const int rates_total, const int prev_calculated, const datetime &Time[], const double &Open[], const double &High[], const double &Low[], const double &Close[], const long &TickVolume[], const long &Volume[], const int &Spread[]) 14. { 15. const int n = 20, 16. a = 2; 17. 18. if ((prev_calculated > (n + a)) && (prev_calculated != rates_total)) 19. { 20. ObjectMove(0, def_NameChannel, 0, Time[rates_total - (n + a)], Close[rates_total - (n + a)]); 21. ObjectMove(0, def_NameChannel, 1, Time[rates_total - a], Close[rates_total - a]); 22. } 23. 24. return rates_total; 25. }; 26. //+------------------------------------------------------------------+ 27. void OnDeinit(const int reason) 28. { 29. ObjectDelete(0, def_NameChannel); 30. ChartRedraw(); 31. }; 32. //+------------------------------------------------------------------+
Код 04
Код 04 демонстрирует, каким будет наш первый объект внутри индикатора. Возможно, смотря на него, вы подумаете: "ну, это же не индикатор, ведь здесь нет тех структур, которые мы рассматривали в предыдущих статьях". Да, уважаемый читатель, код 04 действительно является индикатором. И можно убедиться в этом, взглянув на функцию OnCalculate, которая отвечает за захват и обработку события Calculate, генерируемого MetaTrader 5.
Дело в том, что индикатор, обозначенный кодом 04, не является общепринятым индикатором. Он имеет гораздо более конкретную цель и ориентирован на выполнение определенной задачи. Прежде, чем мы рассмотрим, как работает код 04, давайте посмотрим его работу на графике, что показано в анимации ниже.

Анимация 02
Необходимо увидеть это именно в анимации, поскольку статичного изображения будет недостаточно для понимания того, что мы увидим дальше. Но прежде, чем начать высмеивать код, давайте разберемся, как работает код 04. В строке 04 у нас есть определение, которое позволяет присвоить название создаваемому объекту. И да, всему, что размещено на графике, должно быть присвоено название. Пора начинать привыкать к этому прямо сейчас.
Таким образом, в строке 08 мы лишь попытались создать объект. В данном случае это канал линейной регрессии. Поскольку мы не знаем, где будет отображаться этот канал, мы больше ничего не делаем. Теперь происходит следующее: индикатор будет ждать, пока MetaTrader 5 инициирует событие Calculate с определенной характеристикой. Ожидаемая функция определена в строке 18. Прошу заметить, что строка 18 из кода 04 очень похожа на строку 11 из кода 03, и преследует ту же цель: дождаться появления нового бара. Пока это не произойдёт, созданный нами в строке 08 объект не будет отображаться на графике.
Как только появляется новый бар, мы используем строки 20 и 21 для создания канала линейной регрессии. Посмотрите, как это делается. Мы обсудим это подробнее чуть позже. Пока что следует отметить, что в этом нет ничего загадочного. Строка 20 указывает, где начинается рисование канала, а строка 21 — где заканчивается. Таким образом, мы получаем канал, который будет следовать за ценой с шагом регрессии в 20 баров и игнорировать текущий бар.
Всякий раз, когда вы будете создавать объект и добавлять его на график с помощью приложения, будет вежливо и учтиво со стороны вашего приложения удалить этот объект с графика. Для этого мы используем строку 29 внутри обработчика события Deinit.
Но теперь начинается самое интересное. А что если изменить способ анализа и вывода результатов линейной регрессии? Как поведет себя индикатор? Чтобы это выяснить, мы полностью изменим код 04, как показано ниже.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #define def_NameChannel "Demo" 05. //+------------------------------------------------------------------+ 06. int OnInit() 07. { 08. ObjectCreate(0, def_NameChannel, OBJ_REGRESSION, 0, 0, 0); 09. 10. return INIT_SUCCEEDED; 11. }; 12. //+------------------------------------------------------------------+ 13. int OnCalculate(const int rates_total, const int prev_calculated, const datetime &Time[], const double &Open[], const double &High[], const double &Low[], const double &Close[], const long &TickVolume[], const long &Volume[], const int &Spread[]) 14. { 15. const int n = 20, 16. a = 1; 17. 18. if (prev_calculated > (n + a)) 19. { 20. ObjectMove(0, def_NameChannel, 0, Time[rates_total - (n + a)], Close[rates_total - (n + a)]); 21. ObjectMove(0, def_NameChannel, 1, Time[rates_total - a], Close[rates_total - a]); 22. } 23. 24. return rates_total; 25. }; 26. //+------------------------------------------------------------------+ 27. void OnDeinit(const int reason) 28. { 29. ObjectDelete(0, def_NameChannel); 30. ChartRedraw(); 31. }; 32. //+------------------------------------------------------------------+
Код 05
Обратите внимание, что в коде 05 мы только изменили обработчик события OnCalculate по сравнению с кодом 04. Но результат, как минимум, очень интересен. В этом можно убедиться в анимации ниже.

Анимация 03
То, что мы видим в анимации 03, просто безумие, тем более учитывая, что регрессия создаётся в реальном времени. Иными словами, с каждой новой ценой канал линейной регрессии меняется. И, в зависимости от используемой конфигурации, можно получить действительно чувствительный индикатор тренда, даже более чувствительный, чем экспоненциальная скользящая средняя. Но я оставлю это очередным трейдерам нашего времени, которые всегда жаждут найти способ создания самонастраивающегося канала линейной регрессии.
Возможно, вы смотрите на меня и думаете: «ну и какой тогда смысл в таком индикаторе?» Я бы ответил: не знаю. Нельзя отрицать, что это довольно интересно и весело. Однако любой, у кого более продуманная концепция, уже придумал способ использовать это для других целей, поскольку всё, что нужно сделать, - это изменить тип создаваемого объекта и сразу же указать точки привязки. И время от времени объекты будут автоматически подстраиваться, без необходимости помнить об этом, поскольку сам факт их нахождения на графике будет достаточен для того, чтобы созданные нами правила выполнялись.
Давайте рассмотрим ещё один пример. В этом случае мы будем использовать объект другого типа. Помните, что всё, что мы собираемся показать, предназначено исключительно для образовательных целей. Код показан чуть ниже.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #define def_NameChannel "Demo" 05. //+------------------------------------------------------------------+ 06. int OnInit() 07. { 08. ObjectCreate(0, def_NameChannel, OBJ_TREND, 0, 0, 0); 09. ObjectSetInteger(0, def_NameChannel, OBJPROP_RAY_RIGHT, true); 10. 11. return INIT_SUCCEEDED; 12. }; 13. //+------------------------------------------------------------------+ 14. int OnCalculate(const int rates_total, const int prev_calculated, const datetime &Time[], const double &Open[], const double &High[], const double &Low[], const double &Close[], const long &TickVolume[], const long &Volume[], const int &Spread[]) 15. { 16. const int n = 60; 17. double p = DBL_MIN; 18. int t = 0; 19. 20. for (int c = rates_total - (n + 1); c < rates_total; c++) 21. p = (High[c] > p ? High[t = c] : p); 22. ObjectMove(0, def_NameChannel, 0, Time[t], p); 23. p = DBL_MIN; 24. for (int c = t + 1; c < rates_total; c++) 25. p = ((High[c] > p) && (Open[c] < Close[c]) ? High[t = c] : p); 26. ObjectMove(0, def_NameChannel, 1, Time[t], p); 27. 28. return rates_total; 29. }; 30. //+------------------------------------------------------------------+ 31. void OnDeinit(const int reason) 32. { 33. ObjectDelete(0, def_NameChannel); 34. ChartRedraw(); 35. }; 36. //+------------------------------------------------------------------+
Код 06
При выполнении кода 04 сгенерируется то, что видно ниже.

Анимация 04
Не стоит слишком радоваться увиденному, уважаемые читатели, потому что это всего лишь демонстрация. Ни при каких обстоятельствах это не следует рассматривать как окончательное приложение. Но на рисунке 04 мы видим появление линии нисходящего тренда, построенной в соответствии с критериями, заложенными в коде 04. «Но как это возможно?» Проще говоря: я просто указал коду, как искать нисходящую линию тренда в соответствии с моими критериями.
Давайте теперь разберемся, что произошло. В строке 08, как и в коде 03, мы указываем, какой тип объекта мы хотим поместить на графике. Уже в строке 09 мы изменяем одно из свойств объекта. Если бы это свойство не было определено так, как показано здесь в коде 04, результат был бы, как на изображении ниже.

Изображение 01
Прошу заметить, что теперь, рассматривая изображение 01, мы видим, откуда и куда была проведена линия тренда. В данном случае мы ищем линию нисходящего тренда. Линии восходящего тренда определяются по другим критериям. Но поскольку цель здесь не в том, чтобы показать, как автоматически определять и создавать линии тренда, критерии и способы, которыми мы это делаем, действительно работают. Хорошо, но тогда как индикатору удалось найти эти точки для построения линии тренда? Это похоже на магию.
Нет, уважаемый читатель, это определенно не так. Это всего лишь применение базового критерия. Обратите внимание на обработчик события Calculate. Прошу заметить, что здесь у нас два цикла: один для определения первой точки для построения линии тренда, а другой — для определения второй точки, необходимой для построения линии тренда. Когда первая точка найдена, мы используем строку 22, чтобы указать объекту, где будет находиться первая точка привязки. Сразу после нахождения второй точки мы используем линию 26, чтобы указать местоположение второй точки привязки. А остальное делает сама программа MetaTrader 5.
Однако, несмотря на это, я хочу подчеркнуть, что НЕ СЛЕДУЕТ ВОСПРИНИМАТЬ этот индикатор как нечто достойное похвалы. Он был создан, чтобы мы могли обнаружить то, что показано на изображении 01 и в анимации 04. Вряд ли вам удастся обнаружить другие столь же совершенные детали, как те, что видны чуть выше.
«Хорошо, понятно. Но разве мы не можем изменить другие свойства, чтобы создавать более персонализированные объекты?» Да, такое возможно, уважаемые читатели. И ещё один момент: в отличие от того, что происходит, когда мы пытаемся изменить свойства непосредственно на графике, некоторые из этих объектов имеют свойства, которые можно изменить только с помощью кода.
Но давайте рассмотрим простой пример изменения свойств. Его можно увидеть ниже:
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #define def_NameChannel "Demo" 05. //+------------------------------------------------------------------+ 06. int OnInit() 07. { 08. ObjectCreate(0, def_NameChannel, OBJ_TREND, 0, 0, 0); 09. ObjectSetInteger(0, def_NameChannel, OBJPROP_COLOR, clrLawnGreen); 10. ObjectSetInteger(0, def_NameChannel, OBJPROP_WIDTH, 4); 11. 12. return INIT_SUCCEEDED; 13. }; 14. //+------------------------------------------------------------------+ . . .
Код 07
В данном случае, в коде 07 мы видим только фрагмент, который необходимо было изменить относительно того, что показано в коде 06. Но обратите внимание, что в строке 09 мы указываем, какой цвет мы хотим использовать для объекта. А также, какую толщину линии следует использовать в строке 10. В результате выполнения данного кода мы получаем то, что видим на изображении ниже.

Изображение 02
Итак, слушайте внимательно, уважаемые читатели. В текущей версии кода НЕЛЬЗЯ изменить цвет или толщину линии, используя сочетание клавиш для доступа к информации индикатора, как показано на изображении ниже.

Изображение 03
Для изменения свойств этих объектов нам потребуется использовать другое диалоговое окно. Иными словами, в этом случае нам придётся использовать то, что показано на изображении ниже.

Изображение 04
Я понимаю, это кажется слишком сложным, но это классический способ использования MetaTrader 5. Тем не менее, существуют способы избежать подобных ситуаций, которые позволяют пользователю изменять свойства объекта на основе конфигурации, заданной непосредственно в индикаторе. Но давайте не будем спешить, ведь это лишь наш первый контакт с объектами. В таком случае, я думаю, у вас уже будет много возможностей для экспериментов, так что вы будете готовы к следующей статье.
Заключительные идеи
В сегодняшней статье мы начали рассматривать, как можно работать с объектами непосредственно на графике, используя специально разработанный код, призванный это нам показать. Хотя этот первый контакт, возможно, был несколько поверхностным, он уже показал: если спокойно обдумать цель и хорошо спланировать задачу, мы можем сделать много очень интересных вещей. Для этого вам будет необходимо попрактиковаться и изучить, как работает каждый из объектов, предоставляемых MQL5, и как их можно использовать в MetaTrader 5. Без истинного понимания имеющихся возможностей вы не сможете воплотить в жизнь ни одну из своих идей.
Как всегда, в этой серии статей вы найдете полные коды в приложении. Однако, и особенно в контексте данной статьи, я должен предупредить, что все предоставленные коды предназначены для изучения и отработки на практике того, что объясняется в статье. Не используйте представленный здесь код в качестве готовых приложений или для других целей, не связанных с изучением материалов, поскольку это может серьезно навредить вашему кошельку.
Перевод с португальского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/pt/articles/15975
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Нейросети в трейдинге: Единая архитектура взаимодействия рыночных признаков и торгового контекста (Окончание)
Внедрение в MQL5 практических модулей из других языков (Часть 1): Создание библиотеки SQLite3 как в Python
Переосмысливаем классические стратегии (Часть 13): Обновление стратегии по пересечению скользящих (Часть 2)
Возможности Мастера MQL5, которые вам нужно знать (Часть 70): Использование паттернов SAR и RVI с сетью экспоненциального ядра
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования