Реал-тайм индикатор из советника

 

Добрый день!

Хочу написать индикатор (не используя стандартный индикатор) работающий

из советника в реальном времени (для отображения ASK и BID), но 

не знаю с чего начать. 

Кто-нибудь делал подобное? 

 
Индикатор встроенный внутрь советника? Или индикатор, который вызывается советником?
 
Yury Kirillov:
Индикатор встроенный внутрь советника? Или индикатор, который вызывается советником?
Индикатор ИЗ советника (полностью собственный).
 
Михаил:
Индикатор ИЗ советника (полностью собственный).

Очень хлопотное занятие, пробовал... совсем простенький пример без проверок, шкалы цен и горизонтальной прокрутки:

#include <Canvas\Canvas.mqh>
CCanvas Chart;

int scale_width=8;       //расстояние в пикселях между точками
color clr_ask = clrRed;  //цвет ask
color clr_bid = clrBlue; //цвет bid

MqlTick tick_array[];
int x_p[];
int y_p[];

int widtn_chart=0;
int height_chart=0;
int tick_in_chart=0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   ChartSetInteger(0,CHART_SHOW_DATE_SCALE,false);
   ChartSetInteger(0,CHART_SHOW_PRICE_SCALE,false);

   widtn_chart=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);
   height_chart=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);

   Chart.CreateBitmapLabel("Chart",0,0,widtn_chart,height_chart,COLOR_FORMAT_ARGB_NORMALIZE);
   Chart.Erase(ColorToARGB(clrBlack));
   Chart.Update(true);

   tick_in_chart=widtn_chart/scale_width;
   ArrayResize(tick_array,tick_in_chart);
   ArraySetAsSeries(tick_array,true);

   ArrayResize(x_p,tick_in_chart);
   ArrayResize(y_p,tick_in_chart);

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Chart.Destroy();
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(widtn_chart!=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS) || 
      height_chart!=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS))
     {
      widtn_chart=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);
      height_chart=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);

      Chart.CreateBitmapLabel("Chart",0,0,widtn_chart,height_chart,COLOR_FORMAT_ARGB_NORMALIZE);
      Chart.Erase(ColorToARGB(clrBlack));
      Chart.Update(true);

      tick_in_chart=widtn_chart/scale_width;
      ArrayResize(tick_array,tick_in_chart);
      ArraySetAsSeries(tick_array,true);

      ArrayResize(x_p,tick_in_chart);
      ArrayResize(y_p,tick_in_chart);
     }

   Chart.Erase(ColorToARGB(clrBlack));

   CopyTicks(_Symbol,tick_array,COPY_TICKS_INFO);

   double max = -1.0;
   double min = DBL_MAX;

   for(int i=0; i<tick_in_chart; i++)
     {
      if(tick_array[i].ask > max) max = tick_array[i].ask;
      if(tick_array[i].bid < min) min = tick_array[i].bid;
     }

   double delta=max-min;

//ask   
   for(int i=0; i<tick_in_chart; i++)
     {
      y_p[i]=int(height_chart-height_chart*(tick_array[i].ask-min)/delta);

      if(i==0)
         x_p[i]=widtn_chart-8*scale_width;
      else
         x_p[i]=x_p[i-1]-scale_width;

      Chart.FillCircle(x_p[i],y_p[i],3,ColorToARGB(clr_ask));
     }

   Chart.Polyline(x_p,y_p,ColorToARGB(clr_ask));

//bid
   for(int i=0; i<tick_in_chart; i++)
     {
      y_p[i]=int(height_chart-height_chart*(tick_array[i].bid-min)/delta);

      if(i==0)
         x_p[i]=widtn_chart-8*scale_width;
      else
         x_p[i]=x_p[i-1]-scale_width;

      Chart.FillCircle(x_p[i],y_p[i],3,ColorToARGB(clr_bid));
     }

   Chart.Polyline(x_p,y_p,ColorToARGB(clr_bid));

//выводим на экран
   Chart.Update(true);
  }
//+------------------------------------------------------------------+
//| Обработка событий
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   if(id==CHARTEVENT_CHART_CHANGE)
     {
      OnTick();
     }
  }
//+------------------------------------------------------------------+

 В нем ещё и фон отключить надо - чтобы при изменении размера графика не глючило... Кому лень компилировать - то выглядит это так:

 

 
Andrey Miguzov:

Очень хлопотное занятие, пробовал... совсем простенький пример без проверок, шкалы цен и горизонтальной прокрутки:

 В нем ещё и фон отключить надо - чтобы при изменении размера графика не глючило... Кому лень компилировать - то выглядит это так:

 

Хлопотное, поэтому и спрашиваю :)

Но Вы молодец! Начало положено. 

Только Ask и Bid лучше в одном цикле считать. 

 
Михаил:

Добрый день!

Хочу написать индикатор (не используя стандартный индикатор) работающий

из советника в реальном времени (для отображения ASK и BID), но 

не знаю с чего начать. 

Кто-нибудь делал подобное? 

А зачем из советника отображать какие-то данные ? Если надо их использовать в советнике - то прямо при расчете - они и используются...

Или что там за такая хитрая задача ?

Если уж совсем невтерпеж, чтобы какие-то вещи отображались - я бы пошел на "разделение" - советник готовит данные для индикатора, а самописный индикатор их "подхватывает" и отображает.

 
George Merts:

А зачем из советника отображать какие-то данные ? Если надо их использовать в советнике - то прямо при расчете - они и используются...

Или что там за такая хитрая задача ?

Если уж совсем невтерпеж, чтобы какие-то вещи отображались - я бы пошел на "разделение" - советник готовит данные для индикатора, а самописный индикатор их "подхватывает" и отображает.

Здорово!

1. Но как данные "подхватывать"?

2. Как сделать реал-тайм? 

 
George Merts:

А зачем из советника отображать какие-то данные ? Если надо их использовать в советнике - то прямо при расчете - они и используются...

Или что там за такая хитрая задача ?

Чтобы словами долго не расписывать, зайдите лучше в профиль к Yury Kulikov и посмотрите на его продукты в Маркете. Визуализация данных для контроля, анализа и принятия решений - это и есть основная задача.

George Merts:

Если уж совсем невтерпеж, чтобы какие-то вещи отображались - я бы пошел на "разделение" - советник готовит данные для индикатора, а самописный индикатор их "подхватывает" и отображает. 

И это есть - вроде только недавно обсуждали - в конце темы ссылка на кодбазу - там рабочий пример того о чем Вы говорите.

 

А можно как-нибудь двигать график в стандартном индикаторе

без OnCalculate()

 
Михаил:

А можно как-нибудь двигать график в стандартном индикаторе

без OnCalculate()? 

Горизонтально PLOT_SHIFT. Вертикально можно только стрелки (PLOT_ARROW_SHIFT).
Документация по MQL5: Стандартные константы, перечисления и структуры / Константы индикаторов / Стили рисования
Документация по MQL5: Стандартные константы, перечисления и структуры / Константы индикаторов / Стили рисования
  • www.mql5.com
Стандартные константы, перечисления и структуры / Константы индикаторов / Стили рисования - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Andrey Miguzov:
Горизонтально PLOT_SHIFT. Вертикально можно только стрелки (PLOT_ARROW_SHIFT).

Cпасибо.

Вот как-то так получается (но не полный реал-тайм):

 

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