Функция ArrayMinimum()

 
В хелпе встретил об этой функции следующее:

int ArrayMinimum( double array[], int count=WHOLE_ARRAY, int start=0)

Searches for the element with minimum value. The function returns position of this minimum element in the array.

Parameters:

array[] - The numeric array to search in.
count - The amount of elements to search in.
start - Initial search index.

Sample:

double num_array[15]={4,1,6,3,9,4,1,6,3,9,4,1,6,3,9};
double minValueidx=ArrayMinimum(num_array);
Print("Min value = ", num_array[minValueIdx]);


Пример, мягко говоря, некорректен, так как найденный номер элемента в массиве нехорошо объявлять как double. Но мой вопрос сейчас не об этом.

Я попытался воспользоваться этой функцией, применив ее к созданному специально для этого массиву в индикаторе (не стандартному типа Open[], Close[] и пр.). Вот кусок кода для поиска минимума на отрезке:

double Min(int BarNrFrom, int BarsTotal)
{
  return (PRICE_SERIES[ArrayMinimum(PRICE_SERIES, BarsTotal, BarNrFrom)]);
}
Здесь PRICE_SERIES[] - массив цен (типичных) на текущем чарте.

Я предполагаю, что поиск идет вглубь истории и заканчивается на баре с номером BarNrFrom + BarsTotal - 1.

Не могу понять, почему этот кусок кода не работает. Попытка заменить эту функцию непосредственным вычислением минимума (через сравнение) слишком плохо кончается: терминал зависает на неопределенное время.
 
Массив многомерный?
 
Integer wrote:
Массив многомерный?
Одномерный. Это просто массив цен (High+Low+Close)/3 (PRICE_TYPICAL).

На самом деле я хочу сварганить индикатор FRAMA (Fractal Adaptive Moving Average от Эйлерса). А там для вычисления фрактальной размерности требуется знать макс. и мин. цены по бегущему окну массива цен. Ничего короче указанного выше кода я не нашел.
 

давай формулы попробую сделать

 

Спасибо, Integer. Ну я попробую еще повозиться, нравится мне самому все делать :))). Этот код, слава Богу, на самом деле работает, но считается он почему-то не оттуда, откуда хотелось бы. Вот я и хочу это выяснить. Получится - обязательно выложу в Code Base. Не получится - попрошу у тебя помощи.

Если тебе интересно, формулы вот здесь: http://stocktrade.narod.ru/indicators/FRAMA.pdf

В сети готового кода FRAMA для МТ4 я не нашел. На виаке была дискуссия, но там было в-основном обсуждение адаптивной средней Кауфмана (и только для МТ3), а это нечто другое.

 
double Min(double massiv[], int period, int BarStart)
{
int pos;
pos=ArrayMinimum(massiv[], period, BarStart);
return(massiv[pos]);
}
Попробуйте так, должно работать, возвращать минимальное значение из массива, начиная с индекса BarStart на period баров вглубь.

ЗЫ Статью прочитал
 

Спасибо, Rosh, попробуем.

 
Rosh:
double Min(double massiv[], int period, int BarStart)
{
int pos;
pos=ArrayMinimum(massiv[], period, BarStart);
return(massiv[pos]);
}
Попробуйте так, должно работать, возвращать минимальное значение из массива, начиная с индекса BarStart на period баров вглубь.

Интересно, а так сработает? Сам не проверял.
double Min(double Arr[], int PD, int BS)
  { return(Arr[ArrayMinimum(Arr[],PD,BS)]); }
Вроде то же самое написано. :)
 
Вот FRAMA

//+------------------------------------------------------------------+
//|                                                        FRAMA.mq4 |
//|                                                             Rosh |
//|                                    'Функция ArrayMinimum()' |
//+------------------------------------------------------------------+
#property copyright "Rosh"
#property link      "'Функция ArrayMinimum()'"
 
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 DarkBlue
//---- input parameters
extern int       PeriodFRAMA=10;
extern int       PriceType=0;
//PRICE_CLOSE 0 Цена закрытия 
//PRICE_OPEN 1 Цена открытия 
//PRICE_HIGH 2 Максимальная цена 
//PRICE_LOW 3 Минимальная цена 
//PRICE_MEDIAN 4 Средняя цена, (high+low)/2 
//PRICE_TYPICAL 5 Типичная цена, (high+low+close)/3 
//PRICE_WEIGHTED 6 Взвешенная цена закрытия, (high+low+close+close)/4 
 
//---- buffers
double ExtMapBuffer1[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexEmptyValue(0,0.0);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| возвращает цену                                                  |
//+------------------------------------------------------------------+
double Price(int shift)
  {
//----
   double res;
//----
   switch (PriceType)
      {
      case PRICE_OPEN: res=Open[shift]; break;
      case PRICE_HIGH: res=High[shift]; break;
      case PRICE_LOW: res=Low[shift]; break;
      case PRICE_MEDIAN: res=(High[shift]+Low[shift])/2.0; break;
      case PRICE_TYPICAL: res=(High[shift]+Low[shift]+Close[shift])/3.0; break;
      case PRICE_WEIGHTED: res=(High[shift]+Low[shift]+2*Close[shift])/4.0; break;
      default: res=Close[shift];break;
      }
   return(res);
  }
 
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   double Hi1,Lo1,Hi2,Lo2,Hi3,Lo3;   
   double N1,N2,N3,D;
   double ALFA;
   int limit;
   int    counted_bars=IndicatorCounted();
   if (counted_bars==0) limit=Bars-2*PeriodFRAMA;
   if (counted_bars>0) limit=Bars-counted_bars;
   limit--;
      
//----
   for (int i=limit;i>=0;i--)
      {
      Hi1=High[iHighest(Symbol(),0,MODE_HIGH,PeriodFRAMA,i)];
      Lo1=Low[iLowest(Symbol(),0,MODE_LOW,PeriodFRAMA,i)];
      Hi2=High[iHighest(Symbol(),0,MODE_HIGH,PeriodFRAMA,i+PeriodFRAMA)];
      Lo2=Low[iLowest(Symbol(),0,MODE_LOW,PeriodFRAMA,i+PeriodFRAMA)];
      Hi3=High[iHighest(Symbol(),0,MODE_HIGH,2*PeriodFRAMA,i)];
      Lo3=Low[iLowest(Symbol(),0,MODE_LOW,2*PeriodFRAMA,i)];
      N1=(Hi1-Lo1)/PeriodFRAMA;
      N2=(Hi2-Lo2)/PeriodFRAMA;
      N3=(Hi3-Lo3)/(2.0*PeriodFRAMA);
      D=(MathLog(N1+N2)-MathLog(N3))/MathLog(2.0);
      ALFA=MathExp(-4.6*(D-1.0));
      ExtMapBuffer1[i]=ALFA*Price(i)+(1-ALFA)*ExtMapBuffer1[i+1];
      //Print("i=",i,"  alfa=",ALFA,"  d=",D," N1=",N1," N2=",N2," N3=",N3);
      }
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
Ух ты, не ожидал так быстро, Rosh. И, главное, - без применения ArrayMaximum() и пр. Спасибо, я на него посмотрю внимательно...

P.S. А Вы его выложите в Code Base - легче искать будет. Там уже есть Кауфман, кстати...

P.P.S. Вот и думаю теперь, правильно ли я понял идею в статье.

В Вашем коде экспоненциальный мувинг считается по Applied Price, выбранной как внешний параметр индикатора, а собственно фрактальная размерность (и соответственно Alpha) - по экстремумам ценовых баров (хаям и лоу). Я представлял себе вычисление этой размерности по экстремумам той же Applied Price - потому и применял ArrayMaximum() и ArrayMinimum(). Очевидно, экстремум Typical Price все же отличается от экстремума Hi...

Наверно, это вопрос вкуса. Очень вероятно, что именно Ваш подход правильнее.
 
А меня на http://stocktrade.narod.ru гораздо больше заинтересовали статьи о циклах... Вообще очень интересный сайт.
Причина обращения: