Скачать MetaTrader 5

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

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Не можешь найти ответ на вопрос? Воспользуйся поиском!
Mikhail Filimonov
5931
Mikhail Filimonov 2015.05.22 12:25 

Добрый день!

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

//+------------------------------------------------------------------+
//| 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"


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

Stanislav Korotky
17925
Stanislav Korotky 2015.05.22 16:42  
А в чем ошибка и что за "сбой"? В буферах значения близкие к нулю (откуда взялись - не понятно, похоже на неинициализированный буфер), при проверке на 0 она срабатывает, потому что нормализация до 0 знака. Получаем вывод в лог. На графике вывод нормализуется с точностью до знаков индикатора, так что это тоже 0.
Dennis Kirichenko
11329
Dennis Kirichenko 2015.05.22 17:04  

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

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

Mikhail Filimonov
5931
Mikhail Filimonov 2015.05.22 18:52  
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 :)

Mikhail Filimonov
5931
Mikhail Filimonov 2015.05.22 19:19  

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

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 сек.

Mikhail Filimonov
5931
Mikhail Filimonov 2015.05.22 19:22  

Точно, сбой возникает после появления " неурочного нового" бара, но при 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
Mikhail Filimonov
5931
Mikhail Filimonov 2015.05.22 19:35  

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

int n_diff = ArraySize( AskBuffer ) - prev_calculated;

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

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

Dennis Kirichenko
11329
Dennis Kirichenko 2015.05.22 23:18  
Михаил:

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

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

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

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

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

Mikhail Filimonov
5931
Mikhail Filimonov 2015.05.23 00:46  
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
56185
Andrey Khatimlianskii 2015.05.23 16:37  

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

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

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

Mikhail Filimonov
5931
Mikhail Filimonov 2015.05.24 19:13  
Andrey Khatimlianskii:

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

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

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

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

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

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

1234
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий