Что не так с canvas в мт5? - страница 3

 
Alexandr Gavrilin #:
подготовил для демонстрации некий вариант говнокода) но в мт4 все плавно и быстро, в мт5 ужас.

хорошо, я сейчас загляну в ваш файл и попробую реализовать через мой iCanvas для наглядности

 
Nikolai Semko #:

хорошо, я сейчас загляну в ваш файл и попробую реализовать через мой iCanvas для наглядности

начинаем с профилирования и получаем картину, подтверждающую мои слова


 
Alexandr Gavrilin #:
подготовил для демонстрации некий вариант говнокода) но в мт4 все плавно и быстро, в мт5 ужас.

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

мне нужно минут 10

 
Nikolai Semko #:

вижу еще одну Вашу симантическую ошибку, которая увеличивает расчет в то колличество раз, сколько бар текущего периода помещается в одном дне.

вот о чем речь

было:

for(int i=ileft; i>MathMax(0,iright); i--) 
        {
           int iday=iBarShift(_Symbol,PERIOD_D1,iTime(_Symbol,0,i));

надо:

int iday=iBarShift(_Symbol,PERIOD_D1,iTime(_Symbol,0,left));
for(; iday>=0; iday--) {
 
готово.
В результате ваш код состоял из 496 строк кода и жутко лагал по двум причинам - безбашенное использование функций ChartGet и XY функций, а так же серьезная логическая ошибка, которая дублировала многократно одну и ту же работу
Мой код состоит из 64 строк кода ( по факту моего кода лишь 19 строк, остальное шаблонная нахлабуда) и все летает
на M1 время формирования канваса 0,5 миллисекунд, на M15 - 1 мс, на H2 - 5-7 мс 
Файлы:
 

Сделал замер в исходном индикаторе на видео через GetMicrosecondCount.  и результат разделил на 1000.

13-54 мс разве этого врени не достаточно чтобы успевать обновлять канвас без лишних миганий? ене понимаю, ну да ChartPriceToXY часто используется для определения начала дня, месяца, недели на графике в координаты. Но без нее никак.

У вас такая функция int XYToTimePrice(int x,int y,datetime &Time,double &Price,int id=0)

а обратная функция есть из цены\время в координаты?

 
Alexandr Gavrilin #:

Сделал замер в исходном индикаторе на видео через GetMicrosecondCount.  и результат разделил на 1000.

13-54 мс разве этого врени не достаточно чтобы успевать обновлять канвас без лишних миганий? ене понимаю, ну да ChartPriceToXY часто используется для определения начала дня, месяца, недели на графике в координаты. Но без нее никак.

У вас такая функция int XYToTimePrice(int x,int y,datetime &Time,double &Price,int id=0)

а обратная функция есть из цены\время в координаты?

Ваш код мигает даже после исправления семантической ошибки, о которой писал. 
Мой код нет. Писал почему.
Не надо использовать мою  внутреннюю функцию XYToTimePrice ( забыл ее сделать private)
Все функции есть, внимательно читайте описание кода

https://www.mql5.com/ru/code/22164


   double            X(datetime Time);          // The X coordinate by the time.
   double            Y(double Price);           // The Y coordinate by the price.
   double            Price(int y);              // Price by the Y coordinate
   double            Bar(int x);                // bar number by coordinate X                                                                      
   datetime          TimePos(int x);            // time by coordinate X 
   

Easy Canvas
Easy Canvas
  • www.mql5.com
Данная библиотека и класс iCanvas упростит написание программ с применением Canvas.
 
Alexandr Gavrilin #:

13-54 мс разве этого врени не достаточно чтобы успевать обновлять канвас без лишних миганий?

миганий не должно быть даже при более длительном формировании кадра.
Мигания могут быть из-за неправильной установки Upgrade(), лишней, или не в то время. 
Также могут быть, если вы кроме объекта канваса используете другие объекты, т.к. их перерисовка не входят в замер, и они живут своей отдельной жизнью, в MT5 для них своя отдельная очередь, к которой программист не имеет доступа даже для того чтобы ее замерить.

 
Nikolai Semko #:

миганий не должно быть даже при более длительном формировании кадра.
Мигания могут быть из-за неправильной установки Upgrade(), лишней, или не в то время. 
Также могут быть, если вы кроме объекта канваса используете другие объекты, т.к. их перерисовка не входят в замер, и они живут своей отдельной жизнью, в MT5 для них своя отдельная очередь, к которой программист не имеет доступа даже для того чтобы ее замерить.

Кроме каныас да используются и другие объекты 
 
Nikolai Semko #:
готово.
В результате ваш код состоял из 496 строк кода и жутко лагал по двум причинам - безбашенное использование функций ChartGet и XY функций, а так же серьезная логическая ошибка, которая дублировала многократно одну и ту же работу
Мой код состоит из 64 строк кода ( по факту моего кода лишь 19 строк, остальное шаблонная нахлабуда) и все летает
на M1 время формирования канваса 0,5 миллисекунд, на M15 - 1 мс, на H2 - 5-7 мс 

я поставил крайний правый дневной бар равный 0. 
Но правильнее для производительности, конечно так, особенно если скролить влево:

#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots 0

#include <Canvas\iCanvas_CB.mqh> // https://www.mql5.com/ru/code/22164

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 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[]) {
   OnDraw();
   return(rates_total);
}
//+------------------------------------------------------------------+
void OnChartEvent(const int id,         // идентификатор события
                  const long& lparam,   // параметр события типа long
                  const double& dparam, // параметр события типа double
                  const string& sparam  // параметр события типа string
                 ) {
   if (id==CHARTEVENT_CHART_CHANGE) OnDraw();
}
//+------------------------------------------------------------------+
void      OnDraw() {
   ulong tt = GetMicrosecondCount();
   Canvas.Erase(0x00FFFFFF);
   int iday=iBarShift(_Symbol,PERIOD_D1,iTime(_Symbol,0,W.Left_bar));
   int right_day=iBarShift(_Symbol,PERIOD_D1,iTime(_Symbol,0,(int)W.Right_bar));
   for(; iday>=right_day; iday--) {
      datetime t0 = iTime(_Symbol,PERIOD_D1,iday);
      datetime t1 = TimeCurrent(); 
      if (iday>0) t1 = iTime(_Symbol,PERIOD_D1,iday-1);
      Canvas.LineThick((int)_X(t0),(int)_Y(iHigh(_Symbol,PERIOD_D1,iday)),(int)(iday>0?_X(t1):W.Width),(int)_Y(iHigh(_Symbol,PERIOD_D1,iday)),0xFF0000FF,2,STYLE_DOT,LINE_END_BUTT);
      Canvas.LineThick((int)_X(t0),(int)_Y(iOpen(_Symbol,PERIOD_D1,iday)),(int)(iday>0?_X(t1):W.Width),(int)_Y(iOpen(_Symbol,PERIOD_D1,iday)),0xFF0000FF,2,STYLE_DOT,LINE_END_BUTT);
      Canvas.LineThick((int)_X(t0),(int)_Y(iClose(_Symbol,PERIOD_D1,iday)),(int)(iday>0?_X(t1):W.Width),(int)_Y(iClose(_Symbol,PERIOD_D1,iday)),0xFF0000FF,2,STYLE_DOT,LINE_END_BUTT);
      Canvas.LineThick((int)_X(t0),(int)_Y(iLow(_Symbol,PERIOD_D1,iday)),(int)(iday>0?_X(t1):W.Width),(int)_Y(iLow(_Symbol,PERIOD_D1,iday)),0xFF0000FF,2,STYLE_DOT,LINE_END_BUTT);
      Canvas.CurentFont("Times New Roman",20,20,0xFF0000FF);
      _CommXY((int)_X(t0),(int) _Y(iHigh(_Symbol,PERIOD_D1,iday))-20, TimeToString(iTime(_Symbol,PERIOD_D1,iday),TIME_DATE));
   }
   tt = GetMicrosecondCount() - tt;
   _CommXY(W.Width/3, 40, "Время очистки и формирования канваса = " + DoubleToString(tt/1000.0, 2) + " миллисекунд");
   Canvas.Update();
}
//+------------------------------------------------------------------+