preview
Переходим на MQL5 Algo Forge (Часть 2): Работа с несколькими репозиториями

Переходим на MQL5 Algo Forge (Часть 2): Работа с несколькими репозиториями

MetaTrader 5Интеграция |
94 20
Yuriy Bykov
Yuriy Bykov

Введение

В первой статье мы начали переход от использования MQL5 Storage — встроенного SVN-хранилища в MetaEditor — к более гибкому и современному решению на основе системы контроля версий Git — MQL5 Algo Forge. Основной причиной такого шага стало желание полноценно использовать разные ветки репозитория в процессе работы над разными проектами или функциональностью в рамках одного проекта.

Переход начался с создания нового репозитория в MQL5 Algo Forge и настройки локальной среды разработки с использованием Visual Studio Code, соответствующих расширений для работы с MQL5 и Git, а также установки необходимых инструментов. После этого в созданном репозитории мы добавили файл .gitignore для исключения из отслеживания стандартных и временных файлов. Все текущие проекты были загружены в отдельную ветку archive, которой была отведена роль архивного хранилища всего существующего кода. Основная ветка main была оставлена пустой и подготовлена для организации новых проектных веток. Таким образом, были заложены все необходимые основы для дальнейшего распределения кода разных проектов по разным веткам репозитория.

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


Намечаем путь

Страшно подумать, но на момент написания прошлой статьи по этой теме, в MetaEditor ещё отсутствовал пункт главного меню "Git" и команды контекстного меню файлов по работе с репозиторием MQL5 Algo Forge. Поэтому довольно много усилий было затрачено на выстраивание процесса работы с новым репозиторием с помощью сторонних средств типа Visual Studio Code. Поскольку мы ещё не знали, как будет реализована поддержка репозитория в MetaEditor, то приходилось пользоваться тем, что имелось на тот момент.

Прошло время, в новых версиях MetaEditor появилась поддержка работы с новым репозиторием, недавно вышла новая статья от MetaQuotes "Как начать работу с MQL5 Algo Forge", объясняющая основные моменты и демонстрирующая возможности использования MQL5 Algo Forge. Однако самым важным, на наш взгляд, стала реализация поддержки в MetaEditor механизма разделяемых проектов (Shared Projects).

Попробуем объяснить, что в этом такого существенного. До выхода этой реализации, мы знали, что папка MQL5 теперь будет одним репозиторием, хранящимся на GIT-серверах MQL5 Algo Forge. Судя по всему, у этого репозитория будет фиксированное имя mql5. То есть у разных пользователей в хранилище MQL5 Algo Forge будет существовать репозиторий с именем mql5. Именно этот репозиторий будет клонироваться в папку MQL5 после установки нового терминала, авторизации пользователя в Community и подключения хранилища. Но в хранилище MQL5 Algo Forge изначально можно было создавать дополнительные репозитории. Точнее не дополнительные, а просто другие, никак не связанные с репозиторием mql5. Поэтому естественным образом возникал вопрос: а как с ними можно будет работать в MetaEditor? 

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

MetaQuotes предложили другой, достаточно элегантный способ убить двух зайцев. С одной стороны, остаётся главный репозиторий с именем mql5. Его использование хорошо подойдет тем, кто раньше уже пользовался хранилищем MQL5 Storage. Теперь продолжать использовать систему контроля версий можно так же легко и просто, не обращая особого внимания на то, какая система контроля версий (CVS) лежит в её основе.

С другой стороны, все другие репозитории пользователя, как оказалось, становятся доступны как папки внутри Shared Project. Таким образом, мы получаем новую стандартную корневую папку, наряду с уже существующими подобными папками (MQL5, MQL5/Experts, MQL5/Include и т.п.), предназначенную для хранения кода других репозиториев пользователя.

Смоделируем такую ситуацию: допустим, есть два отдельных наших репозитория в новом хранилище MQL5 Algo Forge, не являющихся основными репозиториями по умолчанию. Один из них (Adwizard) будет содержать только библиотечный код, то есть в нём есть только включаемые файлы *.mqh и нет файлов *.mq5, которые при компиляции превращались бы в советник или, например, индикатор. Второй репозиторий (Simple Candles) уже содержит файлы *.mq5, в которых в качестве включаемых файлов используются файлы из первого репозитория. Для краткости будем далее называть первый репозиторий библиотечным, а второй — проектным.

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


Приступаем

Для начала рассмотрим ситуацию со стороны разработчика этих репозиториев. То есть мы сможем при необходимости легко вносить правки в программный код обоих репозиториев, не ожидая ревизии и принятия правок через механизм Pull Request. Создадим чистую папку терминала и скопируем туда два файла из любой установленной ранее копии терминала MetaTrader 5:

Чтобы не искать рабочую папку терминала в дебрях файловой системы, мы рекомендуем сразу озаботиться запуском терминала в Portable-режиме. Для Windows одним из возможных способов это сделать, будет создание ярлыка на запускаемом файле терминала, с последующим добавлением в свойствах ярлыка к строке запуска ключа /portable. 

Запустим терминал, откроем новый демо-счёт на всякий случай, обновим терминал до последней версии, авторизуемся в Community, после чего вызовем MetaEditor, нажав F4. Подключим хранилище MQL5 Algo Forge, если оно ещё не подключилось автоматически.

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

Теперь кликаем по очереди правой кнопкой мыши на названиях двух интересующих нас репозиториев и в контекстном меню выбираем пункт "Клонировать репозиторий Git". Видим в журнале сообщения об успешном клонировании репозиториев Adwizard и Simple Candles. В проводнике после этой операции тоже видны папки с клонированными репозиториями:

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


Встречаем первую проблему

Попробуем открыть файл советника SimpleCandles.mq5 и скомпилировать его:

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

То есть библиотечный репозиторий располагался внутри подпапки проектного репозитория. Это был во многом вынужденный шаг, чтобы иметь хоть какую-то определённость, где будут находиться библиотечные файлы. Теперь мы эту договорённость поменяем. Вместо обязательной подпапки Include внутри папки проекта, будем использовать папку MQL5/Shared Projects. Очень надеемся, что в ближайшем будущем она продолжит оставаться на своём месте и не поменяет своего текущего предназначения.

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

Посмотрим, какие ветки у нас уже есть в репозитории проекта. Это можно сделать несколькими способами:

  • Через контекстное меню папки репозитория в MetaEditor: 

  • Через веб-интерфейс хранилища на странице веток выбранного репозитория:

  • Через стороннее средство, умеющее работать с Git-репозиториями, например, Visual Studio Code. Напротив имени репозитория указано имя текущей ветки main. При клике на нём мы увидим список доступных веток (и пункты меню для создания новых веток):

Таким образом, у нас сейчас есть четыре ветки в репозитории:

  • main — основная ветка. Она создаётся при создании репозитория. В простейшем случае, кроме этой ветки можно не создавать никаких дополнительных веток, а всю разработку вести в основной ветке. В более сложном случае, эта ветка может использоваться для хранения состояния файлов, обеспечивающих стабильную версию кода на данном этапе. Все изменения, которые ещё не до конца реализованы и протестированы, должны делаться в других ветках.
  • develop — ветка разработки. Опять-таки, в более простом случае можно использовать только одну эту ветку для внесения правок и добавления новой функциональности к проекту. Такой вариант вполне достаточен, если добавление новых возможностей ведётся строго последовательно. То есть, мы не начинаем реализацию новой функциональности, пока не приведём проект в полностью работоспособное состояние после добавления предыдущих новшеств. Перед стартом работы над новой функциональностью выполняется слияние веток: правки, сделанные в ветке develop, вливаются в ветку main. В более сложном случае, предполагающем одновременную работу над несколькими непрекращающимися новыми функциями, работать в одной ветке разработки становится неудобно. Поэтому можно создавать отдельные ветки для каждой обособленной части новой функциональности.
  • article-17608-close-manager и article-17607 — это как раз такие ветки. В первой из них собраны правки, добавляющие модуль менеджера закрытия позиций по достижении заданной прибыли или убытка. Эта ветка уже влита в develop, а develop после этого влита в main. А другая ветка содержит правки, касающиеся модернизации механизма автоматической оптимизации, и она ещё не доведена до конца, то есть её правки ещё не попали ни в develop, ни в main.

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

Но вернёмся к веткам нашего рассматриваемого репозитория.

У кого-то может возникнуть вопрос, а что означает префикс origin/ или, как это показывается в MetaEditor, refs/remotes/origin/? Это всего лишь указание, что эта ветка уже присутствует в удалённом хранилище репозитория, а не только на локальном компьютере. Обычно мы стараемся поддерживать локальную и удалённую ветки в синхронизированном состоянии. MetaEditor нас буквально принуждает к этому: при выборе из контекстного меню команды Commit (фиксации изменений в локальной копии репозитория), автоматически выполняется команда Push (отправки сделанного коммита в удаленный репозиторий).

Если же не пользоваться для коммита интерфейсом MetaEditor, то возможно сделать фиксацию изменений только локально, не отправляя их в удалённый репозиторий. В этом случае, ветка с одним и тем же названием будет находиться в разном состоянии в локальном и удалённом репозитории. Для возможности точно указать, с какой веткой мы хотим что-то сделать, и нужен вышеупомянутый префикс origin/. Если он есть — значит, мы имеем в виду ветку в удалённом репозитории, а если нет — то в локальном.


Создаём новую ветку

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

После этого можно выбрать пункт создания новой ветки (New) и ввести желаемое имя. Будем придерживаться принятого ранее соглашения, что названия веток, которые создаются под конкретную статью, имеют в начале названия слово article, после чего через дефис идёт уникальный числовой идентификатор статьи. Далее к названию можно добавить произвольную часть, отражающую тематику статьи. Поэтому создадим ветку с названием "article-17698-forge2".

Мы могли бы создать ветку и другими способами: используя веб-интерфейс, интерфейс Visual Studio Code или интерфейс командной строки. В последнем случае нам достаточно выполнить такую команду в корневой папке репозитория:

git checkout -b article-17698-forge2 develop

То есть мы просим Git переключиться (checkout) на новую ветку (-b) с именем article-17698-forge2, порождаемую от ветки с именем develop.

Если мы создали ветку не через веб-интерфейс, то до выполнения первой отправки изменений в вышестоящий репозиторий (Push), она будет существовать только на нашем локальном компьютере. Верно и обратное — если ветка была создана в вышестоящем репозитории через веб-интерфейс, то до первого получения изменений из вышестоящего репозитория (Pull), этой ветки не будет на нашем локальном компьютере.

Отправить эти изменения можно так:

или так:

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

git push --set-upstream origin article-17698-forge2

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


Вносим исправления

Необходимые правки будут очень просты. В файле SimpleCandles.mq5 мы изменяем строку, которая подключает файл из библиотеки Adwizard. Теперь корневые папки репозиториев Simple Candles и Adwizard находятся на одном уровне внутри папки Shared Projects, поэтому, чтобы добраться до файла Expert.mqh, необходимо сначала подняться на уровень выше (../), а затем уже спускаться в подпапки библиотечного репозитория:

#include "Include/Adwizard/Experts/Expert.mqh"
#include "../Adwizard/Experts/Expert.mqh"

В файле Strategies/SimpleCandlesStrategy.mqh понадобится сделать аналогичное исправление:

#include "../Include/Adwizard/Virtual/VirtualStrategy.mqh"
#include "../../Adwizard/Virtual/VirtualStrategy.mqh"

После этих изменений советник SimpleCandles.mq5 снова успешно компилируется. Можно сделать фиксацию (Commit) изменений в репозитории:

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

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

git add .

Эта команда добавляет в индекс все найденные в папке репозитория новые файлы. Если вместо точки (.) в этой команде перечислить конкретные имена файлов, то добавятся только они. А дальше уже выполняем команду фиксации изменений с заданным комментарием и команду отправки изменений в вышестоящий репозиторий:

git commit -m "Fix relative paths to include files from Adwizard"
git push

На этом изменения в ветке article-17698-forge2 закончены, её можно вливать в ветку develop и закрывать.


Встречаем вторую проблему

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

У нас есть два основных способа, которыми мы можем выполнить слияние веток. Первый — это воспользоваться интерфейсом слияния веток в Visual Studio Code или консольными командами. Например, для нужного нам слияния достаточно выполнить такие команды:

git checkout develop
git pull
git merge --no-ff article-17698-forge2

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

Однако не будем заострять внимание на нюансах этого способа, а рассмотрим подробнее второй способ. Для него нам понадобится воспользоваться веб-интерфейсом хранилища MQL5 Algo Forge.


Используем Pull Request для слияния

Наряду с другими хранилищами на основе Git (таких, как GitHub, GitLab, Bitbucket), хранилище MQL5 Algo Forge тоже имеет в своём составе механизм под названием Pull Request (PR).

Pull Request (PR) — это механизм, который позволяет разработчику предложить внести сделанные им изменения в некоторый репозиторий. То есть, создание PR — это способ оповестить владельца репозитория и других участников разработки: "Я сделал работу в своей ветке, пожалуйста, 'влейте' (pull) эти изменения в основную ветку (main/master/develop) после проверки".

PR не является особенностью самого Git, это внешняя надстройка над ним, которая организует процесс проверки кода (код-ревью) и обсуждения перед внесением изменений в основную ветку репозитория.

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

Тем не менее сейчас мы как раз воспроизвели начало типичного рабочего процесса (Workflow) для добавления новой функциональности или внесения исправлений с использованием PR:

  1. Получили последние изменения. Перед началом работы мы обновили локальную основную ветку develop.

  2. Создали новую ветку для задачи. От актуальной ветки develop мы создали ветку с понятным названием article-17698-forge2.

  3. Выполнили работу в новой ветке: Исправили/дополнили код нескольких файлов, протестировали, сделали фиксацию (коммит) изменений.

Далее нам нужно выполнить следующие шаги.
  1. Создать Pull Request. Для этого в веб-интерфейсе хранилища MQL5 Algo Forge заходим на вкладку с соответствующим названием и нажимаем большую красную кнопку "New pull request":

Далее мы попадаем на страницу выбора веток создаваемого PR. На этом этапе он ещё не создан, так как нам нужно сначала  определиться в какую и из какой ветки мы хотели бы перенести правки. Выбрав ветки, мы можем посмотреть состав правок, которые должны быть перенесены. И снова нажимаем кнопку "New pull request".

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

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

    • ревьюверы изучают код, оставляют комментарии (общие или привязанные к конкретной строке);

    • автор PR отвечает на комментарии и вносит необходимые правки прямо в эту же ветку;

    • все новые пуши в ветку автоматически добавляются в уже существующий PR.

  1. Слияние. После одобрения ревьюверов (если они есть) и прохождения CI (тоже если есть), PR можно закрыть, выполнив слияние. Обычно есть несколько вариантов переноса правок в целевую ветку:

    • Merge commit: создает отдельный коммит слияния. История сохраняется как есть.

    • Squash and merge: все коммиты из ветки PR объединяются в один коммит, который добавляется в целевую ветку. Подходящий вариант, если не хочется засорять историю мелкими коммитами типа "исправлена опечатка".

    • Rebase and merge: коммиты из PR перебазируются на вершину целевой ветки (в нашем случае — develop). История получается линейной и чистой.

Из предлагаемых вариантов слияния мы выберем первый, так как хотим сохранить в истории все сделанные коммиты. Поэтому нажимаем кнопку "Create merge commit":

    Мы попадаем на финальную страницу работы с Pull Request. Поставим галочку на пункте "Delete branch ...", чтобы сразу закрыть нашу временную ветку разработки. В истории коммитов останется информация, что такая ветка существовала. Однако оставлять открытой эту ветку смысла нет, так как мы уже достигли цели, которая была поставлена. Для дальнейших изменений, решающих уже другие задачи, мы будем создавать новые ветки. Таким образом, посмотрев в любой момент времени на список веток репозитория, мы можем получить представление о том, над какими задачами сейчас идёт параллельная работа.

    Всё остальное на странице можно оставить как есть и нажать кнопку "Create merge commit".

    На этом процесс слияния завершён: ветка article-17698-forge2 влита в ветку develop и удалена:

    В целом, использование Pull Request (PR) для слияния веток даже в своем собственном репозитории — это хорошая и правильная практика, даже если работа над проектом ведётся в одиночку. Перед слиянием мы ещё раз можем визуально просмотреть все изменения в удобном интерфейсе хранилища MQL5 Algo Forge. При такой целенаправленной проверке порой удаётся заметить вещи, которые ускользнули при коммитах: лишние комментарии, случайно добавленные файлы, неоптимальные изменения. По сути, это некоторая форма самодисциплины. К тому же привыкание к правильным процессам вырабатывает привычку работать именно таким образом (создание отдельной ветки, код-ревью, ...). И если придется работать в команде  разработчиков, то не придётся переучиваться — процесс уже будет отлажен.

    Так что да, отправлять PR самому себе — не только можно, но и рекомендуется для любых более-менее серьезных проектов. Это повышает качество кода и дисциплинирует. Хотя никто не мешает для быстрых исправлений из одного-двух коммитов, обойтись прямым слиянием через команду git merge. Но для более ёмких правок лучше использовать PR.


    Заключение

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

    Однако мы рассмотрели только одну сторону: когда владельцем и проектного и библиотечного репозитория является один и тот же пользователь. Другая сторона — когда владелец проектного репозитория хочет воспользоваться чужими репозиториями в качестве библиотечных. Здесь, к сожалению, не всё так просто. Хотя как раз такой способ работы, то есть активное использование чужого кода и совместная работа, заявлялись как одна из целей перехода на новый репозиторий. Но не всё сразу, главное, что начало положено.

    На этом мы прервёмся, до встречи в следующей части!

    Последние комментарии | Перейти к обсуждению на форуме трейдеров (20)
    Vladislav Boyko
    Vladislav Boyko | 9 сент. 2025 в 22:45
    Yuriy Bykov #:
    Если и так известно, что это все файлы, создаваемые ME (в кодировке UTF-16 LE)

    Я тестировал это пару месяцев назад. Визард создает UTF-8 (нормальные, не сломанные файлы). Даже MT4 визард создает нормальные файлы. Во время тех тестов мне ни разу не удалось получить от визарда "сломанный" файл.

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

    Vladislav Boyko
    Vladislav Boyko | 10 сент. 2025 в 00:04
    Vladislav Boyko #:
    Кириллица там вряд-ли была - я уже давно отказался от ее использования даже в комментариях.

    Видимо я ошибался. Только что добавил в .mq5 файл с кодировкой UTF-8 вот это:

    // Кириллица

    и после сохранения кодировка файла сменилась на "UTF-16 LE BOM".


    Похоже, это MetaEditor'а косяк. Я добавил кириллические символы и сохранил файл используя Notepad++ и кодировка осталась UTF-8.

     

    Yuriy Bykov
    Yuriy Bykov | 10 сент. 2025 в 00:12
    Vladislav Boyko #:

    Да и вообще я нахожу странным затею доказывать необходимость возможности удаления бранчей из локального репозитория. Учитывая, что Git’s branching model является его киллер фичей и Git поощряет частое создание, удаление и merging бранчей.

    Так я же тоже за удаление веток после их слияния с основными ветками. Просто впервые услышал, что после удаления создают ветку под новую фичу не с новым, а с таким же именем. 

    Для чего смотреть diff?

    Да, это очень нужная вещь. Тоже активно ей пользуюсь, но только в VS Code. А там, как ни странно, никаких поломок нет, хотя смотрю файлы с "плохой" кодировкой.

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

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

    Посмотрел по истории коммитов, что файлы, добавленные два месяца назад, действительно уже имеют кодировку UTF-8, а файлы, добавленные три месяца назад, - ещё UTF-16 LE. Видимо, где-то в это время был переход на кодировку UTF-8.

    Yuriy Bykov
    Yuriy Bykov | 10 сент. 2025 в 00:17
    Vladislav Boyko #:

    Видимо я ошибался. Только что добавил в .mq5 файл с кодировкой UTF-8 вот это:

    и после сохранения кодировка файла сменилась на "UTF-16 LE BOM".


    Похоже, это MetaEditor'а косяк. Я добавил кириллические символы и сохранил файл используя Notepad++ и кодировка осталась UTF-8. 

    Подтверждаю, после добавления русских букв и сохранения кодировка c UTF-8 меняется на UTF-16 LE. Если все русские буквы убрать и сохранить, то всё равно остаётся UTF-16 LE.

    Vladislav Boyko
    Vladislav Boyko | 10 сент. 2025 в 00:32
    Vladislav Boyko #:
    Похоже, это MetaEditor'а косяк.

    Вот доказательство, что можно подружить UTF-8, кириллицу и Git:

    https://forge.mql5.io/junk/utf8-cyrillic-test/commit/e87d37b02e88d44305dea0f7f6630c6173471aea

    Нужно лишь чтобы MQ попросили MetaEditor не изменять кодировку файла.

    От новичка до эксперта: Создание анимированного советника для новостей в MQL5 (IV) - Анализ рынка локально размещенными моделями с использованием ИИ От новичка до эксперта: Создание анимированного советника для новостей в MQL5 (IV) - Анализ рынка локально размещенными моделями с использованием ИИ
    В сегодняшнем обсуждении мы рассмотрим, как самостоятельно размещать модели искусственного интеллекта с открытым исходным кодом и использовать их для получения информации о рынке. Это является частью наших постоянных усилий по расширению советника «Заголовки новостей» путем внедрения раздела «Анализ искусственного интеллекта» (AI Insights), который превращает советник в мультиинтеграционный вспомогательный инструмент. Обновленный советник предназначен для информирования трейдеров о событиях календаря, последних финансовых новостях, технических индикаторах, а теперь и о перспективах рынка, генерируемых искусственным интеллектом, тем самым, предлагая своевременную, разнообразную и интеллектуальную поддержку при принятии торговых решений. Присоединяйтесь к разговору, в ходе которого мы рассмотрим практические стратегии интеграции и то, как MQL5 может взаимодействовать с внешними ресурсами для создания мощного и интеллектуального торгового рабочего терминала.
    Нейросети в трейдинге: Единый взгляд на пространство и время (Extralonger) Нейросети в трейдинге: Единый взгляд на пространство и время (Extralonger)
    Фреймворк Extralonger демонстрирует подход к интеграции пространственных и временных факторов в единую модель, что позволяет одновременно учитывать локальные закономерности и долгосрочные циклы. Такая архитектура делает прогнозирование временных рядов более устойчивым к рыночному шуму и открывает возможность анализа данных на разных горизонтах. В статье подробно рассматривается, как эти идеи воплощаются на практике средствами OpenCL и MQL5.
    Особенности написания экспертов Особенности написания экспертов
    Написание и тестирование экспертов в торговой системе MetaTrader 4.
    От новичка до эксперта: Создание анимированного советника для новостей в MQL5 (III) — Анализ индикаторов От новичка до эксперта: Создание анимированного советника для новостей в MQL5 (III) — Анализ индикаторов
    В настоящей статье продолжим рассказ о советнике «Заголовки новостей», представив специальную полосу «Анализ индикаторов» (indicator insights) — компактное отображение на графике ключевых технических сигналов, генерируемых популярными индикаторами, такими как RSI, MACD, Stochastic и CCI. Такой подход устраняет необходимость в нескольких подокнах индикаторов в терминале MetaTrader 5, сохраняя ваше рабочее пространство чистым и эффективным. Используя MQL5 API для доступа к данным индикаторов в фоновом режиме, мы можем обрабатывать и визуализировать рыночную информацию в режиме реального времени с помощью пользовательской логики.