При попытке модифицировать открытую позицию возникает ошибка Invalid stops, 10016

 

Пишу простого робота - сначала робот в диаппазоне выставляет лимитные заявки с указанным ТП отдельно для каждой лимитной заявки. Если срабатывает более одной лимитки, то меняет ТП относительно среденей цены входа относительно сработавших лимиток. У меня включен режим хэджирования в МТ5.

Пытаюсь для открытых позиций поменять значения ТП, СЛ в советнике не использую, но при модификации возникает ошибка 10016.

         for (int i = PositionsTotal() - 1; i >= 0; i--){
           if (PositionSelectByTicket(PositionGetTicket(i))){
               if (PositionGetInteger(POSITION_MAGIC) == MAGIC_NUMBER){
                  ZeroMemory (request);
                  ZeroMemory (result);
                  request.action    = TRADE_ACTION_SLTP;
                  request.position  = PositionGetInteger(POSITION_TICKET);
                  request.symbol    = PositionGetString(POSITION_SYMBOL);
                  request.sl        = PositionGetDouble(POSITION_SL);
                  request.tp        = NormalizeDouble(TakeAll, Digits());
                  if(!OrderSend(request,result)) {
                      PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
                  }
               }
           }

Подскажите, пожалуйста, как исправить.

Документация по MQL5: Торговые функции / PositionGetInteger
Документация по MQL5: Торговые функции / PositionGetInteger
  • www.mql5.com
Функция возвращает запрошенное свойство открытой позиции, предварительно выбранной при помощи функции PositionGetSymbol или PositionSelect ...
 
Должна быть проверка на уровни стопов.stop level ,но проще к диапазону размер 3х спредов добавить 
 
Алексей Орлов:

Пишу простого робота - сначала робот в диаппазоне выставляет лимитные заявки с указанным ТП отдельно для каждой лимитной заявки. Если срабатывает более одной лимитки, то меняет ТП относительно среденей цены входа относительно сработавших лимиток. У меня включен режим хэджирования в МТ5.

Пытаюсь для открытых позиций поменять значения ТП, СЛ в советнике не использую, но при модификации возникает ошибка 10016.

         for (int i = PositionsTotal() - 1; i >= 0; i--){
           if (PositionSelectByTicket(PositionGetTicket(i))){
               if (PositionGetInteger(POSITION_MAGIC) == MAGIC_NUMBER){
                  ZeroMemory (request);
                  ZeroMemory (result);
                  request.action    = TRADE_ACTION_SLTP;
                  request.position  = PositionGetInteger(POSITION_TICKET);
                  request.symbol    = PositionGetString(POSITION_SYMBOL);
                  request.sl        = PositionGetDouble(POSITION_SL);
                  request.tp        = NormalizeDouble(TakeAll, Digits());
                  if(!OrderSend(request,result)) {
                      PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
                  }
               }
           }

Подскажите, пожалуйста, как исправить.

1. Получается «масло масляное» Лучше просто

    ulong posTicket=PositionGetTicket(i);

2. Какое значение переменной  TakeAll?

3. Научитесь правильно вставлять код.

 
Alexey Viktorov #:

1. Получается «масло масляное» Лучше просто

2. Какое значение переменной  TakeAll?

3. Научитесь правильно вставлять код.

Спасибо за ответ! Но не помогает.

3. Когда нибудь научусь.

2. Ошибка со стоплосом, хотя мне его не нужно менять. Тейк вычисляется так:

for (int i = PositionsTotal() - 1; i >= 0; i--){
        posTicket=PositionGetTicket(i);
        if (PositionSelectByTicket(posTicket)){
            if (PositionGetInteger(POSITION_MAGIC) == MAGIC_NUMBER){
               VolPrice = VolPrice + PositionGetDouble(POSITION_VOLUME) * PositionGetDouble(POSITION_PRICE_OPEN);
               VolAllOrders = VolAllOrders + PositionGetDouble(POSITION_VOLUME);
               count = count + 1;
            }
        }
      }
      TakeAll = (VolPrice / VolAllOrders) * (1 + TakeProfit / 100); // общий тейк

1. Код переделал, но ошибка осталась.

          for (int i = PositionsTotal() - 1; i >= 0; i--){
             posTicket=PositionGetTicket(i);
             if (PositionSelectByTicket(posTicket)){
               if (PositionGetInteger(POSITION_MAGIC) == MAGIC_NUMBER){
                  ZeroMemory (request);
                  ZeroMemory (result);
                  request.action    = TRADE_ACTION_SLTP;
                  request.position  = PositionGetInteger(POSITION_TICKET);
                  request.symbol    = PositionGetString(POSITION_SYMBOL);
                  request.sl        = PositionGetDouble(POSITION_SL);
                  request.tp        = NormalizeDouble(TakeAll, Digits());
 
 
                  if(!OrderSend(request,result)) {
                      PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
                  }

 
Рaра Нoth #:
Должна быть проверка на уровни стопов.stop level ,но проще к диапазону размер 3х спредов добавить 
Вообще мне стоплосс не нужен совсем. Там ноль. Пытался передавать ноль в переменную request.sl, сейчас просто беру тот, который у позиции, нормализовал, но ошибка всё равно остаётся
 
Что то я совсем не понимаю. Тестер выдаёт ошибку при попытке модификации позиции, но закрытие позиций происходит по общему тейку.
Файлы:
 
Рaра Нoth #:
Должна быть проверка на уровни стопов.stop level ,но проще к диапазону размер 3х спредов добавить 
Это возможная причина. Подробнее тут https://www.mql5.com/ru/articles/2555#invalid_SL_TP_for_position
И уровень заморозки тоже надо проверять.
Какие проверки должен пройти торговый робот перед публикацией в Маркете
Какие проверки должен пройти торговый робот перед публикацией в Маркете
  • www.mql5.com
Все продукты Маркета перед публикацией проходят обязательную предварительную проверку для обеспечения единого стандарта качества. В этой статье мы расскажем о наиболее частых ошибках, которые допускают разработчики в своих технических индикаторах и торговых роботах. А также покажем как самостоятельно проверить свой продукт перед отправкой в Маркет.
 
Алексей Орлов #:
Что то я совсем не понимаю. Тестер выдаёт ошибку при попытке модификации позиции, но закрытие позиций происходит по общему тейку.

BUY_LIMIT это не позиция


Правильно вставить код 
MQL5.community - Памятка пользователя
MQL5.community - Памятка пользователя
  • www.mql5.com
Вы недавно зарегистрировались и у вас возникли вопросы: Как вставить картинку в сообщение на форуме, как красиво оформить исходный код MQL5, где находятся ваши Личные сообщения? В этой статье мы подготовили для вас несколько практических советов, которые помогут быстрее освоиться на сайте MQL5.community и позволят в полной мере воспользоваться доступными функциональными возможностями.
 
Forester #:
Это возможная причина. Подробнее тут https://www.mql5.com/ru/articles/2555#invalid_SL_TP_for_position
И уровень заморозки тоже надо проверять.
У нас например, сработал лимитный ордер и мы хотим выставить ТП без СЛ, но цена инструмента на уровне цены открытия. У меня вроде поэтому ошибку то и выдаёт. Как в таком случае поступать?
 
Алексей Орлов #:

Спасибо за ответ! Но не помогает.

3. Когда нибудь научусь.

2. Ошибка со стоплосом, хотя мне его не нужно менять. Тейк вычисляется так:

for (int i = PositionsTotal() - 1; i >= 0; i--){
        posTicket=PositionGetTicket(i);
        if (PositionSelectByTicket(posTicket)){
            if (PositionGetInteger(POSITION_MAGIC) == MAGIC_NUMBER){
               VolPrice = VolPrice + PositionGetDouble(POSITION_VOLUME) * PositionGetDouble(POSITION_PRICE_OPEN);
               VolAllOrders = VolAllOrders + PositionGetDouble(POSITION_VOLUME);
               count = count + 1;
            }
        }
      }
      TakeAll = (VolPrice / VolAllOrders) * (1 + TakeProfit / 100); // общий тейк

1. Код переделал, но ошибка осталась.

          for (int i = PositionsTotal() - 1; i >= 0; i--){
             posTicket=PositionGetTicket(i);
             if (PositionSelectByTicket(posTicket)){
               if (PositionGetInteger(POSITION_MAGIC) == MAGIC_NUMBER){
                  ZeroMemory (request);
                  ZeroMemory (result);
                  request.action    = TRADE_ACTION_SLTP;
                  request.position  = PositionGetInteger(POSITION_TICKET);
                  request.symbol    = PositionGetString(POSITION_SYMBOL);
                  request.sl        = PositionGetDouble(POSITION_SL);
                  request.tp        = NormalizeDouble(TakeAll, Digits());
 
 
                  if(!OrderSend(request,result)) {
                      PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
                  }

Выделенное не ошибка. Это просто «масло масляное» о чём и было сказано.

 
Alexey Viktorov #:

BUY_LIMIT это не позиция


Правильно вставить код 
Робот тейкнул позицию и выставил новые лимитки. Вроде я уже осознал разницу между ордером и позицией)
Файлы: