MQL4: Советник модификации TP по условию / нужна проверка кода - страница 2

 
Ivan Molchanov:

Да, я понимаю всю корявость конструкции.

Будет ли так правильно:

У вас алгоритм не верно составлен изначально.

В OnTick() проверяете условия для входа и вход, и вызываете функцию модификации существующих позиций.

В функции модификации (своеобразный трал тейка) в цикле выбираете поочерёдно каждую позицию по индексу (не по тикету), проверяете условие на модификацию её стоп-приказов и вызываете функцию модификации собственно стоп-приказа.

 
Ivan Molchanov:

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

Но если говорить о тикете, то:

1. номер тикета я задаю при установке  советника (руками вбиваю), поэтому он выбирается без проблем, по крайней мере на демо это работало.

2. Да, мне необходимо менять только тот ордер, тикет которого я вбиваю.

3. Почему неправильно? Ордер выбирался и менялся. Но я не настаиваю, может Вы и правы, но тогда поясните, пожалуйста, в чем ошибка. 

1. Программа может модифицировать только один-единственный ордер, который вы жёстко задаёте в настройках - по-меньшей мере это очень не оптимально.

2. Если вам так нужно, то делайте так.

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

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

   if(OrderSelect(ticket,SELECT_BY_TICKET) && OrderCloseTime()==0) {
      // выбран рыночный ордер по тикету
      }

или так:

   if(OrderSelect(ticket,SELECT_BY_TICKET)) {
      if(OrderCloseTime()==0) {
         // выбран рыночный ордер по тикету
         }
      else {
         // выбран уже закрытый ордер по тикету
         }
      }
 
Artyom Trishkin:

1. Программа может модифицировать только один-единственный ордер, который вы жёстко задаёте в настройках - по-меньшей мере это очень не оптимально.

2. Если вам так нужно, то делайте так.

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

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

или так:

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

Верно?

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2012, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#property strict
input double checkline=0; // контрольная ближняя граница
input double BE=0; // уровень безубыточности
input int direction=0; //направление торговли: 1 - вверх (long), 2 - вниз (short)
input int ticket=0; // номер ордера
int Slippage= 50; // проскальзывание в пп.
int Magic = 0001; // магический номер эксперта
string com="Перевод в БУ"; // комментарий ордера
datetime last;
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(last>=Time[0]) return;  // если время бара уже проверено то выходим сразу, т.е. ждем новый бар
                              //Модификация LONG (1)
   if(direction==1 && Close[1]<checkline) //условие активации модификации ордера: направление вверх и закрытие прошлой свечи ниже контрольной линии
     {
      OrderSelect(ticket,SELECT_BY_TICKET); // выбираем ордер по тикету
      if(OrderTakeProfit()!=BE && OrderCloseTime()==0) // защита от повторной модификации и модификации закрытых ордеров
        {
         OrderModify(ticket,OrderOpenPrice(),OrderStopLoss(),BE,0,clrNONE); // модифицируем ордер
         OrderSelect(ticket,SELECT_BY_TICKET);
         if(OrderTakeProfit()!=BE) // если модификация не удалась, то возвращаемся для повторной модификации
           {
            Alert(Symbol(),"ошибка установки TP",GetLastError());
            return;
           }
        }
     }
   last=Time[0]; // запомнили время бара для последующего тика
   return;
  }
//+------------------------------------------------------------------+

 А вот насчет "В OnTick() проверяете условия для входа и вход" не понял, извините. Можете более детально помочь? Мне знаний не хватает :(

 
Ivan Molchanov:

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

Верно?

 А вот насчет "В OnTick() проверяете условия для входа и вход" не понял, извините. Можете более детально помочь? Мне знаний не хватает :(

Откуда у вас берётся позиция, тейк которой вы хотите модифицировать?
 
Artyom Trishkin:
Откуда у вас берётся позиция, тейк которой вы хотите модифицировать?

От вручную установленного лимитного ордера.

Алгоритм простой.

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

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

Как-то так, все просто. 

 

Вообще я сейчас проверил на демо его работу - вроде работает. Ошибок не пишет, модифицировал ордер при выполнении условия. Во время модификации было несколько ошибок "off quotes", но цена чуть упала и все, ордер модифицировался и дальше без ошибок.

Но если, конечно, заметите какие-то еще явные ошибки - скажите, пожалуйста. 

Единственное, несколько смущает вот это (выдается во вкладке "Эксперты" по моему запросу "print"

2016.05.03 15:21:02.322 order_BE_v_3 AUDCHF,M1:  direction=1 BE=0.7171999999999999 ticket=335177374 Close=0.7168099999999999 TP=0.7171999999999999 last=2016.05.03 13:20:00 time=2016.05.03 13:21:00

 Что за ненормальные цифры? Я ведь устанавливал обычные пятизначные, без кучи девяток на концах...

 
Ivan Molchanov:

От вручную установленного лимитного ордера.

Алгоритм простой.

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

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

Как-то так, все просто. 

1. Выбираете ордер по заданному тикету

2. Проверяете тип ордера. Он должен быть OP_BUY или OP_SELL. Т.е., if(OrderType()>1) {// выбрана не рыночная позиция и модифицировать ничего не нужно}

3. Если выбран OP_BUY или OP_SELL, то проверить время его закрытия и, если оно равно нулю, то при наличии условия на модификацию, модифицировать тейк

....

Ну вот как-то так... Не проверял ничего - "на коленке" набросал:

//+------------------------------------------------------------------+
void OnTick()
  {
   if(last>=Time[0]) return;  // если время бара уже проверено то выходим сразу, т.е. ждем новый бар
                              //Модификация LONG (1)
   if((direction==1 && Close[1]<checkline) || (direction==2 && Close[1]>checkline)) //условие активации модификации ордера: направление вверх и закрытие прошлой свечи ниже контрольной линии
     {
      if(OrderSelect(ticket,SELECT_BY_TICKET && OrderCloseTime()==0))   // выбираем ордер по тикету
        {
         if(OrderType()>OP_SELL) return;                                // если не рыночный - выходим
         if(NormalizeDouble(fabs(OrderTakeProfit()-BE),Digits())>0)     // если тейк не равен заданному уровню
           {
            ResetLastError();
            if(!OrderModify(ticket,OrderOpenPrice(),OrderStopLoss(),BE,0,clrNONE)) // модифицируем ордер
              {
               Alert(Symbol(),"ошибка установки TP: ",GetLastError());
               return;
              }
           }
        }
     }
   last=Time[0]; // запомнили время бара для последующего тика
   return;
  }
//+------------------------------------------------------------------+
 
Ivan Molchanov:

Вообще я сейчас проверил на демо его работу - вроде работает. Ошибок не пишет, модифицировал ордер при выполнении условия. Во время модификации было несколько ошибок "off quotes", но цена чуть упала и все, ордер модифицировался и дальше без ошибок.

Но если, конечно, заметите какие-то еще явные ошибки - скажите, пожалуйста. 

Единственное, несколько смущает вот это (выдается во вкладке "Эксперты" по моему запросу "print"

 Что за ненормальные цифры? Я ведь устанавливал обычные пятизначные, без кучи девяток на концах...

Для вывода на печать используйте DoubleToString() для чисел double с необходимой точностью, IntegetToString() для int с необходимым форматом.
 
Artyom Trishkin:

1. Выбираете ордер по заданному тикету

2. Проверяете тип ордера. Он должен быть OP_BUY или OP_SELL. Т.е., if(OrderType()>1) {// выбрана не рыночная позиция и модифицировать ничего не нужно}

3. Если выбран OP_BUY или OP_SELL, то проверить время его закрытия и, если оно равно нулю, то при наличии условия на модификацию, модифицировать тейк

....

Ну вот как-то так... Не проверял ничего - "на коленке" набросал:

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

А в журнале что пишет?

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

Причина обращения: