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

 

A fim de reduzir o número de excessos de optimização, utilizo dois métodos para criar uma escala não linear.

Enumerar a duração em horas com precisão suficiente:

enum eHours { _0, _4, _6, _8, _12, _16, _24, _32, _48, _64, _96, _128 };

input eHours TrendHours = _8;

int
eHours2Hours(eHours e) {
	switch (e) {
	case _0:	return 0;
	case _4:	return 4;
	case _6:	return 6;
	case _8:	return 8;
	case _12:	return 12;
	case _16:	return 16;
	case _24:	return 24;
	case _32:	return 32;
	case _48:	return 48;
	case _64:	return 64;
	case _96:	return 96;
	case _128:	return 128;
	default:	return -1;
	}
}

Para enumerar, por exemplo, a etapa SAR com 2 dígitos de precisão (~1%):

// Приводит параметр оптимизации к нелинейному виду
// 001-099 >> 0.0001-0.0099
// 101-199 >> 0.001-0.099
// 201-299 >> 0.10-0.99
// Внимание: коды 000, 100, 200 возвращают 0.0
double
NonlinPar(int code) {
        int order = code / 100;
        int mod = code - order * 100;
        return mod * MathPow(10, order) / 10000;
}

Uma optimização de 0,0001 a 0,99 exigiria quase 10K passos. A utilização dos códigos 001-299 na optimização exigiria menos de 300 passos.

 
Uma forma de correr para a divisão por zero mesmo com um cheque.
void OnStart()
{  
  const double Profit = 100;
  const double Lots = 1;

  double TickValue[];  
  ArrayResize(TickValue, 1);
  
  const double Points = TickValue[0] ? Profit / (Lots * TickValue[0] * _Point) : 0; // zero divide    
}


O erro é, de facto, claro. Mas enquanto se escreve um código como este, nem sempre é óbvio que tal verificação não é suficiente para evitar a divisão por zero.

 
Uma desculpa para não utilizar o operador ternário.
 
TheXpert:
Uma desculpa para não utilizar o operador ternário.

Pois se semelhante, é claro.

 

Só não espere que, se não houver valor, seja necessariamente 0 e portanto falso se não for uma variável do tipo bool. Mesmo uma conversão explícita em tipo bool não a salvará.

void OnStart()
{  
  const double Profit = 100;
  const double Lots = 1;

  double TickValue[];  
  ArrayResize(TickValue, 1);
  
  const double Points = TickValue[0] == 0? Profit / (Lots * TickValue[0] * _Point) : 0;   
}

Funciona desta forma sem erros.

 

Fórum sobre comércio, sistemas automatizados de comércio e teste de estratégias comerciais

Peculiaridades de mql5, dicas e truques

Alexey Viktorov, 2019.10.28 10:22

Só não se espera que se não houver valor, este seja necessariamente 0 e, portanto, é falso se não for uma variável do tipo bool. Mesmo a conversão explícita em tipo bool não poupará.

void OnStart()
{  
  const double Profit = 100;
  const double Lots = 1;

  double TickValue[];  
  ArrayResize(TickValue, 1);
  
  const double Points = TickValue[0] == 0? Profit / (Lots * TickValue[0] * _Point) : 0;   
}

Funciona desta forma sem erros.

Há um erro no local assinalado.
 
fxsaber:
Há um erro no local assinalado.

Não consigo ver o destaque. O que é o erro?

 
fxsaber:
Há um erro no local assinalado.

Escreveu "==", deveria ser "!=".

Está sublinhado "muito amarelo pálido" :)

 
Artyom Trishkin:

Escreveu "==", deveria ser "!=".

Está sublinhado "muito amarelo pálido" :)

Bem, nem todos sabem que sou como aquele macaco, "sou fraco aos olhos quando sou velho".

Acho que sim, mas por alguma razão funcionou sem divisão por 0. E em geral, a minha mensagem era que não devíamos verificar nenhuma variável para 0 como um booleano para falso.

 
Alexey Viktorov:

Acho que sim, mas por alguma razão funcionou sem divisão por 0.

Porque o TickValue não é zero.