Скачать MetaTrader 5

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

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Пиши статьи, помогай другим разработчикам и зарабатывай
Forex Trader
114257
Forex Trader 2005.12.26 07:57 
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. Действительно ли это будет так работать?

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

Пока 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);
     }
  }

 ...

}
Forex Trader
114257
Forex Trader 2005.12.26 12:17  
Если у тебя задача поставить один ордер, сделай проверку перед установкой ордера на наличие данного инструмента в торговле. И если есть, уходи. Тогда другие переменные и не нужны будут.
Forex Trader
114257
Forex Trader 2005.12.26 13:16  
Если у тебя задача поставить один ордер, сделай проверку перед установкой ордера на наличие данного инструмента в торговле. И если есть, уходи. Тогда другие переменные и не нужны будут.
Не пойму, как это обспечит повтор попыток при сбое сети или сервера. И почему оно не будет молотить на каждом тике? К тому же, для проверки понадобится цикл по ордерам. Может экономнее ввести несколько логических переменных? Или я не понял о чём речь. Можешь дать вариант кода?
Forex Trader
114257
Forex Trader 2005.12.26 16:27  
Поскольку пока люди в основном интересуются "зачем так" (хотя вопрос состоит в том, будет ли это работать) :), попробую сформулировать постановку задачи:
Предположим, есть некая система, дающая сигналы на постановку ордеров, причём раз возникнув, сигнал некоторое время сохраняется. Нужно попытаться поставить один ордер, несмотря на возможные сбои связи и сбои сервера. Если через некоторое время сигнал возникнет снова, нужно ставить новый ордер, и.т.д. (то есть режим мультиордер).
Вот более или менее обдуманный вариант кода. Было бы особенно интересно узнать мнение авторов реально торгующих экспертов, а также их варианты (если это не засекреченное ноу хау, конечно).
...
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);
     }
  }
...
}
Forex Trader
114257
Forex Trader 2005.12.26 17:06  
Нужно попытаться поставить один ордер, несмотря на возможные сбои связи и сбои сервера.

И никаких Sleep.

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

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


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

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

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

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


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

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

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


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

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