Cómo hacer que los objetos dibujados por XY cambien suavemente (MT4 vs MT5) - página 2

 
Vitaliy Kuznetsov:

Gracias por este tipo de solución al problema. Efectivamente, la velocidad de renderizado ha mejorado. Parece que tendré que aprender la biblioteca.

También me gustaría aclarar el siguiente matiz. Compila con esta formulación con una advertencia:

Y se compila con este sin aviso, pero la velocidad es un poco más lenta.

¿Qué es más correcto?)

Ah, sí, me olvidé de poner int. La biblioteca está orientada a las coordenadas dobles.
La velocidad no puede bajar. (int) es prácticamente gratis. Menos de un nanosegundo.
Puedes ponerlo así:

y = Round(Canvas.Y(price));

Tampoco afectará a la velocidad (+ ~1 ns), pero posicionará con un poco más de precisión.

La función Round integrada en iCanvas devuelve int y es mucho más rápida que la función regular round(), pero el argumento doble x debe estar dentro de int (-2 147 483 648 <= x <= 2 147 483 647)

int Ceil (double x) { return (x-(int)x>0)?(int)x+1:(int)x; }
int Round(double x) { return (x>0)?(int)(x+0.5):(int)(x-0.5);}
int Floor(double x) { return (x>0)?(int)x:((int)x-x>0)?(int)x-1:(int)x; }
int Fabs(int x) {if (x<0) return -x; else return x;}
 
Vitaliy Kuznetsov:
No estoy muy seguro del tipo Canvas.Y(precio);

qué tipo devuelve

Mira dentro de iCanvas y la pregunta desaparece:

   double            X(double bar){return((double)W.Left_bar-bar)*W.dx_pix;}; //The X coordinate by the bar number. The bar number must be of type double, otherwise, the bar will be interpreted as time.
   double            X(datetime Time)                                         //The X coordinate by the time.
     { if(tester) return X((double)iBarShift(_Symbol,_Period,Time));
       else return X(wBarShift(Time,W.time,_Period));}
   double            Y(double Price) {if(W.dy_pix==0) W.dy_pix=1; return((W.Y_max-Price)/W.dy_pix); }; //The Y coordinate by the price.
   double            Price(int y)     {return (W.Y_max-y*(W.Y_max-W.Y_min)/W.Height);};                // Price by the Y coordinate
   double            Bar(double x) {return((double)W.Left_bar+1-x/(double)W.dx_pix);};                 // bar number by coordinate X                                                                      
   datetime          TimePos(double x)                                                                 // time by coordinate X 
     {
      double B=Bar(x);
      if (tester || W.BarsInWind == 0) iT[0]=iTime(_Symbol,_Period,(int)B);
      else {if(B<0 ) iT[0]=datetime(W.time[W.BarsInWind-1]-(long)B*PeriodSeconds());
      else if(B<W.Right_bar || B>W.Left_bar) iT[0]=iTime(_Symbol,_Period,(int)B);
      else iT[0]=W.time[W.BarsInWind-Floor(B)-1+(int)W.Right_bar];}
      return iT[0]+int((double)PeriodSeconds()*(1-B+(int)B));
     };
 
Como un pez en el agua :)
 
Vitaliy Kuznetsov:

Pero Kanvas es mucho más agradable de trabajar, puedes aplicar transparencia, es más rápido y el código ocupa menos espacio )):

#property indicator_chart_window
#include <Canvas\iCanvas.mqh> //https://www.mql5.com/ru/code/22164
#define  width 50                 
#define  height 10

#property indicator_buffers 0
#property indicator_plots   0

//+------------------------------------------------------------------+
int OnInit() {
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
int OnCalculate (const int rates_total,
                 const int prev_calculated,
                 const int begin,
                 const double& price[]) {
   if (rates_total!=prev_calculated) DrawObj();
   return(rates_total);
}
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam) {
   if(id == CHARTEVENT_CHART_CHANGE) DrawObj();
}
//+------------------------------------------------------------------+
void DrawObj() {

   double startPricePos = SymbolInfoDouble(_Symbol,SYMBOL_BID);
   int step_Pips = 50;
   Canvas.Erase(0x00FFFFFF);
   int x1 = W.Width/2;
   Canvas.CurentFont("Arial",10);
   for(int i=-19; i<=20; i++) {
      double stp = step_Pips*i*_Point;
      int y1 = (int)Canvas.Y(startPricePos + stp);
      Canvas.FillRectangle(x1,y1,x1+width, y1+ height, 0xA0ECE9D8);
      Canvas.Rectangle(x1,y1,x1+width, y1+ height, 0xDD807870);
      _CommXY(x1+5, y1, string(startPricePos + stp));
   }
   Canvas.Update();
}
//+------------------------------------------------------------------+



 
Vitaliy Kuznetsov:

Gracias por este tipo de solución al problema. Efectivamente, la velocidad de renderizado ha mejorado. Parece que tendré que aprender la biblioteca.

También me gustaría aclarar el siguiente matiz. Compila con esta formulación con una advertencia:

Y se compila con este sin aviso, pero la velocidad es un poco más lenta.

¿Qué es más correcto?)

Saca este código tuyo del bucle y llámalo una vez antes del bucle en cada evento de repintado:

 x=(int)(ChartGetInteger(chart_ID,CHART_WIDTH_IN_PIXELS,sub_window)/2);
   ChartXYToTimePrice(chart_ID,x,y,sub_window,time_pos_X_centr,price_pos_Y_tmp);         
         
   ChartTimePriceToXY(chart_ID,sub_window,time_pos_X_centr,price,x,y);

¿Es más complicado que aprender alguna biblioteca?

 
Aleksei Stepanenko:
Como un pez en el agua :)

PNB2))

 
Dmitry Fedoseev:

Saca este código del bucle y llámalo una vez antes de cada evento de redibujado:

¿Es realmente más complicado que aprender alguna biblioteca?

Eso es lo que estaba diciendo.
Sólo me pregunto: ¿puedes hacerlo tú mismo y no repetir mis consejos?
dos de ellos son fáciles de emitir...
Código, por favor.
Si no lo haces, lo escribiré yo mismo mañana cuando me despierte. Pero entonces llamaré idiota a Fedoseev. ))

 
Nikolai Semko:

Eso es lo que he dicho.
Sólo me pregunto: ¿puedes hacerlo tú mismo y no repetir mis consejos?
dos de ellos son fáciles de emitir...
Código, por favor.
Si no lo haces, lo escribiré yo mismo mañana cuando me despierte. Pero entonces llamaré idiota a Fedoseev. ))

Increíblemente impresionado por sus ideas sobre mí))

 
Dmitry Fedoseev:

Estoy increíblemente impresionado por su percepción de mí))

Menos palabras, más acción

 

Gracias por los ejemplos. Muy claro e informativo, y no menos rápido.

Todos los gráficos del ejemplo en el kanvas en las listas de objetos parecen un solo objeto.

¿Es posible obtener diferentes informaciones sobre herramientas (tooltips) al pasar el ratón por encima de elementos gráficos individuales?

¿O puedo crear un objeto de lienzo distinto para cada rectángulo? ¿No afectará a la velocidad?

Si tienes tiempo, espero una respuesta, y quizás un ejemplo de código.

Razón de la queja: