Скользящая средняя(SMA) в количестве 2000 шт. расчитать при минимальных затрат ресурсов. - страница 4

 
Fry_Антон:

*Выше в коде у меня был серьёзный баг! Сейчас увидел и исправил (две строки местами переставил).

Когда я это написал в четвёрке не было никаких классов и не планировалось даже близко, а сейчас у меня нет четвёрки, так что проверить не могу. Работает быстро и экономно, но окупается по настоящему если алгоритм не простой SMA вставить, а какой-нибудь сложный расчёт. Вот тогда разница офигенная.

Этот класс сырой, так что использовать его не очень удобно, но можно развить. Тут главное сам принцип расчёта по цепочке.

Вообще можно статически объявить объект... Индюк для примера (тоже очень давно кодил):

Для автора топика здесь самое полезное, то, что не надо создавать 2000 буферов индикатора если нет нужды графику всю это на каждый бар накладывать. Можно создать 2000 экземпляров объекта и сам расчёт будет весьма экономным во всех смыслах.

Другое дело, что я абсолютно согласен с Андреем (Andrey Khatimlianskii) - столько мувингов не нужно =)

Спасибо - буду пробовать. У меня такая задача - есть N точек, нужно найти МА которая будет наиболее близка к этим точкам, расчет надо делать при появлении минимума точек, тут будет эффект от класса?
 
-Aleks-:
Спасибо - буду пробовать. У меня такая задача - есть N точек, нужно найти МА которая будет наиболее близка к этим точкам, расчет надо делать при появлении минимума точек, тут будет эффект от класса?

Однозначно будет хороший эффект. Ещё раз повторяю, код сырой, слишком давно это было. Возможно там есть приличные ляпы, так что надо вникнуть в каждую строку самостоятельно и тогда все вопросы сами решатся.

Рекомендую сразу избавиться от ArrayResize(), потому что это самый тормозной элемент класса. Ничего страшного не будет, если буфер расчёта будет допустим 500 даблов. Ну а ресайзить только если надо период больше 500.

Можно потом сделать обёртку хотя бы для того чтобы вызывать на тики и на бары одним методом. Можно развить набор алгоритмов мувинга...

 
Fry_Антон:

Однозначно будет хороший эффект. Ещё раз повторяю, код сырой, слишком давно это было. Возможно там есть приличные ляпы, так что надо вникнуть в каждую строку самостоятельно и тогда все вопросы сами решатся.

Рекомендую сразу избавиться от ArrayResize(), потому что это самый тормозной элемент класса. Ничего страшного не будет, если буфер расчёта будет допустим 500 даблов. Ну а ресайзить только если надо период больше 500.

Можно потом сделать обёртку хотя бы для того чтобы вызывать на тики и на бары одним методом. Можно развить набор алгоритмов мувинга...

Я не программист - класс для меня сложная структура, поэтому есть вопрос по содержанию строки

buf_sma[i]=sma.Bar(price[i]); 

price[i] - это цена последнего бара? Допустим надо на 20 баре подсчитать МАшку, то пишем  sma.Bar(20)?

 
-Aleks-:
Спасибо - буду пробовать. У меня такая задача - есть N точек, нужно найти МА которая будет наиболее близка к этим точкам, расчет надо делать при появлении минимума точек, тут будет эффект от класса?
Насчет эффекта от класса не скажу, а наиболее близкой МА всегда будет МА(1). 
 
Алексей Тарабанов:
Насчет эффекта от класса не скажу, а наиболее близкой МА всегда будет МА(1). 
Это не есть факт, да и не относится к моей задаче.
 
-Aleks-:
Это не есть факт, да и не относится к моей задаче.
Не факт, так не факт. 
 
Алексей Тарабанов:
Насчет эффекта от класса не скажу, а наиболее близкой МА всегда будет МА(1). 

ну это уже придирки. Я так понял, что задача примерно такая:

есть ряд значений n1 (обычно цена или значения из какого-нибудь индюка)

есть ряд значений n2 (допустим некие экстремумы, чьи-то сделки или что-то подобное), который совпадает с предположительной SMA(X) к ряду n1.

Задача найти X

 
-Aleks-:

Я не программист - класс для меня сложная структура, поэтому есть вопрос по содержанию строки

buf_sma[i]=sma.Bar(price[i]); 

price[i] - это цена последнего бара? Допустим надо на 20 баре подсчитать МАшку, то пишем  sma.Bar(20)?

Прайс i - это цена i-ного бара.

Обычная итерация.

Если надо на 20-м баре найти SMA, то придётся подать в метод Bar все 20 значений от младшего (левого) к старшему (правому) по цепочке без каких-либо пропусков!

Либо использовать метод Start() на глубину периода SMA. Это окупится если период меньше 20.

 
Andrey Khatimlianskii:

Придумали, придумали )

Это же МТ5, тут другой подход к кастомным индикаторам. Я же не зря говорил справку почитать )

Все работает:

 

А чтоб вернуть период МА, заведите для него еще один буффер индикатора (можно невидимый) и обращайтесь к нему. 

//--- plot Label1
#property indicator_label1  "Lx"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID

//--- input parameters
input int      Pmax=2000;
input int      numMa=51;
//--- indicator buffers
double         Lx[];
double         Lx_[];
//== Определяем Кол-во =
int nBar;
int den=1;
double CenaMuv[];
int KolMuv[];
//== Определяем Наибольшее =
int NaZnKol[11];
int NaZnPrd[];
int vsc, Kol;

#include <SMA_Greed.mqh>  
CSMA_Greed sm;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping

   SetIndexBuffer(0,Lx,INDICATOR_DATA);
   PlotIndexSetInteger(0,PLOT_ARROW,159);
   ArrayResize(Lx_,numMa+1);
   sm.Init(Pmax);
    EventSetTimer(1);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//---

nBar=rates_total-1;
sm.Solve(rates_total,prev_calculated,price);

 for(int a=prev_calculated>Pmax?prev_calculated:Pmax;a<rates_total;a++)
   {
  for(int b=3; b<numMa; b++)
     {
     Lx[a]=NormalizeDouble(sm.d[numMa-1].m[a],Digits());
     Lx_[b]=NormalizeDouble(sm.d[b-1].m[a],Digits());  
     }  
   }
   return(rates_total-1);
  }
//+------------------------------------------------------------------+

 в эксперте

int OnInit()
{
   //--- create timer
        handle = iCustom(_Symbol,PERIOD_CURRENT,"Topqw",Pmax,numMa);
        
        if ( handle == INVALID_HANDLE ) return(INIT_FAILED);
        //---
       EventSetTimer(2);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---     
   double array[], array_[];
        int copy=CopyBuffer(handle,0,0,1,array); // Значение МА заданного в контрольных переменных numMa
        int copy_=CopyBuffer(handle,1,0,20,array_); // здесь ерунду сотворяю какую то - пытаюсь вытащить фид МА 
        Comment("as ",array[0]
          ,"\n","asP ",array_[19]  

  );


   
  }
//+------------------------------------------------------------------+

 Что то не могу уловить логику как достать значение МА по номеру бара.

В индикаторе массив Lx отвечает за бары, а с помощью Lx_ пытаюсь создать возможность схватиться за МА 

В общем не могу связать через эксперт определение фида МА по бару

 
Top2n:

 в эксперте

 Что то не могу уловить логику как достать значение МА по номеру бара.

В индикаторе массив Lx отвечает за бары, а с помощью Lx_ пытаюсь создать возможность схватиться за МА 

В общем не могу связать через эксперт определение фида МА по бару

Что вы называете фидом?

Любый данные (числовые) можно положить в буфер индикатора. Начните с этого. Чтоб нужные данные были видны, если не на графике, то в окне данных (Ctrl+D).

А потом из советника просто возьмите значение нужного буфера на нужном баре. 

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