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

 
Михаил:

УРРРА! 

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

Ну вот, а вы говорите "разработчики". Все можно и самостоятельно сделать )

Почему закладываете 0.01% на пропуск события? Они разве не складываются в очередь и не отрабатываются потом?

 
Andrey Khatimlianskii:

Ну вот, а вы говорите "разработчики". Все можно и самостоятельно сделать )

Почему закладываете 0.01% на пропуск события? Они разве не складываются в очередь и не отрабатываются потом?

Добрый день!

С разработчиками было бы КРАСИВЕЕ и 100%. 

0,1% потому что мы, при каждой итеррации сами сдвигаем буфер + "тикает" OnCalculate() без нас + размер буфера сильно ограничен,

а с разработчиками этого бы не было. 

Я в эксперте вывожу эти значения. Сравнивая их с индикатором и не вижу разницы.

Но сказать, что 100%, думаю что нельзя.... 

 
Михаил:

С разработчиками было бы КРАСИВЕЕ и 100%. 

Красивее - возможно, но 100% - это вряд ли. Не мне вам рассказывать про кол-во багов ;)

 

Михаил:

0,01% потому что мы, при каждой итеррации сами сдвигаем буфер + "тикает" OnCalculate() без нас

Ну и что, что сдвигаем? Главное, чтоб события не терялись из очереди.

А тиканье "без нас" можно не обрабатывать.

 

Михаил:

Я в эксперте вывожу эти значения. Сравнивая их с индикатором я не вижу разницы.

Но сказать, что 100%, думаю что нельзя.... 

Ну, тогда вообще нельзя ни о чем сказать "100%".

Соберите статистику за торговую сессию из советник и из индикатора, и сравните.

Я думаю, результаты будут одинаковыми. 

 
Andrey Khatimlianskii:

Красивее - возможно, но 100% - это вряд ли. Не мне вам рассказывать про кол-во багов ;)

 

Ну и что, что сдвигаем? Главное, чтоб события не терялись из очереди.

А тиканье "без нас" можно не обрабатывать.

 

Ну, тогда вообще нельзя ни о чем сказать "100%".

Соберите статистику за торговую сессию из советник и из индикатора, и сравните.

Я думаю, результаты будут одинаковыми. 

:) Думаю, тоже, что одинаковые (хотя не уверен, что в OnBookEvent() есть кэширование), и размер буфера сильно ограничен.

Но то что сделано - уже огромный прогресс! 

 

Кому сложно вникнуть в детали, привожу полный код реал-тайм индикатора

Ask и Bid значений по выбранному символу (на ФОРЕКС должен быть работающий стакан цен )

Индикатор желательно запускать на файмфрейие М1 (больше значений будет отображаться) 

//+------------------------------------------------------------------+
//|                                                 Test_ask_bid.mq5 |
//|                              Copyright 2015, Mikalas & komposter |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, Mikalas & komposter"
#property link      "http://www.mql5.com"
#property version   "1.00"
//
#property indicator_separate_window

#property indicator_buffers 2
#property indicator_plots   2

//--- plot Label1
#property indicator_label1  "Ask"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//---
//--- plot Label1
#property indicator_label2  "Bid"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrBlue
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//
//--- indicator buffers
double AskBuffer[];
double BidBuffer[];
//
int event_cnt;
//
bool on_call;
//
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
  event_cnt = 0;
  on_call = false;
//--- Add book
  if ( !MarketBookAdd( _Symbol ) )
  {
    MessageBox( "Стакан символа " + _Symbol + " не добавден!", "Ошибка", MB_OK | MB_ICONHAND );
    return( INIT_FAILED );
  }
//---  
  IndicatorSetInteger( INDICATOR_DIGITS, _Digits );
  IndicatorSetString( INDICATOR_SHORTNAME, "Ask_Bid" );
//---  
  SetIndexBuffer( 0, AskBuffer, INDICATOR_DATA );
  PlotIndexSetDouble( 0, PLOT_EMPTY_VALUE, EMPTY_VALUE );
  ArraySetAsSeries( AskBuffer, true );
//---
  SetIndexBuffer( 1, BidBuffer, INDICATOR_DATA );
  PlotIndexSetDouble( 1, PLOT_EMPTY_VALUE, EMPTY_VALUE );
  ArraySetAsSeries( BidBuffer, true );
//---
  return( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+
// Custom indicator DeInit function                                  |
//+------------------------------------------------------------------+
void OnDeinit( const int reason )
{
  MarketBookRelease( _Symbol );
//---  
  if ( reason == REASON_INITFAILED )
  {
    Print( "Индикатор удалён! Причина - ошибка инициализации." );
    string short_name = ChartIndicatorName( 0, 1, 0 );
    ChartIndicatorDelete( 0, 1, short_name ); 
  }
}
//+------------------------------------------------------------------+
//| Custom indicator Get Stakan values function                      |
//+------------------------------------------------------------------+ 
void GetStakanValues( const string aSymbol, double &s_price, double &b_price )
{
  MqlBookInfo book_price[];
  b_price = 0;
  s_price = DBL_MAX;
  
//--- Get stakan
  if ( MarketBookGet( aSymbol, book_price ) )
  {
    int size = ArraySize( book_price );
//---    
    if ( size > 0 )
    { 
      for( int i = 0; i < size; i++ )
      {
        if ( book_price[i].type == BOOK_TYPE_SELL )
        {
          if ( book_price[i].price < s_price )
          {
            s_price = book_price[i].price;
          }
        }
        else
        if ( book_price[i].type == BOOK_TYPE_BUY )
        {
          b_price = book_price[i].price;
          break;
        }
      }
    }
  }
//---
  if ( s_price == DBL_MAX ) s_price = 0;
}
//+------------------------------------------------------------------+
// Custom indicator On book event function                           |
//+------------------------------------------------------------------+
void OnBookEvent( const string& a_symbol )
{
  if ( a_symbol == _Symbol )
  {
    double sell_price, buy_price;
    GetStakanValues( _Symbol, sell_price, buy_price );
    AskBuffer[0] = sell_price;
    BidBuffer[0] = buy_price; 
//---     
    double price[]; 
    on_call = true;
    OnCalculate( event_cnt, event_cnt, 0, price );  
  }
}
//+------------------------------------------------------------------+
//| 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];
    }
  }
  event_cnt = rates_total;
  return( rates_total );
}
 
Михаил:

Кому сложно вникнуть в детали, привожу полный код реал-тайм индикатора

Ask и Bid значений по выбранному символу (на ФОРЕКС должен быть работающий стакан цен )

Индикатор желательно запускать на файмфрейие М1 (больше значений будет отображаться) 

спс
 
Ilnur Khasanov:
спс
Пожалуйста.
 

В первой версии была ошибочка (пропадали предыдущие значения буферов)

здесь исправлено:

//+------------------------------------------------------------------+
//|                                                 Test_ask_bid.mq5 |
//|                              Copyright 2015, Mikalas & komposter |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, Mikalas & komposter"
#property link      "http://www.mql5.com"
#property version   "1.01"
//
#property indicator_separate_window

#property indicator_buffers 2
#property indicator_plots   2

//--- plot Label1
#property indicator_label1  "Ask"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//---
//--- plot Label1
#property indicator_label2  "Bid"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrBlue
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//
//--- indicator buffers
double AskBuffer[];
double BidBuffer[];
double sell_price, buy_price;
//
int event_cnt;
//
bool on_call;
//
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
  event_cnt = 0;
  on_call = false;
//--- Add book
  if ( !MarketBookAdd( _Symbol ) )
  {
    MessageBox( "Стакан символа " + _Symbol + " не добавден!", "Ошибка", MB_OK | MB_ICONHAND );
    return( INIT_FAILED );
  }
//---  
  IndicatorSetInteger( INDICATOR_DIGITS, _Digits );
  IndicatorSetString( INDICATOR_SHORTNAME, "Ask_Bid" );
//---  
  SetIndexBuffer( 0, AskBuffer, INDICATOR_DATA );
  PlotIndexSetDouble( 0, PLOT_EMPTY_VALUE, EMPTY_VALUE );
  ArraySetAsSeries( AskBuffer, true );
//---
  SetIndexBuffer( 1, BidBuffer, INDICATOR_DATA );
  PlotIndexSetDouble( 1, PLOT_EMPTY_VALUE, EMPTY_VALUE );
  ArraySetAsSeries( BidBuffer, true );
//---
  return( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+
// Custom indicator DeInit function                                  |
//+------------------------------------------------------------------+
void OnDeinit( const int reason )
{
  MarketBookRelease( _Symbol );
//---  
  if ( reason == REASON_INITFAILED )
  {
    Print( "Индикатор удалён! Причина - ошибка инициализации." );
    string short_name = ChartIndicatorName( 0, 1, 0 );
    ChartIndicatorDelete( 0, 1, short_name ); 
  }
}
//+------------------------------------------------------------------+
//| Custom indicator Get Stakan values function                      |
//+------------------------------------------------------------------+ 
void GetStakanValues( const string aSymbol, double &s_price, double &b_price )
{
  MqlBookInfo book_price[];
  b_price = 0;
  s_price = DBL_MAX;
  
//--- Get stakan
  if ( MarketBookGet( aSymbol, book_price ) )
  {
    int size = ArraySize( book_price );
//---    
    if ( size > 0 )
    { 
      for( int i = 0; i < size; i++ )
      {
        if ( book_price[i].type == BOOK_TYPE_SELL )
        {
          if ( book_price[i].price < s_price )
          {
            s_price = book_price[i].price;
          }
        }
        else
        if ( book_price[i].type == BOOK_TYPE_BUY )
        {
          b_price = book_price[i].price;
          break;
        }
      }
    }
  }
//---
  if ( s_price == DBL_MAX ) s_price = 0;
}
//+------------------------------------------------------------------+
// Custom indicator On book event function                           |
//+------------------------------------------------------------------+
void OnBookEvent( const string& a_symbol )
{
  if ( a_symbol == _Symbol )
  {
    GetStakanValues( _Symbol, sell_price, buy_price );
//---     
    double price[]; 
    on_call = true;
    OnCalculate( event_cnt, event_cnt, 0, price );  
  }
}
//+------------------------------------------------------------------+
//| 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];
        }
        AskBuffer[0] = sell_price;
        BidBuffer[0] = buy_price;
      }
    }
    else
    {
      if ( on_call )  //мы вызвали OnCalculate
      {
        on_call = false;
        AskBuffer[0] = sell_price;
        BidBuffer[0] = buy_price;
      }
      else
      {  
        AskBuffer[0] = AskBuffer[1];
        BidBuffer[0] = BidBuffer[1];
      }
    }
  }
  event_cnt = rates_total;
  return( rates_total );
}
Причина обращения: