Изучаем язык программирования MQL4

Ugar

Гуру форума
Была у меня дискуссия по поводу этого самого стоп левела с сотрудником MQ на их же форуме. Ошибку признали как и то что исправлять они ее не собирались. Ошибка древняя и была она еще со времен когда МТ4 был молод и полон сил, т.е. лет так 10 назад.

А вот по поводу плавающего стоп левела через MarketInfo я бы посмотрел, так как MQ утверждали что это невозможно. У какого брокера это есть?
Это было давно, ещё в старом языке. Точно не помню, возможно у альфа-форекс. Они тогда только начинали. Может они его вручную подкручивали на время важных новостей. Не важно, если какие то брокеры используют спред, а какие то, на каких то счетах, вообще не используют, придётся приспосабливаться. Ведь главная задача программирования на MQL это получение прибыли от торговли, а не поиски кто виноват и непременно набить морду виновному. Хотя, конечно, о косяках сообщать надо, вдруг исправят.
Исправили же AccountNumber(). Одно время она возвращала 64 когда терминал не подключен к счёту, теперь снова возвращает 0. Исправили тестер который останавливался при большом тесте от слишко большого количества смоделированных тиков... Про таймер им очень давно писал, может то же исправили, давно его не проверял.
 

Ugar

Гуру форума
А вот недокументированное использование функций они не исправляют. Одно время, для упрощения кода, программисты копировали массив в самого себя. В справочнике не было написано что так можно издеваться над функциями, но работало же. Потом, с выходом какого то билда, программы начали барахлить в этом месте. Программисты обратились метаквотам, они отреагировали довольно быстро добавив в справочник предложение
Если копируется массив сам в себя, то результат неопределен.
Программисты любят упрощать себе работу недокументированным, а когда, с выходом очередного билда, от этого программа начинает сбоить, утверждают что метаквоты накосячили.
Например часто можно встретить что в аргументах OrderClose вместо цены используют OrderClosePrice(). Это проще, не надо описывать какая цена для Buy, а какая для Sell. И это работает. Пока работает.
 

MrGreen86

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

Про таймер им очень давно писал, может то же исправили, давно его не проверял.
судя по всему даже не пытались ) тоже писал и создавал тему по этому моменту.
 
  • Like
Реакции: Ugar

vladradon

Программист
Коллеги MrGreen86 & Ugar! Вам не кажется, что Вы как-то слишком углубились в этой теме своими обсуждениями MQ? Тема о другом ведь!!!
И вопрос к BorisSedov
я 9 лет программирую на MQL4-5 и ни разу не использовал % - к чему такая задачка была изначально, если ее нигде не применяешь? :confused:
Почему никто не обозначил, что вариантов решения задачи может быть много и алгоритм решения (об алгоритме, который нужно изначально либо мысленно представлять себе, либо чертить на бумажке) в большинстве случаев не единственный и нужно еще это учитывать, а не преподавать конкретные варианты, как единственные возможные - полет фантазии должен развиваться у прогера - тогда будет должный положительный результат. Извинити за критику - 7 лет преподавания - не могу иначе.)))
 
Последнее редактирование:

Ugar

Гуру форума
Привет, vladradon!
Ну, ты даёшь. Для начинающих и так много инфы надо освоить. А если каждое решение будет в нескольких вариантах, вообще запутаются. Мне кажется что когда освоятся, варианты сами в голову придут. Тут уже пробовали swich вместо нескольких if. У меня опыт программирования может и больше, но опыт обучения у меня всего полтора года, приходилось учить курсантов. Но здесь, в этой ветке, ценнее опыт обучения. Так что, если будет свободное время и желание, поучи. От твоих уроков может больше будет пользы. У меня мозги плавятся, когда пытаюсь сформулировать так что бы поняли новички. И то не уверен что поймут.
Кстати, ты больше предпочитаешь ООП или ПОП? Классы будешь преподавать?
 

vladradon

Программист
Привет,@ vladradon!
Ну, ты даёшь. Для начинающих и так много инфы надо освоить. А если каждое решение будет в нескольких вариантах, вообще запутаются. Мне кажется что когда освоятся, варианты сами в голову придут. Тут уже пробовали swich вместо нескольких if. У меня опыт программирования может и больше, но опыт обучения у меня всего полтора года, приходилось учить курсантов. Но здесь, в этой ветке, ценнее опыт обучения. Так что, если будет свободное время и желание, поучи. От твоих уроков может больше будет пользы. У меня мозги плавятся, когда пытаюсь сформулировать так что бы поняли новички. И то не уверен что поймут.
Кстати, ты больше предпочитаешь ООП или ПОП? Классы будешь преподавать?
Андрей, хватит ерничать - я имел ввиду преподавание в прошлом и не конкретно по MQL, а как специфику с определенной последовательностью излагать информацию с целью не ускорять эффект удовлетворения получения искомого результата, а давая нужные (чтобы не искать в справочнике) данные и возможные для использования функции, для прихода с использованием уже имеющихся навыков и собственных идей, может быть абсолютно разными путями, к единственно правильному результату.
 
Последнее редактирование:
  • Like
Реакции: Ugar

Ugar

Гуру форума
Андрей, хватит ерничать - я имел ввиду преподавание в прошлом и не конкретно по MQL,
Я я и не ёрничал. Я серьёзно считаю что уметь что то делать и уметь учить, это разные умения. Я то же преподавал давно и не язык программирования. Но если у темя есть навык учить и есть навык программировать, это же рецепт хорошего учителя по программированию. Разве нет?
 

vladradon

Программист
навык учить и есть навык программировать, это же рецепт хорошего учителя по программированию. Разве нет?
Прости, дружище, но я по-другому это вижу - умение преподавать - значит с любого уровня суметь продолжить давать прогрессивную информацию каждому индивидууму ту, которая актуальна именно для него с того уровня, на котором он, индивидуум, находится, и которая способствует прогрессированию его (индивидуума) интеллектуального отклонения в сторону развития новых качеств или продвижению в, хотя-бы, математическом плане.
 
Последнее редактирование:
  • Like
Реакции: Ugar

Ugar

Гуру форума
По поводу разных способов решения задач. И по поводу накой вообще нужны массивы. Допустим задача напечатать в лог тип открытого ордера после его выбора. Ордер уже выбран, надо напечатать.
Вариант с if:
Код:
Expand Collapse Copy
int OrdType=OrderType();
if(OrdType==0)Print("Buy");
if(OrdType==1)Print("Sell");
if(OrdType==2)Print("BuyLimit");
if(OrdType==3)Print("SellLimit");
if(OrdType==4)Print("BuyStop");
if(OrdType==5)Print("SellStop");

Вариант с переключателем:
Код:
Expand Collapse Copy
switch(OrderType())
   {
   case 0: Print("Buy"); break;
   case 1: Print("Sell"); break;
   case 2: Print("BuyLimit"); break;
   case 3: Print("SellLimit"); break;
   case 4: Print("BuyStop"); break;
   case 5: Print("SellStop"); break;
   }

Вариант с массивом:
Код:
Expand Collapse Copy
string OrdTypeStr[6]={"Buy","Sell","BuyLimit","SellLimit","BuyStop","SellStop"};
Print(OrdTypeStr[OrderType()]);
Эти примеры только для MQL4.

Видно что использование массива выгоднее, меньше писанины, меньше операторов которые требуют работы процессора. Получается что массивы позволяют некоторые задачи решить проще. Но это случай когда применение массива не обязательно. А есть случаи когда без них никак. Например, когда неизвестно сколько данных надо хранить. Нельзя решить это переменными, ведь неизвестно сколько их понадобится. Уже в самом языке предусмотрены массивы с характиристиками баров Open[], Close[], High[], Low[], Time[], Volume[]. Неизвестно сколько будет баров, а значит переменные для их хранения не подойдут, а в массивах количество ячеек может изменяться.
 

BorisSedov

Активный участник
И вопрос к BorisSedov
я 9 лет программирую на MQL4-5 и ни разу не использовал % - к чему такая задачка была изначально, если ее нигде не применяешь? :confused:
Не могу знать каким программированием вы занимаетесь 9 лет. Но я профессионально программирую на MQL4 более 10 лет, и до этого программировал в процессе обучения и творчества около 7 лет на разных языках (с 13-14 лет). И задачи с необходимостью применения %, на MQL4 в частности, встречаются достаточно часто. Нет в этой операции ничего мистического, знать и уметь применять % должны все. ;)

Примеры применения операции %.

Был забавный заказ.
Советник по заданным диапазонам должен случайно выбирать значение параметра.
Переменные.
C++:
Expand Collapse Copy
// Смещение.
input int     Shift_min = 0;
input int     Shift_max = 0;

// Таймаут в минутах.
input int     Timeout_min = 0;
input int     Timeout_max = 15;

// Объем ордеров в лотах.
input double  Lots_min = 0.01;
input double  Lots_max = 0.01;

// СтопЛосс в пунктах.
input int     StopLoss_min = 500;
input int     StopLoss_max = 700;

// ТейкПрофит в пунктах.
input int     TakeProfit_min = 800;
input int     TakeProfit_max = 1000;
Реализация случайного выбора.
C++:
Expand Collapse Copy
// OnInit()
MathSrand(GetTickCount());


// OnTick()
int SL=0,TP=0,rnd,cnt

rnd=MathRand();

cnt=StopLoss_max-StopLoss_min;

if(cnt>1)
   {
   rnd%=cnt;
   SL=StopLoss_min+rnd;
   }
else
   {
   rnd%=2;
   if(rnd==0) SL=StopLoss_min;
   else SL=StopLoss_max;
   }

// Имеем на выходе SL выбранный случайно из заданного диапазона.

Другой пример.
Расчет координат привязки для группы графических объектов на графике, при распределении по столбцам.
Количество столбцов задано параметром Columns, порядковый номер объекта num.
C++:
Expand Collapse Copy
x1=277*((num-1)%Columns);
y1=25+184*((num-1)/Columns);

Интересный пример.
Функция выводит информацию о количестве оставшихся дней лицензии.
Ответ может быть "дней", "дня" и "день".
Период активации задается переменной LicPeriod.
datetime LicPeriod = D'01.07.2019';
C++:
Expand Collapse Copy
string flicp()
{
int ddr;
string res,strsfx;

ddr=int((LicPeriod-TimeCurrent())/(60*60*24));

if(ddr%10==0 || (ddr%100>10 && ddr%100<15) || (ddr%10>4 && ddr%10<10)) strsfx="дней";
else
   {
   if(ddr%10==1) strsfx="день";
   else
      {
      if(ddr%10>1 && ddr%10<5) strsfx="дня";
      }
   }

res=(string)ddr+" "+strsfx+".";

return(res);
}

И таких примеров у меня сотни.
Даже не представляю, как вы программируете? :)
Но у меня в работу идет очень многое, из того арсенала, что заложен разработчиками в MQL4.
 

BorisSedov

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

Следующая задача.
Напишите скрипт, который находит все выбранные в обзоре рынка инструменты, и выводит имена этих инструментов в журнал. Вывод построчный при помощи функции Print.
Пример:
EURUSD
GBPUSD
USDJPY
...
 

BorisSedov

Активный участник
У меня в этом советнике, все правильно?
Комментарий так и должен быть всегда 1 ордер?
У вас комментарий выводится по условию если CountTrades() не равен 0, а это значит что выведен комментарий будет только после открытия ордера. Далее 1 будет перезаписываться после каждого нового открытия, но при 0 комментарий не выводится и на графике, при CountTrades() = 0, висит статическая 1, которая остается после прошлого открытия.

Пример на основе вашего кода.
Вывод комментария добавлен в условие если CountTrades() == 0.
C++:
Expand Collapse Copy
if(CountTrades() == 0)                                                          // если ордеров еще нет, то ...
  {
     Comment("Количество открытых ордеров = " ,CountTrades());
     if(Close[1] > Close[3]+N*point)                                              // при соблюдении условия...
     {
     ...
 

BorisSedov

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

Справедливость этого мы уже доказали в этой ветке.
Вот два варианта кода.
Вариант №1.
Вариант №2.
Оба варианта производят определенные вычисления и получают результат, но второй вариант работает приблизительно в 4000 раз быстрее чем первый.
(для задачи k = 100 000)

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

DomovenokBrest

♔♕♖♗♘♙
Отвлекся я на выполнение очередной партии заказов.
Продолжим наши занятия.
Посмотрел ветку, многие вопросы были рассмотрены и это очень хорошо.
Андрею за это скажем огромное спасибо! (y)

Следующая задача.
Напишите скрипт, который находит все выбранные в обзоре рынка инструменты, и выводит имена этих инструментов в журнал. Вывод построчный при помощи функции Print.
Пример:
EURUSD
GBPUSD
USDJPY
...
Уже хотел сдаться и попросить помощи... Выводило только цифры - к-во инструментов в обзоре рынка. Но все же справился )

C++:
Expand Collapse Copy
#property strict

//+------------------------------------------------------------------+
input bool SymTotal = true;

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
// Следующая задача.
// Напишите скрипт, который находит все выбранные в обзоре рынка инструменты, и выводит имена этих инструментов в журнал. Вывод построчный при помощи функции Print.
//Пример:
//EURUSD
//GBPUSD
//USDJPY
{
int n=0;

int list = SymbolsTotal(SymTotal);
string symbols[];
ArrayResize(symbols, list);
for(int i=0;i<SymbolsTotal(SymTotal);i++)
   symbols[i] = SymbolName(n, SymTotal);
   if (SymTotal==true)
  Print("Список валют в MarketWatch:" ,list);
  else Print("Общее количество валют в терминале:" ,list);

for(int i=list-1; i>0; i--)
 {
  n++;
  Print("Symbol=",SymbolName(n, SymTotal), "-", n); // Выводится результат.
 }
Вот только не разобрался с массивом до конца, почему Список валют в MarketWatch: показывает = 56
А построчно выдает 55
 

Вложения

  • Снимок.JPG
    Снимок.JPG
    35,9 КБ · Просмотры: 10
  • Снимок1.JPG
    Снимок1.JPG
    46 КБ · Просмотры: 10

Ugar

Гуру форума
Ну допустим я присваиваю значение ячейке массива. Там %= применять нельзя. Так же %= работает только с целочисленными переменными. Но есть же MathMod() или fmod(). Не плохая альтернатива.
 

Ugar

Гуру форума
Уже хотел сдаться и попросить помощи... Выводило только цифры - к-во инструментов в обзоре рынка. Но все же справился )

C++:
Expand Collapse Copy
#property strict

//+------------------------------------------------------------------+
input bool SymTotal = true;

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
// Следующая задача.
// Напишите скрипт, который находит все выбранные в обзоре рынка инструменты, и выводит имена этих инструментов в журнал. Вывод построчный при помощи функции Print.
//Пример:
//EURUSD
//GBPUSD
//USDJPY
{
int n=0;

int list = SymbolsTotal(SymTotal);
string symbols[];
ArrayResize(symbols, list);
for(int i=0;i<SymbolsTotal(SymTotal);i++)
   symbols[i] = SymbolName(n, SymTotal);
   if (SymTotal==true)
  Print("Список валют в MarketWatch:" ,list);
  else Print("Общее количество валют в терминале:" ,list);

for(int i=list-1; i>0; i--)
{
  n++;
  Print("Symbol=",SymbolName(n, SymTotal), "-", n); // Выводится результат.
}
Вот только не разобрался с массивом до конца, почему Список валют в MarketWatch: показывает = 56
А построчно выдает 55
Потому что индексы массивов, как и нумерация символов в списке начинаются с 0 и заканчиваются размер - 1.
for(int i=list-1; i>=0; i--)
 
Верх