Помогите. Ордер на покупку по рынку выдает 10015 invalid price

 

Использую CTrade.

Указано  что для покупки по рынку все переменные заполняются 0.0.

На всех других итструментах работает нормально но вот на VTB где цена 0.037815 шесть знаков после запятой не всегда, но выдает ошибку.

Может знаете как ее обойти? Или что я делаю не правильно?

Вот фрагмент кода. 

               Print("Лотов  на покупку ",_lots );
               double _price = a_symbol.NormalizePrice(0.0);
               if(!a_trade.Buy(_lots,_Symbol,0.0,0.0,0.0,"CM-buy-enter"))
                 {
                  uint _result=a_trade.ResultRetcode();
                  Print("не совершена покупка ",_result);
                  return;
                 }
               uint retcode = a_trade.ResultRetcode();
               if(retcode != TRADE_RETCODE_PLACED && retcode != TRADE_RETCODE_DONE)
                 {
                  Print("Ошибка возврата структуры покупки CM-buy-enter ",retcode);
                  return;
                 }


2022.01.25 21:03:04.827 2021.01.04 13:54:40   failed exchange buy 1 VTBR at 0 [Invalid price]

2022.01.25 21:03:04.827 2021.01.04 13:54:40   CTrade::OrderSend: exchange buy 1.00 VTBR [invalid price]

2022.01.25 21:03:04.827 2021.01.04 13:54:40   не совершена покупка 10015

Спасибо.


 

Используйте:

if(!a_trade.Buy(_lots,Symbol()))

то есть после названия символа НИЧЕГО не пишите.

 
Vladimir Karputov #:

Используйте:

то есть после названия символа НИЧЕГО не пишите.

Мне нужен комментарий 

//+------------------------------------------------------------------+
//| Buy operation                                                    |
//+------------------------------------------------------------------+
bool CTrade::Buy(const double volume,const string symbol=NULL,double price=0.0,const double sl=0.0,const double tp=0.0,const string comment="")
  {
//--- check volume
   if(volume<=0.0)
     {
      m_result.retcode=TRADE_RETCODE_INVALID_VOLUME;
      return(false);
     }
//--- check symbol
   string symbol_name=(symbol==NULL) ? _Symbol : symbol;
//--- check price
   if(price==0.0)
      price=SymbolInfoDouble(symbol_name,SYMBOL_ASK);
//---
   return(PositionOpen(symbol_name,ORDER_TYPE_BUY,volume,price,sl,tp,comment));
  }

Вот метод класса. Он все равно подставляет ASK.  

 
Aleksandr Dziuba #:

Мне нужен комментарий 

Вот метод класса. Он все равно подставляет ASK.  

Он то подставляет - но Вы не контролируете, ЧТО ОН подставляет :). А там может быть запросто "ноль" :).

Хотите делать всё правильно: сами всё прописывайте - тогда Вы будете всё контролировать.

Пример функции 'OpenSell'  из Trading engine 4

было:

      if(m_trade.Sell(short_lot,m_symbol.Name(),
                      m_symbol.Bid(),sl,tp)) // CTrade::Sell -> "true"

я поставил:

      if(m_trade.Sell(short_lot,m_symbol.Name(),
                      0.0,0.0,0.0,"sd-fg")) // CTrade::Sell -> "true"

результат:

2022.01.25 20:39:36.408 2021.01.12 00:05:06   market sell 0.01 EURUSD (1.21494 / 1.21511 / 1.21494)
2022.01.25 20:39:36.408 2021.01.12 00:05:06   deal #2 sell 0.01 EURUSD at 1.21494 done (based on order #2)
2022.01.25 20:39:36.408 2021.01.12 00:05:06   deal performed [#2 sell 0.01 EURUSD at 1.21494]
2022.01.25 20:39:36.408 2021.01.12 00:05:06   order performed sell 0.01 at 1.21494 [#2 sell 0.01 EURUSD at 1.21494]
2022.01.25 20:39:36.424 2021.01.12 00:05:06   CTrade::OrderSend: market sell 0.01 EURUSD [done at 1.21494]


НО: я перед вызовом функции 'OpenSell' обновляю цены - и это важно.

 
Vladimir Karputov #:

Он то подставляет - но Вы не контролируете, ЧТО ОН подставляет :). А там может быть запросто "ноль" :).

Хотите делать всё правильно: сами всё прописывайте - тогда Вы будете всё контролировать.

Пример функции 'OpenSell'  из Trading engine 4

было:

я поставил:

результат:


НО: я перед вызовом функции 'OpenSell' обновляю цены - и это важно.

У меня же вроде бы так и написано, или я что то не понимаю. 

               if(!a_trade.Buy(_lots,_Symbol,0.0,0.0,0.0,"CM-buy-enter"))
                 {
Я подставлял и аск  и бид  все равно выдает инвалид. Может рамки? Но причем здесь заявка по рынку? 
 
Aleksandr Dziuba #:

У меня же вроде бы так и написано, или я что то не понимаю. 

Я подставлял и аск  и бид  все равно выдает инвалид. Может рамки? Но причем здесь заявка по рынку? 

Попринтуйте, что выдаёт

SymbolInfoDouble(symbol_name,SYMBOL_ASK)

Возможно когда цена имеет вид 0.037810
То усекается до  0.03781
Отсюда и инвалид.

То есть в методе класса, желательно добавить

return(PositionOpen(symbol_name,ORDER_TYPE_BUY,volume,NormalizeDouble(price,Digits()),sl,tp,comment));

Если проблема будет в этом, то тогда надо будет постоянно делать эту правку в этом классе, после каждого обновления терминала.
Так как обновление перепишет стандартный класс терминала в исходный вид.

 
Roman #:

Попринтуйте, что выдаёт

Возможно когда цена имеет вид 0.037810
То усекается до  0.03781
Отсюда и инвалид.

То есть в методе класса, желательно добавить

Если проблема будет в этом, то тогда надо будет постоянно делать эту правку в этом классе, после каждого обновления терминала.
Так как обновление перепишет стандартный класс терминала в исходный вид.

Сделал заглушку, Так как покупка по рынку всегда исполняется по ближайшей цене продажи добавил просто 10 пунктов к цене аск. 

               double _price = a_symbol.NormalizePrice(last_tick.ask)+10*a_symbol.Point();
               if(!a_trade.Buy(_lots,_Symbol,_price,0.000000,0.000000,"CM-buy-enter"))
                 {
                  uint _result=a_trade.ResultRetcode();
                  Print("не совершена покупка ",_result);
                  return;
                 }

Идея интересная попринтовать.  Конечно это вероятно что идет такое округление но как оно влияет на цену? И не хочется после всех обновлений заморачиваться с классом. Когда нибудь точно забудешь)))  Можно просто кидать цену по верхней планке.  Я не лазил в код класса. Но пичально конечно что так не продумано. ((((

 
Aleksandr Dziuba #:

Сделал заглушку, Так как покупка по рынку всегда исполняется по ближайшей цене продажи добавил просто 10 пунктов к цене аск. 

Идея интересная попринтовать.  Конечно это вероятно что идет такое округление но как оно влияет на цену? И не хочется после всех обновлений заморачиваться с классом. Когда нибудь точно забудешь)))  Можно просто кидать цену по верхней планке.  Я не лазил в код класса. Но пичально конечно что так не продумано. ((((

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

price=SymbolInfoDouble(symbol_name,SYMBOL_ASK);
Print(price);

И если даже будет проскакивать ноль, то тогда делать проверку bid, ask на ноль.
По моему как то на форуме проскакивала инфа, что мосбиржа в фиде Level2 шлёт нули.

А чтобы класс не перезаписывался в исходный вид при обновлении,
можно просто скопипасить его в свой mqh файл, переименовать имя класса CTrade
и инклудить уже свой класс с исправлениями.
Но тут Digits() я на скорую руку написал

NormalizeDouble(price,Digits())

по хорошему нужно сделать его членом класса, чтоб под любой инструмент подходило.
Я не использую стандартные классы, по этому не вникал в их реализацию.

 
Aleksandr Dziuba:

Использую CTrade.

Указано  что для покупки по рынку все переменные заполняются 0.0.

На всех других итструментах работает нормально но вот на VTB где цена 0.037815 шесть знаков после запятой не всегда, но выдает ошибку.

Может знаете как ее обойти? Или что я делаю не правильно?

Вот фрагмент кода. 


2022.01.25 21:03:04.827 2021.01.04 13:54:40   failed exchange buy 1 VTBR at 0 [Invalid price]

2022.01.25 21:03:04.827 2021.01.04 13:54:40   CTrade::OrderSend: exchange buy 1.00 VTBR [invalid price]

2022.01.25 21:03:04.827 2021.01.04 13:54:40   не совершена покупка 10015

Спасибо.


Сдаётся мне, что у Вас адресное пространство команд ушло в адресное пространство данных. Даже компилятор спятил. 

 
Алексей Тарабанов #:

Сдаётся мне, что у Вас адресное пространство команд ушло в адресное пространство данных. Даже компилятор спятил. 

Спасибо за шутку. Очень вошло ))))

 
Aleksandr Dziuba #:

Спасибо за шутку. Очень вошло ))))

Код ошибки 10015 поищите. 

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