Test de CGraphic - questions et suggestions - page 12

 

CGrafic::Destroy() - Ne fonctionne pas !


//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|                                                     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() - Ne fonctionne pas !

Comment l'avez-vous détecté ? Quels sont les symptômes ?

 
Denis Kirichenko:

Comment l'avez-vous identifié ? Quels sont les symptômes ?

Eh bien, le code est joint pour la lecture :)

Et sur l'image vous pouvez voir qu'après Destroy() les graphiques sont ajoutés

avec préfixe

_exists
 
prostotrader:

Mais le code pour la lecture est joint :)

Et sur l'image vous pouvez voir qu'après Destroy() des graphiques sont ajoutés

avec préfixe

Ma question portait surCGrafic::Destroy(). Cela fonctionne - je l'ai vérifié avec le débogueur... Peut-être y a-t-il un problème dans votre code ?

 
Denis Kirichenko:

Eh bien, la question portait spécifiquement surCGrafic::Destroy(). Cela fonctionne - je l'ai vérifié dans le débogueur... Peut-être y a-t-il un problème dans votre code ?

Entrer dans le corps de la procédure Destroy() ne signifie pas qu'elle (la procédure) fonctionne correctement.

Après la destructioneffective d'un objet, nous ne pouvions pas y ajouter de nouveaux graphes, et ils sont ajoutés !

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:

Entrer dans le corps de la procédure Destroy() ne signifie pas du tout qu'elle (la procédure) fonctionne correctement.

Après la destruction effective d'un objet, nous ne pouvions pas y ajouter de nouveaux graphiques, et c'est pourtant le cas !

Pour les coups, je suis d'accord. Mais néanmoins... Eh bien, tout d'abord,voidCGrafic::Destroy(). C'est-à-dire que la méthode ne nous doit rien. Et deuxièmement, c'est peut-être au programmeur d'ajouter des contrôles ? Vous ne pouvez pas configurer SB pour toutes les tâches...

 
Denis Kirichenko:

Pour les coups, je suis d'accord. Mais néanmoins... Eh bien, tout d'abord,voidCGrafic::Destroy(). C'est-à-dire que la méthode ne nous doit rien. Et deuxièmement, c'est peut-être au programmeur d'ajouter des contrôles ? Vous ne pouvez pas configurer SB pour toutes les tâches.

De plus, j'ai modifié la méthode Destroy.

//+------------------------------------------------------------------+
//| 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!

Et ça ajoute encore des graphiques !

 
Comment faire pour redimensionner dans CGraphic?
 

Je trace les graphiques et j'affiche le texte en utilisant CGraphic. Si une seule instance de l'EA est en cours d'exécution, tout va bien. Si j'exécute le même EA sur différents graphiques, j'ai l'impression que la sortie se fait toujours sur le graphique qui est actuellement à l'écran. Et non sur le graphique qui est spécifié dans la méthode Create. Voici le code de l'EA pour démontrer le problème :

#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 l'Expert Advisor 1 fonctionne, tout va bien

Mais si vous ouvrez le second EA dans un autre graphique, le premier graphique commence à recevoir des informations du premier EA et du second en même temps.

Cela signifie qu'il commence à clignoter, car plusieurs conseillers experts travaillent sur un seul et même graphique. Cependant, dans la fonction Init, chaque Expert Advisor reçoit l'Id du graphique dans lequel il a été lancé. Puis je reçois un appel pour créer.

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);
  }

Veuillez m'aider à comprendre quel est le problème ?

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

Je trace les graphiques et j'affiche le texte en utilisant CGraphic. Si une seule instance de l'EA est en cours d'exécution, tout va bien. Si j'exécute le même EA sur différents graphiques, j'ai l'impression que la sortie se fait toujours sur le graphique qui est actuellement à l'écran. Et non sur le graphique qui est spécifié dans la méthode Create. Voici le code de l'EA pour démontrer le problème :

Si l'Expert Advisor 1 fonctionne, tout va bien

Mais si vous ouvrez le second EA dans un autre graphique, le premier graphique commence à recevoir des informations du premier EA et du second en même temps.

Cela signifie qu'il commence à clignoter, car plusieurs conseillers experts travaillent sur un seul et même graphique. Cependant, dans la fonction Init, chaque Expert Advisor reçoit l'Id du graphique dans lequel il a été lancé. Puis je reçois un appel pour créer.

Veuillez m'aider à comprendre quel est le problème ?

Dans le nom de l'objet, il ne faut pas ajouter ChartId ? Je ne me souviens pas si elle est ajoutée à l'intérieur de la fonction.

Raison: