Any questions from newcomers on MQL4 and MQL5, help and discussion on algorithms and codes - page 704

 
Alexander_K2:

There's something really wrong, though...

I mean, I do OrderSelect once and then again from the function... That's a hell of a thing...

  1. You have selected an order on a ticket
  2. You go to the function that checks the number of orders. If there is more than one order, all the available orders are selected one by one in the cycle
  3. When you return from the function, the order selected will be the one which was last in the list of orders in the client terminal (it will not necessarily be the order you selected in point 1).
  4. Then you check the time of closing of a new order, and you are trying to close the one which was supposedly selected by the ticket, but its selection has been already lost.

Simple logic...

Watch the sequence of operations you are making.

Obviously, you must first check the quantity, then select the required order, and then perform the necessary operations on it.

 
Maxim Kuznetsov:

in which direction do you view the order array?

if there are possible closures/deletions during "revision", it is better to look in the opposite direction. From OrdersTotal()-1 to 0 inclusive.

Otherwise you might get in trouble :-)


I almost discovered my personal grail in this way once :-)

And the removal of old orders from the "depths of time" to the present (once in a while, not all of them) raised the tester profitability to the heavens :-)

 
Artyom Trishkin:
  1. You have selected an order by ticket
  2. You have gone into the function to check the number of orders. If there is more than one order, all of the available orders will be selected one by one to be counted in the cycle
  3. When you return from the function, the order selected will be the one which was last in the list of orders in the client terminal (it does not necessarily have to be the order you selected in point 1).
  4. Then you check the time of closing of a new order, and you are trying to close the one which was supposedly selected by the ticket, but its selection has been already lost.

Simple logic...

Watch the sequence of operations you are making.

It is obvious that you must first check the quantity, then select the right order, and then perform the necessary operations on it

I have done it this way:

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);
                  }
               }
            }
         }

Just put order counting first, and then everything else.

Thank you Artem. I owe the grail to it. That was the mistake that was killing me...

 

How do I calculate the number of decimal places?

for example, i found out that the minimum lot is 0.01.

MarketInfo("EURUSD",MODE_MINLOT)

how do i deduce that the number of decimal places is 2?
to normalise the order volume to two decimal places.

 
multiplicator:

How do I calculate the number of decimal places?

for example, i found out that the minimum lot is 0.01.

how do i deduce that the number of decimal places is 2?
to normalise the order volume to two decimal places later.

Try this one.

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. 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:

Try this one.

Why offer such old stuff?

multiplicator:

How to calculate the number of decimal places?

For example, I have learned that the minimum lot is 0.01.

How can I find out that the number of decimal places is 2?
Then normalize the order volume to two decimal places.

Here's a ready-made function in the article.

//+------------------------------------------------------------------+
//|  Проверяет объем ордера на корректность                          |
//+------------------------------------------------------------------+
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);
  }

All that remains is to add an action depending on the result returned by this function.

Какие проверки должен пройти торговый робот перед публикацией в Маркете
Какие проверки должен пройти торговый робот перед публикацией в Маркете
  • www.mql5.com
Все продукты Маркета перед публикацией проходят обязательную предварительную проверку, так как небольшая ошибка в логике советника или индикатора может привести к убыткам на торговом счете. Именно поэтому нами разработана серия базовых проверок, призванных обеспечить необходимый уровень качества продуктов Маркета. Если в процессе проверки...
 
I see that when I open it, the terminal normalises the order to the required number of decimal places.
I put a lot like this
OrderSend(Symbol(),OP_BUY,1.11111111,Ask,3,0,0);
and the trade opens with a volume of 1.11.

So maybe you don't need to normalize anything?
 
multiplicator:
I see that the terminal normalises the order to the required number of decimal places when I open it.
Maybe there is no need to normalize anything?

If the editor does the same - no need.

 
multiplicator:
I see that the terminal normalises the order to the required number of decimal places when it opens.
Maybe you don't need to normalize anything?

If you want to get error after error, do not normalise.

 
Artyom Trishkin:

If you want to subsequently get error after error, don't normalise.

for some reason the terminal does not show errors)
Reason: