Работаю со скользящими средними(MA) в количестве 2000 шт. Задача, подсчитать количества повторений цены МА на Close[1], при минимальных затрат ресурсов.

 
Здравствуйте, работаю со скользящими средними(MA) в количестве 2000 шт.

Задача, подсчитать количества повторений цены МА на Close[1]. В заданном диапазоне.

- Каким образом можно реализовать, данную задачу, при минимальных затрат ресурсов. 

 
Какие мувинги используете? Если речь идет о SMA то решение практически есть
 
Vinin:
Какие мувинги используете? Если речь идет о SMA то решение практически есть

Индикатор Moving Averege 

Simple

HP/2 

 
Top2n:

Индикатор Moving Averege 

Simple

HP/2 

 

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

//+------------------------------------------------------------------+
//|                                                         SSMA.mq4 |
//|                                            Copyright 2014, Vinin |
//|                                             http://vinin.ucoz.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, Vinin"
#property link      "http://vinin.ucoz.ru"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot average
#property indicator_label1  "average"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input int      CountMA=2000;
input int      Period_start=5;
input int      Period_shift=3;
//--- indicator buffers
double         averageBuffer[];
double         maxBuffer[];
double         minBuffer[];
double         Label1Buffer[];

double tmparray[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,averageBuffer);
//--- setting a code from the Wingdings charset as the property of PLOT_ARROW
   PlotIndexSetInteger(0,PLOT_ARROW,159);
   
   ArrayResize(tmparray, CountMA);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
   if (rates_total<Period_start+Period_shift*CountMA+1) return(0);
   ArrayInitialize(tmparray,0);
   
   int limit=rates_total-prev_calculated;
   if (limit>1) limit=rates_total-(Period_start+Period_shift*CountMA+1);
   
   double min=999999,max=-99999, sum=0;
   int count, countMA;
   
   for (int i=limit;i>=0;i--)
   {
      sum=0;
      count=0;
      countMA=0;
      
      // формируем массив со значенияи машек
      for (int j=0;j<Period_start+Period_shift*CountMA;j++)
      {
         sum+=Close[i+j];
         count++;
         if (count==Period_start+Period_shift*countMA)
         {
            tmparray[countMA]=sum/count);
            countMA++;
         }
      }
      // Массив создан. МОжно обрабатывать
      
   
   }
   
   
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
Vinin:

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

 

 Пытаюсь разобраться в коде, при активации на графике фиксирует ошибку. 

 

 if (count==Period_start+Period_shift*countMA)
         {
            tmparray[countMA]=sum/count; // В ЭТОМ ПОЛЕ
            countMA++;
         }
 
Top2n:

 Пытаюсь разобраться в коде, при активации на графике фиксирует ошибку. 

 

Какая ошибка (я не проверял)

 

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

Надо в init изменить строку    ArrayResize(tmparray, CountMA); на строку    ArrayResize(tmparray, CountMA+1);

Подумаю почему так происходит. 

 
Спасибо За помощь.
for (int j=0;j<Period_start+Period_shift*CountMA;j++)
      {
         sum+= Close[i+j]; //(High[i+j]+Low[i+j])/2;//    - SMA c параметрами Median Price = (highi + lowi)/2  куда вставить?
         count++;
         if (count==Period_start+Period_shift*countMA)
         {
            tmparray[countMA]=sum/count;                  - Что за параметр?
            countMA++;
         }
      }
      // Массив создан. МОжно обрабатывать
      
   
   }
   
 Print("tmparray",tmparray[1]);   
   
//--- return value of prev_calculated for next call
   return(rates_total);
 
for (int j=0;j<Period_start+Period_shift*CountMA;j++)
      {
         sum+= (High[i+j]+Low[i+j])*0.5;
         count++;
         if (count==Period_start+Period_shift*countMA)
         {
            tmparray[countMA]=sum/count;                  //текущее рассчитанное значение мувинга
            countMA++;
         }
      }
      // Массив создан. МОжно обрабатывать
      
   
   }
   
 Print("tmparray",tmparray[1]);   
   
//--- return value of prev_calculated for next call
   return(rates_total);
 
Vinin:

Прикольно!) Интересно получается.

У меня вообще Задача:

- определить значение цен SMA по всему графику

- определить уплотнения на истории?

 

Теперь думаю как лучше определить область скоплений  SMA.

- Перебираем массив (tmparray[]).

- округлить значение цены(условно). До десятитысячной(в зависимости от контрольного параметра): 1.13658 -> 1.1365

- Далее проверяем количество совпадений, между ценами.

Думаю так проще всего. Только вот еще не разобрался как путешествовать по истории. Хотя если прикрепить индикатор к советнику, и перебрать его там через iCustom, то решаемо, правда вопрос только в потребляемости ресурсов.

 
Vinin:


//+------------------------------------------------------------------+
//|                                                         SSMA.mq4 |
//|                                            Copyright 2014, Vinin |
//|                                             http://vinin.ucoz.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, Vinin"
#property link      "http://vinin.ucoz.ru"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 8
#property indicator_plots   1
//--- plot average
#property indicator_label1  "average"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
extern int      CountMA=200;
extern int      Period_start =1;
extern int      Period_shift =5;
//--- indicator buffers
double         averageBuffer[];
double         maxBuffer[];
double         minBuffer[];
double         Label1Buffer[];
double         scBuf[][2];

double tmparray[],tmparrayF1[];
//double tmparrayD[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
  // массив tmparrayF1[] является индикаторным буфером
   SetIndexBuffer(0,tmparrayF1);
   PlotIndexSetInteger(0,PLOT_ARROW,159);
   
   ArrayResize(tmparray, CountMA+1);  // массив для рассчитанных SMA 
   ArrayResize(scBuf, CountMA+1);     // массив для значений повторений на цене  
   ArrayResize(tmparrayF1, CountMA+1); // массив для перевода в одномерный массив для отображения на графике

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
   if (rates_total<Period_start+Period_shift*CountMA+1) return(0);
   ArrayInitialize(tmparray,0);
   ArrayInitialize(scBuf,0);
   
   int limit=rates_total-prev_calculated;
   if (limit>1) limit=rates_total-(Period_start+Period_shift*CountMA+1);
   
   double min=-99999,max=99999, sum=0;
   int count, countMA,schet;
   
   for (int i=limit;i>=0;i--)
   {
      sum=0;
      count=0;
      countMA=0;
      // формируем массив со значения машек
      for (int j=0;j<Period_start+Period_shift*CountMA;j++)
      {
         sum+=(High[i+j]+Low[i+j])*0.5;
         count++;
         if (count==Period_start+Period_shift*countMA)
         {
            tmparray[countMA]=sum/count;
            countMA++;
         }          
      }    
      // Массив создан. Можно обрабатывать
   }
 //***** Рассчитать количество повторений SMA, в десятичном интервале.
   for (int b=0;b<CountMA;b++)
   {
     schet=0;
     for (int a =CountMA;a>=0;a--) 
     {
       if(NormalizeDouble(tmparray[a],4)==NormalizeDouble(tmparray[b],4)&&tmparray[a]!=0) // 1.30000 = 1.30004
       {
         scBuf[b][0]=schet;                       // количество повторений МА
         scBuf[b][1]=tmparray[b];                 // Цена
         tmparray[a]=0;                           // Обнуляем посчитанную ячейку
         schet++;
       }
     } 
   }
   
   ArraySort(scBuf,WHOLE_ARRAY,0,MODE_DESCEND);   // Сортируем массив по убыванию
  
   for (int x=0;x<CountMA;x++) 
   {
     tmparrayF1[x]=scBuf[x][1];           //переносим значения цены в одномерный массив, для отображения через индикатор
   }  
     
      
Print("rates_total = ",rates_total,
"tmparray = ",tmparray[0]
,"KolVBuf ", scBuf[0][0],"+",scBuf[0][1]
       ,"/ ",scBuf[1][0],"+",scBuf[1][1]
       ,"/ ",scBuf[2][0],"+",scBuf[2][1]
       ,"/ ",scBuf[3][0],"+",scBuf[3][1]
       ,"/ ",scBuf[4][0],"+",scBuf[4][1]
       ,"/ ",scBuf[5][0],"+",scBuf[5][1]
     );

   
//--- return value of prev_calculated for next call
   return(rates_total);
  }

 

 Цель:

- Обозначить крестиками, уплотнения сформировавшиеся от объединенных SMA.

 На данном этапе хотел увидеть крестики хоть по последней свече

 В результате крестики раскинуты не упорядоченно, по времени и туда где нет ничего. 

Вопрос:

Получается, что ошибка, по которой крестики распологаются в не соответствии положению скопления SMA, в формировании массива SMA || ..? 

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