Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 704

 
Alexander_K2:

А ведь что-то, действительно, не так...

Т.е. я один раз делаю OrderSelect, а потом еще раз из функции... Чертовщина какая-то...

  1. Вы выбрали ордер по тикету
  2. Ушли в функцию проверки количества ордеров. Если ордеров больше одного, то в цикле выбираются по одному все имеющиеся ордера для их подсчёта
  3. После возврата из функции выделенным оказывается тот, кторый был последним в списке ордеров в терминале, и он не обязательно будет тем, который вы в п.1 выбрали по тикету.
  4. Далее вы проверяете время закрытия уже нового выделенного ордера, а закрывать пытаетесь тот, который якобы выбран по тикету, но его выбор уже утерян.

Простая же логика...

Следите за последовательностью проводимых операций.

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

 
Maxim Kuznetsov:

вы в каком направлении просматриваете массив ордеров ?

если при "ревизии" возможны закрытия/удаления, то лучше смотреть в обратном. От OrdersTotal()-1 до 0 включительно.

иначе можно наступить :-)


я как-то таким образом чуть персональный грааль не открыл :-)

удаление старых ордеров из "глубин времени" в настоящее (через раз, а не всех) подняло тестерную прибыльность в какие-то небеса :-)

 
Artyom Trishkin:
  1. Вы выбрали ордер по тикету
  2. Ушли в функцию проверки количества ордеров. Если ордеров больше одного, то в цикле выбираются по одному все имеющиеся ордера для их подсчёта
  3. После возврата из функции выделенным оказывается тот, кторый был последним в списке ордеров в терминале, и он не обязательно будет тем, который вы в п.1 выбрали по тикету.
  4. Далее вы проверяете время закрытия уже нового выделенного ордера, а закрывать пытаетесь тот, который якобы выбран по тикету, но его выбор уже утерян.

Простая же логика...

Следите за последовательностью проводимых операций.

Очевидно, что сначала нужно проверить количество, затем выбрать нужный ордер, и затем уже проводить над ним нужные вам операции

Сделал вот так:

RefreshRates();
         total_orders_NZDUSD=TotalOrders("NZDUSD.I");
         if(OrderSelect(ticket_sell_NZDUSD, SELECT_BY_TICKET)==true)
         {
         ctm_ticket_sell_NZDUSD=OrderCloseTime();
         order_type_NZDUSD=OrderType();
            if(total_orders_NZDUSD>0)
            {
               if(ctm_ticket_sell_NZDUSD==0)
               {
                  if(order_type_NZDUSD==OP_SELL)
                  {
                  double AskNorm=NormalizeDouble(Ask,Digits);
                  OrderClose(ticket_sell_NZDUSD,0.01,AskNorm,0);
                  }
               }
            }
         }

Просто поставил вначале подсчет ордеров, а потом все остальное.

Благодарствую, Артем. Заработает- с меня Грааль. Именно эта ошибка меня и губила...

 

Как посчитать количество знаков после запятой?

например, я узнал, что минимальный лот 0.01.

MarketInfo("EURUSD",MODE_MINLOT)

как мне теперь вывести, что количество знаков после запятой здесь 2?
чтобы потом нормализовать объем ордера до двух знаков после запятой.

 
multiplicator:

Как посчитать количество знаков после запятой?

например, я узнал, что минимальный лот 0.01.

как мне теперь вывести, что количество знаков после запятой здесь 2?
чтобы потом нормализовать объем ордера до двух знаков после запятой.

Попробуйте вот эту.

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 16.05.2008                                                     |
//|  Описание : Возвращает нормализованное значение торгуемого лота.           |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    lo - нормализуемое значение лота.                                       |
//|    ro - способ округления          (   False    - в меньшую,               |
//|                                        True     - в большую сторону)       |
//|    sy - наименование инструмента   ("" или NULL - текущий символ)          |
//+----------------------------------------------------------------------------+
double NormalizeLot(double lo, bool ro=False, string sy="") {
  double l, k;
  if (sy=="" || sy=="0") sy=Symbol();
  double ls=MarketInfo(sy, MODE_LOTSTEP);
  double ml=MarketInfo(sy, MODE_MINLOT);
  double mx=MarketInfo(sy, MODE_MAXLOT);

  if (ml==0) ml=0.1;
  if (mx==0) mx=100;

  if (ls>0) k=1/ls; else k=1/ml;
  if (ro) l=MathCeil(lo*k)/k; else l=MathFloor(lo*k)/k;

  if (l<ml) l=ml;
  if (l>mx) l=mx;

  return(l);
}
 
Alekseu Fedotov:

Попробуйте вот эту.

Зачем такое старьё предлагать?

multiplicator:

Как посчитать количество знаков после запятой?

например, я узнал, что минимальный лот 0.01.

как мне теперь вывести, что количество знаков после запятой здесь 2?
чтобы потом нормализовать объем ордера до двух знаков после запятой.

Вот в статье есть готовая функция. 

//+------------------------------------------------------------------+
//|  Проверяет объем ордера на корректность                          |
//+------------------------------------------------------------------+
bool CheckVolumeValue(double volume,string &description)
  {
//--- минимально допустимый объем для торговых операций
   double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   if(volume<min_volume)
     {
      description=StringFormat("Объем меньше минимально допустимого SYMBOL_VOLUME_MIN=%.2f",min_volume);
      return(false);
     }

//--- максимально допустимый объем для торговых операций
   double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
   if(volume>max_volume)
     {
      description=StringFormat("Объем больше максимально допустимого SYMBOL_VOLUME_MAX=%.2f",max_volume);
      return(false);
     }

//--- получим минимальную градацию объема
   double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);

   int ratio=(int)MathRound(volume/volume_step);
   if(MathAbs(ratio*volume_step-volume)>0.0000001)
     {
      description=StringFormat("Объем не является кратным минимальной градации SYMBOL_VOLUME_STEP=%.2f, ближайший корректный объем %.2f",
                               volume_step,ratio*volume_step);
      return(false);
     }
   description="Корректное значение объема";
   return(true);
  }

Остаётся только добавить действие в зависимости от возвращённого результата работы этой функции.

Какие проверки должен пройти торговый робот перед публикацией в Маркете
Какие проверки должен пройти торговый робот перед публикацией в Маркете
  • www.mql5.com
Все продукты Маркета перед публикацией проходят обязательную предварительную проверку, так как небольшая ошибка в логике советника или индикатора может привести к убыткам на торговом счете. Именно поэтому нами разработана серия базовых проверок, призванных обеспечить необходимый уровень качества продуктов Маркета. Если в процессе проверки...
 
я вижу, что при открытии, терминал сам нормализовывает ордер до нужного количества знаков после запятой.
я ставлю такой лот
OrderSend(Symbol(),OP_BUY,1.11111111,Ask,3,0,0);
а сделка открывается с объемом 1.11.

так может и не нужно ничего нормализовывать?
 
multiplicator:
я вижу, что при открытии терминал сам нормализовывает ордер до нужного количества знаков после запятой.
может и не нужно ничего нормализовывать?

Если редактор делает то же самое - не нужно. 

 
multiplicator:
я вижу, что при открытии терминал сам нормализовывает ордер до нужного количества знаков после запятой.
может и не нужно ничего нормализовывать?

Если хотите впоследствии получать ошибку за ошибкой - не нормализуйте.

 
Artyom Trishkin:

Если хотите впоследствии получать ошибку за ошибкой - не нормализуйте.

почему-то не показывает ошибок терминал)
Причина обращения: