Конструкция для OrderSend()

 
int ticket = 0;
bool FirstAttempt = TRUE;
if (ticket == -1 || FirstAttempt) {
  FirstAttempt = FALSE;
  ticket = OrderSend( ...);
  if(ticket<0) {
    Print("OrderSend failed with error #",GetLastError());
    return(0);
   }
}


Предполагается, что повторные попытки отправки ордера будут делаться только после того, как OrderSend() закончит работу и вернёт ошибку. И никаких Sleep. Действительно ли это будет так работать?

 
P.S. Понятно, что нужна дополнительная логика, чтобы присвоение ticket = 0 и FirstAttempt = TRUE не делалось каждый раз. То есть код просто иллюстрирует идею.
 
Ну, и будет молотить на каждом тике. А смысл постановки переменных вообще не могу понять. Что они решают? Где собака то порылась?
 
Тогда уж IsTradeAllowed() применять для проверки завершенности предыдущей попытки...
 
Ну, и будет молотить на каждом тике. А смысл постановки переменных вообще не могу понять. Что они решают? Где собака то порылась?

Пока OrderSend() пытается дозвониться, молотить не должно. Когда выяснилось, что облом - новая попытка. И так пока не поставит. Переменные именно это и должны обеспечивать. Я не имею достаточного опыта автоматической реальной торговли, да и документирован MQ4 недостаточно, вот собака и роется.

IsTradeAllowed() возможно всё равно нужно использовать. Но смысл в том, чтобы повторять запрос пока ордер не будет установлен (не на каждом тике, а только при провале предыдущей попытки).

Вот более реалистичный код, но тоже писался сходу, могут быть огрехи.
...

int ticket = 0;
bool FirstAttempt = FALSE;

...

bool IsSignal() {
  ...
  if (условие сигнала) {
    ticket = 0;
    FirstAttempt = TRUE;
    return(TRUE);
  } else return(FALSE);
}

int start() {
  
...

  if (IsSignal() && (ticket == -1 || FirstAttempt)) {
    FirstAttempt = FALSE;
    ticket = OrderSend( ...);
    if(ticket<0) {
      Print("OrderSend failed with error #",GetLastError());
      return(0);
     }
  }

 ...

}
 
Если у тебя задача поставить один ордер, сделай проверку перед установкой ордера на наличие данного инструмента в торговле. И если есть, уходи. Тогда другие переменные и не нужны будут.
 
Если у тебя задача поставить один ордер, сделай проверку перед установкой ордера на наличие данного инструмента в торговле. И если есть, уходи. Тогда другие переменные и не нужны будут.
Не пойму, как это обспечит повтор попыток при сбое сети или сервера. И почему оно не будет молотить на каждом тике? К тому же, для проверки понадобится цикл по ордерам. Может экономнее ввести несколько логических переменных? Или я не понял о чём речь. Можешь дать вариант кода?
 
Поскольку пока люди в основном интересуются "зачем так" (хотя вопрос состоит в том, будет ли это работать) :), попробую сформулировать постановку задачи:
Предположим, есть некая система, дающая сигналы на постановку ордеров, причём раз возникнув, сигнал некоторое время сохраняется. Нужно попытаться поставить один ордер, несмотря на возможные сбои связи и сбои сервера. Если через некоторое время сигнал возникнет снова, нужно ставить новый ордер, и.т.д. (то есть режим мультиордер).
Вот более или менее обдуманный вариант кода. Было бы особенно интересно узнать мнение авторов реально торгующих экспертов, а также их варианты (если это не засекреченное ноу хау, конечно).
...
int ticket = 0;
bool FirstAttempt = FALSE;
bool SendOrder = FALSE;
...
bool IsSignal() {
  ...
  if (условие сигнала) {                           //  Есть сигнал
    if (!SendOrder )  {                               // Сигнал только что возник, заряжаем логику 
      SendOrder = TRUE;                          // Пока сигнал не прервётся, мы сюда больше не попадём
      ticket = 0;                      // Чтобы не вызывать OrderSend(), пока не отработан предыдущий вызов
      FirstAttempt = TRUE;      // Чтобы в первый раз вызвать OrderSend(), вопреки ticket = 0
    } else {                                             
      if (ticket > 0) return(FALSE);              // Сигнал продолжается, но ордер уже стоит
    }
    return(TRUE);                                     // Есть сигнал, но нет ордера
  } else {                                                 // Сигнал отсутствует
     SendOrder = FALSE;       // Обеспечим зарядку логики при возникновении  следующего сигнала
     return(FALSE);
  }
}

int start() {
...
// Пытаемся ставить ордер только в момент возникновения сигнала или
// если OrderSend() отработала и вернула ошибку, а сигнал ещё сохраняется
  if (IsSignal() && (ticket == -1 || FirstAttempt)) {  
    FirstAttempt = FALSE;              // Чтобы не попадать сюда пока работает OrderSend()
    if (ticket == -1) ticket = 0;       // Чтобы не попадать сюда пока работают повторные вызовы OrderSend()
    ticket = OrderSend( ...);
    if(ticket<0) {
      Print("OrderSend failed with error #",GetLastError());
      return(0);
     }
  }
...
}
 
Нужно попытаться поставить один ордер, несмотря на возможные сбои связи и сбои сервера.

И никаких Sleep.

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

Одним из методов выяснения отношений с сервером является точное знание его реакции. Более-менее ясен вопрос обработки ошибок, возвращаемых сервером. Но что делать в случае, если информационный пакет с ответом сервера по какой-то причине (здесь - не суть важно) не пришёл?
Какое развитие при этом получит программа, содержащая такой фрагмент?
ticket = OrderSend( ...);


Мои представления о судьбе этого эксперта таковы:
Переменная ticket никогда не получит никакого значения и программа в ожидании ответа сервера (наполняющего хоть чем-то OrderSend() для возврата этому ticket-у) по идее просто "застрянет".

Существует ли какой-нибудь штатный способ разрешения этого конфликта?

Хотелось бы узнать рекомендации разработчиков.

 
Более-менее ясен вопрос обработки ошибок, возвращаемых сервером. Но что делать в случае, если информационный пакет с ответом сервера по какой-то причине (здесь - не суть важно) не пришёл?
Какое развитие при этом получит программа, содержащая такой фрагмент?
ticket = OrderSend( ...);


Мои представления о судьбе этого эксперта таковы:
Переменная ticket никогда не получит никакого значения и программа в ожидании ответа сервера (наполняющего хоть чем-то OrderSend() для возврата этому ticket-у) по идее просто "застрянет".

Существует ли какой-нибудь штатный способ разрешения этого конфликта?

Хотелось бы узнать рекомендации разработчиков.


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

Эксперт на торговой операции не может зависнуть навечно. Максимум на несколько десятков секунд.
 
Функция OrderSend в любом случае завершится. В сетевом протоколе (и в его независимом диспетчере) есть жесткие ограничения на время проведения операций и таймауты. Если заявка не может быть выполнена из-за сетевых проблем, то операция будет прервана с кодом ошибки.
А если представить следующее: ордер на сервере ставится, связь нарушается, OrderSend не получает информации и прерывается по времени с кодом ошибки. Таким образом операция фактически исполнена, но возвращён код ошибки и, следовательно, при восстановлении связи возникает риск установки лишнего ордера. Можно ли как-то распознать такую ситуацию?
Причина обращения: