Особенности языка mql4, тонкости и приёмы работы

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

Для закрытия ордера совсем не обязательно определять тип ордера и цену соответствующую этому типу. Достаточно написать закрыть по цене OrderClosePrice()

/********************Script program start function********************/
void OnStart()
{
   int i, total = OrdersTotal()-1;
    for(i = total; i >= 0; i--)
     {
      if(OrderType() < OP_SELLSTOP)
       {
        if(!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100))
        printf("***********");
       }
     }
}/********************************************************************/
 

Неточностей в справке еще много. Возьмем, например, SetIndexBuffer(). Что не так в справке?

"Параметры

index

[in]  Номер индикаторного буфера. Нумерация начинается с 0. Номер должен быть меньше значения, объявленного в #property indicator_buffers." (это утверждение не соответствует действительности)

#property indicator_buffers указывает количество отображаемых буферов. Возможно, справка имеет в виду, хотя я этого и не проверял, что, буферам, используемым для расчета, не обязательно указывать номер с помощью SetIndexBuffer(). Но, что я проверял, так это, если буферу, используемому для расчетов, указать номер с помощью функции SetIndexBuffer(), то его значение можно будет получить через iCustom().

 
Ничего не понял
 

Раз разработчики посещают топик - есть вопрос про "тонкости и приёмы":

Пример форматированной печати: PrintFormat("Bid=%.5f", Bid)

Вопрос: есть ли возможность вместо фиксированной точности (здесь 5) задавать в описании формата условие, чтобы точность зависела от _Digits? Чтобы обходиться без 'препроцессинга' типа PrintFormat("Bid=%s", DoubleToString(Bid, _Digits))

 

В MQL4 один и тот же код может выдавать разные результаты, в зависимости от состояния наличия #property strict. И это при успешной компиляции в обоих случаях. Поэтому, если выполнение "бредит", можно долго искать причину не там (strict). 

 
Alexander Puzanov:

Вопрос: есть ли возможность вместо фиксированной точности (здесь 5) задавать в описании формата условие, чтобы точность зависела от _Digits?

Нет, примеры есть https://www.mql5.com/ru/docs/common/printformat
Документация по MQL5: Общие функции / PrintFormat
Документация по MQL5: Общие функции / PrintFormat
  • www.mql5.com
Общие функции / PrintFormat - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 

Описание проблемы

Пишу индикатор на MQL4. Столкнулся с недокументированной особенностью стиля DRAW_HISTOGRAM.

Чтобы отобразить значения на графике нужно два буфера: для верхнего значения гистограммы и для нижнего. При сопоставлении индикаторным буферам массивов, если буферы для стиля будут иметь значения 0 и 1, 2 и 3, 4 и 5 и т.д. все отображается нормально. Однако, если буферам стиля будут присвоены значения начиная с НЕЧЕТНОГО, т.е. 1 и 2, 3 и 4, 5 и 6, на графике линии гистограммы будут отображаться некорректно, хотя значения в окне данных будут корректными.

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

Из СД.
 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

-Aleks-, 2017.02.07 18:21

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


Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

Slawa, 2017.02.08 08:20

Все буферы рассчитываются сразу. Спокойно опрашивайте значения индикатора - перерасчёта не будет

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

 
Alexey Viktorov:
Для закрытия ордера совсем не обязательно определять тип ордера и цену соответствующую этому типу. Достаточно написать закрыть по цене OrderClosePrice()

Так использовать OrderClosePrice можно только СРАЗУ после соответствующего OrderSelect. Т.к. OrderSelect копирует один раз данные для Order(const)-функций, а тот же RefreshRates их обновить не в состоянии.

Т.е. если, например, по OrderClosePrice закрыть не удалось, то нужно перед следующей попыткой сделать снова OrderSelect (RefreshRates не требуется).

 

ЗЫ Это тема аж 2005 года! Здесь подробные доводы разработчиков.

 
Rashid Umarov:
Нет, примеры есть https://www.mql5.com/ru/docs/common/printformat

Жаль..

---

Чтобы пост не был бесполезным:

вместо StringGetCharacter("a", 0) можно писать просто 'a' - часто бывает нужно при разборе строк на части с помощью StringSplit