Установка StopLoss и TakeProfit для BUY_STOP_LIMIT и SELL_STOP_LIMIT ордеров

 

Столкнулся с ошибкой 10015 - Invalid price при попытке модификации StopLoss и TakeProfit у ордеров типа BUY_STOP_LIMIT и SELL_STOP_LIMIT.

В качестве точки отсчёта использую не цену открытия ордера OrderGetDouble(ORDER_PRICE_OPEN), а именно цену OrderGetDouble(ORDER_PRICE_STOPLIMIT) - по которой ордер BuyLimit / SellLimit должен разместиться, когда стоплимитник сработает. То есть точка отсчёта верная и цены тоже получаются правильные. После того как стоплимитник активируется, ровно по таким "инвалидным" ценам ордера StopLoss и TakeProfit размещаются. 

Значит, ордера BUY_STOP_LIMIT и SELL_STOP_LIMIT не могут иметь предустановленные StopLoss и TakeProfit до момента активации? 

 

совсем народ потерял рулило.

физически только отложенные лимитные ордера и моментальные мелкие рыночные сделки. 

всё прочее - способ босо косо 

 
Maxim Kuznetsov:

совсем народ потерял рулило.

физически только отложенные лимитные ордера и моментальные мелкие рыночные сделки. 

всё прочее - способ босо косо 

Ну то есть, пока не разместился Buy Limit / Sell Limit, нет сущности, для которой можно было бы разместить StopLoss и TakeProfit, верно я понял?

 
Oleg Remizov:

Ну то есть, пока не разместился Buy Limit / Sell Limit, нет сущности, для которой можно было бы разместить StopLoss и TakeProfit, верно я понял?

Проверил в терминале, всё ставится, значит и программно должно работать


 
Oleg Remizov:

Столкнулся с ошибкой 10015 - Invalid price при попытке модификации StopLoss и TakeProfit у ордеров типа BUY_STOP_LIMIT и SELL_STOP_LIMIT.

В качестве точки отсчёта использую не цену открытия ордера OrderGetDouble(ORDER_PRICE_OPEN), а именно цену OrderGetDouble(ORDER_PRICE_STOPLIMIT) - по которой ордер BuyLimit / SellLimit должен разместиться, когда стоплимитник сработает. То есть точка отсчёта верная и цены тоже получаются правильные. После того как стоплимитник активируется, ровно по таким "инвалидным" ценам ордера StopLoss и TakeProfit размещаются. 

Значит, ордера BUY_STOP_LIMIT и SELL_STOP_LIMIT не могут иметь предустановленные StopLoss и TakeProfit до момента активации? 

цифры приведите если вам нужен ответ. или вы их сами глазами не проверили после ошибки?..

 
Oleg Remizov:

Столкнулся с ошибкой 10015 - Invalid price при попытке модификации StopLoss и TakeProfit у ордеров типа BUY_STOP_LIMIT и SELL_STOP_LIMIT.

В качестве точки отсчёта использую не цену открытия ордера OrderGetDouble(ORDER_PRICE_OPEN), а именно цену OrderGetDouble(ORDER_PRICE_STOPLIMIT) - по которой ордер BuyLimit / SellLimit должен разместиться, когда стоплимитник сработает. То есть точка отсчёта верная и цены тоже получаются правильные. После того как стоплимитник активируется, ровно по таким "инвалидным" ценам ордера StopLoss и TakeProfit размещаются. 

Значит, ордера BUY_STOP_LIMIT и SELL_STOP_LIMIT не могут иметь предустановленные StopLoss и TakeProfit до момента активации? 

Смотрите документацию. Там детальные примеры. В частности для BUY_STOP_LIMIT и SELL_STOP_LIMIT пример.

https://www.mql5.com/ru/docs/constants/structures/mqltraderequest

Я когда не пользуюсь стандартной библиотекой беру от туда. Всё прекрасно устанавливается и модифицируется. Можно устанавливать без стопов и тейков и потом их добавлять,  можно сразу с ними.

Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура торгового запроса
Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура торгового запроса
  • www.mql5.com
Структура торгового запроса - Структуры данных - Константы, перечисления и структуры - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Aleksey Mavrin:

цифры приведите если вам нужен ответ. или вы их сами глазами не проверили после ошибки?..

Вот как раз смог сделать скриншот до срабатывания BUY STOP LIMIT и после срабатывания. 

До срабатывания ордера BUY STOP LIMIT:

до срабатывания

После срабатывания ордера BUY STOP LIMIT:

после срабатывания

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

Код бы полный выложить. Предположения - в структуре запроса не указываете цены ордера, помимо СЛ и ТП.

Точно знаю что для установки СЛ и ТП необязательно ждать сработки стоп ордера. ошибка в коде скорее всего.

 
Aleksey Mavrin:

Код бы полный выложить. Предположения - в структуре запроса не указываете цены ордера, помимо СЛ и ТП.

Точно знаю что для установки СЛ и ТП необязательно ждать сработки стоп ордера. ошибка в коде скорее всего.

Да, ошибка была в запросе на модификацию. Исправил, но частично. Ордера StopLoss и TakeProfit теперь выставляет, но почему-то иногда выдаёт ошибку 10013 - Invalid request.

Вот кусок кода, отвечающий за модификацию отложенных ордеров:

      if(_type_orders == Pending || _type_orders == MarketPending)
        {
         // блок работы с отложенными ордерами
         // срабатывает если выбран тип отложенный или рыночный и отложенный
         // отложенные ордера: buy_stop, buy_limit, sell_stop, sell_limit, buy_stop_limit, sell_stop_limit
         // причина установить тейк: у ордера тейк нулевой, а в настройках указан более нуля
         // причина установить стоп: у ордера стоп нулевой, а в настройках указан более нуля
         bool need_modify = false;
         for(int i = 0; i < ats.pending_order_quantity; i++)
           {
            if(OrderSelect(ats.pending_order_tickets[i]))
              {
               // ордер выделился по тикету
               // записываем свойства ордера
               ENUM_ORDER_TYPE ord_type = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
               double ord_op = OrderGetDouble(ORDER_PRICE_OPEN);
               ulong ord_ticket = ats.pending_order_tickets[i];
               string ord_symbol = OrderGetString(ORDER_SYMBOL);
               datetime ord_exp = (datetime)OrderGetInteger(ORDER_TIME_EXPIRATION);
               ENUM_ORDER_TYPE_TIME ord_type_time = (ENUM_ORDER_TYPE_TIME)OrderGetInteger(ORDER_TYPE_TIME);
               double ord_tp = OrderGetDouble(ORDER_TP);
               double ord_sl = OrderGetDouble(ORDER_SL);
               // чистим флаг модификации
               need_modify = false;
               // флаг очищен, теперь проверяем нужно ли его изменить
               if((ord_tp == 0) && (_tp > 0))
                 {
                  // реальный тейк нулевой, а в настройках более нуля
                  ord_tp = TakeProfitPrice(ord_symbol, _tp, ord_type, ord_ticket, ord_op, true, _sf_lvl_free);
                  if(ord_tp > 0)
                     need_modify = true;
                 }
               if((ord_sl == 0) && (_sl > 0))
                 {
                  // реальный стоп нулевой, а в настройках более нуля
                  ord_sl = StopLossPrice(ord_symbol, _sl, ord_type, ord_ticket, ord_op, true, _sf_lvl_free);
                  if(ord_sl > 0)
                     need_modify = true;
                 }
               // теперь на основании флага проводим модификацию ордера
               if(need_modify)
                 {
                  ZeroMemory(req);
                  ZeroMemory(res);
                  req.action = TRADE_ACTION_MODIFY;
                  req.order = ord_ticket;
                  req.price = ord_op;
                  req.sl = ord_sl;
                  req.tp = ord_tp;
                  req.type_time = ord_type_time;
                  req.expiration = ord_exp;
                  if(!OrderSend(req, res) || res.retcode != TRADE_RETCODE_DONE)
                     Print("Ticket:", ord_ticket, " Error: ", ResultRetcode(res));
                  else
                    {
                     if(res.retcode == TRADE_RETCODE_DONE) // модификация успешна
                        break;
                    }
                 }
              }
           }
        }
 
Oleg Remizov:

Да, ошибка была в запросе на модификацию. Исправил, но частично. Ордера StopLoss и TakeProfit теперь выставляет, но почему-то иногда выдаёт ошибку 10013 - Invalid request.

Вот кусок кода, отвечающий за модификацию отложенных ордеров:

подозреваю что для вашего типа ордера в структуре stoplimit надо ещё явно указать, хоть в справке и не написано)

а может кривые функции расчета ТП и СЛ? вы их не привели.

Ещё бросилось в глаза- break выходит из for? зачем? вы разве не хотите все ордера пройти?

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