Отображение буфера в индикаторе

 

Добрый день!

Есть код в индикаторе:

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate( const int rates_total,
                 const int prev_calculated,
                 const int begin,
                 const double &price[] )

{
  if ( prev_calculated == 0 )
  {
    for( int i = rates_total - 1; i >= 0; i-- )
    {
      AskBuffer[i] = EMPTY_VALUE;
      BidBuffer[i] = EMPTY_VALUE;
    }
  }
  else
  {
    event_cnt = ArraySize( AskTemp );
    if ( event_cnt != ArraySize( BidTemp ) || ( event_cnt == 0 ) )
    {
      Print( "Буферы данных не совпадают. Размер буфера равен 0!" );
      event_cnt = 0;
      return( rates_total );
    }
//---
    if ( event_cnt >= rates_total )
    {
      for( int i = rates_total - 1; i >= 0; i-- )
      {
        AskBuffer[i] = AskTemp[i];
        BidBuffer[i] = BidTemp[i];
      }
    }
    else
    {
      int n_diff = rates_total - prev_calculated;
      Print( " n_diff = ", n_diff );
//---
      for( int i = rates_total - 1; i >= 0; i-- )
      {
        if ( i > ( event_cnt - 1 ) )
        {
          AskBuffer[i] = AskBuffer[i - event_cnt + n_diff];
          BidBuffer[i] = BidBuffer[i - event_cnt + n_diff];
          if ( ( NormalizeDouble( AskBuffer[i], 0 ) == 0 ) && ( NormalizeDouble( BidBuffer[i], 0 ) == 0 ) )
          Print( "Сдвиг значений буферов. i = ", i, "; rates total = ", rates_total,
                 "; prev calc = ", prev_calculated, "; event cnt = ", event_cnt, 
                 "; Ask buff = ", AskBuffer[i], "; Bid buff = ", BidBuffer[i] );
        }
        else
        {
          AskBuffer[i] = AskTemp[i];
          BidBuffer[i] = BidTemp[i];
          if ( ( NormalizeDouble( AskBuffer[i], 0 ) == 0 ) && ( NormalizeDouble( BidBuffer[i], 0 ) == 0 ) )
          Print( "Заполнение новыми значениями. i = ", i, "; rates total = ", rates_total,
                 "; prev calc = ", prev_calculated, "; event cnt = ", event_cnt, 
                 "; Ask buff = ", AskBuffer[i], "; Bid buff = ", BidBuffer[i] );
        }
      }
    }   
    event_cnt = 0;
  }
  IndicatorSetDouble( INDICATOR_LEVELVALUE, 0, LevelHigh );
  IndicatorSetDouble( INDICATOR_LEVELVALUE, 1, LevelExitHigh );
  IndicatorSetDouble( INDICATOR_LEVELVALUE, 2, LevelLow );
  IndicatorSetDouble( INDICATOR_LEVELVALUE, 3, LevelExitLow );
//--- 
  return( rates_total );
}

 Есть проверка значений буферов на "0"

В журнале нет сообщений о том, что значение буферов = 0

( сообщения появляются после "сбоя"

2015.05.22 15:11:52.755 MIX (MIX-6.15,M1)        сдвиг значений буферов. i = 41; rates total = 32279; prev calc = 32279; event cnt = 41; Ask buff = 8.893181625142438e-323; Bid buff = 2.964393875047479e-323
2015.05.22 15:11:52.885 MIX (MIX-6.15,M1)        сдвиг значений буферов. i = 49; rates total = 32279; prev calc = 32279; event cnt = 8; Ask buff = 8.893181625142438e-323; Bid buff = 2.964393875047479e-323
2015.05.22 15:11:52.903 MIX (MIX-6.15,M1)        сдвиг значений буферов. i = 52; rates total = 32279; prev calc = 32279; event cnt = 3; Ask buff = 8.893181625142438e-323; Bid buff = 2.964393875047479e-323
2015.05.22 15:11:53.425 MIX (MIX-6.15,M1)        сдвиг значений буферов. i = 98; rates total = 32279; prev calc = 32279; event cnt = 46; Ask buff = 8.893181625142438e-323; Bid buff = 2.964393875047479e-323
2015.05.22 15:11:53.677 MIX (MIX-6.15,M1)        сдвиг значений буферов. i = 120; rates total = 32279; prev calc = 32279; event cnt = 22; Ask buff = 8.893181625142438e-323; Bid buff = 2.964393875047479e-323
2015.05.22 15:11:55.252 MIX (MIX-6.15,M1)        сдвиг значений буферов. i = 239; rates total = 32279; prev calc = 32279; event cnt = 119; Ask buff = 8.893181625142438e-323; Bid buff = 2.964393875047479e-323
2015.05.22 15:11:55.285 MIX (MIX-6.15,M1)        сдвиг значений буферов. i = 242; rates total = 32279; prev calc = 32279; event cnt = 3; Ask buff = 8.893181625142438e-323; Bid buff = 2.964393875047479e-323
2015.05.22 15:11:56.951 MIX (MIX-6.15,M1)        сдвиг значений буферов. i = 375; rates total = 32279; prev calc = 32279; event cnt = 133; Ask buff = 8.893181625142438e-323; Bid buff = 2.964393875047479e-323
2015.05.22 15:11:56.981 MIX (MIX-6.15,M1)        сдвиг значений буферов. i = 378; rates total = 32279; prev calc = 32279; event cnt = 3; Ask buff = 8.893181625142438e-323; Bid buff = 2.964393875047479e-323
2015.05.22 15:11:58.284 MIX (MIX-6.15,M1)        сдвиг значений буферов. i = 455; rates total = 32279; prev calc = 32279; event cnt = 77; Ask buff = 8.893181625142438e-323; Bid buff = 2.964393875047479e-323
2015.05.22 15:12:07.215 MIX (MIX-6.15,M1)        сдвиг значений буферов. i = 697; rates total = 32279; prev calc = 32279; event cnt = 242; Ask buff = 8.893181625142438e-323; Bid buff = 2.964393875047479e-323

А на графике явно видно, что "0"


Как такое может быть? 

 
А в чем ошибка и что за "сбой"? В буферах значения близкие к нулю (откуда взялись - не понятно, похоже на неинициализированный буфер), при проверке на 0 она срабатывает, потому что нормализация до 0 знака. Получаем вывод в лог. На графике вывод нормализуется с точностью до знаков индикатора, так что это тоже 0.
 

Михаил, Вас приветствую!

Если позволите, выскажу своё имхо. Подобная ошибка встречается тогда, когда появляется новый бар. Тогда OnCalculate() обрабатывает именно новый бар. Причём новый бар в буфере индикатора с индексом [rates_total-1] или [0], если тайм-серия, равен 0.0. В Вашем коде скорее всего присутствует неучтёнка этого момента. Нужно сдвинуть буферы вверх, я лично эту функцию называю UpshiftBuffer()... без этого получите пролапс линии индикатора...

 
Dennis Kirichenko:

Михаил, Вас приветствую!

Если позволите, выскажу своё имхо. Подобная ошибка встречается тогда, когда появляется новый бар. Тогда OnCalculate() обрабатывает именно новый бар. Причём новый бар в буфере индикатора с индексом [rates_total-1] или [0], если тайм-серия, равен 0.0. В Вашем коде скорее всего присутствует неучтёнка этого момента. Нужно сдвинуть буферы вверх, я лично эту функцию называю UpshiftBuffer()... без этого получите пролапс линии индикатора...

Добрый вечер, Денис!

int n_diff = rates_total - prev_calculated;

 n-diff как раз и учитывает новый бар(ы)

AskBuffer[i] = AskBuffer[i - event_cnt + n_diff];

 Причём, такой провал, бывает достаточно редко и когда n_diff = 0 :)

 

Думаю, что в этом "косяк":

2015.05.22 20:03:34.813 MIX (MIX-6.15,M1)         n_diff = 1
2015.05.22 20:03:37.313 MIX (MIX-6.15,M1)         n_diff = 0
2015.05.22 20:03:44.071 MIX (MIX-6.15,M1)         n_diff = 0
2015.05.22 20:03:44.083 MIX (MIX-6.15,M1)         n_diff = 0
2015.05.22 20:03:50.592 MIX (MIX-6.15,M1)         n_diff = 0
2015.05.22 20:03:50.604 MIX (MIX-6.15,M1)         n_diff = 0
2015.05.22 20:03:50.702 MIX (MIX-6.15,M1)         n_diff = 0
2015.05.22 20:03:50.902 MIX (MIX-6.15,M1)         n_diff = 0
2015.05.22 20:03:50.924 MIX (MIX-6.15,M1)         n_diff = 0
2015.05.22 20:03:51.204 MIX (MIX-6.15,M1)         n_diff = 0
2015.05.22 20:03:51.222 MIX (MIX-6.15,M1)         n_diff = 0
2015.05.22 20:03:51.430 MIX (MIX-6.15,M1)         n_diff = 0
2015.05.22 20:03:51.576 MIX (MIX-6.15,M1)         n_diff = 1
2015.05.22 20:03:52.000 MIX (MIX-6.15,M1)         n_diff = 0
2015.05.22 20:03:55.112 MIX (MIX-6.15,M1)         n_diff = 0
2015.05.22 20:03:55.362 MIX (MIX-6.15,M1)         n_diff = 0

 Бар не должен появляться через 24 сек.

 

Точно, сбой возникает после появления " неурочного нового" бара, но при n_diff = 0:

2015.05.22 20:18:45.652 MIX (MIX-6.15,M1)        n_diff = 0
2015.05.22 20:18:45.731 MIX (MIX-6.15,M1)        n_diff = 1
2015.05.22 20:18:45.831 MIX (MIX-6.15,M1)        n_diff = 0
2015.05.22 20:19:00.263 MIX (MIX-6.15,M1)        n_diff = 0
2015.05.22 20:19:00.863 MIX (MIX-6.15,M1)        n_diff = 0
2015.05.22 20:19:01.060 MIX (MIX-6.15,M1)        n_diff = 0
2015.05.22 20:19:01.070 MIX (MIX-6.15,M1)        n_diff = 1
2015.05.22 20:19:21.621 MIX (MIX-6.15,M1)        n_diff = 0
 

Переделал на:

int n_diff = ArraySize( AskBuffer ) - prev_calculated;

 Не помогло..... 

Карма что ли у меня такая - "косяки" искать? 

 
Михаил:

Переделал на:

 Не помогло..... 

Карма что ли у меня такая - "косяки" искать? 

Михаил,  а та версия индюка, что делал я, у Вас работает нормально?

Шаманство в OnCalculate() с буферами, имхо, не прокатит... да и нужно весь код видеть...

 
Dennis Kirichenko:

Михаил,  а та версия индюка, что делал я, у Вас работает нормально?

Шаманство в OnCalculate() с буферами, имхо, не прокатит... да и нужно весь код видеть...

О чём Вы? Какое шаманство?

 

Формула очень простая:  

AskBuffer[i] = AskBuffer[i - event_cnt + n_diff];

1. Случай размер буфера 100

AskBuffer[99] = AskBuffer[99 - 10 + 0];

2 Случай размер увеличился на 1 бар = 101:

AskBuffer[100] = AskBuffer[100 - 10 + 1]; 

Где "шаманство"? 

 

P/S Все буферы как серии 

Всё дело в том, что индикатор 3-5 мин работает правильно (время варьируется и в ту и другую стороны),

а потом "схлопывается" в ноль в одной точке, а потом вновь  правильно работает!

Потом опять взбрыкивает, а потом опять тихий и спокойный  

 

При появлении нового бара не сдвигайте данные.

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

Должно работать. 

 
Andrey Khatimlianskii:

При появлении нового бара не сдвигайте данные.

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

Должно работать. 

А может и не должно...

Я заполняю буфер ровно по его размеру (без пропусков).

Откуда берётся "0", если я в буфер его не помещаю? 

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