English 中文 Español Deutsch 日本語 Português
preview
От начального до среднего уровня: Массивы и строки (II)

От начального до среднего уровня: Массивы и строки (II)

MetaTrader 5Примеры |
405 0
CODE X
CODE X

Введение

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

В предыдущей статье, "От начального до среднего уровня: Массивы и строки (I)", мы дали краткое представление о строках и массивах, хотя данная статья почти полностью посвящена строкам, всё, что в ней было показано, - лишь легкое и краткое введение в тему. Однако для того, чтобы разобраться с другими темами, нам нужно немного углубиться в предыдущие объяснения. Поэтому для понимания сегодняшней статьи необходимо разобраться в том, что было представлено в предыдущей.

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

Теперь мы можем перейти к основной теме данной статьи. Вот наша с вами новая тема.


Пользовательский формат

Один из самых интересных моментов в программировании на MQL5 - это то, что нам не нужно беспокоиться о создании определенных вещей. На самом деле, редко встречается такое, чтобы стандартная библиотека не соответствовала нашим требованиям. Однако вполне возможно, что она не будет полностью соответствовать тому, что нам нужно или хочется сделать. Примером может служить создание пользовательского формата для представления какой-либо информации либо на терминале, либо на графическом объекте, который будет использоваться.

Поскольку на данном этапе мы не будем использовать графические объекты, вся наша работа будет ориентирована на использование стандартного вывода MetaTrader 5, то есть терминала. Скоро покажем, как можно сделать всё гораздо интереснее. Но чтобы добиться этого, нужно сначала приобрести надежные знания о некоторых особенностях языка программирования.

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

Самая увлекательная часть работы программиста - это не определение цели для конкретного знания, а разработка способов использования данных знаний для решения конкретной проблемы. Самое интересное, что как только вы поймете, как работают определенные вещи, и начнете придумывать способы использования данных знаний для решения конкретной проблемы, эти знания станут целенаправленными.

Теперь я хочу, чтобы вы задумались над следующей проблемой: предположим, вы хотите отображать или печатать двоичные значения в терминале MetaTrader 5. Причина не имеет значения, важна только проблема. Перед вами стоит четкая задача, и вы думаете: "Хорошо, я могу использовать форматирование строк для представления двоичных значений в терминале". Отлично, это было бы первой мыслью хорошего программиста. Однако более опытный программист уже знает ответ. Начинающий программист будет искать в документации способ отформатировать строку, чтобы показать двоичное представление числового значения, и обнаружит, что такой функции нет. Именно в данный момент творчество, соединенное со знанием, начинает указывать путь вперед.

Очень хорошо, так как не существует предопределенного формата для представления двоичных значений, нам придется его создать. Будучи новичком в программировании и принимая во внимание только информацию, представленную в предыдущих статьях, можно подумать, что это невозможно. Но так ли это на самом деле? Давайте посмотрим, можно ли это сделать, используя только информацию, представленную в других статьях.

Во-первых, мы знаем, что в стандартной библиотеке есть функция, которая позволяет форматировать различные типы данных. Всё, что нам нужно сделать, - это создать наш пользовательский формат, чтобы можно было форматировать двоичные значения. Это самая простая часть, но есть и более сложная задача. Это связано с тем, что, в отличие от C и C++, где в функцию можно добавить неограниченное количество данных или аргументов, в MQL5 такой возможности нет. И насколько я знаю, C и C++ это единственные языки, которые позволяют реализовать подобную функциональность. Конечно, также есть Assembly, но никто не может быть настолько безумен, чтобы программировать что-то на Assembly. Честно говоря, это было бы проверкой на адекватность.

Хорошо. Несколько усложняет ситуацию то, что в функцию нельзя передать неограниченное количество аргументов, по крайней мере, на первый взгляд. Однако, для решения проблемы, мы можем разбить её на более мелкие части. Поскольку мы хотим создать новый формат и использовать тот, который уже присутствует в стандартной библиотеке MQL5, мы можем работать с данными для достижения этой цели. Как? Очень просто: мы создадим функцию, которая возвращает строку со значением, преобразованным в двоичное представление. Поскольку стандартная библиотека MQL5 умеет работать со строками для форматирования текста, нам не составит труда создать собственное форматирование.

Рассуждая таким образом, может показаться, что реализация слишком сложная. Но если посмотреть на приведенный ниже код, то можно увидеть, что всё просто:

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     uchar value = 138;
07. 
08.     PrintFormat("The value %d in binary is written as: %s", value, BinaryToString(value));
09. }
10. //+------------------------------------------------------------------+
11. string BinaryToString(const uchar arg)
12. {
13.     return "--BINARY--";
14. }
15. //+------------------------------------------------------------------+

Код 01

Когда мы запустим код 01, результат будет таким:

Рисунок 01

В этот момент можно подумать: "Вау, но это не то, что мы хотели реализовать". Действительно, это не то, чего мы хотим. Но это служит для того, чтобы показать вам: мы можем опираться на уже существующее и пытаться создать что-то новое. Обратите внимание, что текстовая строка, которая находится в строке 13, такая же, как на изображении 01. Другими словами, это работает.

Теперь нам только остается преобразовать или перевести значение, получаемое функцией, в двоичное представление. Затем мы вставляем это представление в строку и возвращаем его. Это мы делаем на строке 13.

Как же преобразовать полученное значение в строку, которая содержит только нули и единицы? Всё очень просто, дорогие читатели. Для этого мы используем цикл. Однако есть один маленький момент. Но я объясню это непосредственно в коде, который можно увидеть ниже:

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     uchar value = 138;
07. 
08.     PrintFormat("The value %d in binary is written as: %s", value, BinaryToString(value));
09. }
10. //+------------------------------------------------------------------+
11. string BinaryToString(const uchar arg)
12. {
13.     string  sz0 = "";
14.     uchar   mask = 0x80;
15. 
16.     while (mask)
17.     {
18.         sz0 = sz0 + ((arg & mask) == mask ? "1" : "0");
19.         mask = mask >> 1;
20.     }
21. 
22.     return sz0;
23. }
24. //+------------------------------------------------------------------+

Код 02

При запуске этого кода в терминале MetaTrader 5 появляется изображение, показанное ниже:

Рисунок 02

Безусловно, это отлично. Другими словами, обладая довольно базовыми знаниями, мы справились с поставленной задачей, но в этом коде есть небольшая деталь, которую не стоит упускать. С теми знаниями, которые были продемонстрированы до настоящего момента, мы НЕ МОЖЕМ использовать любой тип данных для преобразования его в двоичное представление. Это было бы возможным только при углублении в более сложные вопросы программирования. Но для простых вопросов мы будем использовать только один тип данных, в данном случае uchar. У нас уже есть функция, которая действительно работает. И заметьте, что она очень простая. Более того, нет необходимости объяснять, как эта функция выполняет свою задачу, поскольку всё, что сделано здесь, уже объяснялось в предыдущих статьях. Однако, поскольку оператор сдвига еще не был объяснен и используется в этой функции, я считаю разумным объяснить, как он работает. Мы рассмотрим это в следующей теме. Прежде чем продолжить, я хотел бы обратить ваше внимание на одну важную деталь: переменная `mask` должна иметь ту же ширину битов, что и переменная `arg`. Это гарантирует идеальное преобразование и перевод значений. По мере публикации новых статей с более сложным содержанием мы будем рассматривать, как сделать так, чтобы компилятор решил эту проблему за нас. Это позволит нам использовать любые типы данных, от сложных типов до более простых, не изменяя практически ничего в функции, которую показываем в коде 02. Но мы разберемся с этим позже. А пока давайте узнаем, как работает оператор сдвига. Так что давайте перейдем к новой теме.


Оператор Shift, или оператор сдвига

Как правило, операторы достаточно понятны на интуитивном уровне. Однако оператор shift может смутить некоторых людей, поскольку он предназначен исключительно для работы с вычислительной информацией. По крайней мере, мне не известно о его использовании вне вычислительной техники или цифровой электроники. Данный оператор, который можно увидеть в строке 19 кода 02, очень практичен и даже интересен в нескольких случаях. Однако это НЕ специальный оператор, ведь он просто заменяет два других оператора, которые часто встречаются в некоторых кодах. Я говорю о двух операторах, потому что существует два типа сдвига: один для сдвига вправо, другой для сдвига влево. Некоторые начинающие программисты путают этих операторов сдвига с операторами отношения, используемых для определения того, является ли одно значение больше или меньше другого. Такая путаница часто случается из-за невнимательности, так как оператор сдвига состоит из двух стрелок - вправо или влево, - в то время как в операторах соотношения используется только одна стрелка.

Хорошо, но что говорит нам этот оператор сдвига? При его использовании этот оператор сообщает нам, на сколько бит данное значение сдвинется вправо или влево. На первый взгляд этот тип операции может показаться несколько сложным. Однако это гораздо проще, чем использовать операторы, которые он заменяет. 

Как такое возможно? Это не понятно. Если есть другой способ сказать то же самое, почему бы нам не использовать его? Может надо показать, что это за альтернативный путь? Конечно, я могу показать его. Собственно, именно поэтому я и пишу об этом, ведь я хочу, чтобы вы поняли, почему иногда один ответ не использует одну и ту же реализацию. Маловероятно, что у двух программистов возникла одна и та же идея для решения той же задачи. Однако я не утверждаю, что это не может произойти, я лишь говорю, что это маловероятно. А это связано с тем, что способ решения проблемы зависит от уровня знаний и опыта каждого отдельного программиста.

Давайте вернемся к нашему вопросу. Чтобы просто и наглядно объяснить, как работают операторы сдвига, давайте поэкспериментируем с приведенным ниже кодом.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     const uchar shift = 1;
07.     uchar   i0 = 153,
08.             i1,
09.             i2,
10.             i3,
11.             i4;
12. 
13.     i1 = i0 << shift;
14.     i2 = i0 * (uchar)MathPow(2, shift);
15.     i3 = i0 >> shift;
16.     i4 = i0 / (uchar)MathPow(2, shift);
17. 
18.     PrintFormat("Shift value          : %d\n" + 
19.                 "Original             : %s\t%d\n" +
20.                 "Shifted to the left  : %s\t%d\n" +
21.                 "Multiplication result: %s\t%d\n" +
22.                 "Shifted to the right : %s\t%d\n" +
23.                 "Division result      : %s\t%d"
24.                 , shift, BinaryToString(i0), i0, 
25.                          BinaryToString(i1), i1, 
26.                          BinaryToString(i2), i2, 
27.                          BinaryToString(i3), i3, 
28.                          BinaryToString(i4), i4
29.                 );
30. }
31. //+------------------------------------------------------------------+
32. string BinaryToString(const uchar arg)
33. {
34.     string  sz0 = "";
35.     uchar   mask = 0x80;
36. 
37.     while (mask)
38.     {
39.         sz0 = sz0 + ((arg & mask) == mask ? "1" : "0");
40.         mask = mask >> 1;
41.     }
42. 
43.     return sz0;
44. }
45. //+------------------------------------------------------------------+

Код 03

Запустив данный код, мы увидим изображение, показанное ниже.

Рисунок 03

А теперь внимание, дорогие читатели. Код 03, который поначалу может показаться запутанным, довольно четко сформулирован и отлично выполняет свою задачу. Однако, чтобы понять это, нужно знать, что означает функция MathPow. Поскольку она является частью библиотеки MQL5, ознакомьтесь с документацией для получения более подробной информации. Проще говоря, данная функция выполняет вычисление возведения на степень и возвращает значение типа double. Поскольку у наших данных тип uchar, мы должны выполнить явное преобразование типа. Таким образом, компилятор не выдаст предупреждения о том, что мы работаем с разными типами.

Теперь обратите внимание, что на рисунке 03 мы показываем значение и его двоичное представление на каждой из строк. Это двоичное представление важно, потому что оно наглядно показывает, что произошло с нашим исходным значением. Можно сказать, что при сдвиге значения влево, мы умножаем его на два, а сдвигая вправо, делим на два. В некотором смысле вы не ошибетесь, анализируя рисунок 3. Однако, что произойдет если мы изменим значение сдвига, например, с одного на три?

Рисунок 04

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

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

Надеюсь, стало понятным, как работает оператор сдвига. Таким образом, код 02 уже полностью объяснен. Мы можем перейти к другой теме, связанной со строками и массивами.


Панграмма и Анаграмма

Есть довольно интересное и, в некоторых случаях, даже забавное применение, которое мы можем рассмотреть прямо сейчас, даже при таком скромном содержании. Это панграммы. Панграмма - это фраза, в которой используются все буквы алфавита для проверки. Несмотря на то, что это сравнительно старая разработка, она может быть очень интересной и познавательной. Пожалуй, самая известная панграмма - это:

A QUICK BROWN FOX JUMPS OVER THE LAZY DOG 0123456789

Она использовалась для тестирования старых телеграфов. В него вошли все символы, которые могут встречаться в предложении. Но, вероятно, еще большую известность она получила, при использовании в Microsoft Word, чтобы показать, как будет выглядеть печатный текст. В то время некоторые люди даже утверждали, что в инструментах Microsoft есть скрытые вещи, из-за чего многие люди боялись пользоваться компьютерами.

Но даже в том контексте, с которым мы имеем дело в данный момент, мы можем использовать такие фразы. Это позволит нам продемонстрировать и изучить некоторые понятия о строках и массивах. Поскольку они довольно просты и очень увлекательны, я думаю, вам понравится разбираться в том, как они работают.

Нередко можно услышать советы по созданию надежных паролей или даже фраз, которые работают как пароли. Однако создать надежный пароль или запомнить его может быть очень сложно. С другой стороны, многие говорят (и вы найдете немало информации на эту тему), что существуют специализированные программы для хранения паролей. Но если эти программы требуют пароль для безопасного хранения других, то, на мой взгляд, это не слишком полезно.

Однако даже начинающие программисты, которые уже понимают, как работают некоторые базовые операторы и функции, могут создать приложение для генерации относительно надежного пароля. Конечно, надежность пароля зависит от определенных характеристик системы, в которой он создан. Тем не менее, следуя данной логике, вы сможете создать нечто весьма интересное, если только будете знать, как улучшить то, что мы рассмотрим здесь, поскольку основная цель - чисто дидактическая.

Для начала давайте подумаем, что такое пароль? Пароль - это набор напечатанных символов, которые находятся в текстовой строке. Если мы берем строку и работаем с ней, то сможем создать программу, которая перемешает или зашифрует ее. Наша цель - создать надежный пароль, для которого процесс перемешивания, который может быть шифром или даже анаграммой, будет частично скрывать оригинальный пароль. Однако анаграммы не очень эффективны для сокрытия информации, которую нужно использовать в другом месте, как, например, пароль. Лучше всего использовать смесь знаков или шифр, используя в качестве шифрующей фразы анаграмму или панграмму. Ключевым моментом является фраза, которую можно запомнить, а конечным результатом будет пароль, который мы будем использовать.

Чтобы вы поняли, что я пытаюсь описать, давайте посмотрим на довольно простой и незамысловатый код. Его можно увидеть чуть ниже:

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     const string sz_Secret_Phrase = "Um pequeno jabuti xereta viu dez cegonhas felizes";
07. 
08.     Print("Result:\n", PassWord(sz_Secret_Phrase));
09. }
10. //+------------------------------------------------------------------+
11. string PassWord(const string szArg)
12. {
13.     const string szCodePhrase = "The quick brown fox jumps over the lazy dog";
14. 
15.     string  szPsw = "";
16.     uchar   pos;
17. 
18.     for (int c = 0; c < StringLen(szArg); c++)
19.     {
20.         pos = (uchar)(StringGetCharacter(szArg, c) % StringLen(szCodePhrase));
21.         szPsw = StringFormat("%s%c", szPsw, StringGetCharacter(szCodePhrase, pos));
22.     }
23. 
24.     return szPsw;
25. }
26. //+------------------------------------------------------------------+

Код 04

Глядя на этот код, можно подумать: "Что за безумие вы тут творите?!" Спокойно, дорогие читатели. То, что мы здесь делаем, кажется странным и бессмысленным, но скоро вы поймете, что я хочу вам показать. Обратите внимание на следующее: в этом коде используется только то, что с чем мы уже знакомы, ничего нового не добавляется. Всё, что здесь делается, вполне понятно, если вы разобрались с предыдущими статьями и уделили время изучению библиотечных функций, используемых в данном коде. Всё, что здесь используется, можно легко найти в документации по MQL5. Поэтому я не буду останавливаться на используемых функциях. Однако, если вы запустите данный код без модификаций, то увидите такой рисунок:

Рисунок 05

Область, отмеченная на рисунке 05, представляет собой пароль, который мы должны использовать. Но обратите внимание, что в нем есть очевидная проблема: пробелы. Обычно пароли не содержат пробелов, поэтому мы должны исправить эту ошибку. Очень простой способ - убрать пробелы и сделать первую букву большой. Добиться этого довольно просто. После внесения этого изменения в строку 13 кода 04, мы получим нечто похожее на приведенный ниже код:

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     const string sz_Secret_Phrase = "Um pequeno jabuti xereta viu dez cegonhas felizes";
07. 
08.     Print("Result:\n", PassWord(sz_Secret_Phrase));
09. }
10. //+------------------------------------------------------------------+
11. string PassWord(const string szArg)
12. {
13.     const string szCodePhrase = "TheQuickBrownFoxJumpsOverTheLazyDog";
14. 
15.     string  szPsw = "";
16.     uchar   pos;
17. 
18.     for (int c = 0; c < StringLen(szArg); c++)
19.     {
20.         pos = (uchar)(StringGetCharacter(szArg, c) % StringLen(szCodePhrase));
21.         szPsw = StringFormat("%s%c", szPsw, StringGetCharacter(szCodePhrase, pos));
22.     }
23. 
24.     return szPsw;
25. }
26. //+------------------------------------------------------------------+

Код 05

На данный момент, сравнивая код 05 и код 04, можно сказать: "Ведь ничего не изменилось. Это не сработает. Результат будет очень похож на предыдущий". Так ли это на самом деле? Давайте посмотрим. Когда код 05 выполнится, результат будет таким:

Рисунок 06

Ух ты! Он изменился, и значительно. Это совершенно разные вещи, не имеющие никакого отношения к рисунку 05. Многие думают, что для программирования чего-то подобного нужно быть гением в области математики или иметь многолетний опыт. Однако здесь мы видим, что, обладая минимальными знаниями в области программирования и хорошей порцией креативности, можно получить очень хорошие и даже удивительные результаты. Если вам кажется, что этот пароль слишком прост, хотя и довольно длинный, мы можем легко исправить ситуацию. Обратите внимание, что единственное различие между кодами 04 и 05 заключается именно в строке 13; ни одна другая строка не была изменена. Поэтому, вполне естественно задаться вопросом, не улучшит ли пароль добавление дополнительных символов в данную строку 13? Хорошо, мы можем попробовать и это. Поэтому давайте изменим строку 13, заменив ее на ту, которую показываем ниже.

    const string szCodePhrase = ")0The!1quick@2brown#3fox$4jumps%5over^6the&7lazy*8dog(9";

Результат будет таким:

Рисунок 07

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

Мы поступим немного иначе, чтобы вы поняли еще одну деталь, упомянутую в предыдущей статье. Там я упоминал, что тип `string` НЕ существует в C и C++. Однако в MQL5 такой тип существует именно для того, чтобы избежать необходимости использовать стиль программирования из C и C++. Это связано с тем, что в языках C и C++ строка на самом деле является массивом, который содержит специальное значение, указывающее, где заканчивается строка. Поскольку в MQL5 для этого используется одно и то же значение, мы можем изменить код, который генерирует пароль, так, чтобы он не зависел от обращений к стандартной библиотеке MQL5.

А теперь прошу вашего внимания, потому что мы будем использовать то, что также используется в C и C++. Это ставит MQL5 в промежуточное положение, как я уже говорил в предыдущей статье. Однако здесь мы рассмотрим лишь краткое введение в тему, более подробно о ней будет рассказано в следующей статье.


Строки - это массивы

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

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

Таким образом, код 04 преобразуется в такой код:

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     const string sz_Secret_Phrase = "Um pequeno jabuti xereta viu dez cegonhas felizes";
07. 
08.     Print("Result:\n", PassWord(sz_Secret_Phrase));
09. }
10. //+------------------------------------------------------------------+
11. string PassWord(const string szArg)
12. {
13.     const string szCodePhrase = "The quick brown fox jumps over the lazy dog";
14. 
15.     uchar   psw[],
16.             pos;
17. 
18.     ArrayResize(psw, StringLen(szArg));
19.     for (int c = 0; szArg[c]; c++)
20.     {
21.         pos = (uchar)(szArg[c] % StringLen(szCodePhrase));
22.         psw[c] = (uchar)szCodePhrase[pos];
23.     }
24.     return CharArrayToString(psw);
25. }
26. //+------------------------------------------------------------------+

Код 06

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

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


Заключительные идеи

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

Я твердо убежден, увидев собственными глазами, как эти вещи делаются с минимальными знаниями - ведь всё, что было сделано здесь, можно понять на основе того, что объяснялось в предыдущих статьях, - вы станете более инициативным и не будете думать, что увиденное ранее не принесет пользы. Вот и всё. Так что смело изучайте файлы из приложения. Увидимся в следующей статье, где речь пойдет о МАССИВАХ.

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

Прикрепленные файлы |
Anexo.zip (2.43 KB)
Нейросети в трейдинге: Двухмерные модели пространства связей (Окончание) Нейросети в трейдинге: Двухмерные модели пространства связей (Окончание)
Продолжаем знакомство с инновационным фреймворком Chimera — двухмерной моделью пространства состояний, использующей нейросетевые технологии для анализа многомерных временных рядов. Этот метод обеспечивает высокую точность прогнозирования при низких вычислительных затратах.
Фибоначчи на Форекс (Часть I): Проверяем отношения цены и времени Фибоначчи на Форекс (Часть I): Проверяем отношения цены и времени
Как рынок ходит по отношениям, основанным на числах Фибоначчи? Эта последовательность, где каждое следующее число равно сумме двух предыдущих (1, 1, 2, 3, 5, 8, 13, 21...), не только описывает рост популяции кроликов. Рассмотрим гипотезу Пифагора о том, что все в мире подчиняется определенным соотношениям чисел...
Построение модели для ограничения диапазона сигналов по тренду (Часть 8): Разработка советника (I) Построение модели для ограничения диапазона сигналов по тренду (Часть 8): Разработка советника (I)
В этой статье мы разработаем наш первый советник на MQL5 на основе индикатора, который мы создали в предыдущей статье. Мы рассмотрим все функции, необходимые для автоматизации процесса, включая управление рисками. Это позволит перейти от ручного выполнения сделок к автоматизированным системам.
Переосмысливаем классические стратегии (Часть IV): SP500 и казначейские облигации США Переосмысливаем классические стратегии (Часть IV): SP500 и казначейские облигации США
В этой серии статей мы анализируем классические торговые стратегии с использованием современных алгоритмов, чтобы определить, можно ли улучшить стратегию с помощью искусственного интеллекта (ИИ). В сегодняшней статье мы рассмотрим классический подход к торговле индексом SP500, используя его взаимосвязь с казначейскими облигациями США (US Treasury Notes).