Ваши вопросы по языку MQL4

ale002

::: __,,,^._.^,,,__ :::
Можно конечно извернуться, и в функции найти все нужные значения, но возвращать их придётся через глобальные переменные, так как нормально функция возвращает только одно значение.
Это не обязательно, функция может вернуть сколько нужно значений - ей можно передать переменные поштучно или целый массив, куда ф-ция запишет что нужно и вернёт в основную программу. Напр:

PHP:
Expand Collapse Copy
// тело программы:
double
 dOne = 0,
 dTwo = 0
;
bool bResult = fSetNine(dOne, dTwo);

// функция:
bool fSetNine(double& dOne, double& dTwo) {
 dOne = dTwo = 9;
 return(true)
}
После выполнения в bResult будет true, в dOne и dTwo будут девятки. Для этого используется значок & меж типом и именем в перечислении переменных функции

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

А нафига нам знать уровень гемоглобина, если у пациента пульса нет? Проверки выстроены в порядке приоритетности, если предыдущая не пройдена, последующие лишены смысла
 

Ugar

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

PHP:
Expand Collapse Copy
// тело программы:
double
 dOne = 0,
 dTwo = 0
;
bool bResult = fSetNine(dOne, dTwo);

// функция:
bool fSetNine(double& dOne, double& dTwo) {
 dOne = dTwo = 9;
 return(true)
}
После выполнения в bResult будет true, в dOne и dTwo будут девятки. Для этого используется значок & меж типом и именем в перечислении переменных функции
Ну или так.
 

hoz

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

PHP:
Expand Collapse Copy
// тело программы:
double
 dOne = 0,
 dTwo = 0
;
bool bResult = fSetNine(dOne, dTwo);

// функция:
bool fSetNine(double& dOne, double& dTwo) {
 dOne = dTwo = 9;
 return(true)
}
После выполнения в bResult будет true, в dOne и dTwo будут девятки. Для этого используется значок & меж типом и именем в перечислении переменных функции


Хм. А при невыполнении в bResult будет false. Я вот смотрю на эту конструкцию и не въезжаю, какое у неё может быть применение...


А нафига нам знать уровень гемоглобина, если у пациента пульса нет? Проверки выстроены в порядке приоритетности, если предыдущая не пройдена, последующие лишены смысла


Мой затуп, тут всё элементарно.
 

ale002

::: __,,,^._.^,,,__ :::
Я вот смотрю на эту конструкцию и не въезжаю, какое у неё может быть применение...

Ну вы вроде советниками увлеклись, если делаете их не 1 шт, то используете модульную структуру - работа с ордерами, тралами и проч сопровождение сделок остается неизменным (хотя..), а стратегии меняются. Эту изменяемую часть - получение сигнала по конкретной стратегии - помещаете в отдельную функцию. Если, напр, стратегия предусматривает расчёт размеров SL и TP в зависимости от каких-то условий, то функция может вернуть их через сданные ей на время переменные, как в этом примере. А возвращаемое ф-ей основное значение true/false даст отмашку есть ли там ваще какой-ть сигнал
 

hoz

Активный участник
Хм. А при невыполнении в bResult будет false. Я вот смотрю на эту конструкцию и не въезжаю, какое у неё может быть применение...

PHP:
Expand Collapse Copy
/ тело программы:
double
 dOne = 0,
 dTwo = 0
;
bool bResult = fSetNine(dOne, dTwo);

// функция:
bool fSetNine(double& dOne, double& dTwo) {
 dOne = dTwo = 9;
 return(true)
}


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

hoz

Активный участник
У меня возникла ошибка в эксперте:

Код:
Expand Collapse Copy
2012.11.28 23:58:00	2012.11.01 21:51  Gann_2Days EURUSD,H1: OrderSend error 138


Торговля ведётся на ТФ Н1. Цены вроде как не обновляются часто, торговля лимитными ордерами выставленными заранее до открытие следующего дня.
В чём может быть загвоздка?

Вот нужные функции:

PHP:
Expand Collapse Copy
//+-------------------------------------------------------------------------------------+
//| Открытие длинной позиции                                                            |
//+-------------------------------------------------------------------------------------+
bool OpenBuy()
{
   string qwert = "баянул сов";
   
   if(g_type == OP_SELL)               // Если есть противоположная позиция,..
     if(!CloseDeal(g_ticket))          // Закроем её
     return(false);
     
   if(g_type == OP_BUY)                // Если есть баевый ордер,..
     return(true);
                          // Ничего не делаем
      
   return(SendOrder(Symbol(),g_type,lot,priceForBuy,0,0,qwert,magic));
}
//+-------------------------------------------------------------------------------------+
//| Посыл ордера                                                                        |
//+-------------------------------------------------------------------------------------+
int SendOrder(int symbol, int g_type, double lot, double price, double SL,double TP, string qwert, int magic)
{
  RefreshRates();
//Print("g_type = ", g_type);
//Print("lot = ", lot);
//Print("GetPriceToInput() = ", GetPriceToInput());
//Print("SL = ", SL);
//Print("TP = ", TP);
  int ticket = OrderSend(Symbol(),g_type,lot,GetPriceToInput(),NULL,0,0," ",magic,86400,Green);

  
  return(ticket);
}
//+-------------------------------------------------------------------------------------+
//| Получение цены установки отложенного ордера                                         |
//+-------------------------------------------------------------------------------------+
double GetPriceToInput()
{ 
  double firstBarClosed = iClose(Symbol(),1440,2);                          // Цена закрытия предпоследнего дня
  double secondBarClosed = iClose(Symbol(),1440,1);                         // Цена закрытия последнего дня
  
  if(firstBarClosed > secondBarClosed)                                      // Если закрытие вчерашнего дня ниже закрытия предыдущего..
  {                                                                         //.. (линия по ценам закрытий направлена вниз), то..
    double deltaForSell = (firstBarClosed - secondBarClosed)/2;             // Находим дельту изменения цены до 12 часов текущего дня
    double priceForSell = secondBarClosed - deltaForSell;                   // Вычисляем цену продажи
    return(NormalizeDouble(priceForSell,Digits));
  }

  if(firstBarClosed < secondBarClosed)                                      // Если закрытие предыдущего днях ниже закрытия вчерашнего..
  {                                                                         //..(линия по ценам закрытий направлена вверх), то..
    double deltaForBuy = (secondBarClosed - firstBarClosed)/2;              // Находим дельту изменения цены до 12 часов текущего дня
    double priceForBuy = secondBarClosed + deltaForBuy;                     // Вычисляем цену покупки
    return(NormalizeDouble(priceForBuy,Digits));
  }
}


В чём неверность?
 
Последнее редактирование модератором:

ale002

::: __,,,^._.^,,,__ :::
В теле программы же все переменные глобальные. На сколько я читал, по ссылке передаются значения переменных только из функций т.е. тел функций, а не программы самой.
Для моих мозгов слишком умное что-то загнули, не понял. Мозги, чу-чу помычав, выдали тока это: "в mql никакой код не выполняется в глобальной области, всё в функциях, включая основной рабочий цикл". Что это значит я тоже не понял :)

У меня возникла ошибка в эксперте: EURUSD,H1: OrderSend error 138

Сравните полученную после RefreshRates() цену Bid (или Ask, смотря какой ордер) с тем уровнем, котор вам возвращает GetPriceToInput. Вполне вероятно, что этот уровень уже проехали, соотв ставить отложку нужного вам типа туда уже нельзя
 
Последнее редактирование:

hoz

Активный участник
Сравните полученную после RefreshRates() цену Bid (или Ask, смотря какой ордер) с тем уровнем, котор вам возвращает GetPriceToInput. Вполне вероятно, что этот уровень уже проехали, соотв ставить отложку нужного вам типа туда уже нельзя


Нет. Там у меня тип был другой. Не отложка, а рыночный же. В функции OpenBuy() нужно было явно задать тип ордера. Вместо g_type прописать OP_BUYLIMIT.

PHP:
Expand Collapse Copy
return(SendOrder(Symbol(),g_type,lot,priceForBuy,0,0,qwert,magic));


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


У меня есть ф-ция которая вычисляет цену для открытия лимитного ордера:

PHP:
Expand Collapse Copy
//+-------------------------------------------------------------------------------------+
//| Получение цены установки отложенного ордера                                         |
//+-------------------------------------------------------------------------------------+
double GetPriceToInput()
{ 
  double firstBarClosed = iClose(Symbol(),1440,2);                          // Цена закрытия предпоследнего дня
  double secondBarClosed = iClose(Symbol(),1440,1);                         // Цена закрытия последнего дня
  
  if(firstBarClosed > secondBarClosed)                                      // Если закрытие вчерашнего дня ниже закрытия предыдущего..
  {                                                                         //.. (линия по ценам закрытий направлена вниз), то..
    double deltaForSell = (firstBarClosed - secondBarClosed)/2;             // Находим дельту изменения цены до 12 часов текущего дня
    double priceForSell = secondBarClosed - deltaForSell;                   // Вычисляем цену продажи
    return(NormalizeDouble(priceForSell,Digits));
  }

  if(firstBarClosed < secondBarClosed)                                      // Если закрытие предыдущего днях ниже закрытия вчерашнего..
  {                                                                         //..(линия по ценам закрытий направлена вверх), то..
    double deltaForBuy = (secondBarClosed - firstBarClosed)/2;              // Находим дельту изменения цены до 12 часов текущего дня
    double priceForBuy = secondBarClosed + deltaForBuy;                     // Вычисляем цену покупки
    return(NormalizeDouble(priceForBuy,Digits));
  }
}


Можно как-н. мне использовать её не так GetPriceToInput() , а по-скольку данная ф-ция возвращает не одно значение, то я хотел бы напрямую вызвать либо priceForBuy либо priceForSell непосредствеено. Типа прописать данную переменную в нужном месте.
Такого я нигде не встречал, но может быть подобные варианты существуют?
 
Последнее редактирование модератором:

Алекc1234

Местный житель
Приветствую всех. Как в коде написать, чтобы стоплосс второго открытого ордера(конкретно бая или селла) ставился на уровне первого открытого ордера(если открыт бай, то бая, если селл, то селла)?
 

Ugar

Гуру форума
Приветствую всех. Как в коде написать, чтобы стоплосс второго открытого ордера(конкретно бая или селла) ставился на уровне первого открытого ордера(если открыт бай, то бая, если селл, то селла)?
Перебирай в цикле ордера в порядке открытия. Сначала попадётся ордер открытый первым, пиши в переменную его стоп лосс. Когда попадётся второй ордер сравни его стоп лосс со значением переменной, если отличается модифицируй ордер задав стоп лосс из переменной.
 

Алекc1234

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

Спасибо, только возможно это всё в коде написать? Я сам не осилю...
 

Ugar

Гуру форума
Спасибо, только возможно это всё в коде написать? Я сам не осилю...
Примерно так:
Код:
Expand Collapse Copy
int total, i;
   double sl1Buy=-1, sl1Sell=-1;
   for(i=0; i<total; i++)
      {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
         {
         Print("Ордер не выбран, ошибка = ",GetLastError());
         return(0);
         }
      if(OrderType()==OP_BUY)
         {
         if(sl1Buy<0)sl1Buy=OrderStopLoss();
         else
            {
            if(MathAbs(OrderStopLoss()-sl1Buy)>Point)
               {
               if(!OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(sl1Buy,Digits),
               OrderTakeProfit(),0,Blue))
                  {
                  Print("Ордер не модифицирован, ошибка=",GetLastError());
                  Sleep(3000);
                  }
               }
            }
         }
      if(OrderType()==OP_SELL)
         {
         if(sl1Sell<0)sl1Sell=OrderStopLoss();
         else
            {
            if(MathAbs(OrderStopLoss()-sl1Sell)>Point)
               {
               if(!OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(sl1Sell,Digits),
               OrderTakeProfit(),0,Red))
                  {
                  Print("Ордер не модифицирован, ошибка=",GetLastError());
                  Sleep(3000);
                  }
               }
            }
         }
      }
Только не стоит всё копировать и надеяться что будет работать как надо. Надо разобрать код с помощью справочника и понять почему сделано так. Может в конкретном случае что то нужно добавить или изменить. Пользы больше будет.
 
Последнее редактирование модератором:

Алекc1234

Местный житель
Примерно так:
Код:
Expand Collapse Copy
int total, i;
   double sl1Buy=-1, sl1Sell=-1;
   for(i=0; i<total; i++)
      {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
         {
         Print("Ордер не выбран, ошибка = ",GetLastError());
         return(0);
         }
      if(OrderType()==OP_BUY)
         {
         if(sl1Buy<0)sl1Buy=OrderStopLoss();
         else
            {
            if(MathAbs(OrderStopLoss()-sl1Buy)>Point)
               {
               if(!OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(sl1Buy,Digits),
               OrderTakeProfit(),0,Blue))
                  {
                  Print("Ордер не модифицирован, ошибка=",GetLastError());
                  Sleep(3000);
                  }
               }
            }
         }
      if(OrderType()==OP_SELL)
         {
         if(sl1Sell<0)sl1Sell=OrderStopLoss();
         else
            {
            if(MathAbs(OrderStopLoss()-sl1Sell)>Point)
               {
               if(!OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(sl1Sell,Digits),
               OrderTakeProfit(),0,Red))
                  {
                  Print("Ордер не модифицирован, ошибка=",GetLastError());
                  Sleep(3000);
                  }
               }
            }
         }
      }
Только не стоит всё копировать и надеяться что будет работать как надо. Надо разобрать код с помощью справочника и понять почему сделано так. Может в конкретном случае что то нужно добавить или изменить. Пользы больше будет.

Спасибо большое. Я подстроился под свой код и всё получилось!
 

sochinik

Местный житель
Пытаюсь понять, как правильно составлять функции в MQL? просматривая коды советников( декомпил) заметил что в них часто появляются такие функции " f0_23" может только цифровое обозначение сменится. Как образуются такие функции?
 

Ugar

Гуру форума
Пытаюсь понять, как правильно составлять функции в MQL? просматривая коды советников( декомпил) заметил что в них часто появляются такие функции " f0_23" может только цифровое обозначение сменится. Как образуются такие функции?
Мммдааа... Может стоит начинать с учебника? Вряд ли получится хоть как то изучить язык программирования методом научного тыка.
Все функции образуются одинаково. Их пишет программист, иногда вспомогательное программное обеспечение. Скорее всего они имели нормальные имена, пока их декомпил не покорёжил. Каждый программист именует свои функции как хочет. По этому функции с одинаковыми именами в разных программах не обязательно одинаковые. Декомпил вообще именует не по смыслу, а чуть ли не по порядку. По этому функции с одинаковыми именами в разных программах, наверняка разные.
Я имел ввиду пользовательские функции.
 
Последнее редактирование:

sochinik

Местный житель
Мммдааа... Может стоит начинать с учебника? Вряд ли получится хоть как то изучить язык программирования методом научного тыка.
Все функции образуются одинаково. Их пишет программист, иногда вспомогательное программное обеспечение. Скорее всего они имели нормальные имена, пока их декомпил не покорёжил. Каждый программист именует свои функции как хочет. По этому функции с одинаковыми именами в разных программах не обязательно одинаковые. Декомпил вообще именует не по смыслу, а чуть ли не по порядку. По этому функции с одинаковыми именами в разных программах, наверняка разные.
Я имел ввиду пользовательские функции.
Спасибо , уроки по MQL почитал и даже посмотрел видеоуроки, но пока практика на О, вот и пытаюсь понять составление функций с помощью кодов советников с которыми я знаком в работе, но к сожалению больщинство из них декомпилл,
Ещё для новичков могу заметить есть прога Forex EA Generator 4 , как утверждают разработчики в ней можно составить сову не зная MQL? да это так, но только простую, а для составления сложного эксперта функций в ней недостаточно.А вот для поннимания правильного написания кода очень полезная штука, так как сгенерирвав в ней код можно его доработать в метаэдиторе..
 

Ugar

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

sochinik

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

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

AlexeyVik

Программист mql4 mql5
Это я уже и начинаю понимать, просто подыскать как составлена функция для того чтобы составить свою очень сложно в нете, так как в массе советников надо разбираться- но мне теперья ясно что в декомпил лучще не лезть
А ты попробуй почитать здесь http://docs.mql4.com/ru/basis/functions
Функция - это поименованная часть программы, которая может вызываться из других частей программы столько раз, сколько необходимо. Она состоит из описания типа возвращаемого значения, имени, формальных параметров и составного оператора (блока) из выполняемых действий. Количество параметров, передаваемых в функцию, ограничено и не может превышать 64.
А можно такую часть кода написать столько раз, сколько необходимо. Вот и вся разница... А как удобней читать и как легче заблудиться в строках как в лесу...
 

vetallic

Местный знаток
прет,
хотел сделать чтоб робот работал после открытия ордера вручную и вел дальше...
какой меджик прописать чтоб он определял и вел их дальше правильно? 0?
 
Верх