Mql4 дописать в файл

Обновлено: 06.07.2024

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

MQL (MQL4 и MQL5) не является таким языком из-за очень узкой специализации. Программистов мало, и их интерес часто поверхностный. То, что MQL корнями уходит к популярным C/C++, не делает его таковыми автоматически. Что касается оформления кода, то эти языки послужили ему скорее дурным примером. Когда C и даже C++ уже стали популярными, еще не были развиты некоторые современные методы и технологии программирования. В основном, это касается массового применения систем контроля версий и увеличения взаимодействия в целом.

MetaQuotes предлагает как стандартный весьма спорный стиль, чем-то похожий на GNU (см. стилизатор в MetaEditor с настройками по умолчанию). Тем, кто использует популярные языки программирования и методы разработки, такое оформление может быть неудобным из-за отличия от большинства стандартов оформления кода, используемых сейчас в больших сообществах и проектах. Далее предлагаются некоторые альтернативные правила, оптимизированные для работы с системами контроля версий и дающие лучшую читаемость кода.

Комментарии

Комментарии не должны использоваться для разметки кода

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

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

  • если вместо пропуска строки стоит комментарий-разделитель (часто //----- ), то при изменении строки в список изменений попадет сразу несколько соседних строк вместо одной, которую действительно изменили, так как программы поиска изменений используют в первую очередь пустые строки как разделители блоков кода;
  • при правке только разделителей-украшений вы получаете пустую ревизию (коммит), что усложняет работу с версиями;
  • украшения отвлекают внимание от действительных изменений.


Четыре строки бесполезных украшений. И четыре строки кода. Без комментариев.

Комментарии должны быть

Длинными или короткими, на русском или английском - зависит от конкретных требований, лично ваших или заказчика. Главное, чтобы они были. Переделаем кусок выше:


Может показаться, что здесь комментарии излишни, т.к. вроде и так всё понятно. Увы, для новичка в MQL или даже программировании в целом (многие начинают с MQL) совсем непонятно, что такое хэндл файла. Если хочется избавиться здесь от "лишних" комментариев, лучше написать функцию FileCloseIfOpen и не писать каждый раз проверку на существование хэндла. Либо можно использовать стандартную библиотеку, где есть относительно удобные классы-обёртки для файловых операций.

Также может быть не лишним отметить, что функция deinit() запускается при завершении программы. Не зная особенностей исполнения MQL-программ, я не смог бы предположить, что эта функция какая-то особенная. В MQL5 и обновлённом MQL4 эта функция заменена на более понятную OnDeinit.

Ваши контакты

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

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

Пунктуация и отступы

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

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

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


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

Пунктуация

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

Пример кода без соблюдения этих элементарных правил пунктуации:


Тот же код с пунктуацией:

Отступы

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

Дополнение. С моим любимым шрифтом оказалось, что лучше выглядит отступ в 5 или 6 пробелов, хотя раньше очень долго использовал 4. Символы в этом шрифте довольно узкие, и обычно достаточно широкий отступ в 4 пробела здесь оказался маловат. Одна быстрая настройка в редакторе кода, и весь мой код теперь с новым отступом.

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

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


Длинные строки разбиваются на несколько так, чтобы каждая часть была не слишком длинной. Длина определяется современным состоянием рынка мониторов, удобством чтения длинных строк и прочими критериями. Распространенные стандарты - 80 и 120 символов. Массовое распространение мышек с колесом делает такое ограничение менее нужным, теперь для листания по горизонтали можно совершать меньше движений, чем, например, 10 лет назад (если бы MetaEditor поддерживал горизонтальную прокрутку). Однострочные выражения лучше подходят для систем контроля версий. Исключением может быть ситуация, когда выражение разбивается на несколько строк для лучшего отображения его структуры.

Другое ограничение связано с использованием систем контроля версий. Сейчас еще популярно начинать следующую часть строки с отступом до некоторой отметки, например, началу списка параметров, вот так:


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


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


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

Дополнение. Чтобы комментарии справа от кода сдвигать как можно реже, используйте какой-нибудь удобный шаг (сетку), например, кратную 4, 5, 8 или 10, тогда в большинстве случаев новые изменения не будут смещать остальные комментарии.

Структура

Под структурой подразумевается группировка блоков кода с помощью добавления отступов слева. Хорошая структура позволяет быстро оценить возможные ветвления выполнения программы. Это самый важный элемент стилизации кода.

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

В стиле MetaQuotes фигурные скобки имеют дополнительный отступ относительно оператора, для которого они применяются.


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

Использование дополнительного отступа затрудняет определение структуры, особенно если размер отступа невелик:


Этот пример будет проще прочесть без дополнительных отступов у скобок:


Здесь фигурные скобки выделяют операторы сравнения и их блоки кода выравниванием по меньшему числу отступов (уровней структуры), чем в исходном примере. Нет никакого смысла плодить лишние уровни.

Особое место в аду уготовано тем, кто пытается здесь сократить число скобок, получив в итоге что-то вроде этого:


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

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


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


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


При использовании else в операторе ветвления выделение внутренних блоков должно быть одинаковым - либо с фигурными скобками везде, либо нигде.

Классы

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

Возьмем для примера простейший класс с двумя полями и методом:


Это почти типичное оформление кода класса от MetaQuotes, встречающееся в документации и стандартной библиотеке, приведённое в соответствие с правилами предыдущих статей. Здесь получаем несколько проблем, которые попытаемся решить.

Модификаторы доступа выходят из структуры

В коде выше модификаторы public и private находятся на том же уровне, что и название класса, хотя они являются частью структуры (группировка), причем их верхним уровнем является как раз объявление класса. То есть эти модификаторы должны писаться с отступом. Некоторые современные стандарты оформления кода C++ уже учитывают эту ошибку и предлагают делать дополнительный отступ.


Дополнение. Это спорный момент. Сам я пока следую за большинством, которое отступы здесь не добавляет.

Изменение модификатора и контроль версий

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

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


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

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

Изменение модификатора доступа для двух полей класса:


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


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

Вы можете использовать более продвинутые средства сравнения, например TortoiseMerge, Meld и т.п.:


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

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

Модификаторы доступа. Порядок

С одной стороны, хочется, чтобы публичные методы были как можно выше, поэтому желательна сортировка типа public-protected-private. С другой стороны, неудобно располагать члены класса (часто приватные) в конце класса и рассеивать их по телу класса.

  1. Члены класса (или структуры) всегда идут перед методами.
  2. Члены и методы сортируются в порядке public-protected-private.
  1. public члены
  2. protected члены
  3. private члены
  4. public методы
  5. protected методы
  6. private методы
  • конструкторы и деструкторы
  • геттеры и сеттеры
  • операторы
  • статические методы
  • виртуальные методы и переопределения
  • обычные методы

Объявление и реализация

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

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


Такой же подход предлагается по умолчанию и в MQL5. Хорошо, что синтаксис языка позволяет писать реализацию метода прямо за объявлением, что решает проблему.


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

Пример излишне усложненной навигации (функция "Перейти к определению"):


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

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


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

Сначала скачиваем архив включаемых файловinclude.zip и распаковываем его в папку «experts => include» терминала MetaTrader 4.
experts => scripts»[/color] терминала MetaTrader 4:
После этого помещаем программу MQL4 (индикатор, советник или скрипт), которую хотим преобразовать в MQL5 в папку «experts => files» терминала MetaTrader 4. Теперь открываем MetaTrader 4 и запускаем на исполнение скрипт mq4to5rewrite_sample_v5_02.zip. В окне параметров скрипта необходимо ввести имя конвертируемого MQL4 файла без расширения. А в следующем параметре ставим код типа этого файла. Если конвертируемый MQL4 файл это индикатор, ставим (0), если советник – (1), если скрипт – (2).

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


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

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


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

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

Почему не поможет? Он может заказать написание программы на МТ4, затем переконвертировать в МТ5. Или это не реально? Он же собирается "развиваться" в этой теме

У МТ5 есть некоторые преимущества. Если у кого переворотная стратегия или пирамидку безлоковую строит, тому есть большой смысл на МТ5 переходить. Выбор таймфреймов в МТ5 большой - удобно графики под открытия рынков подстраивать. Я умиляюсь, когда в стратегиях под h4 предлагают обязательно дождаться закрытия свечи. У одних ДЦ терминальное время GMT+1, у других GMT+2, у третьих GMT+3 . А тут ещё летнее-зимнее время. Что это закрытие h4 подтверждает?
А вот mql у 5 очень замудрённый по сравнению с 4. А наработок под MT5 пока очень мало. Я некоторые простые вещи ручками переделываю, но всё это туго и долго. Еще нужно знать, что некоторые советники с МТ4, будучи даже идеально переконвертированными в МТ5, все равно не будут работать из-за особенностей торговли в мт5. Здесь сама стратегия заложенная в советник просто не будет работать. Это касается локов. Мое мнение конвертировать с МТ4 в МТ5 это тоже что переделывать бензиновый двигатель под дизель. Хотя задача у них одна приводить в движение авто, да вот только механизм разный. Интересно, а есть может конвертер с MQL4 на другие языки для программирования? И в частности интересует на те языки, которые поддерживают NT и TOS. И где можно найти все это что бы может бесплатно.

extern int TimeFrame=0;
extern int EMA_Period=13;
extern int MACD_FastPeriod=12;
extern int MACD_SlowPeriod=26;
extern int MACD_SignalPeriod=9;
extern bool UseMT4MACD=false;

//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];

double MACDLineBuffer[];
double MACDSignalLineBuffer[];
double MACDHistogramBuffer[];

//---- indicators
SetIndexStyle(0,DRAW_HISTOGRAM, 0, 3);
SetIndexBuffer(0, ExtMapBuffer1);
SetIndexStyle(1,DRAW_HISTOGRAM, 0, 3);
SetIndexBuffer(1, ExtMapBuffer2);
SetIndexStyle(2,DRAW_HISTOGRAM, 0, 3);
SetIndexBuffer(2, ExtMapBuffer3);
SetIndexStyle(3,DRAW_HISTOGRAM, 0, 3);
SetIndexBuffer(3, ExtMapBuffer4);
//----
SetIndexDrawBegin(0,MACD_SlowPeriod);
SetIndexDrawBegin(1,MACD_SlowPeriod);
SetIndexDrawBegin(2,MACD_SlowPeriod);
SetIndexDrawBegin(3,MACD_SlowPeriod);

//---- indicator buffers mapping
SetIndexBuffer(0,ExtMapBuffer1);
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexBuffer(2,ExtMapBuffer3);
SetIndexBuffer(3,ExtMapBuffer4);

SetIndexEmptyValue(4,0.0);
SetIndexBuffer(4,MACDSignalLineBuffer);
SetIndexEmptyValue(5,0.0);
SetIndexBuffer(5,MACDLineBuffer);
SetIndexEmptyValue(6,0.0);
SetIndexBuffer(6,MACDHistogramBuffer);
//---- initialization done

//----
return(0);
>
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
<
int limit,y=0,counted_bars=IndicatorCounted();
double ema1, main1, signal1, ema0, main0, signal0, macd1, macd0, main;
double alpha = 2.0 / (MACD_SignalPeriod + 1.0);
double alpha_1 = 1.0 - alpha;
double BarValue, aOpen, aClose;

if(Bars 0) ExtCountedBars--;
int pos=Bars-ExtCountedBars-1;
while(pos>=0)
<
y = iBarShift(NULL,TimeFrame,Time[pos]);
ema0=iMA(NULL,TimeFrame,EMA_Period,0,MODE_EMA,PRICE_CLOSE,y);
ema1=iMA(NULL,TimeFrame,EMA_Period,0,MODE_EMA,PRICE_CLOSE,y+1);

if(UseMT4MACD)
<
main0=iMACD(NULL, TimeFrame, MACD_FastPeriod, MACD_SlowPeriod, MACD_SignalPeriod, PRICE_CLOSE,0,y);
main1=iMACD(NULL, TimeFrame, MACD_FastPeriod, MACD_SlowPeriod, MACD_SignalPeriod, PRICE_CLOSE,0,y+1);

signal0=iMACD(NULL, TimeFrame, MACD_FastPeriod, MACD_SlowPeriod, MACD_SignalPeriod, PRICE_CLOSE,1,y);
signal1=iMACD(NULL, TimeFrame, MACD_FastPeriod, MACD_SlowPeriod, MACD_SignalPeriod, PRICE_CLOSE,1,y+1);

main=main0;
macd0=main0-signal0;
macd1=main1-signal1;
> else
<
MACDLineBuffer[y] = iMA(NULL,TimeFrame,MACD_FastPeriod,0,MODE_EMA,PRICE_CLOSE,y)-
iMA(NULL,TimeFrame,MACD_SlowPeriod,0,MODE_EMA,PRICE_CLOSE,y);
MACDSignalLineBuffer[y]=(alpha*MACDLineBuffer[y]) + (alpha_1*MACDSignalLineBuffer[y+1]);
MACDHistogramBuffer[y]=MACDLineBuffer[y]-MACDSignalLineBuffer[y];


Добрый день, друзья!

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

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

Общая идея


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

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

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

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

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

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

По сути, метод “backup” создает бэкап-файл, через который мы затем будем проверять изменения в открытых позициях.

Также есть вариант для чтения из файла, где возвращается количество сохраненных позиций.

Имеются такие же методы для шаринга позиций. “pull” – для получения данных о позициях из общего файла, “share” – для записи изменений в общий файл. В “share” имеется поддержка нескольких провайдеров. Чтобы исключить конфликт нескольких мастер-счетов, пытающихся получить доступ к одному файлу, каждый провайдер идентифицируется по номеру аккаунта.

Метод “opened” возвращает текущие открытые позиции на счету. В начале я говорил, что при частичном закрытии Метатрейдер изменяет тикет ордера, а старый записывает в комментарий к новому. Поэтому, чтобы клиент понимал, что это не новый ордер, запоминаем старый тикет, записывая в поле “magic”.

Основная функция копировальщика, непосредственно копирование сделок, реализовано через метод “mergeAndTrade”. Точную реализацию смотрите в полном исходнике. Если кратко, то все что мы делаем, это сравниваем последний локальный бэкап с общим файлом. Если в общем файле появились изменения, модифицируем текущие позиции или открываем новые.

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

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

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

Также, можно выбрать способ копирования объемов. Фиксированный объем копируется один в один, независимо от размера депозита. Динамический объем копируется кратно размеру эквити на клиенте. То есть, если на провайдере открыта позиция 0.1 лота с депозитом 100 долларов, то на клиенте с депозитом в 200 долларов откроется сделка объемом 0.2 лота.

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

Для запуска копирования кидаем эксперта на график и выбираем тип копира – Master или Slave. Количество как провайдеров, так и клиентов не ограничено – вы можете копировать сделки с нескольких счетов любого типа, на любые реальные/демо счета.

Заключение


Итак, на данном этапе реализовано:

  • Надежность передачи – файлы не используются одновременно разными процессами, при этом у каждого клиента имеется снимок текущих позиций;
  • Копирование фиксированного и относительного объема позиций, поддержка модификации стоп уровней и частичного закрытия;
  • Возможность применения на любом количестве терминалов MT4/MT5, с неограниченным количеством Провайдеров/Клиентов.

К недостаткам можно отнести:

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


С уважением, Дмитрий аkа Silentspec

Mql iCustom

Всем доброго времени суток. На прошлых уроках по программированию советников на языке MQL4 мы использовали данные классических индикаторов MA, Stochastic, MACD и т.д., непосредственно встроенных в торговый терминал Meta Trader 4. В данном случае функция импорта данных уже встроена в редактор Meta Editor и разобраться в ней не составит труда. Но что делать, если вы нашли сторонний индикатор, который удовлетворяет вашим требованиям, и вы жаждете попробовать его в своем советнике?

В этом уроке мы разберем, как использовать функцию iCustom на примере двух рандомных индикаторов и импортируем их данные в наш простенький советник. Почему двух? Потому что один будет с открытым кодом, а второй с закрытым.

Основы импорта данных индикаторов

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

Bollinger Bands

буферы индикатора

В этом окне отображаются OHLC цены текущей свечи, на которую наведена мышь, а также данные всех индикаторов, что установлены на этом графике. В нашем случае это BB и тремя буферами: Band SMA (средняя линия), Bands Upper (верхняя линия) и Bands Lower (нижняя линия).

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

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

Создаем простенькую основу советника

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

Читайте также: