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

Ugar

Гуру форума
Ugar, ты же меня сам запутал:oops: У меня же и до того были выбраны ордера, которые в последствии по коду модифицируются.
Да ну. Где же я тебя запутал? Где же ты выбрал ордер? Речь изначально шла о том что принтуется.
Я вижу что в начале функции принтуешь значения OrderStopLoss() и OrderTakeProfit(), но не вижу где перед этим был выбран ордер. Где то до вызова этой функции? Так надо было показать этот кусок кода.
Я вижу что выбор ордера идёт дальше по коду, же после открытия. Вот после этого и надо использовать OrderStopLoss() и OrderTakeProfit().
Вот я всё исправил в данной функции. Всё лишнее пока что убрал. Ошибка 130 всё-равно на месте. Может есть что посоветовать? Читать учебник одно, а практике это уже другое.
Ошибки в работе этой функции меня не удивляют. А какая практика то нужна? Как построить код что бы никто не понял? Как использовать пользовательскую функцию внутри другой? Я же не знаю в чём ты практикуешься? Я давал советы как проще начать, но видать проще не надо. Видать надо так что бы сам ничего не понял. Тогда ковыряй декомпилы, веселее будет.
Я иногда пишу, если заказчик просит, запутанные коды. Жаль что они все коммерческие, а то бы поделился. Там так запутано, что даже опытные программисты, от одного вида начинают разговаривать матом.
 

hoz

Активный участник
Да ну. Где же я тебя запутал? Где же ты выбрал ордер? Речь изначально шла о том что принтуется.
Я вижу что в начале функции принтуешь значения OrderStopLoss() и OrderTakeProfit(), но не вижу где перед этим был выбран ордер. Где то до вызова этой функции? Так надо было показать этот кусок кода.
Я вижу что выбор ордера идёт дальше по коду, же после открытия. Вот после этого и надо использовать OrderStopLoss() и OrderTakeProfit().

Ошибки в работе этой функции меня не удивляют. А какая практика то нужна? Как построить код что бы никто не понял? Как использовать пользовательскую функцию внутри другой? Я же не знаю в чём ты практикуешься? Я давал советы как проще начать, но видать проще не надо. Видать надо так что бы сам ничего не понял. Тогда ковыряй декомпилы, веселее будет.
Я иногда пишу, если заказчик просит, запутанные коды. Жаль что они все коммерческие, а то бы поделился. Там так запутано, что даже опытные программисты, от одного вида начинают разговаривать матом.

Где запутал смысла писать уже нет. Но что я сложного написал это вопрос точно. Тут всё просто. Даже комменты есть.. Специально написал комменты, что б было видно, что происходит в каждом канкретном моменте:

PHP:
//+-------------------------------------------------------------------------------------+
//| Открытие длинной позиции                                                            |
//+-------------------------------------------------------------------------------------+
int OpenBuy()
{
  g_ticket = -1;
  string myNote = "сов баянул";
         
  g_ticket = OrderSend(Symbol(),OP_BUYLIMIT,0.1,GetPriceToInput(),3,0,0,myNote,myMagic,0,Blue);
  if(g_ticket > 0 && OrderSelect(g_ticket,SELECT_BY_TICKET,MODE_TRADES) == true)
  
  return(g_ticket);
}
//+-------------------------------------------------------------------------------------+
//| Открытие короткой позиции                                                           |
//+-------------------------------------------------------------------------------------+
int OpenSell()
{
  g_ticket = -1;
  string myNote = "сов шортанул";

  g_ticket = OrderSend(Symbol(),OP_SELLLIMIT,0.1,GetPriceToInput(),3,0,0,myNote,myMagic,0,Red);
  if(g_ticket > 0 && OrderSelect(g_ticket,SELECT_BY_TICKET,MODE_TRADES) == true)
  
  return(g_ticket);
}
//+-------------------------------------------------------------------------------------+
//| Открытие позиций                                                                    |
//+-------------------------------------------------------------------------------------+
bool Trade (int signal)
{
  double sl = 0, tp = 0;

  if(signal == SIGNAL_BUY && FindOrders() == 0)                                     // Если сигнал на покупку и открытых ордеров нет...
  {
    g_ticket = OpenBuy();                                                           // открываем лимитный ордер на покупку
  
    if(g_ticket > 0 && OrderSelect(g_ticket,SELECT_BY_TICKET,MODE_TRADES) == true)  // Если ордер есть и он выбран..
    {
      if(i_sl != 0)                                                                 // Если входной параметр стоп-лосса не равен 0, то..
        sl = NormalizeDouble(OrderOpenPrice() - i_sl*Point,Digits);                 // Получаем значение стоп-лосса для выбранного ордера
      if(i_tp != 0)                                                                 // Если входной параметр тейкпрофита не равен 0, то..
        tp = NormalizeDouble(OrderOpenPrice() + i_tp*Point,Digits);                 // Получаем значение тейкпрофита для выбранного ордера
    }  
  }  
  else if(signal == SIGNAL_SELL && FindOrders() == 0)                               // Если сигнал на продажу и открытых ордеров нет..
  {
    g_ticket = OpenSell();                                                          // Открываем лимитный ордер на продажу
  
    if(g_ticket > 0 && OrderSelect(g_ticket,SELECT_BY_TICKET,MODE_TRADES) == true)  // Если ордер есть и он выбран..
    {
      if(i_sl != 0)                                                                 // Если входной параметр стоп-лосса не равен 0, то..
         sl = NormalizeDouble(OrderOpenPrice() + i_sl*Point,Digits);                // Получаем значение стоп-лосса для выбранного ордера
      if(i_tp != 0)                                                                 // Если входной параметр тейкпрофита не равен 0, то..
         tp = NormalizeDouble(OrderOpenPrice() - i_tp*Point,Digits);                // Получаем значение тейкпрофита для выбранного ордера
    }
  }
  if(sl != 0 || tp != 0)                                                            // Если полученные значения sl и tp не равныы 0, то..
  {
    OrderModify(g_ticket,OrderOpenPrice(),sl,tp,OrderOpenTime() + 86400,Lime);      // Модифицируем ордер
    return(true);
  }
  return(true);
}

Декомпилы я не ковыряю, писал всё сам. Попросил подсказать, где есть неверность. А в ответ, что ничего не понятно... Что может быть тут не понятно вообще?
Теперешний вариант уже вполне верный, ведь всё прокомментировано.
 
Последнее редактирование модератором:

berlios

Заблокирован
Братцы, помогите неДОобразованному.
Есть вот такой индикатор.
Мне надо :
1. Сделать из него функцию.
2. Там есть такая строка, в которой явно указана Close :
indx = (kk - factor) * (Close[Len - kk + i]);
Как мне прописать, чтоб с помощью входных параметров я мог выбирать что-нить другое,
например High или другую переменную (вместо Close), например :
double PlusDI1 = iADX(Symbol(), 0, ADXPeriod, ADXPrice, MODE_PLUSDI, 1);
3. Как вызывать эту функцию, например для другого индикатора.

Премного благодарен.

// ---------------------------------------------------

#property indicator_chart_window
#property indicator_buffers 1

#property indicator_color1 Aqua

extern int Length = 15;

int limit;
int Len;
double factor;
double indx;
double IndBuffer[];
double sumDB[];


int init() {
IndicatorBuffers(2);
SetIndexBuffer(0, IndBuffer);
SetIndexStyle(0, DRAW_LINE, STYLE_SOLID, 1);

SetIndexBuffer(1, sumDB);

return (0);
}

int start() {
limit = Bars - Length - 5;
Len = Length;

for (int i = limit - Len - 1; i >= 0; i--) {

sumDB[1] = 0;
for (int kk = Len; kk >= 1; kk--) {
factor = Len + 1;
factor /= 3.0;
indx = 0;
indx = (kk - factor) * (Close[Len - kk + i]);
sumDB[1] += indx;
}

IndBuffer = 6.0 * sumDB[1] / (Len * (Len + 1));

}

return (0);
}
 

Ugar

Гуру форума
Где запутал смысла писать уже нет. Но что я сложного написал это вопрос точно. Тут всё просто. Даже комменты есть.. Специально написал комменты, что б было видно, что происходит в каждом канкретном моменте:

PHP:
//+-------------------------------------------------------------------------------------+
//| Открытие длинной позиции                                                            |
//+-------------------------------------------------------------------------------------+
int OpenBuy()
{
  g_ticket = -1;
  string myNote = "сов баянул";
         
  g_ticket = OrderSend(Symbol(),OP_BUYLIMIT,0.1,GetPriceToInput(),3,0,0,myNote,myMagic,0,Blue);
  if(g_ticket > 0 && OrderSelect(g_ticket,SELECT_BY_TICKET,MODE_TRADES) == true)
  
  return(g_ticket);
}
//+-------------------------------------------------------------------------------------+
//| Открытие короткой позиции                                                           |
//+-------------------------------------------------------------------------------------+
int OpenSell()
{
  g_ticket = -1;
  string myNote = "сов шортанул";

  g_ticket = OrderSend(Symbol(),OP_SELLLIMIT,0.1,GetPriceToInput(),3,0,0,myNote,myMagic,0,Red);
  if(g_ticket > 0 && OrderSelect(g_ticket,SELECT_BY_TICKET,MODE_TRADES) == true)
  
  return(g_ticket);
}
//+-------------------------------------------------------------------------------------+
//| Открытие позиций                                                                    |
//+-------------------------------------------------------------------------------------+
bool Trade (int signal)
{
  double sl = 0, tp = 0;

  if(signal == SIGNAL_BUY && FindOrders() == 0)                                     // Если сигнал на покупку и открытых ордеров нет...
  {
    g_ticket = OpenBuy();                                                           // открываем лимитный ордер на покупку
  
    if(g_ticket > 0 && OrderSelect(g_ticket,SELECT_BY_TICKET,MODE_TRADES) == true)  // Если ордер есть и он выбран..
    {
      if(i_sl != 0)                                                                 // Если входной параметр стоп-лосса не равен 0, то..
        sl = NormalizeDouble(OrderOpenPrice() - i_sl*Point,Digits);                 // Получаем значение стоп-лосса для выбранного ордера
      if(i_tp != 0)                                                                 // Если входной параметр тейкпрофита не равен 0, то..
        tp = NormalizeDouble(OrderOpenPrice() + i_tp*Point,Digits);                 // Получаем значение тейкпрофита для выбранного ордера
    }  
  }  
  else if(signal == SIGNAL_SELL && FindOrders() == 0)                               // Если сигнал на продажу и открытых ордеров нет..
  {
    g_ticket = OpenSell();                                                          // Открываем лимитный ордер на продажу
  
    if(g_ticket > 0 && OrderSelect(g_ticket,SELECT_BY_TICKET,MODE_TRADES) == true)  // Если ордер есть и он выбран..
    {
      if(i_sl != 0)                                                                 // Если входной параметр стоп-лосса не равен 0, то..
         sl = NormalizeDouble(OrderOpenPrice() + i_sl*Point,Digits);                // Получаем значение стоп-лосса для выбранного ордера
      if(i_tp != 0)                                                                 // Если входной параметр тейкпрофита не равен 0, то..
         tp = NormalizeDouble(OrderOpenPrice() - i_tp*Point,Digits);                // Получаем значение тейкпрофита для выбранного ордера
    }
  }
  if(sl != 0 || tp != 0)                                                            // Если полученные значения sl и tp не равныы 0, то..
  {
    OrderModify(g_ticket,OrderOpenPrice(),sl,tp,OrderOpenTime() + 86400,Lime);      // Модифицируем ордер
    return(true);
  }
  return(true);
}

Декомпилы я не ковыряю, писал всё сам. Попросил подсказать, где есть неверность. А в ответ, что ничего не понятно... Что может быть тут не понятно вообще?
Теперешний вариант уже вполне верный, ведь всё прокомментировано.
Для меня ничего сложного нет. По крайней мере мне эти комментарии не нужны. Есть куча косяков и засекреченные функции. Так же нет прозрачности обмена данными между ними.
Сложности не у меня. У меня функции свои, их коды мне понятны, к каждой есть комментарии по особенностям применения, обмен данными прозрачен. При комбинировании функций лишних операций нет. Если применение готовых пользовательских функций приводит к лишним операциям и вычислениям, я лучше напишу без них. Такой дурью, как использование функций ради использования функций, я не страдаю.
Может кто то дугой поможет. Я устал объяснять.
 

hoz

Активный участник
Сложности не у меня.


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

Nata_FX

Активный участник
hoz, у тебя везде идет проверка g_ticket > 0, это не верно, тикет может быть равным 0.
 

AlexeyVik

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

PHP:
bool Trade (int signal)
{
  double OSL = OrderStopLoss();
  double OTP = OrderTakeProfit();
  double sl = 0, tp = 0;
  OSL = 0; OTP = 0;
  
  Print("OSL = ", OSL); Print("OTP = ", OTP);
  Print("OrderTakeProfit() = ", OrderTakeProfit()); Print("OrderStopLoss() = ", OrderStopLoss());


Далее начинается самое интересно! Я принтую как переменные так и полные названия соответствующих им ф-ций и вижу:

PHP:
2012.12.07 00:27:54    2008.12.05 00:03  Gann_2Days GBPUSD,H1: open #1 buy limit 0.10 GBPUSD at 1.46425 ok
2012.12.07 00:27:54    2008.12.05 00:03  Gann_2Days GBPUSD,H1: OrderStopLoss() = 1.4639
2012.12.07 00:27:54    2008.12.05 00:03  Gann_2Days GBPUSD,H1: OrderTakeProfit() = 1.4729
2012.12.07 00:27:54    2008.12.05 00:03  Gann_2Days GBPUSD,H1: OTP = 0
2012.12.07 00:27:54    2008.12.05 00:03  Gann_2Days GBPUSD,H1: OSL = 0
2012.12.07 00:27:51    Gann_2Days inputs: i_sl=450; i_tp=450; i_momTF=60; i_momPeriod=18;


Что это такое? Глюки МТ4 ?

По логике должно распринтовать одинаковые значения для OrderStopLoss() и OSL, и, соответственно, для OrderTakeProfit() и OTP.

Ну давай попробую я объяснить.
Для начала совет (бесплатный) Прежде чем заявлять о глюках компа, при написании программы, попробуй стать компом...
Ну давай к делу... Вот часть твоего кода. Допустим что ты где-то, в другой части программы, выбрал ордер для работы с ним.

double OSL = OrderStopLoss();// Здесь ты присваиваешь переменной OSL значение StopLoss того ордера который у тебя выбран.
double OTP = OrderTakeProfit();// То-же самое с OTP и TakeProfit
double sl = 0, tp = 0;
OSL = 0; OTP = 0;// А здесь переменным OSL и OTP присваиваешь значение нуль...

Только после этого принтуешь и получаешь то, что сам пожелал...
И по логике твоя логика не дружит с логикой. :)
 

AlexeyVik

Программист mql4 mql5
hoz, у тебя везде идет проверка g_ticket > 0, это не верно, тикет может быть равным 0.

Ну конечно g_ticket как и любая переменная может быть равна нулю. Но почему ты утверждаешь что проверять g_ticket > 0 не верно???
В этом случае g_ticket может быть = 0 только если нет открытого ордера, но когда ордер откроется то g_ticket будет больше 0 и соответственно такая проверка очень уместна. Только надо позаботиться о том, чтобы обнулить её после закрытия ордера.
 

Nata_FX

Активный участник
AlexeyVik, читай мануал.
int OrderSend( string symbol, int cmd, ...)
Основная функция, используемая для открытия позиции или установки отложенного ордера.
Возвращает номер тикета, который назначен ордеру торговым сервером или -1 в случае неудачи.
Поэтому уместна была бы проверка вида g_ticket > -1
 

hoz

Активный участник
hoz, у тебя везде идет проверка g_ticket > 0, это не верно, тикет может быть равным 0.

Если g_ticket <= 0, значит нет открытой позиции, а значит дальше по коду мы не продвигается.
А если g_ticket > 0, значит ф-ции либо OpenSell(), либо OpenBuy() вернула значение тикета, тогда эксперт уже продолжает с ними работу. Тут всё логично.

Ну давай к делу... Вот часть твоего кода. Допустим что ты где-то, в другой части программы, выбрал ордер для работы с ним.

double OSL = OrderStopLoss();// Здесь ты присваиваешь переменной OSL значение StopLoss того ордера который у тебя выбран.
double OTP = OrderTakeProfit();// То-же самое с OTP и TakeProfit
double sl = 0, tp = 0;
OSL = 0; OTP = 0;// А здесь переменным OSL и OTP присваиваешь значение нуль...

Только после этого принтуешь и получаешь то, что сам пожелал...
И по логике твоя логика не дружит с логикой. :)


Это было давно и не правда, написано в спешке, я уже писал. Ты последний вариант видел? Или нужно пятится назад? Я тот вариант, что ты упомянул писал поздно ночью, написал чушь.. признаю.
Но последний вариант полностью рабочий. О каких ошибка ugar говорит вот это уже вопрос!
Видать их просто нет.. Ведь сова заработала уже без ошибок, после одной поправки.. Не трудно понять, что не из-за этой ф-ции.
 
Последнее редактирование:

hoz

Активный участник
AlexeyVik, читай мануал.

Поэтому уместна была бы проверка вида g_ticket > -1


Значение 0 не присваивается тикету насколько мне известно. А -1 в мануале, потому что это как обычно в булевых переменных, если выход из ф-ции с значением -1, то значит не отработана ф-ция. Я так понимаю. Тикета со значением 0 я не встречал..


Хотя опять же мануал кривоват. Если верить учебнику и не смотреть на другие аспекты в других его местах, то Ната права..
Ведь написано, -1 это не открылся ордер, значит.. открытый может быть и 0, и выше, а не только >0. Но почему-то никто так не пишит в коде.
 
Последнее редактирование:

eevviill

Заблокирован
...Но почему-то никто так не пишит в коде.
0-ой тикет по любому присваивается ордерам открытым вручную. Ну или советником можно присвоить.

Вот мой шаблон советника. Пользуюсь тикет >-1.

Тьфу. Переплутал с меджиком.
 

Вложения

  • Shabl (8).mq4
    16,2 КБ · Просмотры: 21
Последнее редактирование:

hoz

Активный участник
Ну если только ручные, но для эксперта чаще всего они не нужны. Хотя.. кому как.
 

AlexeyVik

Программист mql4 mql5
Дама и господа. Я уже давно и достаточно внимательно читаю справку по языку, а не мануал, который у каждого свой.
У Наташи, например, если OrderSend() возвращает -1 то это обязательно должно быть присвоено переменной g_ticket
У Василия ... Я не дочитал, он оказывается сам понял что перепутал.

Так вот поясняю почему все эти функции, не только OrderSend(...), возвращают значение или -1.
По той простой причине, что объявляя переменную без присваивания ей значения она автоматом равна нулю. Так вот -1 в этом случае просто означает, что функция не выполнена, а 0 означает что ордера ещё не открывались (не-было попыток это сделать) и соответственно если больше нуля значит ордер открыт.
 

eevviill

Заблокирован
...
У Василия ... Я не дочитал, он оказывается сам понял что перепутал.

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

AlexeyVik

Программист mql4 mql5
Это было давно и не правда, написано в спешке, я уже писал. Ты последний вариант видел? Или нужно пятится назад? Я тот вариант, что ты упомянул писал поздно ночью, написал чушь.. признаю.
Но последний вариант полностью рабочий. О каких ошибка ugar говорит вот это уже вопрос!
Видать их просто нет.. Ведь сова заработала уже без ошибок, после одной поправки.. Не трудно понять, что не из-за этой ф-ции.

Я не буду перечитывать весь ваш диалог, но знаю, что Ugar, (Андрей) очень грамотный программист. И если он что-то не понял значит об этом было не так сказано. Я почти уверен, что он говорил о том-же коде который процитировал я, а ты уже о другом, с поправками.
 
Последнее редактирование:

AlexeyVik

Программист mql4 mql5
Если так, то да. А если как в шаблоне (я уже точно про тикет говорю), то я делаю так. Сначало присвиваю переменной тикет -1.
Василий, это не совсем правильно, хотя и не критично. В этом случае нет различия, ордер не открыт из-за ошибки или просто не-было выполнено условие и соответственно попытки открыть ордер.
 

Nata_FX

Активный участник
Дама и господа. Я уже давно и достаточно внимательно читаю справку по языку, а не мануал, который у каждого свой.
У Наташи, например, если OrderSend() возвращает -1 то это обязательно должно быть присвоено переменной g_ticket
У Василия ... Я не дочитал, он оказывается сам понял что перепутал.

Так вот поясняю почему все эти функции, не только OrderSend(...), возвращают значение или -1.
По той простой причине, что объявляя переменную без присваивания ей значения она автоматом равна нулю. Так вот -1 в этом случае просто означает, что функция не выполнена, а 0 означает что ордера ещё не открывались (не-было попыток это сделать) и соответственно если больше нуля значит ордер открыт.
Плохо ты справку читаешь.
функция OrderSend(...) возвращает или -1 или номер тикета. И точка. Если она вернет 0 значит это тикет ордера, а не по твоему
а 0 означает что ордера ещё не открывались (не-было попыток это сделать)
а строка в коде g_ticket = OrderSend(...); говорит о том, это обязательно должно быть присвоено переменной g_ticket.
Так что это не по моему, а по алгоритму.
 

eevviill

Заблокирован
...
а строка в коде g_ticket = OrderSend(...); говорит о том, это обязательно должно быть присвоено переменной g_ticket.
Так что это не по моему, а по алгоритму.
Кажется он имел ввиду такую конструкцию.

PHP:
int g_ticket;

if(sig==buy)
g_ticket=OrderSend(...);

В такос случае если нет сигнала, то тикет будет равен 0.
 

AlexeyVik

Программист mql4 mql5
Если она вернет 0 значит это тикет ордера, а не по твоему
Это может произойти только если солнце повернётся.
Даже тестер начинает нумеровать ордера с единицы.

Спорить с женщинами не в моих правилах. Я умолкаю.
 
Последнее редактирование модератором:
Верх