Español Português
preview
От начального к среднему уровню: Подокна (IV)

От начального к среднему уровню: Подокна (IV)

MetaTrader 5 — Примеры |
49 1
CODE X
CODE X

Введение

В предыдущей статье, От начального к среднему уровню: Подокна (III), мы объясняли, как можно работать с определёнными ситуациями, связанными с подокнами. Основная идея той статьи связана со свойствами, которые мы можем назначить определённому индикатору. Эти свойства позволяют указать компилятору, как именно должно создаваться — или не создаваться — определённое подокно.

Как объяснялось в предыдущей статье, бывают случаи, когда МЫ НЕ ХОТИМ, чтобы у нашего индикатора был второй экземпляр. Этот тип ситуации будет более подробно рассмотрен в другой статье позже, когда мы начнём использовать определённые свойства, чтобы лучше контролировать то, что MetaTrader 5 действительно должен делать.

Поэтому нам ещё многое предстоит рассмотреть из того, что я считаю базовыми знаниями по MQL5. Хотя MetaTrader 5 в первую очередь задумывался как торговая платформа, мы можем многое в ней изменить так, чтобы в итоге она служила совсем иной цели.

Помните, что мы можем заставить MetaTrader 5 делать что угодно. Во многих случаях нам придётся прибегать к средствам, выходящим за рамки того, что MQL5 предлагает по умолчанию. В таких случаях нам придётся перейти к C или C++ и использовать какой-либо способ связать код MQL5 с C или C++. Сделав это, перед вами откроются врата рая — или, возможно, ада.

Эта серия статей не будет заходить на эту территорию, поскольку я считаю, что использование других языков, таких как C и C++, для ещё большего расширения контроля MQL5 над MetaTrader 5 — это действительно продвинутая тема. И это здесь рассматриваться не будет.

Вернёмся к нашему главному вопросу. Идея этой статьи — показать первые шаги, необходимые для того, чтобы обойти некоторые особенности — или, точнее, помочь MetaTrader 5 управлять индикаторами в подокнах. То, что мы здесь увидим, поначалу может показаться немного запутанным. Однако, если вы будете практиковаться и поймёте то, что будет показано, то в будущем сможете справляться со многими разнообразными и сложными ситуациями.
Итак, давайте на время оставим повседневные заботы и сосредоточим внимание на том, что будет объяснено здесь, в этой новой теме.

Подокна (IV)

В предыдущей статье мы рассмотрели то, что позволило бы нам создать код, показанный ниже.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #property description "DEMO Indicator"
05. //+------------------------------------------------------------------+
06. #property indicator_separate_window
07. #property indicator_height          50
08. #property indicator_plots           0
09. //+------------------------------------------------------------------+
10. int OnInit(void)
11. {
12.     IndicatorSetString(INDICATOR_SHORTNAME, "Test 123.");
13.     
14.     return INIT_SUCCEEDED;
15. };
16. //+------------------------------------------------------------------+
17. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
18. {
19.     return rates_total;
20. };
21. //+------------------------------------------------------------------+

Код 01

И хотя все коды, рассмотренные в предыдущей статье, работоспособны, то есть могут выполняться в MetaTrader 5, при компиляции некоторые из них могут вызывать предупреждение компилятора. Это можно исправить, добавив то, что показано в восьмой строке этого кода 01. Поскольку этот показанный выше индикатор я считаю «пустым», он идеально подходит для демонстрации и изучения всех свойств индикаторов. Когда я говорю, что индикатор пустой, я имею в виду, что он абсолютно ничего не делает и не имеет никакой практической функциональности при размещении на графике. Поскольку при использовании этого кода 01 мы не будем отображать на графике ни линий, ни кривых, мы указываем, что количество построений индикатора равно нулю, чтобы компилятор не выдавал никаких предупреждений.

Хорошо, как мы видели в предыдущей статье, шестая строка этого кода 01 сообщит MetaTrader 5, что при попытке использовать этот индикатор на графике его следует разместить в подокне. Оно может быть создано или нет, как было показано в предыдущих статьях. Седьмая строка укажет размер этого подокна, если возникнет необходимость его создать. Что касается этих свойств индикатора, думаю, ни у кого из вас не должно возникнуть сомнений, поскольку всё это довольно просто, понятно и прямолинейно.

Мне нужно, чтобы вы поняли: этот код 01 служит основой для другого подхода, который мы можем использовать. Хотя поначалу это может показаться несколько запутанным, такой подход позволяет нам гораздо лучше контролировать происходящее в определённых ситуациях, которыми в противном случае было бы гораздо сложнее управлять.

Чтобы вы поняли, какого рода проблему мы можем решить, глубоко разобравшись в том, что делает этот код 01, необходимо, чтобы вы усвоили материал, показанный в последних статьях этой серии. Там было показано, что MetaTrader 5 может не допустить появления более одного экземпляра индикатора на одном графике. Это позволяет избежать ненужной траты ресурсов. То же самое уже не применимо, когда мы начинаем использовать свойство, указывающее на необходимость подокна. В этом случае MetaTrader 5 игнорирует наличие уже открытого экземпляра и создаёт новые экземпляры по мере того, как пользователь или трейдер снова добавляет тот же индикатор на график. Всё это подробно объяснялось в предыдущих статьях. Тем не менее существует способ избежать этого и, по крайней мере в общем случае, не допустить, чтобы новый экземпляр определённого реализованного нами индикатора размещался на графике, когда мы работаем с подокнами.

Чтобы понять, как мы можем это сделать, нужно обратиться к документации MQL5, поскольку именно там объясняется, как это сделать. Если вы внимательно присмотритесь, то найдёте функцию ChartIndicatorAdd. Эта функция очень интересна, хотя, если судить только по документации, она может показаться самой обычной. То, что вы, возможно, не представляете себе иных способов использования этой функции, кроме предусмотренных, сильно ограничивает ваши возможности и нередко даже мешает понять, почему код ведёт себя определённым образом. Прежде чем разбирать это, я хочу, чтобы вы обратили внимание на одно замечание из самой документации. Чтобы облегчить понимание дальнейшего объяснения, ниже мы полностью приведём важный фрагмент документации об этой функции, который вскоре нам понадобится.

Примечание

Если индикатор должен отображаться в отдельном подокне (например, при создании iMACD или пользовательского индикатора с указанным свойством #property indicator_separate_window) и применяется к главному окну графика, он может быть невидим, хотя по-прежнему будет отображаться в списке индикаторов. Это означает, что шкала индикатора отличается от шкалы ценового графика и что значение применённого индикатора не попадает в видимый диапазон ценового графика. В этом случае функция GetLastError() возвращает код 0, что указывает на отсутствие ошибок. Значения этого «невидимого» индикатора можно увидеть в окне данных (Data Window) и получить из других приложений MQL5.

Если кратко, документация говорит, что в главное окно можно загрузить индикатор, предназначенный для использования в подокне. Он не будет виден и не создаст подокно для своего отображения, если это не будет правильно указано при вызове функции ChartIndicatorAdd.

То, что вы не сразу понимаете объяснение в документации, совершенно нормально. Многие хорошие программисты поначалу сталкиваются с этой трудностью. Это происходит потому, что документация призвана в упрощённой форме объяснить, какого поведения следует ожидать, а не описывать то, что вы, возможно, захотите сделать, но что не было учтено при создании системы. И это применимо к любому языку программирования. Для тех, кто только начинает, значительная часть информации, представленной в документации, может показаться довольно запутанной. С опытом вы научитесь извлекать из неё ценную информацию для создания нестандартных решений. Именно потому, что я знаю об этой трудности и понимаю, насколько многим бывает сложно пользоваться документацией, я время от времени связываю объяснение в статье с тем, что можно увидеть в ней. Так со временем вы сможете понять любое объяснение, которое там встретится, и обходиться своими силами. По этой причине мы можем немного глубже разобраться в том, что уже было сказано, чтобы вы действительно поняли, что именно говорится в документации.

Для этого мы поступим следующим образом: мы знаем, что код 01 создаст подокно при применении к графику. Итак, давайте создадим ещё один код, который на этот раз НЕ БУДЕТ СОЗДАВАТЬ ПОДОКНО. Этот код приведён ниже.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #property description "DEMO Indicator"
05. //+------------------------------------------------------------------+
06. #property indicator_chart_window
07. #property indicator_plots           0
08. //+------------------------------------------------------------------+
09. int OnInit(void)
10. {
11.     IndicatorSetString(INDICATOR_SHORTNAME, "Test 456S.");
12.     
13.     return INIT_SUCCEEDED;
14. };
15. //+------------------------------------------------------------------+
16. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
17. {
18.     return rates_total;
19. };
20. //+------------------------------------------------------------------+

Код 02

Отлично, теперь у нас есть два довольно простых кода, соответствующих двум пустым индикаторам. А теперь самое интересное, напрямую связанное с тем, что сказано в документации. Так что будьте внимательны, чтобы понять, что мы будем делать и почему в итоге получится тот или иной результат. Итак, вопрос: что произойдёт, если мы заставим этот код 02 добавить на график индикатор из кода 01, используя для этого функцию ChartIndicatorAdd? Наверняка вы сразу скажете, что это заставит код 01 создать подокно, ведь он и так делает это естественным образом. Однако что именно заставляет вас так утверждать? Возможно, дело в том, что в шестой строке кода 01 мы указываем компилятору, чтобы он сообщил MetaTrader 5, что индикатор, созданный на основе кода 01, должен находиться в подокне? Если причина именно в этом, то сейчас мы сделаем то, что вам действительно нужно проверить локально. На практике всё не всегда так просто, как иногда вам может казаться. Итак, чтобы объяснение было действительно наглядным и вы поняли, что происходит, давайте изменим код 02, чтобы можно было использовать функцию ChartIndicatorAdd. В результате получаем приведённый ниже код.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #property description "DEMO Indicator"
05. //+------------------------------------------------------------------+
06. #property indicator_chart_window
07. #property indicator_plots           0
08. //+------------------------------------------------------------------+
09. int OnInit(void)
10. {
11.     IndicatorSetString(INDICATOR_SHORTNAME, "Test 456.");
12.     ChartIndicatorAdd(0, 0, iCustom(NULL, NULL, "Tutor\\Code 01"));
13.     
14.     return INIT_SUCCEEDED;
15. };
16. //+------------------------------------------------------------------+
17. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
18. {
19.     return rates_total;
20. };
21. //+------------------------------------------------------------------+

Код 03

Хорошо, теперь обратите внимание на некоторые детали этого кода 03. Обратите внимание, что в двенадцатой строке мы используем функцию ChartIndicatorAdd. Здесь мы не выполняем никакую проверку ошибок времени выполнения (run-time). Именно поэтому следует соблюдать осторожность при попытке запустить этот код 03 локально. Во-первых, убедитесь, что код 01 был правильно скомпилирован. Таким образом, при выполнении двенадцатой строки этого кода 03 MetaTrader 5 получит доступ к исполняемому файлу индикатора 01. Во-вторых, можно заметить, что внутри функции ChartIndicatorAdd я использую вызов iCustom. Цель этого вызова — создать ссылку на пользовательский индикатор. То есть это позволяет нам расширить возможности или, точнее, использовать индикаторы, кроме тех, которые MetaTrader 5 уже предоставляет средствами MQL5.

В статье "От начального к среднему уровню: Индикатор (V)" мы начали говорить об этих индикаторах, то есть о так называемых технических индикаторах. Здесь мы продолжаем развивать эту тему. Хорошо, на этом этапе необходимо убедиться, что и каталог, и имя индикатора, который будет загружен с помощью iCustom, указаны правильно. В приложенном файле необходимая структура каталогов уже будет настроена правильно. Поэтому, чтобы протестировать этот код 03, не изменяйте структуру, если только вы действительно не понимаете, что делаете. В противном случае конечный результат будет отличаться от того, который будет показан здесь.

После этих мер предосторожности мы можем перейти к проверке того, какой результат получим при использовании этого кода 03. Это можно увидеть на следующей анимации.

Анимация 01

Что это было? Я этого не понимаю. Разве индикатор из кода 03 не добавил индикатор 01 на график? Давайте проверим, что произошло. Для этого достаточно открыть список индикаторов, присутствующих на графике, и проверить, какие из них там отображаются. Это можно увидеть на следующем изображении.

Изображение 01

Как странно. Индикатор 03 действительно смог загрузить индикатор 01 на график. Индикатор 01 не создал подокно, как ожидалось. Или, точнее, я предполагал, что при выполнении индикатора 01 должно было создаться подокно. Хм, подождите-ка минутку. Действительно ли выполняется этот индикатор 01? Потому что, на мой взгляд, произошедшее только что не имеет никакого смысла. Честно говоря, я немного растерян.

Поэтому важно, чтобы вы старались применять все знания, изложенные в этих статьях, дорогой читатель, и всегда проводили собственные локальные тесты, чтобы понять детали. Любые вопросы, которые вы не проясните на этом этапе обучения, позже обязательно дадут о себе знать. В любом случае, анализируя происходящее здесь, вы заметите, что индикатор 01 не только загружается, но и выполняется. И вот что важно: он не отображается на графике. Это происходит потому, что в коде 03 мы не указываем, что индикатор должен отображаться. Именно это и объясняется в тексте документации.

Хорошо, давайте теперь вернёмся к документации, чтобы разобраться ещё в одном вопросе: как нам добиться создания подокна. Чтобы избежать любых упущений или ошибок в переводе, обратите внимание на следующее изображение и на то, какой именно информации мы должны уделить внимание.

Изображение 02

Область, выделенная на изображении 02, — именно та часть, которая нас интересует. Обратите внимание на следующее: здесь указано, что при добавлении индикатора с помощью функции ChartIndicatorAdd мы должны указать подокно, в которое его следует добавить. Обратите самое пристальное внимание на эту информацию, мой дорогой читатель, потому что в зависимости от того, что именно вы планируете делать с помощью кода, автоматизируя тем самым ту или иную стратегию, чёткое и объективное понимание того, что выделено на изображении 02, может определить, будет ли ваш код работать так, как задумано.

Чтобы немного упростить ситуацию и одновременно объяснить этот момент тем, кто, возможно, не понял, что означает выделенная область на изображении 02, мы проведём краткую демонстрацию. Но сначала давайте разберёмся, как эта простая информация, выделенная на изображении 02, полностью меняет работу кода 03. Поскольку я хочу, чтобы вы могли проверить это на практике, я создам новый индикатор, который также будет доступен в прикреплённом файле. Его код приведён ниже.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #property description "DEMO Indicator"
05. //+------------------------------------------------------------------+
06. #property indicator_chart_window
07. #property indicator_plots           0
08. //+------------------------------------------------------------------+
09. int OnInit(void)
10. {
11.     IndicatorSetString(INDICATOR_SHORTNAME, "Test 456.");
12.     ChartIndicatorAdd(0, (int)ChartGetInteger(0, CHART_WINDOWS_TOTAL), iCustom(NULL, NULL, "Tutor\\Code 01"));
13.     
14.     return INIT_SUCCEEDED;
15. };
16. //+------------------------------------------------------------------+
17. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
18. {
19.     return rates_total;
20. };
21. //+------------------------------------------------------------------+

Код 04

А теперь — максимальное внимание к тому, что будет объяснено, потому что это крайне важно для понимания того, что мы будем делать дальше. Обратите внимание, что единственное различие между кодом 03 и этим кодом 04 заключается именно во втором аргументе функции ChartIndicatorAdd, который находится в двенадцатой строке обоих кодов. И вот что важно: этого простого различия более чем достаточно, чтобы исполняемый файл индикатора вёл себя совершенно иначе, чем в анимации 01.

Так же, как нам пришлось принять некоторые меры предосторожности при выполнении кода 03, мы должны проявить такую же осторожность при попытке выполнить код 04. То есть мы должны убедиться, что код 01 был правильно скомпилирован и что исполняемый файл находится в месте, указанном в двенадцатой строке кода 04. Убедившись в этом, мы можем запустить код 04 в MetaTrader 5 на любом графике. Результат показан в следующей анимации.

Анимация 02

Посмотрите, как любопытно. В отличие от того, что происходило раньше, теперь действительно создаётся новое подокно, как мы и ожидали. И, посмотрев список индикаторов, мы увидим следующий результат.

Изображение 03

Отлично. Вопрос в том: почему сейчас это работает, а раньше — нет? Ответ заключается в том, что, если вы посмотрите код 03, то увидите: второй аргумент, передаваемый в функцию ChartIndicatorAdd, указывает MetaTrader 5 добавить индикатор в главное окно. Поскольку индикатор из кода 01 ОЖИДАЕТ И ТРЕБУЕТ подокно, он не отображается на экране. Даже если бы он отображал важную информацию, ОН НЕ ОТОБРАЖАЛСЯ БЫ и оставался бы невидимым для пользователя или оператора, наблюдающего за графиком.

В коде 04, напротив, в том же аргументе, который раньше указывал на главное окно, мы теперь просим MetaTrader 5 определить и сообщить нам количество подокон, имеющихся на графике, а затем добавить индикатор, указанный в третьем аргументе, в следующее подокно. По этой причине код 04 позволяет коду 01 создать новое подокно. Это очень полезно и позволяет нам делать много интересных вещей, которые мы рассмотрим и изучим в другой раз.

Прежде чем завершить эту статью, я хочу объяснить вам ещё одну вещь о функции ChartIndicatorAdd. Считайте это небольшим бонусом. Если вы внимательно следили за тем, что мы делали до сих пор, то наверняка заметили кое-что. Во всех случаях мы можем получить довольно интересные результаты очень простым способом и практически без усилий. В одном случае мы указали, что добавляемый индикатор должен быть размещён в главном окне, а в другом — что должно быть создано новое подокно. Вопрос: что произойдёт, если на графике уже есть подокно, а мы загрузим индикатор и разместим его в нём? "Подождите немного. К чему вы ведёте этой гипотезой?".

Итак, идея, которую я хочу, чтобы вы поняли, уже рассматривалась в другой статье из этой же серии. Речь идёт о статье "От начального к среднему уровню: Подокна (II)". В той статье было показано, что мы можем заставить один индикатор использовать значения, рассчитанные другим индикатором, для создания третьего индикатора. Сама по себе идея довольно проста и интересна. Чтобы это происходило автоматически сразу после добавления индикатора на график, необходимо точно понимать, что именно вы реализуете.

Чтобы не усложнять всё чрезмерно и без необходимости, рассмотрим здесь довольно простой пример. Хотя это и не работает на 100 %, это поможет вам понять некоторые моменты, связанные с более продвинутой работой с индикаторами. Итак, давайте начнём с того, что показано на следующей анимации.

Анимация 03

Теперь, когда это сделано, давайте создадим новый индикатор, и вы сразу поймёте, зачем это нужно. Его код приведён ниже.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #property description "DEMO Indicator"
05. //+------------------------------------------------------------------+
06. #property indicator_chart_window
07. #property indicator_plots           0
08. //+------------------------------------------------------------------+
09. int OnInit(void)
10. {
11.     for (int c0 = 0; c0 < (int)(ChartGetInteger(0, CHART_WINDOWS_TOTAL)); c0++)
12.         for (int c1 = (ChartIndicatorsTotal(0, c0) - 1); c1 >= 0; c1--)
13.             PrintFormat("In the sub window [%d] was found this indicator >>%s<<", c0, ChartIndicatorName(0, c0, c1));
14. 
15.     return INIT_SUCCEEDED;
16. };
17. //+------------------------------------------------------------------+
18. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
19. {
20.     return rates_total;
21. };
22. //+------------------------------------------------------------------+

Код 05

Цель этого кода 05 заключается просто в том, чтобы показать названия индикаторов, присутствующих на графике. Об этом уже говорилось в предыдущих статьях; здесь мы пойдём ещё дальше. Итак, при выполнении этого кода 05 мы получим результат, показанный на следующем изображении.

Изображение 04

Нас интересует информация, выделенная на этом же изображении 04, а именно название индикатора, присутствующего в подокне. А теперь будьте внимательны, потому что эта часть очень важна и скоро нам понадобится. Поскольку мы хотим добавить индикатор и он должен быть связан с индикатором, добавленным в анимации 03, нам необходимо знать его название. Пользователь или оператор мог добавить на график тот или иной индикатор, даже того же типа, но не тот, который нам действительно нужен или который мы хотим использовать. В таком случае искомый индикатор может находиться не совсем там, где мы ожидали. Таким образом, зная имя индикатора, легко найти индекс подокна, который наш код должен использовать, чтобы привязать новый индикатор к тому, который мы хотим использовать в качестве основы для расчёта. На практике код будет выглядеть следующим образом.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #property description "DEMO Indicator"
05. //+------------------------------------------------------------------+
06. #property indicator_chart_window
07. #property indicator_plots           0
08. //+------------------------------------------------------------------+
09. int OnInit(void)
10. {
11.     int index = -1;
12. 
13.     for (int c0 = 0; (index < 0) && (c0 < (int)(ChartGetInteger(0, CHART_WINDOWS_TOTAL))); c0++)
14.         index = (ChartIndicatorName(0, c0, 0) == "StdDev(20)" ? c0 : index);
15. 
16.     IndicatorSetString(INDICATOR_SHORTNAME, "Demo 123.");
17.     if (index >= 0)
18.         ChartIndicatorAdd(0, index, iCustom(NULL, NULL, "Examples\\Custom Moving Average", 20, 0, 0, PRICE_CLOSE));
19. 
20.     return (index < 0 ? INIT_FAILED : INIT_SUCCEEDED);
21. };
22. //+------------------------------------------------------------------+
23. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
24. {
25.     return rates_total;
26. };
27. //+------------------------------------------------------------------+

Код 06

Итак, прежде чем посмотреть результат выполнения этого кода 06, я должен пояснить один момент. Обратите внимание на то, какой индикатор мы используем в строке 18. В данном случае я использую индикатор, встроенный в сам MQL5. Это значительно упрощает дело и существенно сокращает количество моментов, которые пришлось бы здесь объяснять. Однако это не решает ситуацию полностью и не делает код на 100 % работоспособным. Причина проста. Видите последний аргумент в вызове iCustom? Итак, этот аргумент, PRICE_CLOSE, приведёт к тому, что добавленный индикатор будет рассчитывать данные на основе котировочной информации основного графика. Чтобы использовать значения, рассчитанные индикатором, добавленным в анимации 03, необходимо, чтобы этот аргумент был другим. Недостаточно просто изменить его; нам нужно пойти другим путём. Об этом пути мы поговорим позже, поскольку, чтобы понять причину, сначала нужно объяснить ещё один вопрос, который в этой серии статей пока не был должным образом освещён. Так что наберитесь терпения.

Несмотря на это, основная идея этого кода 06 по-прежнему вполне справедлива и её стоит рассмотреть, потому что в некоторых конкретных случаях вы можете использовать подход, очень похожий на показанный здесь, и получить хороший результат. Хорошо, чтобы упростить сравнение между тем, чего мы ожидали, и тем, что действительно будет показано, мы воспользуемся тем, что уже видели в предыдущих статьях, где я объяснял, как использовать значения одного индикатора для расчёта другого. Итак, исходное изображение показано ниже.

Изображение 05

Обратите внимание, что при добавлении этого кода 06 на график необходимо, чтобы индикатор, загруженный в строке 18, имел то же отображение, что и чёрная линия на изображении 05. Именно по этой ранее упомянутой причине результат будет отличаться и потребует настройки со стороны пользователя или оператора. Посмотрите в следующих анимациях, как это делается.

Анимация 04

Итак, действительно, код 06 смог добавить нужный индикатор. Однако расчётные значения неверны, так как используются значения, полученные из котировок символа. Поэтому нам придётся внести небольшую корректировку.

Анимация 05

Теперь расчётное значение действительно верно. Возможно, вы задаётесь вопросом: не проще ли сразу разместить на графике индикатор, рассчитывающий скользящую среднюю? Ответ — и да, и нет. Дело в том, что в зависимости от конфигурации, которую вы хотите использовать, скользящая средняя может в итоге оказаться не в том месте. Помните следующее: скользящая средняя будет добавлена только в том случае, если имя индикатора совпадает с именем, указанным в коде 06. Если имена не совпадают, скользящая средняя не будет добавлена.


Заключительные замечания

В этой статье было показано, как работать несколько более продвинутым образом со всем, что связано с использованием подокон. Хотя рассмотренное здесь — лишь часть того, что я считаю базой для гораздо более глубокого изучения, понимание этого поможет вам более правильно использовать ресурсы, доступные в MetaTrader 5. Чтобы этого добиться, нам нужно использовать MQL5, чтобы лучше контролировать то, что будет отображаться.

В любом случае, постарайтесь попрактиковаться и изучить то, что здесь объяснялось. Вскоре мы подробнее рассмотрим, как правильно запрограммировать код 06, чтобы после размещения индикатора на графике не требовалось выполнять никаких дополнительных настроек.

Файл MQ5 Описание
Indicators\Code 01 Базовая демонстрация
Indicators\Code 02 Базовая демонстрация
Indicators\Code 03 Базовая демонстрация
Indicators\Code 04 Базовая демонстрация
Indicators\Code 05 Базовая демонстрация






Перевод с португальского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/pt/articles/17152

Прикрепленные файлы |
Anexo.zip (2.71 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (1)
Vitaly Muzichenko
Vitaly Muzichenko | 6 окт. 2026 в 19:16

Write an article on how to create two subwindows in one indicator; that would be progress!

Напишите статью, как сделать в одном индикаторе два подокна, вот это будет прогресс!

Особенности написания Пользовательских Индикаторов Особенности написания Пользовательских Индикаторов
Написание пользовательских индикаторов в торговой системе MetaTrader 4
Стресс-тестирование последовательностей сделок методом Монте-Карло в MQL5 Стресс-тестирование последовательностей сделок методом Монте-Карло в MQL5
Бэктест показывает лишь одну траекторию из множества возможных исходов. Данный MQL5-скрипт выполняет 1000 бутстрап-передискретизаций Монте-Карло для ряда P&L по сделкам, строит на графике веерную диаграмму процентилей с помощью CCanvas и выводит вероятность разорения, Value at Risk (VaR) и наихудшую просадку на уровне 95-го процентиля. В результате получается практический взгляд на траекторный риск и подверженность просадкам, выходящий за рамки одной кривой эквити.
Особенности написания экспертов Особенности написания экспертов
Написание и тестирование экспертов в торговой системе MetaTrader 4.
Нейронная сеть на практике: График функции ReLU Нейронная сеть на практике: График функции ReLU
Мы создадим индикатор, полностью написанный на MQL5, для отображения на графике функции активации и её производной, взяв в качестве примера ReLU. Мы объясним влияние производных на выбор функции активации и необходимые меры предосторожности в недифференцируемых точках. Читатель сможет интерактивно визуализировать кривые и получит практическую основу, чтобы решать, когда стоит использовать те или иные функции активации, а когда — нет.