Prueba CGraphic - preguntas y sugerencias - página 12

 

CGrafic::Destroy() - ¡No funciona!


//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|                                                     F_Spread.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.000"
#property indicator_separate_window
#property indicator_plots   1
#property indicator_buffers 1
//---
#define  IND_RESIZE 1
#define  RESULT_OR_NAN(x,expression) ((x==0)?(double)"nan":expression)
//--- Functions
double BlueFunction(double x)   { return(RESULT_OR_NAN(x,10*x*sin(1/x)));      }
double RedFunction(double x)    { return(RESULT_OR_NAN(x,sin(100*x)/sqrt(x))); }
double OrangeFunction(double x) { return(RESULT_OR_NAN(x,sin(100*x)/sqrt(-x)));}
//---
#include <Graphics\Graphic.mqh>
CGraphic Chart;
CColorGenerator generator;
bool is_create;
int sub_window;
int cur_height, cur_width;
//double a_array[];
double v_max, v_min, i_step;
int cnt = 0;
uint blue, red, orange;
double a_from, a_to, a_step;
//+------------------------------------------------------------------+
//| inputs                                                           |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Custom indicator Fill data function                              |
//+------------------------------------------------------------------+
void FillData()
{
  Chart.CurveAdd(RedFunction,a_from,a_to,a_step,red,CURVE_LINES,"Red");
  Chart.CurveAdd(OrangeFunction,a_from,a_to,a_step,orange,CURVE_LINES,"Orange");
  Chart.CurveAdd(BlueFunction,a_from,a_to,a_step,blue,CURVE_LINES,"Blue");
  Chart.CurvePlotAll();
  Chart.Update();
}
//+------------------------------------------------------------------+
//| Custom indicator ChartResize function                            |
//+------------------------------------------------------------------+
void ChartResize()
{
  cnt++;
  if(cnt > 2) return;
  if(is_create == true)
  {
    Chart.Destroy();
    
    
    Chart.CurveAdd(RedFunction,a_from,a_to,a_step,red,CURVE_LINES,"Red_exists");
    Chart.CurveAdd(OrangeFunction,a_from,a_to,a_step,orange,CURVE_LINES,"Orange_exists");
    Chart.CurveAdd(BlueFunction,a_from,a_to,a_step,blue,CURVE_LINES,"Blue_exists");
    Chart.CurvePlotAll();
    Chart.Update();
    is_create = false;
  }  
  cur_height =  int(ChartGetInteger(ChartID(),CHART_HEIGHT_IN_PIXELS, sub_window));
  cur_width =  int(ChartGetInteger(ChartID(),CHART_WIDTH_IN_PIXELS, sub_window));
  is_create = Chart.Create(ChartID(), "Spread", sub_window, 0, 0, cur_width, cur_height);
  if(is_create == true)
  {
    Chart.BackgroundColor(clrWhite);
    
    FillData();
  }
}
//+------------------------------------------------------------------+
//| Custom indicator OnInit function                                 |
//+------------------------------------------------------------------+
int OnInit()
{
  IndicatorSetInteger(INDICATOR_DIGITS, 0);
  IndicatorSetString(INDICATOR_SHORTNAME, "F_Spread");
  sub_window = ChartWindowFind(ChartID(),"F_Spread");
  v_max = SymbolInfoDouble(Symbol(), SYMBOL_SESSION_PRICE_LIMIT_MAX);
  v_min = -SymbolInfoDouble(Symbol(), SYMBOL_SESSION_PRICE_LIMIT_MIN);  
  i_step = SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_SIZE);
  is_create = false;
//===
  a_from=-1.2;
  a_to=1.2;
  a_step=0.005;
  blue= generator.Next();
  red = generator.Next();
  orange=generator.Next();
//---  
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator OnDeinit function                               |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  if(is_create == true)
  {
    Chart.Destroy();
  }
}
//+------------------------------------------------------------------+
//| Custom indicator ChartEvent function                             |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
  if(id == CHARTEVENT_CHART_CHANGE)
  {
    int i_heigth =  int(ChartGetInteger(ChartID(),CHART_HEIGHT_IN_PIXELS, sub_window));
    int i_width =  int(ChartGetInteger(ChartID(),CHART_WIDTH_IN_PIXELS, sub_window));
    if((i_heigth != cur_height) || (i_width != cur_width))
    {
      EventChartCustom(ChartID(), CHARTEVENT_CUSTOM + IND_RESIZE, 1, 1, "resize");
    }
  }
  else
  if((id > CHARTEVENT_CUSTOM) && (sparam == "resize"))
  {
    PlaySound("");
    ChartResize();
  }   
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
{
  
  return(rates_total);
}
//+------------------------------------------------------------------+
 
prostotrader:

CGrafic::Destroy() - ¡No funciona!

¿Cómo lo has detectado? ¿Cuáles son los síntomas?

 
Denis Kirichenko:

¿Cómo lo ha identificado? ¿Cuáles son los síntomas?

Bueno, el código se adjunta para la reproducción :)

Y en la imagen se puede ver que después de Destroy() se añaden los gráficos

con el prefijo

_exists
 
prostotrader:

Pero el código se adjunta para la reproducción :)

Y en la imagen se puede ver que después de Destroy() se añaden los gráficos

con el prefijo

Bueno, mi pregunta era sobreCGrafic::Destroy(). Funciona - Lo he comprobado con el depurador... ¿Tal vez algo está mal en su código?

 
Denis Kirichenko:

Bueno, la pregunta era específicamente sobreCGrafic::Destroy(). Funciona - Lo he comprobado en el depurador... ¿Tal vez algo está mal en su código?

Entrar en el cuerpo de Destroy() no significa que éste (el procedimiento) funcione correctamente.

Después de la destrucciónreal de un objeto no podemos añadir nuevos gráficos a él, ¡y se añaden!

Chart.Destroy();
    
    
    Chart.CurveAdd(RedFunction,a_from,a_to,a_step,red,CURVE_LINES,"Red_exists");
    Chart.CurveAdd(OrangeFunction,a_from,a_to,a_step,orange,CURVE_LINES,"Orange_exists");
    Chart.CurveAdd(BlueFunction,a_from,a_to,a_step,blue,CURVE_LINES,"Blue_exists");
 
prostotrader:

Entrar en el cuerpo del procedimiento Destroy() no significa en absoluto que éste (el procedimiento) esté funcionando correctamente.

Después de la destrucción real de un objeto, no podíamos añadirle nuevos gráficos, ¡y lo hacen!

Sobre los golpes, estoy de acuerdo. Pero sin embargo... Bueno, en primer lugar,voidCGrafic::Destroy(). Es decir, el método no nos debe nada. Y en segundo lugar, ¿quizás sea el programador quien deba añadir comprobaciones? No se puede configurar SB para todas las tareas...

 
Denis Kirichenko:

Sobre los golpes, estoy de acuerdo. Pero sin embargo... Bueno, en primer lugar,voidCGrafic::Destroy(). Es decir, el método no nos debe nada. Y en segundo lugar, ¿quizás sea el programador quien deba añadir comprobaciones? No se puede configurar SB para todas las tareas.

Además, he modificado el método de destrucción.

//+------------------------------------------------------------------+
//| Remove graphic from chart                                        |
//+------------------------------------------------------------------+
void CGraphic::Destroy(const long chart,const string name)
  {
    if(ObjectFind(chart,name)>=0)
    {
      SetDefaultParameters();
      m_generator.Reset();
      m_canvas.Destroy();
      bool res = ObjectDelete(chart,name);
      if(res == true)
      {
        Print("Object destroyed!"); 
      }
     }  
   }
2020.11.02 17:16:45.408 F_Spread (Si-12.20,M1)  Object destroyed!

¡Y sigue añadiendo gráficos!

 
¿Cómo se hace el cambio de tamaño en CGraphic?
 

Trazo los gráficos y la salida del texto utilizando CGraphic. Si ejecuto una instancia del EA, todo va bien. Si ejecuto el mismo EA en diferentes gráficos, me da la impresión de que la salida siempre es en el gráfico que está actualmente en la pantalla. Y no en el gráfico que se especifica en el método Create. Aquí está el código del EA para demostrar el problema:

#include <Graphics\Graphic.mqh>

CGraphic          Graphic;     // Для вывода графика.
long ChartId;
int OnInit()
  {
   ChartId= ID_Grafika_S_Expertom(); // Узнаем Id графика на котором запущен советник.
   Graphic.Create(ChartId,"CPrecieIdealnayFast ", 0, 10, 30, 500, 500);   
   Print("OnInit ",Symbol()," ChartId=",ChartId);
   EventSetMillisecondTimer(1000);
   return(INIT_SUCCEEDED);
  }

void OnTimer()
  {  
   string Str;
   StringConcatenate(Str,ChartId," ",Symbol()," ",TimeLocal());
   Graphic.FontSet("Arial",20);
   Graphic.TextAdd(20,30, Str, ColorToARGB(clrRed), TA_LEFT|TA_TOP);
   Graphic.Update();
   Graphic.Redraw(true);     
  }
void OnDeinit( const int Reanson )
  {
  Graphic.Destroy();
  }
  
  long ID_Grafika_S_Expertom()
  {
   string MaskaNameExpert=              MQLInfoString(MQL_PROGRAM_NAME);
   int SekyndNaGrafikeSTekygemExpertom= PeriodSeconds();
   string SimvolExpert=                 Symbol();
//--- 1. Настраиваемся на первый график. Если не получилось возращаем советник не найден. 

//--- В цикле.
//--- 2. Получаем Имя эксперта.
//--- --- 2.1 Если не удалось получить имя эксперта смотрим следующий график.
//--- --- --- 2.2 Если не удалось получить слеюущий график выходим из цикла.
//--- 3.A Если на графике есть эксперт И в его названии есть маска: Запоминаем Id и выходим из цикла.
//--- 3.B Если Нет эксперта или НЕ нашли смотрим следующий график.  
//--- --- 3.B.A Если не удалось получить слеюущий график выходим из цикла.   
//--- --- 3.B.B Если  Удалось получить слеюущий график ищем в начало цикла.  

   long ID_Chart= -1;
   string NameExpert="";   
   long   IskomoeIdChart= -1;
   int    LimitChatr= 1000;            // Наверняка ведь не 1000 графиков.
   int    i=0;                         // Cчетчик графиков
   
//--- 1. Настраиваемся на первый график. Если не получилось возращаем советник не найден. 
   ID_Chart= ChartFirst();
   if( ID_Chart < 0 ) return -1;
   
   string Simvol;
   int    KolichestvoSekynd;
   while( i < LimitChatr )
     {
//--- 2. Получаем Имя эксперта.     
      NameExpert=             ChartGetString( ID_Chart, CHART_EXPERT_NAME );
      Simvol=                 ChartSymbol(ID_Chart);
      KolichestvoSekynd=      PeriodSeconds( ChartPeriod(ID_Chart) );
    //  Print("На графике ",ChartSymbol(ID_Chart)," Period=",ChartPeriod(ID_Chart)," Расположен советник (",NameExpert,")");
      
//--- 3.A Если на графике есть эксперт И в его названии есть маска: Запоминаем Id и выходим из цикла.  
      if( NameExpert != ""  && 
         StringFind(NameExpert,MaskaNameExpert) > -1 &&
          Simvol            == SimvolExpert &&
          KolichestvoSekynd == SekyndNaGrafikeSTekygemExpertom )
        {
     //    Print("НАШЛИ На графике ",ChartSymbol(ID_Chart)," Period=",ChartPeriod(ID_Chart)," Расположен советник (",NameExpert,")");
         IskomoeIdChart= ID_Chart; break; 
        }
//--- 3.B Если Нет эксперта или НЕ нашли смотрим следующий график.      
      else
        {
       //  Print("Не удалось найти маску (",MaskaNameExpert," в названии эксперта (",NameExpert,") ",ChartSymbol(ID_Chart)," Period=",ChartPeriod(ID_Chart)," ID=",ID_Chart);
         ID_Chart= ChartNext(ID_Chart);
         i++;
//--- --- 3.B.A Если не удалось получить слеюущий график выходим из цикла.         
         if( ID_Chart < 0 ) {/*Print("Закончились графики.");*/break;}
//--- --- 3.B.B Если  Удалось получить слеюущий график ищем в начало цикла.       
         else               {/* Print("Получили новое Id графика ",ChartSymbol(ID_Chart)," Period=",ChartPeriod(ID_Chart)," ID=",ID_Chart);*/continue;}
        }        
     }   
    return IskomoeIdChart;
  }

Si el Asesor Experto 1 funciona, todo está bien

Pero si abre el segundo EA en otro gráfico, el primer gráfico comienza a recibir información del primer EA y del segundo al mismo tiempo.

Significa que empieza a parpadear, porque varios Asesores Expertos trabajan en un mismo gráfico. Sin embargo, en la función Init, cada Asesor Experto recibe el Id del gráfico en el que ha sido lanzado. Entonces recibo una llamada para crear.

int OnInit()
  {
   ChartId= ID_Grafika_S_Expertom(); // Узнаем Id графика на котором запущен советник.
   Graphic.Create(ChartId,"CPrecieIdealnayFast ", 0, 10, 30, 500, 500);   
   Print("OnInit ",Symbol()," ChartId=",ChartId);
   EventSetMillisecondTimer(1000);
   return(INIT_SUCCEEDED);
  }

Por favor, ayúdenme a entender cuál es el problema.

Визуализируй это! Графическая библиотека в MQL5 как аналог plot из R
Визуализируй это! Графическая библиотека в MQL5 как аналог plot из R
  • www.mql5.com
При исследовании и изучении закономерностей важную роль играет визуальное отображение с помощью графиков. В популярных среди научного сообщества языках программирования, таких как R и Python, для визуализации предназначена специальная функция plot. С её помощью можно рисовать линии, точечные распределения и гистограммы для наглядного представления закономерностей. В MQL5 вы можете делать всё то же самое с помощью класса CGraphics.
 
pivomoe:

Trazo los gráficos y la salida del texto utilizando CGraphic. Si una instancia del EA se está ejecutando, todo está bien. Si ejecuto el mismo EA en diferentes gráficos, me da la impresión de que la salida siempre es en el gráfico que está actualmente en la pantalla. Y no en el gráfico que se especifica en el método Create. Aquí está el código del EA para demostrar el problema:

Si el Asesor Experto 1 funciona, todo está bien

Pero si abre el segundo EA en otro gráfico, el primer gráfico comienza a recibir información del primer EA y del segundo al mismo tiempo.

Significa que empieza a parpadear, porque varios Asesores Expertos trabajan en un mismo gráfico. Sin embargo, en la función Init, cada Asesor Experto recibe el Id del gráfico en el que ha sido lanzado. Entonces recibo una llamada para crear.

Por favor, ayúdenme a entender cuál es el problema.

En el nombre del objeto, ¿no es necesario añadir ChartId? No recuerdo si se añade dentro de la función.

Razón de la queja: