Корректный выбор наибольшего значения из трех вариантов

 

Здравствуйте!

Прошу совета, - как наиболее грамотно и, соответственно, оптимально выбрать наибольшее значение из трех вариантов.

Прилагаются фрагменты кода индикатора.

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   double ma_F; // Быстрая МА
   double ma_M; // Средняя МА
   double ma_S; // Медленная МА
   double ma_V; // Наибольшая МА
//----
  int max = rates_total-draw_begin2-1;
//---- check for rates total
   if(rates_total<=draw_begin2)
     return(0);
//----
   for(int i=max; i>=0; i--) 
        {
      ma_F  = iMA(NULL,0,5,0,MODE_SMA,PRICE_MEDIAN,i);
      ma_M  = iMA(NULL,0,13,0,MODE_SMA,PRICE_MEDIAN,i);
      ma_S  = iMA(NULL,0,20,0,MODE_SMA,PRICE_MEDIAN,i);
//----      
      ma_V  = fmax(ma_F,fmax(ma_M,ma_S));
//----      
      ....// some code
      ....// some code
        }
//========================================================================================== 

 и

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   double ma_F; // Быстрая МА
   double ma_M; // Средняя МА
   double ma_S; // Медленная МА
   double ma_V; // Наибольшая МА
//----
  int max = rates_total-draw_begin2-1;
//---- check for rates total
   if(rates_total<=draw_begin2)
     return(0);
//----
   for(int i=max; i>=0; i--) 
        {
      ma_F  = iMA(NULL,0,5,0,MODE_SMA,PRICE_MEDIAN,i);
      ma_M  = iMA(NULL,0,13,0,MODE_SMA,PRICE_MEDIAN,i);
      ma_S  = iMA(NULL,0,20,0,MODE_SMA,PRICE_MEDIAN,i);
//----      
      ma_V  = ma_F || ma_M || ma_S;
//----      
      if(ma_F>=ma_M && ma_F>=ma_S){ma_V = ma_F;}
      
      if(ma_M>=ma_F && ma_M>=ma_S){ma_V = ma_M;}
      
      if(ma_S>=ma_F && ma_S>=ma_M){ma_V = ma_S;}
//----      
      ....// some code
      ....// some code
        }
//==========================================================================================

В обоих вариантах (с #property strict) индикатор работает без замечаний. Профилирование отдает предпочтение второму варианту, но выигрыш в скорости расчета - ничтожен.

Кроме того, возможно появление неоднозначности при равенстве сравниваемых переменных. И здесь второй вариант предпочтительнее.

И в то же время, мне нравится первый вариант. Но добавление условий для предотвращения неоднозначности лишит его изящества. Правда, "изящество" на хлеб не намажешь..

Друзья, прошу вашего совета- 

 
ingensi:

Здравствуйте!

Прошу совета, - как наиболее грамотно и, соответственно, оптимально выбрать наибольшее значение из трех вариантов.

Прилагаются фрагменты кода индикатора.

 и

В обоих вариантах (с #property strict) индикатор работает без замечаний. Профилирование отдает предпочтение второму варианту, но выигрыш в скорости расчета - ничтожен.

Кроме того, возможно появление неоднозначности при равенстве сравниваемых переменных. И здесь второй вариант предпочтительнее.

И в то же время, мне нравится первый вариант. Но добавление условий для предотвращения неоднозначности лишит его изящества. Правда, "изящество" на хлеб не намажешь..

Друзья, прошу вашего совета- 

ловля блох..

первый вариант легче читается - ему и предпочтение.

 
ingensi:

И в то же время, мне нравится первый вариант. Но добавление условий для предотвращения неоднозначности лишит его изящества. Правда, "изящество" на хлеб не намажешь..

Отсюда https://www.mql5.com/ru/code/15945

Математический аппарат также расширился, поиск максимального значения из нескольких теперь не выглядит как куча вложенных MathMax(MathMax(MathMax...))), а реализовано вплоть до 5 аргументов через шаблоны функций и можно вызвать:

double max;

max = MathMax(12.4, 55.432, 128e-4, 8003.44);

Исходник там такой

//=============================/ MathMax /=============================================
template<typename T>
T MathMax(T v1,T v2,T v3)
{
   return MathMax(v1, MathMax(v2, v3));
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
template<typename T>
T MathMax(T v1,T v2,T v3,T v4)
{
   return MathMax(v1, MathMax(v2, MathMax(v3,v4)));
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
template<typename T>
T MathMax(T v1,T v2,T v3,T v4,T v5)
{
   return MathMax(v1, MathMax(v2, MathMax(v3,MathMax(v4, v5))));
}
RAD - Rapid Application Development library
RAD - Rapid Application Development library
  • голосов: 8
  • 2016.07.18
  • Andrew Gomanchuk
  • www.mql5.com
Библиотека ускоренной разработки приложений.
 

Выбор максимального значения из трех требует всего два сравнения:

ma_V = ma_F;
if(ma_V < ma_M) {ma_V = ma_M;}
if(ma_V < ma_S) {ma_V = ma_S;}
 
fxsaber:

Отсюда https://www.mql5.com/ru/code/15945

Исходник там такой

Grazie. Mille. Пора бы математическому аппарату и остановиться..

Значит путь в библиотеку-

 
ingensi:
...

В обоих вариантах (с #property strict) индикатор работает без замечаний. Профилирование отдает предпочтение второму варианту, но выигрыш в скорости расчета - ничтожен.

Кроме того, возможно появление неоднозначности при равенстве сравниваемых переменных. И здесь второй вариант предпочтительнее.

И в то же время, мне нравится первый вариант. Но добавление условий для предотвращения неоднозначности лишит его изящества. Правда, "изящество" на хлеб не намажешь..

Друзья, прошу вашего совета- 

Первый вариант нравится, так как он лучше читаем.  Со временем, когда идея забудется, если обратитесь опять к коду этого индикатора, то быстрее будет вникнуть в первый, на мой вкус.

Только я вот не понимаю одного. Важное - это же не скорость расчета индикатора, а прибыль, которую можно получить, используя его. Будет прибыльная стратегия - можно и скорость подлатать. А так не получив прибыль, индикатор забросится, и не вспомнится уже о нем.

Или у вас уже есть прибыльная стратегия, и вы красоту наводите?

 
Oksana Berenko:

Первый вариант нравится, так как он лучше читаем.  Со временем, когда идея забудется, если обратитесь опять к коду этого индикатора, то быстрее будет вникнуть в первый, на мой вкус.

Только я вот не понимаю одного. Важное - это же не скорость расчета индикатора, а прибыль, которую можно получить, используя его. Будет прибыльная стратегия - можно и скорость подлатать. А так не получив прибыль, индикатор забросится, и не вспомнится уже о нем.

Или у вас уже есть прибыльная стратегия, и вы красоту наводите?

Оксана, здравствуйте!

Интерес сугубо академический. К тому же, я делаю первые шаги в азах программирования и хочу привить себе "здоровые привычки".

По совету fxsaber подключил библиотеку rad_lib.mqh, все работает. Благодарность автору. Теперь прикидываю, как сократить библиотеку, оставив только "математику".

В любом случае благодарю за вопрос, - интереснее писать об оказанной помощи, чем читать о блохах.

Если только.. интересно, Кузнецов - левша?

 
#define MACROS_MATH(A)                          \
  template<typename T>                          \
  T Math##A( T v1, T v2, T v )                  \
  {                                             \
    return Math##A(Math##A(v1, v2), v);         \
  }                                             \
                                                \
  template<typename T>                          \
  T Math##A( T v1, T v2, T v3, T v )            \
  {                                             \
    return Math##A(Math##A(v1, v2, v3), v);     \
  }                                             \
                                                \
  template<typename T>                          \
  T Math##A( T v1, T v2, T v3, T v4, T v )      \
  {                                             \
    return Math##A(Math##A(v1, v2, v3, v4), v); \
  }

MACROS_MATH(Max)
MACROS_MATH(Min)

#undef MACROS_MATH

#define PRINT(A) Print(#A + " = " + (string)A);

void OnStart( void )
{  
  PRINT(MathMax(1, 2, 3, 4, 5))
  PRINT(MathMin(1, 2, 3, 4, 5))

  return;
}
Вроде, очевидно, что макрос можно сократить, т.к. сплошные повторы. Но как - не догадался.
 
ingensi:

Оксана, здравствуйте!

Интерес сугубо академический. К тому же, я делаю первые шаги в азах программирования и хочу привить себе "здоровые привычки".

По совету fxsaber подключил библиотеку rad_lib.mqh, все работает. Благодарность автору. Теперь прикидываю, как сократить библиотеку, оставив только "математику".

В любом случае благодарю за вопрос, - интереснее писать об оказанной помощи, чем читать о блохах.

Если только.. интересно, Кузнецов - левша?

По логике, вызов библиотеки скорость расчета должен уменьшить.

Я не писала вам о блохах, о чем вы?

 
ingensi:

Оксана, здравствуйте!

Интерес сугубо академический. К тому же, я делаю первые шаги в азах программирования и хочу привить себе "здоровые привычки".

Есть такая привычка у многих программистов (я, к сожалению, не исключение) - преждевременная оптимизация. Вот о ней Оксана и говорит. Если разработка кода еще не закончена, то говорить об оптимизации нет смысла. На первом месте должна быть легкость восприятия кода. Лишь в том случае, когда после завершения разработки оказывается, что быстродействие программы не удовлетворяет каким-то критериям, начинается поиск ее "узких" мест. Не думаю, что узким местом в  приложенном коде будет вычисление максимального значения.

Отсюда вывод - первый вариант лучше второго, т. к. наиболее удобочитаем. 

 
Ihor Herasko:

Есть такая привычка у многих программистов (я, к сожалению, не исключение) - преждевременная оптимизация. Вот о ней Оксана и говорит. Если разработка кода еще не закончена, то говорить об оптимизации нет смысла. На первом месте должна быть легкость восприятия кода. Лишь в том случае, когда после завершения разработки оказывается, что быстродействие программы не удовлетворяет каким-то критериям, начинается поиск ее "узких" мест. Не думаю, что узким местом в  приложенном коде будет вычисление максимального значения.

Отсюда вывод - первый вариант лучше второго, т. к. наиболее удобочитаем. 

Игорь, я согласен и с Вами, и с Оксаной. Но я действительно был уверен, что выбор максимального значения - "узкое место". Именно, что был..

В "Золотом теленке" профессор географии сошел с ума, не найдя на карте Берингова пролива, из-за опечатки в типографии.

Вопрос, возможна ли "опечатка" в коде терминала, из-за которой iMAOnArray возвращает значение технического индикатора Moving Average, рассчитанного с методом усреднения MODE_LWMA, с колоссальной ошибкой?

Еще в благословенном 2006 году уважаемый  Forex Trader обращался к разработчикам с подобной проблемой: https://www.mql5.com/ru/forum/54641

Это ж сколько "билдов" утекло? ... и что делать? Подключать MovingAverages.mqh?

А может у меня только на MODE_LWMA все и держится, а может - это правда?

Ошибка в расчете стандартной функции LWMA в МТ4
Ошибка в расчете стандартной функции LWMA в МТ4
  • www.mql5.com
Форум трейдеров MQL5.community
Причина обращения: