Почему так происходит? - страница 2

 
Talex:

Вот, что получилось.

Теперь есть предмет для разговора ;)

Я еще упростил 1-ю версию индикатора и посмотрел что она считает. Оказалось, что функция iMAOnArray работает неправильно (или я не понимаю как ей пользоваться ;). Код для проверки:
#property indicator_separate_window
#property indicator_buffers 1 // отображаемый буфер индикатора
#property indicator_color1 Lime
 
extern int TF = 1; // ТФ на котором проверяется появление нового бара
extern int Depth = 2; // Период усреднения 
 
double buffer1[], buffer2[];
 
void init()
{
   IndicatorBuffers(2); // два буфера для вычислений пользовательского индикатора
   SetIndexBuffer(0, buffer2); // этот буфер отображается
   SetIndexBuffer(1, buffer1); // этот буфер используется для расчета
   return;
}
 
void start() 
{
    static datetime newbar = 0;
 
   if ( newbar != iTime(NULL, TF, 0) )
   { 
        for( int i = 10; i > 0; i--)
        {
            buffer1[i] = (iMA(NULL, TF, 1, 0, 0, 0, i) - iMA(NULL, TF, 1, 0, 0, 0, i+1))*10000;
        }
 
        for(i = 9; i > 0; i--) 
        {
//            buffer2[i] = iMAOnArray(buffer1, 0, Depth, 0, 0, i);    // считает НЕправильно
            buffer2[i] = (buffer1[i+1] + buffer1[i])/2.0;             // считает правильно
        }
        ArraySetAsSeries( buffer2, true );
 
        CommentArray( buffer1, buffer2 );
 
        newbar = iTime(NULL, TF, 0); // присваиваем newbar новое значение
   }
 
   return;
}
 
void CommentArray( double array[], double array2[] )
{
    int size = 10; string tmp = StringConcatenate( "[1]: ", array[1] ), tmp1 = StringConcatenate( "[1]: ", array[1] );
    for ( int i = 2; i < size; i ++ )
    {
        tmp = StringConcatenate( tmp, "\n[", i, "]: ", array[i], "   ", DoubleToStr( array2[i-1], 1 ) );
        tmp1 = StringConcatenate( tmp1, "   [", i, "]: ", array[i], "   ", DoubleToStr( array2[i-1], 1 ) );
    }
 
    Comment( tmp );
    Print(tmp1);
}

Лог:
Вариант:
Сразу после загрузки : [1]: 2 [2]: -2 0.0 [3]: -1 -1.5 [4]: 0 -0.5 [5]: 0 0.0 [6]: -1 -0.5 [7]: 1 0.0 [8]: 1 1.0 [9]: -2 -0.5
Появился новый бар : [1]: -2 [2]: 2 0.0 [3]: -2 -1.5 [4]: -1 -0.5 [5]: 0 0.0 [6]: 0 -0.5 [7]: -1 0.0 [8]: 1 1.0 [9]: 1 -0.5
Перезапустили индюк: [1]: -2 [2]: 2 -0.0 [3]: -2 -0.0 [4]: -1 -1.5 [5]: 0 -0.5 [6]: 0 -0.0 [7]: -1 -0.5 [8]: 1 -0.0 [9]: 1 1.0

Вариант "(buffer1[i+1] + buffer1[i])/2.0":
Сразу после загрузки : [1]: -2 [2]: 2 0.0 [3]: -2 0.0 [4]: -1 -1.5 [5]: 0 -0.5 [6]: 0 0.0 [7]: -1 -0.5 [8]: 1 0.0 [9]: 1 1.0
Появился новый бар : [1]: 1 [2]: -2 -0.5 [3]: 2 0.0 [4]: -2 0.0 [5]: -1 -1.5 [6]: 0 -0.5 [7]: 0 0.0 [8]: -1 -0.5 [9]: 1 0.0
Перезапустили индюк: [1]: 1 [2]: -2 -0.5 [3]: 2 0.0 [4]: -2 0.0 [5]: -1 -1.5 [6]: 0 -0.5 [7]: 0 0.0 [8]: -1 -0.5 [9]: 1 0.0
Т.е. после появления нового бара buffer1 содержит правильные значения, а iMAOnArray их не видит.
 
komposter:
Т.е. после появления нового бара buffer1 содержит правильные значения, а iMAOnArray их не видит.

Хочу просто добавить, что это касается только индикаторных буферов, но не пользовательских массивов.

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

 
komposter:
Talex:

Вот, что получилось.

Теперь есть предмет для разговора ;)

Я еще упростил 1-ю версию индикатора и посмотрел что она считает. Оказалось, что функция OnArray работает неправильно (или я не понимаю как ей пользоваться ;). Код для проверки:
Т.е. после появления нового бара buffer1 содержит правильные значения, а OnArray их не видит.

Не понял о чем речь. Индикатор изначально написан неправильно (зачем использовать ArraySetAsSeries( ) для индикаторного буфера?). Почему так написана не симметрично относительно буферов функция Comment()?

Я переписал индикатор для проверки:
//+------------------------------------------------------------------+
//|                                             Check_iMaOnArray.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
 
#property indicator_separate_window
#property indicator_buffers 2 // отображаемый буфер индикатора
#property indicator_color1 Lime
#property indicator_color2 Blue
 
extern int TF = 1;      // ТФ на котором проверяется появление нового бара
 
double buffer1[];
double buffer2[];
double buffer3[];
 
int Depth = 2;   // Период усреднения 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   IndicatorBuffers(3); // два буфера для вычислений пользовательского индикатора
   SetIndexBuffer(0, buffer1); // этот буфер отображается
   SetIndexBuffer(1, buffer2); // этот буфер отображается
   SetIndexBuffer(2, buffer3); // этот буфер используется для расчета
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int  i,limit,counted_bars=IndicatorCounted();
   static datetime newbar = 0;
//----
   if (counted_bars>0) limit=Bars-counted_bars;
   if (counted_bars==0) limit=Bars-1;
       
   for(i = limit ; i >= 0; i--)
      {
      buffer1[i] = (iMA(NULL, TF, 1, 0, MODE_SMA, PRICE_CLOSE, i) - iMA(NULL, TF, 1, 0, MODE_SMA, PRICE_CLOSE, i+1))*10000;
      }
 
   for(i = limit; i >= 0; i--) 
      {
      //
      buffer2[i] = iMAOnArray(buffer1, 0, Depth, 0, MODE_SMA, i); // один способ расчет
      buffer3[i] = (buffer1[i+1] + buffer1[i])/2.0;               // другой    способ
      }
   if ( newbar != iTime(NULL, TF, 0) )
      { 
      CommentArray( buffer2, buffer3 );
      newbar = iTime(NULL, TF, 0); // присваиваем newbar новое значение
      }
//----
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CommentArray( double array[], double array2[] )
   {
   int size = 10; 
   string tmp  = StringConcatenate( "[1]: ", DoubleToStr(array[1],1),"   ",DoubleToStr( array2[1], 1 ) ); 
   string tmp1 = StringConcatenate( "[1]: ", DoubleToStr(array[1],1),"   ",DoubleToStr( array2[1], 1 ) );
//----
   for ( int i = 2; i <= size; i ++ )
      {
      tmp  = StringConcatenate( tmp, "\n["  , i, "]: ", DoubleToStr(array[i],1),  "   ", DoubleToStr( array2[i], 1 ) );
      tmp1 = StringConcatenate( tmp1, "   [", i, "]: ", DoubleToStr(array[i],1), "   ", DoubleToStr( array2[i], 1 ) );
      }
   Comment( tmp );
   Print(tmp1);
//----
   return;
   }
//+------------------------------------------------------------------+


Запустил на графике.




Видно, что значения буферов buffer2[] и buffer3[], построенных разными способами, совпадают. Или вопрос был в чем-то другом?
 
Rosh:
Или вопрос был в чем-то другом?

Имено в другом.

Ситуация примерно такая. Хочу на старшем ТФ видеть ситуацию с младшего. Для этого надо чтобы при появлении на младшем ТФ нового бара индикатор обновлял свои значения, но он не хочет этого делать, т.к. не правильно работает функция iMAOnArray с индикаторным буфером.

У Вас индикатор показывает на ТФ М1, ситуацию с М1.

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

 
Talex:
Rosh:
Или вопрос был в чем-то другом?

Имено в другом.

Ситуация примерно такая. Хочу на старшем ТФ видеть ситуацию с младшего. Для этого надо чтобы при появлении на младшем ТФ нового бара индикатор обновлял свои значения, но он не хочет этого делать, т.к. не правильно работает функция iMAOnArray с индикаторным буфером.

У Вас индикатор показывает на ТФ М1, ситуацию с М1.

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

Переписал индикатор, проверил, понял в чем вопрос. Завтра попробуем разобраться.
 
Объяснение такое: все встроенные индикаторы, которые рассчитываются на массивах (iBandsOnArray, iCCIOnArray, iEnvelopesOnArray, iMomentumOnArray, iMAOnArray, iRSIOnArray, iStdDevOnArray), написаны со своей встроенной оптимизацией, которая экономно рассчитывает последние 1-2 бара. При этом алгоритм расчета в какой-то мере опирается на значение количества неизмененных баров с момента последнего пришедшего тика (вспомните IndicatorCounted). Такой механизм экономного расчета удовлетворяет в 99% случаев. Меняться это не будет, если Ваш случай не подходит под данный механизм расчета, Вы можете написать собственную функцию, что собственно Вы и сделали.
 
Rosh:
Объяснение такое: все встроенные индикаторы, которые рассчитываются на массивах (iBandsOnArray, iCCIOnArray, iEnvelopesOnArray, iMomentumOnArray, iMAOnArray, iRSIOnArray, iStdDevOnArray), написаны со своей встроенной оптимизацией, которая экономно рассчитывает последние 1-2 бара. При этом алгоритм расчета в какой-то мере опирается на значение количества неизмененных баров с момента последнего пришедшего тика (вспомните IndicatorCounted). Такой механизм экономного расчета удовлетворяет в 99% случаев. Меняться это не будет, если Ваш случай не подходит под данный механизм расчета, Вы можете написать собственную функцию, что собственно Вы и сделали.

Спасибо, Рош. Да я не против, что меняться не будет, просто все "скользские места" лучше сразу описать в документации, чтобы не тратить время на поиск "ошибок". А то периодически всплывает одно и тоже (например о сравнении double). А также структурировать и может быть использовать перекрестные ссылки, а то я вчера тоже, нашел "ошибку" и написал в ветке 'Обновленный клиентский терминал MetaTrader 4 build 211 от 26 февраля 2008'. Хотя честно поискал в хэлпе по поводу работы функции Time[], но ответ был в описании RefreshRates(), а все помнить, к сожалению, не получается. Вобщем такие вот пожелания. Вопрос закрыт.
Причина обращения: