Не сравнивается тикет ордера с целым числом

 

Есть такой блок кода, который мне не даёт покоя уже не 1 час:

  while (cnt < m_tryCount && !IsStopped()) {
    writeLog(MESSAGE_ERROR, __FUNCTION__ + " { cnt = " + iToS(cnt)+ " }" );
    if (!sent) {
      sent = OrderSend(m_request, m_result);
      writeLog(MESSAGE_ERROR, __FUNCTION__ + " { m_result.retcode = }" + iToS(m_result.retcode));
      Sleep(100); cnt++; continue;
    }
     else {
      if (m_result.retcode == TRADE_RETCODE_PLACED) {
        if (m_result.order > 0) break;
      }
      if (m_result.retcode == TRADE_RETCODE_INVALID_PRICE) {
        marketPriceToTrade = getCurMarketPrice(m_request, true);               // Получение рыночной цены для открытия ордера соответствующего типа
        orderOpenPriceCorrection(m_request, ptrSymbol, marketPriceToTrade);    // Корректировка цены открытия(или модификации) отложенного ордера
      }
    }
  }

Когда происходить попадание а цикл, то программа из него уже не может выйти. Я крутил вертел это всё хозяйство, думал. Решил пройтись под отладчиком. Оказывается как только флаг sent возводится в true, то первый из уже не проверяется. Дальше отрабатывает в цикле только else. Это всё понятно и логично. На то у меня был расчёт изначально. Дальше начинается самое интересное. Когда доходит до блока:

if (m_result.retcode == TRADE_RETCODE_PLACED) {
  if (m_result.order > 0) break;
}

В отладчике я вижу:

m_result.retcode = 10009, а это и есть TRADE_RETCODE_DONE

m_result.order = 2, а это больше 0

Тем не менее оператор break не срабатывает. И таким образом цикл подвисает и из него программа не выходит вообще. Как это так получается вообще? Баг?

 

И где "баг" ?

До проверки m_result.order вобще доходить не должно - оно у тебя и не доходит. И оператор break, само собой, не сработает...

Что не так-то ?

 

А зачем вообще if (!sent)

sent - это какая-то глобальная переменная?

 
А посмотреть отладчиком? F9 - установить точку остановки, F5 - запустить отладку. В правом нижнем углу вписать имя переменной, чтобы посмотреть значение.
 
//---
  bool sent = false;            // Признак успешной отправки ордера
  char cnt = 0;                 // Счётчик количества попыток совершения торговых операций
  double marketPriceToTrade;    // Текущая рыночная цена(Ask или Bid)

  clearTradeStructures();    // Опустошение всех структур, связанных с торговым запросом

  while (cnt < m_tryCount && !IsStopped()) {
    writeLog(MESSAGE_ERROR, __FUNCTION__ + " { cnt = " + iToS(cnt)+ " }" );
    if (!sent) {
      sent = OrderSend(m_request, m_result);
      writeLog(MESSAGE_ERROR, __FUNCTION__ + " { m_result.retcode = }" + iToS(m_result.retcode));
      Sleep(100); cnt++; continue;
    }
     else {
      if (m_result.retcode == TRADE_RETCODE_PLACED) {
        if (m_result.order > 0) break;
      }
      if (m_result.retcode == TRADE_RETCODE_INVALID_PRICE) {
        marketPriceToTrade = getCurMarketPrice(m_request, true);               // Получение рыночной цены для открытия ордера соответствующего типа
        orderOpenPriceCorrection(m_request, ptrSymbol, marketPriceToTrade);    // Корректировка цены открытия(или модификации) отложенного ордера
      }
    }
  }  

. ... Rick D. ... .
:

А зачем вообще if (!sent)

sent - это какая-то глобальная переменная?

Нет, локальная. Вот в таком видео, будет более ясное представление и ситуации:

Ну да m_tryCount это глобальна переменная количества попыток на совершение торговых операций. Сейчас m_tryCount = 15.

Georgiy Merts:

И где "баг" ?

До проверки m_result.order вобще доходить не должно - оно у тебя и не доходит. И оператор break, само собой, не сработает...

Что не так-то ?

В смысле само собой? Как только функция OrderSend() успешно выполнилась, sent принимает значение true. Соответственно, в блок:

if (!sent) {
  sent = OrderSend(m_request, m_result);
  writeLog(MESSAGE_ERROR, __FUNCTION__ + " { m_result.retcode = }" + iToS(m_result.retcode));
  Sleep(100); cnt++; continue;
}

мы больше не зайдёт, т.к. флаг sent уже принял значение true.

Значит должны идти в else. Код возврата торгового сервера я приводил, а так же номер тикета нового ордера:

m_result.retcode = 10009, а это и есть TRADE_RETCODE_DONE

m_result.order = 2, а это больше 0

Все условия истинны для того, что бы оператор break выполнился. Но он не выполняется..

 
Ilya Baranov:
А посмотреть отладчиком? F9 - установить точку остановки, F5 - запустить отладку. В правом нижнем углу вписать имя переменной, чтобы посмотреть значение.

Так я из отладчика эти данные и показал. На цикле у меня брейкпоинт установлен. Я же писал, что отладчиком нашёл, то что не работает break. Сколько лет им пользуюсь, такого ещё не было ни разу раньше..

 
hoz:
if (m_result.retcode == TRADE_RETCODE_PLACED) {
        if (m_result.order > 0) break;

В отладчике я вижу:

m_result.retcode = 10009, а это и есть TRADE_RETCODE_DONE

m_result.order = 2, а это больше 0

Тем не менее оператор break не срабатывает. И таким образом цикл подвисает и из него программа не выходит вообще. Как это так получается вообще? Баг?

TRADE_RETCODE_PLACED!=TRADE_RETCODE_DONE

 
Aleksey Lebedev:

Я это уже понял пару минут назад, как начал тест((

 
hoz:

Мне кажется - вы немного мудрите. Напишите проще.

bool OrderSendEx(...)
{
 clearTradeStructures();

 int SleepOk = 100;
 int SleepErr = 1000;
 bool bRC;

 for (int i=0; i < m_tryCount; i++)
 {
  if (IsStopped()) return (false);

  bRC = OrderSend(m_request, m_result);
    
  if (m_result.retcode == TRADE_RETCODE_PLACED || m_result.retcode == TRADE_RETCODE_DONE)
  {
    Sleep(SleepOk);
    return (true);
  }

  if (m_result.retcode == TRADE_RETCODE_REQUOTE || любая другая подобная ошибка)
  {
   //повторить
   Sleep(SleepErr);
   continue;
  }

  Print("Фатальная ошибка");
  break;
 }
 
 Sleep(SleepErr);
 return (false);
}
Причина обращения: