Особенности языка mql5, тонкости и приёмы работы - страница 232

 

Explanation of the definition of DBL_EPSILON:

void OnStart()
  {
   double epsilon = 1.0;
   while(1.0 + epsilon != 1.0)
      epsilon /= 2;
   epsilon *= 2;

   Print(epsilon);  // 2.220446049250313e-16
  }
 
fxsaber # :

This is a bad explanation, because

This is a proof that the standard mathematical properties are not guaranteed for doubles.

The example you provided uses the "distributive" property for multiplication.
 

Another way to explain the meaning of DBL_EPSILON:

//+------------------------------------------------------------------+
//| Returns the size of a unit in the last place (machine epsilon)   |
//| for a specified double value. This is the positive distance      |
//| between this double value and the representable value next       |
//| larger in magnitude.                                             |
//+------------------------------------------------------------------+
double machine_eps(const double value)
  {
   union _d {double value; long bits;} dbl;
   dbl.value = value;
   dbl.bits++;

   return dbl.value - value;
  }

void  OnStart()
  {
   double epsilon = machine_eps(1.0);

   Print(epsilon);   // 2.220446049250313e-16
  }

DBL_EPSILON is just the gap size between consecutive doubles in [1,2).

https://www.exploringbinary.com/the-spacing-of-binary-floating-point-numbers/

https://en.wikipedia.org/wiki/Machine_epsilon

 

To better understand DBL_EPSILON, consider incrementing a floating-point counter:

//+------------------------------------------------------------------+
//| Advances a fp double value by a specified number of epsilons.    |
//+------------------------------------------------------------------+
double DoubleAdvance(const double value, const long distance)
  {
   union _d {double value; long bits;} dbl;
   dbl.value = value;
   dbl.bits += distance;

   return dbl.value;
  }

void OnStart()
  {
   double myvalue = 1.0;
   //doubel myvalue = 1024.0;

   // Print the first 10 representable numbers from the counter
   for (int i = 0; i < 10; i++)
     {
      myvalue = DoubleAdvance(myvalue, 1);  // Increment the integer representation by 1 bit
      Print(myvalue);
     }
  }

 if the initial value of the counter is 1.0, the step size (epsilon) of the counter will be 2.220446049250313e-16 (DBL_EPSILON) ≈ 2 at the 16th decimal place.

/*
1.0000000000000002
1.0000000000000004
1.0000000000000007
1.0000000000000009
1.000000000000001
1.0000000000000013
1.0000000000000016
1.0000000000000018
1.000000000000002
1.0000000000000022
*/

If the initial value of the counter is 1024, the step size (epsilon) of the counter will be 2.273736754432321e-13 (1024 * DBL_EPSILON)  ≈ 2 at the 13th decimal place.

/*
1024.0000000000002
1024.0000000000005
1024.0000000000007
1024.000000000001
1024.0000000000011
1024.0000000000014
1024.0000000000016
1024.0000000000018
1024.000000000002
1024.0000000000023
*/

If the initial value of the counter is 4503599627370496 (2^52), the step size of the counter will be 1.0 (2^52 * DBL_EPSILON) = 1. At this range, a double behaves like an integer counter, no fractions could be representable.

/*
 4503599627370497.0
 4503599627370498.0
 4503599627370499.0
 4503599627370500.0
 4503599627370501.0
 4503599627370502.0
 4503599627370503.0
 4503599627370504.0
 4503599627370505.0
 4503599627370506.0
*/

You can see that the smaller numbers have smaller gaps between them, and the larger numbers have larger gaps between them.

Therefore, DBL_EPSILON is the relative error rate. relative means relative to the magnitude of the number.

at 1.0, the absolute error = 1 * 2.2204460492503131e-016 (DBL_EPSILON)

at d, the absolute error ≈ d * DBL_EPSILON.

(DBL_EPSILON is a reference rate at 1.0, something like the bank's annual interest rate, and it is equal to 2^-52).


A side-note: if you try to print 1024.0000000000003, it will print 1024.0000000000002 instead (rounding to the nearest representable number), because 1024.0000000000003 is not a representable number (non-existing fp number).

This is called a representation error:

void OnStart()
  {
   Print(1024.0000000000003);  // 1024.0000000000002
  }

The previous/next representable numbers are reached at through bit manipulation (enum as before: DoubleAdvance(value, -1)) or by using DBL_EPSILON:

void OnStart()
  {
   double myvalue = 1024.0000000000014;
   Print( myvalue * (1 - DBL_EPSILON) );  // 1024.0000000000011
   Print( myvalue * (1 + DBL_EPSILON) );  // 1024.0000000000016
  }

DBL_EPSILON is mainly used to estimate (or correct) fp round-off errors after mathematical operations on doubles (numerical analysis):

|true result - fp result| / true result <= DBL_EPSILON

 

Отключается ли в MT5-тестере при генетическом алгоритме оптимизации и НЕ пользовательском критерии оптимизации вызов OnTester()?

Мне кажется - нет. А хотелось бы... Желательно без парсинга конфигов.

PS. КАРАУЛ!!! Всё пропало! При каждом проходе оптимизации (надо/не надо) - вызывается OnTester(), что может сильно увеличивать общее время оптимизации!

Поможите кто чем может...   )))))

 
Подскажите, пожалуйста, как определить IP_ADAPTER_INFO ? Это определение значения не является правильным
struct IP_ADAPTER_INFO {
// struct _IP_ADAPTER_INFO *Next; // Информация о следующей сетевой карте.
uint ComboIndex; // Индекс комбо & nbsp;
uchar AdapterName[256]; // Имя сетевой карты
uchar Description[256]; // Описание сетевой карты.
uchar Address[6]; // MAC-адрес &nbsp uchar Address[6]; // MAC-адрес.
uint AddressLength; // Длина MAC-адреса
uint Index; // индекс сетевой карты
uint Type; // Тип сетевой карты NIC Type; // Тип сетевой карты
bool DhcpEnabled; // Включен ли DHCP или нет. nbsp;; DhcpEnabled
uchar CurrentIpAddress[16];// текущий IP-адрес
uchar IpAddressList[16]; // Список IP-адресов.
uchar GatewayList[16]; // Шлюз по умолчанию
uchar DhcpServer[16]; // Сервер DHCP
datetime LeaseObtained; // Получение времени аренды
datetime LeaseExpires; // Время истечения срока аренды
}; datetime LeaseObtained; // Аренда получена.

#import "iphlpapi.dll"
int GetAdaptersInfo(IP_ADAPTER_INFO &AdapterInfo[], int &Size);
#import
 
Перевод немного вперед локального времени сразу приводит к разрыву соединения с торговым сервером.
2023.05.24 11:11:15.645 '4999464569': connection to MetaQuotes-Demo lost
 

в поиске наткнулся на интересную недокументированную функцию

можно скрыть input комментарий для диалогового окна

input int  param=0;  /* показываемый комментарий */   // комментарий для программиста

оригинальный пост тут

https://www.mql5.com/ru/forum/1271#comment_9019

Предложение по комментариям к внешним переменным
Предложение по комментариям к внешним переменным
  • 2010.06.30
  • www.mql5.com
Общее обсуждение: Предложение по комментариям к внешним переменным
 
lynxntech #:

в поиске наткнулся на интересную недокументированную функцию

можно скрыть input комментарий для диалогового окна

оригинальный пост тут

https://www.mql5.com/ru/forum/1271#comment_9019

Спасибо, пропустил... Полезно. 
 

В Тестере в History-таблицу идет дозапись только в двух случаях.

  1. Вызов HistorySelect.
  2. Вызов OnTrade (даже если не прописан).
Сделано это для экономии ресурсов. Поэтому можно нарваться на такую неоднозначность.

#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006

#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

void OnTick()
{
  const ulong Ticket1 = OrderSend(_Symbol, OP_BUYLIMIT, 1, Ask - 1000 * _Point, 0, 0, 0);
  const ulong Ticket2 = OrderSend(_Symbol, OP_BUYLIMIT, 1, Ask - 1000 * _Point, 0, 0, 0);

  OrderDelete(Ticket2);
  HistorySelect(0, INT_MAX); // Если убрать эту строку, то конечный Print-результат будет иным.
  
  OrderDelete(Ticket1);    
  HistorySelect(0, INT_MAX);
  
  for (int i = 0; i < HistoryOrdersTotal(); i++)
    Print(HistoryOrderGetTicket(i)); // 2 3 или 3 2.
      
  TesterStop();
}
Строка для поиска: Uluchshenie 064.
Причина обращения: