Características da linguagem mql5, subtilezas e técnicas - página 232

 

Explicação da definição de DBL_EPSILON:

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

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

Essa é uma explicação ruim, porque

Essa é uma prova de que as propriedades matemáticas padrão não são garantidas para duplas.

O exemplo que você forneceu usa a propriedade "distributiva" para a multiplicação.
 

Outra maneira de explicar o significado de 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 é apenas o tamanho do intervalo entre duplas consecutivas em [1,2).

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

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

 

Para entender melhor o DBL_EPSILON, considere o incremento de um contador de ponto flutuante:

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

Se o valor inicial do contador for 1,0, o tamanho da etapa (epsilon) do contador será 2,220446049250250313e-16 (DBL_EPSILON) ≈ 2 na 16ª casa decimal.

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

Se o valor inicial do contador for 1024, o tamanho da etapa (epsilon) do contador será 2,2737363675443232321e-13 (1024 * DBL_EPSILON) ≈ 2 na 13ª casa dec imal.

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

Se o valor inicial do contador for 4503599627370496 (2^52), o tamanho da etapa do contador será 1,0 (2^52 * DBL_EPSILON)= 1. Nesse intervalo, um double se comporta como um contador inteiro, nenhuma fração pode ser representada.

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

Você pode ver que os números menores têm intervalos menores entre eles, e os números maiores têm intervalos maiores entre eles.

Portanto, DBL_EPSILON é a taxa de erro relativa. relativo significa relativo à magnitude do número.

Em 1,0, o erro absoluto = 1 * 2,2204460492503131e-016 (DBL_EPSILON).

em d, o erro absoluto ≈ d * DBL_EPSILON.

(DBL_EPSILON é uma taxa de referência em 1,0, algo como a taxa de juros anual do banco, e é igual a 2^-52).


Uma observação: se você tentar imprimir 1024.0000000000003, ele imprimirá 1024.0000000000002 (arredondando para o número representável mais próximo), pois 1024.0000000000003 não é um número representável (número fp inexistente).

Isso é chamado de erro de representação:

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

Os números representáveis anteriores/seguintes são alcançados por meio da manipulação de bits (enum como antes: DoubleAdvance(value, -1)) ou usando DBL_EPSILON:

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

O DBL_EPSILON é usado principalmente para estimar (ou corrigir) erros de arredondamento fp após operações matemáticas em duplas (análise numérica):

|resultado verdadeiro - resultado fp| / resultado verdadeiro <= DBL_EPSILON

 

A chamada OnTester() é desativada no testador do MT5 quando há um algoritmo de otimização genética e NÃO um critério de otimização personalizado?

Acho que não. Mas eu gostaria de fazê-lo... De preferência, sem análise de configuração.

PS. CARAUL!!! Tudo se foi! Em cada passagem de otimização (deveria/não deveria) - OnTester() é chamado, o que pode aumentar muito o tempo total de otimização!

Quem puder ajudar... )))))

 
Você pode me dizer como definir IP_ADAPTER_INFO ? Esta é a definição do valor que não está correta
struct IP_ADAPTER_INFO {
// struct _IP_ADAPTER_INFO *Next; // Informações da próxima NIC.
uint ComboIndex; // Índice do combo & nbsp;
uchar AdapterName[256]; // Nome da NIC
uchar Description[256]; // Descrição da NIC.
uchar Address[6]; // Endereço MAC &nbsp uchar Address[6]; // Endereço MAC.
uint AddressLength; // Comprimento do endereço MAC
uint Index; // Índice da NIC
uint Type; // Tipo de NIC NIC Type; // Tipo de NIC
bool DhcpEnabled; // Se o DHCP está ativado ou não. nbsp;; DhcpEnabled
uchar CurrentIpAddress[16];// endereço IP atual
uchar IpAddressList[16]; // Lista de endereços IP.
uchar GatewayList[16]; // Gateway padrão
uchar DhcpServer[16]; // Servidor DHCP
datetime LeaseObtained; // Obter tempo de concessão
datetime LeaseExpires; // Tempo de expiração do leasing
}; datetime LeaseObtained; // Obteve o arrendamento.

#importar "iphlpapi.dll"
int GetAdaptersInfo(IP_ADAPTER_INFO &AdapterInfo[], int &Size);
#importar
 
O fato de se adiantar um pouco em relação ao horário local leva imediatamente à desconexão do servidor de negociação.
2023.05.24 11:11:15.645 '4999464569': connection to MetaQuotes-Demo lost
 

Em minha pesquisa, deparei-me com uma função interessante não documentada

você pode ocultar o comentário de entrada de uma caixa de diálogo

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

Postagem original aqui

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

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

Em minha pesquisa, encontrei uma função não documentada interessante

você pode ocultar o comentário de entrada de uma caixa de diálogo

postagem original aqui

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

Obrigado, não vi... Útil.
 

No Tester, a tabela de histórico é substituída somente em dois casos.

  1. Chamada de HistorySelect.
  2. Chamada de OnTrade (mesmo que não seja especificado).
Isso é feito para economizar recursos. É por isso que você pode se deparar com essa ambiguidade.

#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();
}
Cadeia depesquisa: Uluchshenie 064.