Мигание линий и прямоугольников в момент прогрузки котировок

 

Столкнулся со следующей проблемой в МТ5.

Есть индикаторы, которые рисуют линии и прямоугольники на указанное кол-во свечей.

Если мы переходим на W1, MN, где видно, как появляются свечи, то если объекты умещаются в видимой части окна, то они не мигают.

А если объекты заходят за видимую часть экрана, то мигают синхронно в разных индикаторах в момент прогрузки котировок.

Т.е. даже Bars Count 200 и все двести свечей загружены, то подвинув ползунок смещения экрана, тем самым убрав видимую часть за левый край, то будут мигать, пока грузятся котировки.

Индикатор уже всё посчитал и нарисовал. Но из-за дозагрузки котировок объекты мигают (если частично заходят за невидимый край).


Это баг терминала или что-то можно прописать в индикатор, чтобы мигания не было из-за долёта котировок?

 

И так в догонку. Почему так долго удаляется индикатор с объектами? Точнее индюк сразу удаляется, а объекты ждут чего-то.

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

Тут мне нахваливают, что МТ5 такой быстрый и совершенный, но я что-то никак не привыкну к таким скоростям :)

 
Vitaliy Kuznetsov:

И так в догонку. Почему так долго удаляется индикатор с объектами? Точнее индюк сразу удаляется, а объекты ждут чего-то.

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

Тут мне нахваливают, что МТ5 такой быстрый и совершенный, но я что-то никак не привыкну к таким скоростям :)

они (индикаторы) ещё и загружаются наизнанку...подчас сначала загружается новый, потом выгружается прежний. Если судить по журналу в момент переключения ТФ :-)

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

с другой стороны наличествует ситуация гонок. 

Подкачка истории, тот ещё ребус. В конкретных индикаторах надо ловить что докаченная история не влияет на отображённое в последнем моменте и не надо что-то с этим делать. 

А это тонны кода и ошибок  на ровном месте. Проще и надёжнее (про тонны кода, которых лучше не делать) пересчитать заново.

Ограничивайте глубину докачки истории в настройках терминала, а перед запуском сов скачивайте требуемую им историю принудительно. 

 

Я приготовил прототип. Прямоугольники и линии. Оба мигают, как только прогрузка котировок врезается в отсечку.

Если длина линии помещается в экране, то миганий не будет.

Воспроизведение. Устанавливаете на M15, переключаетесь на W1 и выше. Тут без разницы, главное что котировки будут подгружаться.

Можете также мышкой перетягивать новые пары в окно.

Мигание закончится, когда прогрузятся все свечи инструмента (а не длины линии), а это порой долгий процесс.

А если отключить автопрокрутку и погонять колёсиком мыши туда-сюда, то увидите странный эффект пропадания графика.


Вот вам код

//+------------------------------------------------------------------+
//|                                   Prototype_RectangleAndLine.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window


#property indicator_buffers 0
#property indicator_plots   0

input int BarsCount = 1000;   // Bars Count
input int Distance  = 1000;    // Distance 

string obj_name = "mYInd_";

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(){
   ObectDel();
return(INIT_SUCCEEDED);}

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnDeinit(const int reason){
   ObectDel();
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[]){
   if(NewBar()){
      DrawObj();
   }
return(rates_total);}

//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam){
   if(id == CHARTEVENT_CHART_CHANGE){
      DrawObj();
   }
}

//+------------------------------------------------------------------+
//| Выводим на график                                                |
//+------------------------------------------------------------------+

void DrawObj(){
   string GenName = obj_name;
   double startPricePos = SymbolInfoDouble(Symbol(),SYMBOL_BID);
   for(int i=1; i<=20;i++){
      double stp1 = (Distance*i)*Point();
      double stp2 = ((Distance/2)*i)*Point();

      RectangleCreate(GenName+"_RECT_UP_"+IntegerToString(i),startPricePos + stp1);
      RectangleCreate(GenName+"_RECT_DN_"+IntegerToString(i),startPricePos - stp1);
      
      TrendCreate(GenName+"_LINE_UP_"+IntegerToString(i),startPricePos + stp2);
      TrendCreate(GenName+"_LINE_DN_"+IntegerToString(i),startPricePos - stp2);
   }
   ChartRedraw(0);
}

//+------------------------------------------------------------------+ 
//| Cоздает прямоугольник по заданным координатам                    | 
//+------------------------------------------------------------------+ 

void RectangleCreate(
                     string name,   // имя метки 
                     double price   // цена
                     ){
   int distPips = Distance / 4;
   const long            chart_ID=0;        // ID графика 
   const int             sub_window=0;      // номер подокна  
   datetime              time1=iTime(NULL,0,0);                                  // время первой точки 
   double                price1 = price + distPips * Point();                    // цена первой точки 
   datetime              time2=iTime(NULL,0,MathMin(BarsCount,iBars(NULL,0)-1)); // время второй точки 
   double                price2 = price - distPips * Point();                    // цена второй точки 
   const color           clr=clrRed;        // цвет прямоугольника 
   const ENUM_LINE_STYLE style=STYLE_SOLID; // стиль линий прямоугольника 
   const int             width=1;           // толщина линий прямоугольника 
   const bool            fill=true;         // заливка прямоугольника цветом 
   const bool            back=true;        // на заднем плане 
   const bool            selection=false;   // выделить для перемещений 
   const bool            hidden=true;       // скрыт в списке объектов 
   const long            z_order=0;         // приоритет на нажатие мышью  
 
   if(!ObjectIsExist(name)){
      if(ObjectCreate(chart_ID,name,OBJ_RECTANGLE,sub_window,time1,price1,time2,price2)){
         ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr); 
         ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style); 
         ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width); 
         ObjectSetInteger(chart_ID,name,OBJPROP_FILL,fill); 
         ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back); 
         ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection); 
         ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection); 
         ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden); 
         ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
      }
   }else{
      ObjectMove(chart_ID,name,0,time1,price1);
      ObjectMove(chart_ID,name,1,time2,price2);
   }
}


//+------------------------------------------------------------------+ 
//| Создает линию тренда по заданным координатам                     | 
//+------------------------------------------------------------------+
void TrendCreate(
                  string name,   // имя метки 
                  double price   // цена
                  ){
   const long            chart_ID=0;        // ID графика 
   const int             sub_window=0;      // номер подокна 
   datetime              time1=iTime(NULL,0,0);                                  // время первой точки 
   double                price1=price;          // цена первой точки 
   datetime              time2=iTime(NULL,0,MathMin(BarsCount,iBars(NULL,0)-1)); // время второй точки 
   double                price2=price;          // цена второй точки 
   const color           clr=clrBlue;       // цвет линии 
   const ENUM_LINE_STYLE style=STYLE_SOLID; // стиль линии 
   const int             width=1;           // толщина линии 
   const bool            back=true;         // на заднем плане 
   const bool            selection=false;   // выделить для перемещений 
   const bool            ray_right=false;   // продолжение линии вправо 
   const bool            hidden=true;       // скрыт в списке объектов 
   const long            z_order=0;         // приоритет на нажатие мышью 

   if(!ObjectIsExist(name)){
      if(ObjectCreate(chart_ID,name,OBJ_TREND,sub_window,time1,price1,time2,price2)){
         ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr); 
         ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style); 
         ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width); 
         ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back); 
         ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection); 
         ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection); 
         ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right); 
         ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden); 
         ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
      }
   }else{
      ObjectMove(chart_ID,name,0,time1,price1);
      ObjectMove(chart_ID,name,1,time2,price2);
   }
} 


//+------------------------------------------------------------------+
//| Есть-ли обьект на графике                                        |
//+------------------------------------------------------------------+
bool ObjectIsExist(string name){
   if(ObjectGetString(0,name,OBJPROP_NAME,0)==name)return(true);
return(false);}

//+------------------------------------------------------------------+
//| Появился новый бар                                               |
//+------------------------------------------------------------------+

bool NewBar(){
   static int countLastBar=0;
   int curBars = iBars(Symbol(),PERIOD_CURRENT);
   bool flg = false;
   if(countLastBar!=curBars){
      countLastBar=curBars;
      flg=true;
   }
return(flg);}

//+------------------------------------------------------------------+
//| Удалить обьекты                                                  |
//+------------------------------------------------------------------+
void ObectDel(){
   ObjectsDeleteAll(0,obj_name+"_RECT_",0,OBJ_RECTANGLE);
   ObjectsDeleteAll(0,obj_name+"_LINE_",0,OBJ_TREND);
}

Что можно сделать, чтобы такого эффекта на было?

Файлы:
 

Если реализовать через канвас прямоугольники с длиной по кол-ву баров, то графика при прогрузке свечей ведёт себя так



Уважаемые Админы и программисты проекта, просьба самым тщательным образом подумать над загрузкой котировок в терминале МТ5.

Это не только я считаю проблемой. Пример в комменте:

https://www.mql5.com/ru/forum/373748/page5#comment_23572002

 
Проблема существует и довольно давно с отрисовкой объектов.
 

Сама проблема мигания как мне кажется из-за получения неверных данных или пропуске данных из-за очереди (что-то с синхронностью намудрили в МТ5).

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


Но как по мне, это своего рода костыль.

Файлы:
 
Очень интересно, а что же такое "прогрузка" котировок и особенно ее момент.
 

Дмитрий, Я думаю, что если Вы внимательно прочтёте ветку с начала, то не будет возникать подобных вопросов, а то какой-то троллинг получается.

Если не понимаете, что такое "момент прогрузки", то читайте как "процесс загрузки". В любом случае, когда всё на скринах с анимацией, называйте как хотите, ведь всё видно без слов.

 
Vitaliy Kuznetsov:

Дмитрий, Я думаю, что если Вы внимательно прочтёте ветку с начала, то не будет возникать подобных вопросов, а то какой-то троллинг получается.

Если не понимаете, что такое "момент прогрузки", то читайте как "процесс загрузки". В любом случае, когда всё на скринах с анимацией, называйте как хотите, ведь всё видно без слов.

Ну пусть будет "процесс загрузки", это ничего не меняет. Почитал бы, если было бы что читать, а пока все на уровне какой-то "прогрузки" чего-то. И заметьте, проблемы не у меня.

 

Vitaliy Kuznetsov:

...прогрузка котировок врезается в отсечку...

...

Ну ваще))

Фэйспалм

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