Caratteristiche del linguaggio mql5, sottigliezze e tecniche - pagina 142

 

Per ridurre il numero di overshoots di ottimizzazione, uso due metodi per creare una scala non lineare.

Enumerare la durata in ore con sufficiente precisione:

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

Per enumerare, per esempio, il passo SAR con una precisione di 2 cifre (~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;
}

L'ottimizzazione da 0,0001 a 0,99 richiederebbe quasi 10K passi. L'utilizzo dei codici 001-299 nell'ottimizzazione richiederebbe meno di 300 passi.

 
Un modo per incorrere nella divisione per zero anche con un controllo.
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    
}


L'errore è chiaro nei fatti. Ma mentre si scrive codice come questo, non è sempre ovvio che un tale controllo non è sufficiente per evitare la divisione per zero.

 
Una scusa per non usare l'operatore ternario.
 
TheXpert:
Una scusa per non usare l'operatore ternario.

Per se simile, naturalmente.

 

Basta non aspettarsi che se non c'è un valore, è necessariamente 0 e quindi falso se non è una variabile di tipo bool. Anche una conversione esplicita al tipo bool non lo salverà.

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

Funziona così senza errori.

 

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Peculiarità di mql5, consigli e trucchi

Alexey Viktorov, 2019.10.28 10:22

Semplicemente non vi aspettate che se non c'è un valore, è necessariamente 0 e quindi è falso se non è una variabile di tipo bool. Anche la conversione esplicita al tipo bool non salverà.

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

Funziona così senza errori.

C'è un errore nel posto evidenziato.
 
fxsaber:
C'è un errore nel posto evidenziato.

Non riesco a vedere il punto culminante. Qual è l'errore?

 
fxsaber:
C'è un errore nel posto evidenziato.

Hai scritto "==", dovrebbe essere "!=".

È sottolineato "giallo molto pallido" :)

 
Artyom Trishkin:

Hai scritto "==", dovrebbe essere "!="

È sottolineato "giallo molto pallido" :)

Beh, non tutti sanno che sono come quella scimmia: "Sono debole negli occhi quando sono vecchio".

Credo di sì, ma per qualche ragione ha funzionato senza divisione per 0. E in generale, il mio messaggio era che non dovremmo controllare qualsiasi variabile per 0 come un booleano per false.

 
Alexey Viktorov:

Credo di sì, ma per qualche motivo ha funzionato senza divisione per 0.

Perché TickValue non è zero.

Motivazione: