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

 

Для уменьшения количества переборов параметров оптимизации применяю два приёма создания нелинейной шкалы.

Для перебора длительности в часах с достаточной точностью:

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

Для перебора, например, шага SAR с точностью 2 цифры (~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;
}

При оптимизации от 0.0001 до 0.99 требовалось бы почти 10К шагов. При использовании в оптимизации кодов 001-299 требуется меньше 300 шагов.

 
Способ нарваться на деление на ноль даже с проверкой.
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    
}


Ошибка понятна по факту. Но во время написания подобного кода не всегда очевидно, что такой проверки не достаточно, чтобы избежать деления на ноль.

 
Повод не пользоваться тернарным оператором.
 
TheXpert:
Повод не пользоваться тернарным оператором.

Для if аналогично, конечно.

 

Просто не надо надеяться, что если отсутствует значение, то это обязательно 0 и соответственно false если это переменная не типа bool. Даже явное приведение к типу bool не спасёт.

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

Так работает без ошибок.

 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

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

Alexey Viktorov, 2019.10.28 10:22

Просто не надо надеяться, что если отсутствует значение, то это обязательно 0 и соответственно false если это переменная не типа bool. Даже явное приведение к типу bool не спасёт.

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

Так работает без ошибок.

В выделенном месте ошибка.
 
fxsaber:
В выделенном месте ошибка.

Не вижу выделенного места. В чём ошибка?

 
fxsaber:
В выделенном месте ошибка.

Ты написал "==", а должно быть "!="

Там выделено "очень-бледно-жёлтым" :)

 
Artyom Trishkin:

Ты написал "==", а должно быть "!="

Там выделено "очень-бледно-жёлтым" :)

Ну ведь не все знают что я как та мартышка "К старости слаба глазами стала".

Наверное да, но почему-то такой вариант прокатил без деления на 0. А в общем, мой посыл был о том, что не надо проверять на 0 любую переменную как булеву на false.

 
Alexey Viktorov:

Наверное да, но почему-то такой вариант прокатил без деления на 0.

Потому что TickValue не ноль.

Причина обращения: