Помогите решить проблему с "iMAOnArray"

 

Доброго времени суток.

Не могу разобраться с вот этим фрагментом кода.

for(X1 = 0; X1 < ArraySize(Will_Buf); X1++) //цикл заполнения `Williams Percent Range` (100 баров)
{
Will_Buf[X1] = NormalizeDouble(iWPR(NULL, TimeFrame, Will_Period, X1), Digits); //получение очередного значения `Williams Percent Range`
} //for
MA_Will_Buf[2] = NormalizeDouble(iMAOnArray(Will_Buf, 0, MA_Will_Period, 0, MA_Will_Metod, 2), Digits); //получение третьего значения `MA` от `Williams`
MA_Will_Buf[1] = NormalizeDouble(iMAOnArray(Will_Buf, 0, MA_Will_Period, 0, MA_Will_Metod, 1), Digits); //получение второго значения `MA` от `Williams`
MA_Will_Buf[0] = NormalizeDouble(iMAOnArray(Will_Buf, 0, MA_Will_Period, 0, MA_Will_Metod, 0), Digits); //получение второго значения `MA` от `Williams`

Параметры для него (среди прочих) задаются в окне настроек советника.

Когда стал выслеживать причину неверной работы советника в тестере выставляя контрольные точки с выводом через "Comment" или "Print", обнаружил, что это фрагмент ведет себя непонятно:

в окне терминала в онлайн все параметры выводимые советником соответствуют значениям из окна данных для индикатора и его средней, а вот в тестере средняя на втором баре (MA_Will_Buf[2])

постоянно равна первому значению найденному при запуске теста. Код прогоняется побарно и (для нулевых баров по тикам). 2 таких же фрагмента для других индикаторов также глючат.

MA_Will_Buf[1] и MA_Will_Buf[0] всегда считаются правильно. массивы перед использованием объявлены как таймсерии.

Подскажите пожалуйста. В чем проблема ?

 
Alex.Ru:

Доброго времени суток.

Не могу разобраться с вот этим фрагментом кода. Параметры для него (среди прочих) задаются в окне настроек советника.

Когда стал выслеживать причину неверной работы советника в тестере выставляя контрольные точки с выводом через "Comment" или "Print", обнаружил, что вот это фрагмент ведет себя непонятно:

в окне терминала в онлайн все параметры выводимые советником соответствуют значениям из окна данных для индикатора и его средней, а вот в тестере средняя на втором баре (MA_Will_Buf[2])

постоянно равна первому значению найденному при запуске теста. Код прогоняется побарно и (для нулевых баров по тикам). 2 таких же фрагмента для других индикаторов также глючат.

MA_Will_Buf[1] и MA_Will_Buf[0] всегда считаются правильно. массивы перед использованием объявлены как таймсерии.


for(X1 = 0; X1 < ArraySize(Will_Buf); X1++) //цикл заполнения `Williams Percent Range` (100 баров)
{
Will_Buf[X1] = NormalizeDouble(iWPR(NULL, TimeFrame, Will_Period, X1), Digits); //получение очередного значения `Williams Percent Range`
} //for
MA_Will_Buf[2] = NormalizeDouble(iMAOnArray(Will_Buf, 0, MA_Will_Period, 0, MA_Will_Metod, 2), Digits); //получение третьего значения `MA` от `Williams`
MA_Will_Buf[1] = NormalizeDouble(iMAOnArray(Will_Buf, 0, MA_Will_Period, 0, MA_Will_Metod, 1), Digits); //получение второго значения `MA` от `Williams`
MA_Will_Buf[0] = NormalizeDouble(iMAOnArray(Will_Buf, 0, MA_Will_Period, 0, MA_Will_Metod, 0), Digits); //получение второго значения `MA` от `Williams`

Подскажите пожалуйста. В чем проблема ?


Сделайте два цикла. В первом расчет буфера, во втором его сглаживание
 

Я уже пробовал и двумя циклами и брать больше трех баров для расчета и ставить весь код в прогон по тикам (хотя и смысла в этом вроде маловато), но результат один и тот же

iMAOnArray по текущему (расчет по тикам) и прошлому барам всегда верные, а начиная с бара № 2 (MA_Will_Buf[2]) и глубже значения рассчитанные при старте больше не меняются.

 
Alex.Ru:

Я уже пробовал и двумя циклами и брать больше трех баров для расчета и ставить весь код в прогон по тикам (хотя и смысла в этом вроде маловато), но результат один и тот же

iMAOnArray по текущему (расчет по тикам) и прошлому барам всегда верные, а начиная с бара № 2 (MA_Will_Buf[2]) и глубже значения рассчитанные при старте больше не меняются.


Приведите весь код (с двумя циклами)
 

Это с двумя циклами и проверкой большего количества записей.

  double   Will_Buf[100], //буфер вспомогательного индикатора `Williams Percent Range`
            MA_Will_Buf[5]; //буфер Moving Average от вспомогательного индикатора `Williams Percent Range`
   int CurBar;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ArraySetAsSeries(Will_Buf, true);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   string Text_Out,
          Text_Out_2;
   int MA_Will_Period = 5;
   int MA_Will_Metod = MODE_LWMA;
   int Will_Period = 21;
   int X1; //счетчик циклов
//---
   if (CurBar != iBars(Symbol(), 15))
     {
      CurBar = iBars(Symbol(), 15);
      for(X1 = 0; X1 < ArraySize(Will_Buf); X1++) //цикл заполнения `Williams Percent Range`
        {
         Will_Buf[X1] = NormalizeDouble(iWPR(Symbol(), 15, Will_Period, X1), Digits); //получение очередного значения `Williams Percent Range`
        } //for
      for(X1 = 0; X1 < ArraySize(MA_Will_Buf); X1++) //цикл заполнения MA от `Williams Percent Range`
        {
         MA_Will_Buf[X1] = NormalizeDouble(iMAOnArray(Will_Buf, 0, MA_Will_Period, 0, MA_Will_Metod, X1), Digits); //получение очередного значения `MA` от `Williams`
        } //for
     } //if
   Will_Buf[0] = NormalizeDouble(iWPR(Symbol(), 15, Will_Period, 0), Digits); //получение очередного значения `Williams Percent Range`
   MA_Will_Buf[0] = NormalizeDouble(iMAOnArray(Will_Buf, 0, MA_Will_Period, 0, MA_Will_Metod, 0), Digits); //получение второго значения `MA` от `Williams`
   
   for(X1 = ArraySize(MA_Will_Buf) - 1; X1 >= 0; X1--)
     {
      Text_Out = StringConcatenate(Text_Out, "Will(", X1, ") = ", DoubleToStr(Will_Buf[X1], Digits), " | ");
      Text_Out_2 = StringConcatenate(Text_Out_2, "MA_Will(", X1, ") = ", DoubleToStr(MA_Will_Buf[X1], Digits), " | ");
     } //for
   Comment("| ", Text_Out, "\n| ", Text_Out_2);
//---
  }
 
Alex.Ru:

Это с двумя циклами и проверкой большего количества записей.


В советнике пытаетесь сделать сглаживание? А чем индикатор не устраивает?

 

В советнике мне надо брать только несколько сглаженных значений от нескольких индикаторов. (Вильямс 1 из них, но глюк у всех один и тот же).

Сглаживать приходится для уменьшения ложных сигналов, а iMAOnArray глубже второго бара не пересчитывает первые вычисленные при запуске тестера значения).

Третий день уже с этой непоняткой борюсь, вначале сам, потом за инфой в сеть полез, а теперь вот на форум обратился.

 
Alex.Ru:

В советнике мне надо брать только несколько сглаженных значений от нескольких индикаторов. (Вильямс 1 из них, но глюк у всех один и тот же).

Сглаживать приходится для уменьшения ложных сигналов, а iMAOnArray глубже второго бара не пересчитывает первые вычисленные при запуске тестера значения).

Третий день уже с этой непоняткой борюсь, вначале сам, потом за инфой в сеть полез, а теперь вот на форум обратился.


Сделайте индикатор. Значительно проще и надежней
 

Индикаторы я никогда вообще не писал (не приходилось), так что и "проще" и "надежней" под большим вопросом. (поэтому и обратился в форум с просьбой о помощи по конкретному вопросу)

У меня пока получилось только частично обойти проблему вот таким кодом:

   double   Will_Buf[100], //буфер вспомогательного индикатора `Williams Percent Range`
            MA_Will_Buf[3]; //буфер Moving Average от вспомогательного индикатора `Williams Percent Range`
   int CurBar;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   ArraySetAsSeries(Will_Buf, true);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   string Text_Out,
          Text_Out_2;
   int MA_Will_Period = 5;
   int MA_Will_Metod = MODE_LWMA;
   int Will_Period = 21;
   int X1; //счетчик циклов
//---
   if (CurBar != iBars(Symbol(), 15))
     {
      for(X1 = 0; X1 < ArraySize(Will_Buf); X1++) //цикл заполнения `Williams Percent Range`
        {
         Will_Buf[X1] = NormalizeDouble(iWPR(Symbol(), 15, Will_Period, X1), Digits); //получение очередного значения `Williams Percent Range`
        } //for
      if (MA_Will_Buf[1] != 0 && CurBar + 1 == iBars(Symbol(), 15)) MA_Will_Buf[2] = MA_Will_Buf[1]; //если прошлый бар рассчитывался, то перенести его в №2
      else MA_Will_Buf[2] = NormalizeDouble(iMAOnArray(Will_Buf, 0, MA_Will_Period, 0, MA_Will_Metod, 1), Digits); //иначе взыть №2 как прошлый бар
      MA_Will_Buf[1] = NormalizeDouble(iMAOnArray(Will_Buf, 0, MA_Will_Period, 0, MA_Will_Metod, 1), Digits);//получение второго значения `MA` от `Williams`
      CurBar = iBars(Symbol(), 15);
     } //if
   Will_Buf[0] = NormalizeDouble(iWPR(Symbol(), 15, Will_Period, 0), Digits); //получение очередного значения `Williams Percent Range`
   MA_Will_Buf[0] = NormalizeDouble(iMAOnArray(Will_Buf, 0, MA_Will_Period, 0, MA_Will_Metod, 0), Digits); //получение первого значения `MA` от `Williams`
   
   for(X1 = ArraySize(MA_Will_Buf) - 1; X1 >= 0; X1--)
     {
      Text_Out = StringConcatenate(Text_Out, "Will(", X1, ") = ", DoubleToStr(Will_Buf[X1], Digits), " | ");
      Text_Out_2 = StringConcatenate(Text_Out_2, "MA_Will(", X1, ") = ", DoubleToStr(MA_Will_Buf[X1], Digits), " | ");
     } //for
   Comment("| ", Text_Out, "\n| ", Text_Out_2);
//---
  }

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

а при некоторых ситуациях и вовсе ошибочны).

 
Тебе проще попробовать написать индикатор. Всё когда-то бывает впервые. Дело в том, что пользовательские массивы и динамические массивы индикаторных буферов очень отличаются и для того чтобы к массиву в советнике применить iMAOnArrai() надо над массивом потрудиться правильно его заполнить и постоянно переписывать.
 

Понимаю, что когда нибудь придется и за индикаторы засесть, но сейчас из-за 1 корявой функции начинать изучение индикаторов вообще с нуля да еще и не факт, что я оставлю именно текущую комбинацию

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

функцию с реализацией алгоритма, а в основной код добавил только условие на принятие решения по ордеру (централизованно) или максимум изменил пару строк в основной программе и все - новый прогон в

тестере на поиск ошибок алгоритма или в реализации (иногда бывает кинул еще индикатор на график в конкретной ситуации где советник начал захлебываться - помогло - дописываю в код строку вызова этой функции)).

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