Скачать MetaTrader 5

Тонкости работы функции OrderSelect()

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Как купить продукт в MetaTrader AppStore? Прочитай статью об этом!
voix_kas
681
voix_kas 2009.11.09 23:42 
Доброе время суток, уважаемые форумчане!

Возник вопрос: обращается ли советник/терминал к серверу ДЦ при выполнении функции выбора ордера OrderSelect()?
Для уточнения формулировки, приведу два примера:
Пример №1:
while (!IsStopped()) {
 if (OrderSelect(OrderCount, SELECT_BY_POS, MODE_TRADES)) {
 //...
 break;
 }
 else Print("Ошибка при выборе ордера!");
}
Пример №2 (добавлены вторая и предпоследняя строчки):
while (!IsStopped()) {
 while (IsTradeContextBusy()) Sleep(SleepTime);
 if (OrderSelect(OrderCount, SELECT_BY_POS, MODE_TRADES)) {
 //...
 break;
 }
 else Print("Ошибка при выборе ордера!");
 Sleep(SleepTime);
}

Какой из вариантов правильнее и/или надежнее?
Если бы перечень идентификаторов активных ордеров хранился на клиенте, то зачем обрабатывать возможную ошибку при выполнении операции выборки?
В таком случае ведь функция элементарно выполняла бы поиск в "локальном массиве ордеров" и (!)гарантированно выдавала нужный "тиккет" (либо "0" в случае отсутствия ордеров).
Но, полагаю, это не так. Функция все же обращается к серверу, иначе зачем в документации предусмотрен вариант возврата ошибки?
Следовательно, обращение за "тиккетом" идет именно на сервер.
Отсюда вопрос. Почему на форуме принято публиковать код, в котором при вызове функции OrderSelect():
1. Предварительно не проверяется загруженность потока торговых операций (IsTradeContextBusy() или IsTradeAllowed() - кому как нравится/удобно).
2. При выполнении повторной попытки не вводится пауза, чтобы спокойно дождаться освобождения потока торговых операций и/или не перегружать сервер частыми запросами.
И еще дополнительный вопрос либо к разработчикам MT, либо к матерым программистам:
Какие конкретно типы ошибок могут возникнуть в результате выполнения этой функции (перечень)?

Спасибо.

Alexander
2441
Alexander 2009.11.10 00:10  

Первый вариант - правильный, никуда терминал не обращается, все у него есть. А проверку ввели горе-программисты, которые не могут правильно посчитать, сколько ордеров и какие могут быть определены. Мне встречалось даже обращение и минусовым ордерам. Если диапазон задал правильно, ошибок быть не должно. Проверка оправдана, когда идет выбор по тикету, т.е. ордера с таким тикетом может и не быть.

Nikolay Demko
12465
Nikolay Demko 2009.11.10 00:15  
Roger >>:

Первый вариант - правильный, никуда терминал не обращается, все у него есть. А проверку ввели горе-программисты, которые не могут правильно посчитать, сколько ордеров и какие могут быть определены. Мне встречалось даже обращение и минусовым ордерам. Если диапазон задал правильно, ошибок быть не должно.

Вообщето история храниться на серверной части и регулярно синхронизируется,

но Roger прав терминал имеет для этих целей всё необходимое у себя и по OrderSelect() к серверу не обращается.

Alexander
4034
Alexander 2009.11.10 00:19  
voix_kas писал(а) >>
Если бы перечень идентификаторов активных ордеров хранился на клиенте, то зачем обрабатывать возможную ошибку при выполнении операции выборки?
В таком случае ведь функция элементарно выполняла бы поиск в "локальном массиве ордеров" и (!)гарантированно выдавала нужный "тиккет" (либо "0" в случае отсутствия ордеров).

Дергать сервер каждый раз для выбора ордера было бы накладно.

Гарантированно выбрать тоже нельзя, т.к. позиция может в любой момент закрыться (например по СЛ или ТП), попав из MODE_TRADES в MODE_HISTORY.

voix_kas
681
voix_kas 2009.11.10 00:34  

Ну, допустим, вы правы, и надо использовать первый вариант.

Но у меня остается вполне логичный вопрос: для чего в таком случае авторы МТ ввели обработчик ошибки для данной функции.


Все было бы просто, если, например, в документации было бы сказано: "истина" - тиккет получен, "ложь" - нет.

Но в документации на данную функцию (OrderSelect) сказано:

...Возвращает TRUE при успешном завершении функции. Возвращает FALSE при неудачном завершении функции. Чтобы получить информацию об ошибке, необходимо вызвать функцию GetLastError().

Если у терминала имеется массив с текущими ордерами, то в каком, даже теоритическом случае, он может вернуть "ложь"?! Ситуации типа "недостаточно памяти" и т.п. рассматривать не будем.

Отсюда также следует и последний мой вопрос: какие конкретно типы ошибок могут возникнуть в результате выполнения этой функции (перечень)?

Спасибо.

Nikolay Demko
12465
Nikolay Demko 2009.11.10 00:57  
voix_kas >>:

Ну, допустим, вы правы, и надо использовать первый вариант.

Но у меня остается вполне логичный вопрос: для чего в таком случае авторы МТ ввели обработчик ошибки для данной функции.


Все было бы просто, если, например, в документации было бы сказано: "истина" - тиккет получен, "ложь" - нет.

Но в документации на данную функцию (OrderSelect) сказано:

Если у терминала имеется массив с текущими ордерами, то в каком, даже теоритическом случае, он может вернуть "ложь"?! Ситуации типа "недостаточно памяти" и т.п. рассматривать не будем.

Отсюда также следует и последний мой вопрос: какие конкретно типы ошибок могут возникнуть в результате выполнения этой функции (перечень)?

Спасибо.

Во первых вариантов выбора ордера два по тикету и по позицие и обе могут выбрать не существующий ордер, во вторых может быть выбран ордер которых в это время закрылся по профиту(стопу) тогда (OrderSelect) тоже верьнёт ошибку в общем ошибок несколько а раз так то нужна обработка ошибок.

Плюс может быть выбран ордер который уже обрабатывается кемто или чемто другим.

voix_kas
681
voix_kas 2009.11.10 01:24  
Urain >>:

Во первых вариантов выбора ордера два по тикету и по позицие...

Согласен, при использовании SELECT_BY_TICKET могут быть нюансы. Сузим условия: выборка производится с параметрами SELECT_BY_POS + MODE_TRADES.

Urain >>:

...и обе могут выбрать не существующий ордер...

Пример:

1. OrderCount вернул значение "1".

2. OrderSelect вернул значение "инстина".

3. Ордер закрылся.

Но на втором этапе функция отработает штатно, вернет "истину".

Интересно, а если сразу за этим попытаться использовать переменные типа OrderLots()/OrderSymbol()/OrderType() не будет ли сгенерирована ошибка? Формально ведь будут использоваться уже несуществующие данные.

Urain >>:

...во вторых может быть выбран ордер которых в это время закрылся по профиту(стопу) тогда (OrderSelect) тоже верьнёт ошибку...

Здесь согласен. Хронология:

1. OrderCount вернул значение "1".

2. Ордер закрылся.

3. OrderSelect вернул значение "ложь".

Urain >>:

Плюс может быть выбран ордер который уже обрабатывается кемто или чемто другим.

Т.е.? Один и тот же ордер не может быть одновременно выбран более одним советником? Хмм... этого я не знал (если вы именно это имели в виду).

Aleksey Lebedev
6057
Aleksey Lebedev 2009.11.10 05:43  
voix_kas >>:
Доброе время суток, уважаемые форумчане!

Возник вопрос: обращается ли советник/терминал к серверу ДЦ при выполнении функции выбора ордера OrderSelect()?
Для уточнения формулировки, приведу два примера:
Пример №1:
Пример №2 (добавлены вторая и предпоследняя строчки):

Какой из вариантов правильнее и/или надежнее?
Если бы перечень идентификаторов активных ордеров хранился на клиенте, то зачем обрабатывать возможную ошибку при выполнении операции выборки?
В таком случае ведь функция элементарно выполняла бы поиск в "локальном массиве ордеров" и (!)гарантированно выдавала нужный "тиккет" (либо "0" в случае отсутствия ордеров).
Но, полагаю, это не так. Функция все же обращается к серверу, иначе зачем в документации предусмотрен вариант возврата ошибки?
Следовательно, обращение за "тиккетом" идет именно на сервер.
Отсюда вопрос. Почему на форуме принято публиковать код, в котором при вызове функции OrderSelect():
1. Предварительно не проверяется загруженность потока торговых операций (IsTradeContextBusy() или IsTradeAllowed() - кому как нравится/удобно).
2. При выполнении повторной попытки не вводится пауза, чтобы спокойно дождаться освобождения потока торговых операций и/или не перегружать сервер частыми запросами.
И еще дополнительный вопрос либо к разработчикам MT, либо к матерым программистам:
Какие конкретно типы ошибок могут возникнуть в результате выполнения этой функции (перечень)?

Спасибо.

Опасные у Вас примеры)

Если OrderSelect() возвращает ошибку, то эксперт зависнет до остановки вручную.


1. Проверка потока торговых операций в тестере не нужна :)

2. Sleep тем более.


Ошибка при OrderSelect одна. Ордера с передаваемым тикетом или позицией уже нет в списке открытых ордеров.

Alexander
2441
Alexander 2009.11.10 07:21  
Как раз сейчас встретил интересную конструкцию внутри двойного цикла, когда проверка необходима только для определения свойств ордера:
if(OrderSelect(k,SELECT_BY_POS)&& OrderMagicNumber()==MagicNumber21 && OrderProfit() >= 38)
{
OrderSelect(i, SELECT_BY_POS);
int type = OrderType();
bool result = false;
switch(type)
{
//Close opened positions
case OP_BUY : result = OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),Slippage,Pink);
break; 
case OP_SELL : result = OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),Slippage,Pink);
break; 
}
}
voix_kas
681
voix_kas 2009.11.10 13:46  
Swan
Извините, но я думаю, вы далеки от сути разговора.
Во-первых, при возникновении торговой ошибки эксперт не зависнет, а скорее всего пойдет по некорректному алгоритму работы (не предусмотрена обработка возможной ошибки).
Во-вторых, речь идет не об исключительно тестере стратегий, а вообще о качетсве кода, который в том числе будет работать и в режиме реального времени.
Понять не могу, я ведь даже не упоминал о тестере... откуда у вас такие ответы? :)

Roger
Уточните, пожалуйста, на чем акцентировать внимание. Я не совсем понимаю, на какой из заданных мною вопросов дает ответ этот пример.
К тому же, совершенно очевидно, корректность исполнения второй функции OrderSelect() ни чем не проверяется. Что уже есть 100% ошибка.

Спасибо.
Комбинатор
15932
Комбинатор 2009.11.10 14:00  
voix_kas >>:
Извините, но я думаю, вы далеки от сути разговора.

Извините, но вы наверное еще дальше.

Оболакивать OrderSelect в бесконечный цикл -- это убийство.

1. Предварительно не проверяется загруженность потока торговых операций (IsTradeContextBusy() или IsTradeAllowed() - кому как нравится/удобно).

А это вообще в ан(н?)алы.

12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий