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

От начального до среднего уровня: Переменные (I)

MetaTrader 5Примеры | 17 января 2025, 09:08
438 0
CODE X
CODE X

Введение

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

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

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

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


Переменные. Основы программирования

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

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

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

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

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

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

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     int     value1;
07.     char    value2;
08.     long    value3;
09. 
10.     value1 = 10;
11.     value2 = 5;
12.     Print("Result: ", value1 + value2 + value3);
13. }
14. //+------------------------------------------------------------------+

Код 01

Этот код очень простой и базовый. Здесь у нас есть три объявления переменных, расположенных в строках 06, 07 и 08. Пока что не стоит беспокоиться о типах. Поговорим подробнее об этом в другой статье. Пока обращайте внимание только на то, что будет объясняться. Хотя у нас есть три объявленные переменные, две из них на самом деле являются временными константами, а на другую мы не ссылаемся или, как это правильно называется, не инициализируем её. Часто можно думать, что этот код приведет к определенному результату, но непонимание того, как функционируют разные элементы или игнорирование этого факта может поставить под угрозу всю работу.

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


Рисунок 01:

В своем случае я использую другой инструмент для редактирования кодов, но он также использует компилятор MetaTrader 5 для создания приложений. Результат выглядит так:


Рисунок 02

Обратите внимание, что в обоих случаях компилятор выдает предупреждение, и мы должны быть внимательны при их появлении. Потому что часто предупреждение указывает на то, что наше приложение может работать неожиданным образом. Если понадобится отобразить какой-то момент, связанный с выводом компилятора, мы сделаем это в соответствии с моделью, показанной на рисунке 02. Однако результат будет очень похож на те сообщения, которые мы увидим при использовании MetaEditor. Поэтому обязательно следите за появлением каждой новой статьи.

Теперь предположим, что мы проигнорировали это предупреждение компилятора. Некоторые из них можно игнорировать, а другие - нет. И мы решили запустить данное приложение, уже скомпилированное в MetaTrader 5. Какой результат будет получен? Наверное, вы ожидаете получить значение 15, поскольку в строке 10 мы говорим, что переменная value1 равна десяти, а в строке 11 - что переменная value2 равна пяти. Таким образом, при выполнении строки 12 ожидаемым результатом будет сумма этих двух значений, не так ли? Давайте посмотрим. Результат показан ниже.


Рисунок 03

Так что же здесь произошло? Неужели такое возможно?! Да, дорогой читатель, такое возможно. В этом вы можете убедиться сами. Но ваше удивление вполне оправдано, ведь вы явно ожидали, что напечатанное значение будет равно 15. А почему же тогда возникает нулевое значение? Причина кроется именно в переменной value3. Поскольку она участвует в вычислениях и НЕ БЫЛА должным образом инициализирована, она может содержать любое значение. И в зависимости от этого значения, которое в программировании мы называем "мусором", оно сделает конечный результат неверным.

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

Print("Result: ", value1 + value2);

В этом случае, при попытке компиляции кода, компилятор выдаст предупреждение следующего вида.


Рисунок 04

Обратите внимание, что предупреждение отличается от того, которое мы видели ранее. Затем, проанализировав его, мы решаем, что в данном конкретном случае его можно проигнорировать. Запускаем приложение в MetaTrader 5 и получаем результат, показанный ниже.


Рисунок 05

Получилось! Мы добились именно того, на что рассчитывали. Теперь давайте вернемся к исходному коду 01, чтобы понять некоторые основные понятия. Как уже говорилось выше, переменные value1 и value2 можно и нужно рассматривать как временные константы. Но почему? Причина этого как раз в том, что они НЕ меняют своего значения на протяжении всего кода, они всё время имеют одинаковое значение. Однако здесь есть одна проблема, и именно в этот момент всё становится немного интереснее.

Хотя value1 и value2, а также value3 являются переменными, мы, как программисты, можем это изменить. Таким образом, мы гарантируем, что значение, присвоенное данной переменной, НЕ ИЗМЕНИТСЯ, независимо от любых ошибок, которые можем допустить в процессе написания кода. Многие опытные программисты, которые работают с более сложным и запутанным кодом, предпочитают использовать языки, позволяющие осуществлять подобный контроль. В таких случаях вы, как программисты, можете сказать: «Слушай, компилятор, эта переменная не должна рассматриваться как переменная, я хочу, чтобы это была константа». А компилятор поможет вам обеспечить сохранение данной переменной в качестве константы. Чтобы добиться такого контроля в MQL5, мы используем зарезервированное слово. Таким образом, код, результат которого будет таким же, как и предыдущий, может быть написан иным способом. Но прежде чем приступить к этому на практике, давайте посмотрим на кое-что другое. В результате мы создаем такой код.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     const int   value1;
07.     char        value2;
08. 
09.     value1 = 10;
10.     value2 = 5;
11.     Print("Result: ", value1 + value2);
12. }
13. //+------------------------------------------------------------------+

Код 02

Если вы попытаетесь скомпилировать код 02, компилятор не даст вам это сделать из-за ошибок, показанных ниже.


Рисунок 06

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

Обратите внимание, - это может сильно помочь вам в программировании на MQL5. Когда мы определяем переменную как константу, любая попытка изменить ее значение во время выполнения кода будет расценена как СЕРЬЕЗНАЯ ошибка. Однако мы еще не запустили наше приложение. Несмотря на это, компилятор MQL5 уже предупреждает нас о возможности серьезной ошибки во время выполнения. По этой причине он не позволяет скомпилировать код 02. И это происходит, потому что мы сообщили компилятору, что переменная value1 - это НЕ переменная, а КОНСТАНТА. Для этого перед оператором используется слово const, как показано в шестой строке кода 02. Многие менее опытные программисты предпочли бы убрать слово const из объявления в шестой строке. Само по себе это не будет ошибкой, но при этом мы лишимся помощи компилятора, чтобы избежать того, что переменная value1 будет обработана как константа. А это может привести к другим проблемам в приложении, например, к генерации неправильных значений в определенное время, не понимая, почему код ведет себя не так, как ожидалось.

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

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

Хорошо, раз мы прояснили это, как тогда следует написать код 02, чтобы его можно было скомпилировать? Учитывая, что мы действительно хотим, чтобы всё было именно так, код следует изменить так, как показано ниже.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     const int   value1 = 10;
07.     char        value2;
08. 
09.     value2 = 5;
10.     Print("Result: ", value1 + value2);
11. }
12. //+------------------------------------------------------------------+

Код 03

Теперь правильно. Данный код 03 действительно будет скомпилирован. Результат можно видеть на изображении 05. Однако, возможно, у вас возникло сомнение: зачем программировать что-то именно так, как показал автор? Не было бы проще использовать что-то другое, как показано ниже?

1. #property copyright "Daniel Jose"
2. //+------------------------------------------------------------------+
3. void OnStart(void)
4. {
5.     Print("Result: ", 10 + 5);
6. }
7. //+------------------------------------------------------------------+

Код 04

Да, в некоторых случаях программирование чего-то похожего на код 04 на самом деле является самым простым способом, поскольку мы имеем дело исключительно с константами. Однако такой подход не всегда желателен. Это происходит так, потому что числовые константы "холодные" и не несут никакой информации о том, почему они существуют. Рассмотрев код 04, смогли бы вы сказать, в чем причина использования значений десять и пять? Возможно, мы выполняем некую факторизацию, чтобы обнаружить изначально неизвестный результат. Если бы дело было в этом, мы бы использовали другой вид переменных, о чем мы подробно расскажем в другой статье. Однако, если бы это было не так, мы бы в конце концов задались вопросом, почему производится такое вычисление, и в итоге у нас могли бы возникнуть трудности с пониманием собственного кода.

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

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


Срок действия и видимость

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

Пока что мы остановимся на самом главном: когда переменная "рождается", где она "умирает" и можно ли предотвратить ее "смерть".

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

Переменная "рождается" в момент ее объявления.

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

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     const int value1 = 10;
07.     int value2;
08. 
09.     value2 = 5;
10.     {
11.         int value2;
12. 
13.         value2 = 8;
14. 
15.         Print("Result #01: ", value1 + value2);
16.     }
17.     Print("Result #02: ", value1 + value2);
18. }
19. //+------------------------------------------------------------------+

Код 05

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

Когда код 05 будет выполнен, то вы увидите результат, показанный на изображении ниже.


Рисунок 07

Теперь я снова спрашиваю вас: понятны ли вам эти результаты? Это лишь небольшая демонстрация того, что мы действительно можем сделать. Многие программисты, даже достаточно опытные, избегают присвоение переменным одинаковые имена в одном и том же блоке кода. Но здесь мы используем не один блок кода, а два. Но как это возможно? Разве у нас два блока кода здесь, в коде 05, или это сон наяву? Нет, дорогой читатель, я еще не потерял рассудок. Дело в том, что мы пока только коснулись темы, которая станет понятной в другой раз. Но в MQL5, как и в других языках на основе C и C++, каждый блок кода начинается с открывающей скобки `{` и заканчивается закрывающей скобкой `}`.

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

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

Этот второй аспект немного сложнее для понимания, но давайте разберем его шаг за шагом. Сначала давайте рассмотрим, почему код 05 генерирует результат так, как на изображении 07. Из приведенных выше объявлений можно видеть, что в строках семь и одиннадцать объявляется переменная с тем же именем. А в строках девять и тринадцать мы присваиваем разные значения переменной, которая в теории кажется одной и той же. Однако, если обратить внимание на код, то можно заметить, что они находятся в разных блоках: одна в одном блоке, а другая - в блоке, находящемся внутри первого.

Проще говоря, блок, в котором мы объявляем value2 в седьмой строке, является глобальным. Поэтому value2, объявленное в седьмой строке, является глобальной переменной. В свою очередь, переменная value2, объявленная в одиннадцатой строке, является локальной переменной. Если смотреть извне блока, то переменная в одиннадцатой строке является локальной; но внутри блока, который начинается с десятой строки, переменная, объявленная в одиннадцатой строке, считается глобальной в этом контексте.

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

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

Таким образом, легко понять следующий факт: когда в тринадцатой строке мы говорим, что value2 равно 8, это не удалит значение, которое value2 имеет в глобальной области видимости, а именно 5 и было определено в девятой строке. По этой причине, когда мы используем строку 15 для вывода результата сложения значения1 со значением2, в первом случае мы получим 18. А когда строка 17 выполняет тот же расчет, результат будет равен 15.

Однако, если вы попытаетесь сделать нечто подобное, используя код, похожий на приведенный ниже:

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     const int value1 = 10;
07.     int value2;
08. 
09.     value2 = 5;
10. 
11.         int value2;
12. 
13.         value2 = 8;
14. 
15.         Print("Result #01: ", value1 + value2);
16. 
17.     Print("Result #02: ", value1 + value2);
18. }
19. //+------------------------------------------------------------------+

Код 06

Компилятор пожалуется и покажет вам нечто такое как на рисунке 08, чуть ниже.


Рисунок 08

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

Однако можно столкнуться с несколько иной ситуацией. Это можно увидеть в приведенном ниже коде.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. int value2;
05. //+------------------------------------------------------------------+
06. void OnStart(void)
07. {
08.     const int value1 = 10;
09. 
10.     value2 = 5;
11. 
12.         int value2;
13. 
14.         value2 = 8;
15. 
16.         Print("Result #01: ", value1 + value2);
17. 
18.     Print("Result #02: ", value1 + value2);
19. }
20. //+------------------------------------------------------------------+

Код 07

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


Рисунок 09

Глядя на это сообщение, представленное на изображении 09, какие действия должны быть предприняты в отношении кода 07, если наша цель - получить результат, аналогичный изображенному на изображении 07? Дорогие читатель, вот и наступил тот момент, когда всё сильно усложняется. Причина в том, что объявление value2, выполненное в четвертой строке, "умрет" только тогда, когда приложение прекратит свое существование или перестанет выполняться. По этой причине в случаях такого типа НЕЛЬЗЯ использовать переменные с локальной областью видимости вместе с одноименными переменными, имеющими глобальную область видимости.

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


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

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

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


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

Прикрепленные файлы |
Anexo.zip (0.73 KB)
Нейросети в трейдинге: Многоагентная система с концептуальным подтверждением (Окончание) Нейросети в трейдинге: Многоагентная система с концептуальным подтверждением (Окончание)
Продолжаем реализацию подходов, предложенных авторами фреймворка FinCon. FinCon является многоагентной системой, основанной на больших языковых моделях (LLM). Сегодня мы реализуем необходимые модули и проведем комплексное тестирование модели на реальных исторических данных.
Разработка системы репликации (Часть 58): Возвращаемся к работе над сервисом Разработка системы репликации (Часть 58): Возвращаемся к работе над сервисом
После перерыва в разработке и улучшении сервиса, используемого для репликации/моделирования, сегодня мы возобновляем над ним работу. Теперь, когда мы отказались от использования таких ресурсов, как глобальные переменные терминала, нам придется полностью реструктурировать некоторые его части. Не волнуйтесь, этот процесс будет подробно объяснен, чтобы каждый мог следить за разработкой нашего сервиса.
Квантовые вычисления и трейдинг: Новый взгляд на прогнозы цен Квантовые вычисления и трейдинг: Новый взгляд на прогнозы цен
В статье рассматривается инновационный подход к прогнозированию движения цен на финансовых рынках с использованием квантовых вычислений. Основное внимание уделяется применению алгоритма квантовой оценки фазы (QPE) для поиска продобразов ценовых паттернов, что позволяет значительно ускорить процесс анализа рыночных данных.
Использование JSON Data API в MQL-проектах Использование JSON Data API в MQL-проектах
Представьте, что вы можете использовать данные, которых нет в MetaTrader. Обычно вы получаете информацию только от индикаторов, основанных на анализе цен и техническом анализе. Теперь представьте, что у вас есть доступ к данным, которые выведут ваши торговые возможности на новый уровень. Вы можете значительно увеличить мощность платформы MetaTrader, если объедините её возможности с результатами работы других программ, методов макроанализа и ультрасовременных инструментов через API. В этой статье мы расскажем, как использовать API, и представим полезные и ценные API-сервисы.