Отображение буфера в индикаторе - страница 3

 
Алексей Тарабанов:
Потому, что никто не сказал этому значению, что оно должно быть EMPTY_VOLUME, а не остаться проинициализированным нулем по-умолчанию. 

Алексей, ещё раз!

Я заполняю ВЕСЬ буфер! от корки до корки НЕ НУЛЕВЫМИ ЗНАЧЕНИЯМИ! 

Если бы была ошибка в коде, то он бы не проработал правильно 3 часа! 

Буферы ПОЛНОСТЬЮ переписываются, при КАЖДОМ OnCalculate() 

 
Михаил:

Алексей, ещё раз!

Я заполняю ВЕСЬ буфер! от корки до корки НЕ НУЛЕВЫМИ ЗНАЧЕНИЯМИ! 

Если бы была ошибка в коде, то он бы не проработал правильно 3 часа! 


          Михаил, я берусь утверждать, что Ваш код правильно работает 3 часа 59 минут, а после - новый бар и все такое. 
 
Алексей Тарабанов:

          Михаил, я берусь утверждать, что Ваш код правильно работает 3 часа 59 минут, а после - новый бар и все такое. 

График, на котором работает индикатор имеет таймфрейм равный М1 (ОДНА МИНУТА!!!!!!!!!!)

За 3 часа = 180 баров!!!!!! 

 
Михаил:

График, на котором работает индикатор имеет таймфрейм равный М1 (ОДНА МИНУТА!!!!!!!!!!)

За 3 часа = 180 баров!!!!!! 

Тогда, спим. 
 
Алексей Тарабанов:
Тогда, спим. 
Точно! Я только сейчас на время посмотрел... :)
 
Михаил:

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

За 1 OnCalculate() в AskTemp( BidTemp) приходит более 200 значений (event_cnt = 242 

В Вашей реализации, потеряется 241 значение из 242.

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

Чтоб значения, поступающие из ОнБукИвента не терялись, нужно вызывать OnCalculate при появлении каждой новой цены.

 

Вот новая версия, в которой появление цены эмулируется через таймер (по умолчанию - каждые 10 мс):

//+------------------------------------------------------------------+
//|                                                       iTicks.mq4 |
//|                                      Copyright © 2015, komposter |
//|                                          http://www.komposter.me |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2015, komposter"
#property link      "http://www.komposter.me"
#property version   "2.00"

//---
#property indicator_separate_window
#property indicator_buffers                     1
#property indicator_plots                               1

//---
input string                                    Main_Properties                 = "";                                   // Main properties:
input int                                               MaxTicksOnChart         = 500;                          // * Max Ticks On Chart
input int                                               TimerResolution         = 10;                                   // * Pause (ms)

//--- plot
#property indicator_label1  "bid"
#property indicator_type1   DRAW_SECTION
#property indicator_color1  clrWhite
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

//--- indicator buffers
double         bid[];
int                             prev_rates_total        = 0;
int                             LastRatesTotal  = 0;
double                  LastPrice                       = 0;
double                  PrevPrice                       = 0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
        int buffer_index = -1, plot_index = -1;

//--- Colors
        buffer_index ++;
        SetIndexBuffer(buffer_index,bid,INDICATOR_DATA);

//--- indicator buffers mapping
        plot_index ++;
        PlotIndexSetString (plot_index,PLOT_LABEL, "Bid" );
        PlotIndexSetInteger(plot_index,PLOT_DRAW_TYPE,DRAW_SECTION );

//---
        ArraySetAsSeries( bid, true );

        prev_rates_total = 0;
        LastRatesTotal  = 0;
        LastPrice = 0.0;
        PrevPrice = 0.0;

//---
        MathSrand(GetTickCount());
        EventSetMillisecondTimer( TimerResolution );

//---
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTimer()
{
        // Если удается получить цену, используем ее
        MqlTick last_tick;
        if ( SymbolInfoTick( _Symbol, last_tick ) ) LastPrice = last_tick.bid;

        // Если не было ни одной цены, ничего не рисуем
        if ( LastPrice < DBL_EPSILON ) return;

        // Если цена не изменилась, добавляем случайные +/- (1-4) пункта
        if ( MathAbs( LastPrice - PrevPrice ) < DBL_EPSILON ) LastPrice = PrevPrice += (MathRand()%8-4)*_Point;

        // Рисуем
        double p[];
        OnCalculate( LastRatesTotal, LastRatesTotal, 0, p );
        ChartRedraw( 0 );
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate (const int rates_total, const int prev_calculated, const int begin, const double& price[] )
{
//---
        if ( LastPrice < DBL_EPSILON ) return(0);

//---
        if ( prev_rates_total == 0 )
        {
                ArrayInitialize( bid, EMPTY_VALUE );
        }

//---
        LastRatesTotal  = rates_total;

//--- Новых баров нет
        if ( rates_total == prev_rates_total )
        {
                // Сдвигаем данные
                for ( int i = MaxTicksOnChart-1; i > 0; i -- )
                {
                        bid[i] = bid[i-1];
                }
        }
        else
        {
                prev_rates_total = rates_total;

                // удаляем старое значение
                bid[MaxTicksOnChart]= EMPTY_VALUE;
        }

//--- Заполняем последнее значение
        bid[0] = LastPrice;
        PrevPrice = LastPrice;

//--- return value of prev_calculated for next call
        return(rates_total);
}

 

Запустите ее, и сами все поймете.

Для реализации вашей задачи достаточно сделать аналогичный вызов OnCalculate из OnBookEvent. 

 
Andrey Khatimlianskii:

Запустите ее, и сами все поймете.

Вот видео, демонстрирующее работу:

 

 

Всё классно, но бага осталась и, при удалении индикатора, 

виснит советник на этом чарте 

 

 

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

{
  if ( prev_calculated == 0 )
  {
    ArrayInitialize( AskBuffer, EMPTY_VALUE );
    ArrayInitialize( BidBuffer, EMPTY_VALUE ); 
  }
  else
  {
    if ( rates_total == event_cnt )
    {
      if ( on_trans )  //мы вызвали OnCalculate()
      {
        on_trans = false;
//---        
        for ( int i = rates_total - 1; i > 0; i-- )
        {
          AskBuffer[i] = AskBuffer[i - 1];
          BidBuffer[i] = BidBuffer[i - 1];
        }
      }
    }
    else
    {
      AskBuffer[0] = EMPTY_VALUE;
      BidBuffer[0] = EMPTY_VALUE;
    }
    event_cnt = rates_total;
  }
  IndicatorSetDouble( INDICATOR_LEVELVALUE, 0, LevelHigh );
  IndicatorSetDouble( INDICATOR_LEVELVALUE, 1, LevelExitHigh );
  IndicatorSetDouble( INDICATOR_LEVELVALUE, 2, LevelLow );
  IndicatorSetDouble( INDICATOR_LEVELVALUE, 3, LevelExitLow );
//--- 
  return( rates_total );
}
 

При удалении индикатора, по прежнему 

виснет советник. Видимо это из-за деинициализации индикатора

//+------------------------------------------------------------------+
// Custom indicator DeInit function                                  |
//+------------------------------------------------------------------+
void OnDeinit( const int reason )
{
  MarketBookRelease( _Symbol );
  MarketBookRelease( sec_symbol );
  MarketBookRelease( last_symbol );
//---  
  if ( reason == REASON_INITFAILED )
  {
    Print( "Индикатор удалён! Причина - ошибка инициализации." );
    string short_name = ChartIndicatorName( 0, 1, 0 );
    ChartIndicatorDelete( 0, 1, short_name ); 
  }
}

 В советнике в OnBookEvent() тоже используются эти символы.

 Вот с этим кодом, работает правильно:

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

{
  if ( prev_calculated == 0 )
  {
    ArrayInitialize( AskBuffer, EMPTY_VALUE );
    ArrayInitialize( BidBuffer, EMPTY_VALUE ); 
  }
  else
  {
    if ( rates_total == event_cnt )
    {
      if ( on_call )  //мы вызвали OnCalculate
      {
        on_call = false;
//---        
        for ( int i = rates_total - 1; i > 0; i-- )
        {
          AskBuffer[i] = AskBuffer[i - 1];
          BidBuffer[i] = BidBuffer[i - 1];
        }
      }
    }
    else
    {
      AskBuffer[0] = AskBuffer[1];
      BidBuffer[0] = BidBuffer[1];
    }
  }
  IndicatorSetDouble( INDICATOR_LEVELVALUE, 0, LevelHigh );
  IndicatorSetDouble( INDICATOR_LEVELVALUE, 1, LevelExitHigh );
  IndicatorSetDouble( INDICATOR_LEVELVALUE, 2, LevelLow );
  IndicatorSetDouble( INDICATOR_LEVELVALUE, 3, LevelExitLow );
//--- 
event_cnt = rates_total;
  return( rates_total ); }
 

Да, советник вис из-за деинициализации индикатора.

УРРРА!

 

Совместными усилиями с Андреем, удалось создать на 99,9% реал-тайм индикатор! 

Код в OnBookEvent()

//+------------------------------------------------------------------+
// Custom indicator On book event function                           |
//+------------------------------------------------------------------+
void OnBookEvent( const string& a_symbol )
{
  if ( ( a_symbol == _Symbol ) || ( a_symbol == sec_symbol ) )
  {
    double prim_sell_price, prim_buy_price,
           sec_sell_price, sec_buy_price;
//         
    GetStakanValues( _Symbol, prim_sell_price, prim_buy_price );
    GetStakanValues( sec_symbol, sec_sell_price, sec_buy_price );
//---    
    AskBuffer[0] = ( prim_sell_price + sec_sell_price ) / _Point;
    BidBuffer[0] = ( prim_buy_price + sec_buy_price ) / _Point; 
//---
    double p[]; 
    on_call = true;
    OnCalculate( event_cnt, event_cnt, 0, p ); 
     
  }
}
Причина обращения: