Выдает ошибку, но работает ( в чем дело ? )

 
Скрипт по закрытию стал давать сообщение об ошибке в Алерт: 129 - неправильная цена, но при этом работает нормально. Что не так?

     for(i=Total-1; i>=0; i--) 
     {
        if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true && 
           OrderType()==OP_BUY)  // Только Buy
        {
           Result=OrderClose(OrderTicket(),
                             OrderLots(),
                             Bid,
                             Slippage,
                             CLR_NONE);
           if(Result!=true) 
           { 
              Error=GetLastError(); 
              Alert("CloseBuy LastError = ",Error); 
           }
           else Error=0;
        }
     }
 
Сколько времени длится закрытие позиций? Может за это время цены могут измениться?

Стандартная ошибка - нет обновления рыночного окружения после торговых операций.
 
Renat писал (а):
Сколько времени длится закрытие позиций? Может за это время цены могут измениться?

Стандартная ошибка - нет обновления рыночного окружения после торговых операций.

Открываю только одну позицию. И закрываю, естественно, тоже одну. Все равно надо обновлять ? перед Result=OrderClose( ... ? 
 
По коду видно, что работа идет со всеми открытыми позициями. В любом случае код 100% ошибочен.
 
Renat писал (а):
По коду видно, что работа идет со всеми открытыми позициями. В любом случае код 100% ошибочен.

Не понял.

Алгоритм вроде без излишеств:

1. Проверить наличие ордеров.
2. Если ордера есть - Total>0 - перебрать по очереди все ордера и для каждого
2.1. Проверить ордер на соответствие OP_BUY.
2.2. Если да, закрыть его по Bid. Если закрытие не удачно - просто на Алерт его и перейти к следующему. Если удачно (закрылся - комментариев на Алерт нет) - перейти к следующему.
2.3. Если не OP_BUY - перейти к следующему.
3. Перебор всех ордеров закончен - должен быть результат: все OP_BUY закрыты (если нет сообщений на Алерт), остальное живет своей жизнью.

И тогда не понятно с обновлением обстановки - цену Bid на закрытие я каждый раз заново "спрашиваю" непосредственно в момент выполнения OrderClose - когда же эти изменения происходят? И совсем тогда уже не понятно - для чего Slippage, я наивно и предполагал, что если после запроса и пока я получу ответ цена дернется, слипаж и сдемпфирует, обеспечивая "мое согласие" на отличие цены от заказанной в OrderClose.

Что-то не так?
 
Bookkeeper:
я наивно и предполагал, что если после запроса и пока я получу ответ цена дернется, слипаж и сдемпфирует, обеспечивая "мое согласие" на отличие цены от заказанной в OrderClose.

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

Никто не пропустит ордер, к которому есть даже малейшие вопросы. Приоритет только и исключительно за абсолютной точностью формирования торговых заявок.
 
Тогда Вы правы, я действительно не понимаю.

Выходит, что значения переменных Bid и Ask формируются в момент запуска скрипта? а не в момент обращения к ним из программы?

И если существуют обращения к OrderClose, OrderModify, OrderSend, ... (особенно в цикле) - перед всеми торговыми функциями всюду, где есть цены Bid и Ask, надо ставить RefreshRates() ? если хочешь быть уверен, что сработает?

  Total=OrdersTotal();
  if(Total>0)
  {
     for(i=Total-1; i>=0; i--) 
     {
        if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true) 
        {
           Pos=OrderType();
           if(Pos==OP_BUY || Pos==OP_SELL) // Только Buy и Sell
           {
//---------------------------------------------------------------
//---------------------------------------------------------------
              RefreshRates();
//---------------------------------------------------------------
//---------------------------------------------------------------
              if(Pos==OP_BUY) price=Bid; 
              else price=Ask;
              Result=OrderClose(OrderTicket(),
                                OrderLots(),
                                price,
                                Slippage,
                                CLR_NONE);
              if(Result!=true) 
              { 
                 Error=GetLastError(); 
                 Alert("CloseAllBuySell LastError = ",Error); 
              }
              else Error=0;
           }
        }
     }
  }
Теперь правильно? Если нет - я уже пас, не объясняйте, а покажите пальцем, плиz.
Если да - на что еще влияет RefreshRates() ?

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

Эксперт на входе в функцию start() получает текущий снимок (snapshot) рынка (это касается статических переменных типа Bid, Ask) и может спокойно работать, не пугаясь, что Ask в одной строке кода вдруг не равен Ask в другой строке. Все обращения к штатным _функциям_(именно штатным функциям MQL4) являются прямыми и не кешируются. Например, тот же самый Ask можно получить через MarketInfo().

Мы многократно описывали модель работы экспертов, кеширование данных и особенности функции RefreshRates - поищите по форуму http://www.metatrader4.com/ru/forum , пожалуйста.
 
Спасибо, Renat, пошарю - я там не был, глянул - там интересно. Очень утешило - еще целая толпа там же и в тех же дураках, причем не чайников, судя по НИКам. Но честно говоря в консерватории надо что-то менять. Простейшая операция по закрытию или открытию позы "с рынка" по цене дилера, без условий, а ... Без рефреша нет уверенности, но и одного рефреша мало, нодо еще и засекать время от последнего, проверять - прошло ли 5 секунд или "держи паузу", и наличие еррора еще не факт, что поза не закрылась/открылась ... опять проверять ... и простейший скрипт превращается в многоэтажную конструкцию.

Интересно ? - а можно смоделировать обычную процедуру:
запрос "купить/продать/закрыть" -> ответ ДЦ "цена" -> автоматом не глядя "согласен" -> ура, свершилось.
 
Bookkeeper:
Спасибо, Renat, пошарю - я там не был, глянул - там интересно. Очень утешило - еще целая толпа там же и в тех же дураках, причем не чайников, судя по НИКам. Но честно говоря в консерватории надо что-то менять. Простейшая операция по закрытию или открытию позы "с рынка" по цене дилера, без условий, а ... Без рефреша нет уверенности, но и одного рефреша мало, нодо еще и засекать время от последнего, проверять - прошло ли 5 секунд или "держи паузу", и наличие еррора еще не факт, что поза не закрылась/открылась ... опять проверять ... и простейший скрипт превращается в многоэтажную конструкцию.

Интересно ? - а можно смоделировать обычную процедуру:
запрос "купить/продать/закрыть" -> ответ ДЦ "цена" -> автоматом не глядя "согласен" -> ура, свершилось.
И действительно - если мы хотим продать/купить по рынку зачем тогда нужно подавать цену? Если трейдер решился на вход/выход по рынку, ему нужно сделать это скорее, пусть и с каком-то скольжение.

Некоторые терминалы имеют опцию "Instant execution" - как раз для этого случая.

Было бы проще всего добавить пару констант - типы операции: OP_BUY_INSTANT и OP_SELL_INSTANT. Тогда цена и скольжение игнорируются и операция производиться на риск трейдера.
 
С учетом того, что мы много лет занимаемся именно автоматическим трейдингом, то в консерватории менять не нужно. Нужно глубже думать и на практике заниматься разработкой информационно-торговых платформ.

Если пойти по пути "Bid, Ask" пусть всегда подставляются рыночные, то трейдеры будут в шоке и обольют нас грязью из-за того, что логика работает по одним ценам, а сделки проходят совершенно по другим. То есть, будет ситуация, когда может срабатывать условие Ask!=Ask. Трейдеры разбираться не будут. Будут просто тыкать пальцем в код и обвинять разработчиков.

К чему приведет подстройка под небрежного трейдера-программиста? К нивелированию ошибок трейдера, когда он будет писать такой чудовищный код, который мы будем подправлять и отрабатывать. Тем самым усугубляя неверное понимание логики работы экспертов.

Практический автотрейдинг - это не простейшие конструкции "купить" и "продать" (некоторые информационных терминалы добавляют такую возможность, а потом заявляют о себе как об платформе автотрейдинга!), а осознанное и детальное управление практически всеми этапами совершения сделок в прямой связке с торговым сервером.

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