Prüfung von CGraphic - Fragen und Anregungen - Seite 12

 

CGrafic::Destroy() - Funktioniert nicht!


//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|                                                     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() - Funktioniert nicht!

Wie haben Sie es entdeckt? Was sind die Symptome?

 
Denis Kirichenko:

Wie haben Sie sie identifiziert? Was sind die Symptome?

Nun, der Code ist zum Abspielen beigefügt :)

Und auf dem Bild können Sie sehen, dass nach Destroy() Graphen hinzugefügt werden

mit Vorsilbe

_exists
 
prostotrader:

Aber der Code für die Wiedergabe ist beigefügt :)

Und auf dem Bild können Sie sehen, dass nach Destroy() Graphen hinzugefügt werden

mit Vorsilbe

Nun, meine Frage bezog sich aufCGrafic::Destroy(). Es funktioniert - ich habe es mit dem Debugger überprüft... Vielleicht ist etwas in Ihrem Code falsch?

 
Denis Kirichenko:

Nun, die Frage bezog sich speziell aufCGrafic::Destroy(). Es funktioniert - ich habe es im Debugger überprüft... Vielleicht ist etwas in Ihrem Code falsch?

Der Einstieg in den Körper von Destroy() bedeutet nicht, dass er (die Prozedur) korrekt funktioniert.

Nach dertatsächlichen Zerstörung eines Objekts konnten wir keine neuen Graphen hinzufügen, und sie werden hinzugefügt!

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:

Der Einstieg in den Körper der Destroy()-Prozedur bedeutet keineswegs, dass sie (die Prozedur) korrekt funktioniert.

Nach der eigentlichen Zerstörung eines Objekts konnten wir ihm keine neuen Graphen mehr hinzufügen, und sie tun es doch!

Was das Schlagen angeht, stimme ich zu. Aber trotzdem... Nun, zunächst einmal:voidCGrafic::Destroy(). Das heißt, die Methode ist uns nichts schuldig. Und zweitens, vielleicht ist es Sache des Programmierers, Kontrollen hinzuzufügen? Sie können SB nicht für alle Aufgaben konfigurieren...

 
Denis Kirichenko:

Was das Schlagen angeht, stimme ich zu. Aber trotzdem... Nun, zunächst einmal,voidCGrafic::Destroy(). Das heißt, die Methode ist uns nichts schuldig. Und zweitens, vielleicht ist es Sache des Programmierers, Kontrollen hinzuzufügen? Sie können SB nicht für alle Aufgaben konfigurieren.

Außerdem habe ich die Destroy-Methode geändert.

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

Und es fügt immer noch Karten hinzu!

 
Wie kann man die Größe in CGraphic ändern?
 

Ich zeichne die Diagramme und gebe den Text mit CGraphic aus. Wenn eine Instanz des EA ausgeführt wird, ist alles in Ordnung. Wenn ich denselben EA auf verschiedenen Charts laufen lasse, habe ich den Eindruck, dass die Ausgabe immer auf dem Chart erfolgt, der gerade auf dem Bildschirm ist. Und nicht auf dem Diagramm, das in der Methode Create angegeben ist. Hier ist der Code des EA zur Veranschaulichung des Problems:

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

Wenn Expert Advisor 1 funktioniert, ist alles in Ordnung.

Wenn Sie jedoch den zweiten EA in einem anderen Diagramm öffnen, erhält das erste Diagramm gleichzeitig Informationen vom ersten und zweiten EA.

Das bedeutet, dass er zu flackern beginnt, weil mehrere Expert Advisors auf ein und demselben Chart arbeiten. In der Init-Funktion erhält jedoch jeder Expert Advisor die Id des Charts, in dem er gestartet wurde. Dann bekomme ich einen Aufruf zum Erstellen.

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

Bitte helfen Sie mir zu verstehen, wo das Problem liegt?

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

Ich zeichne die Diagramme und gebe den Text mit CGraphic aus. Wenn eine Instanz des EA ausgeführt wird, ist alles in Ordnung. Wenn ich denselben EA auf verschiedenen Charts laufen lasse, habe ich den Eindruck, dass die Ausgabe immer auf dem Chart erfolgt, der gerade auf dem Bildschirm ist. Und nicht auf dem Diagramm, das in der Methode Create angegeben ist. Hier ist der Code des EA zur Veranschaulichung des Problems:

Wenn Expert Advisor 1 funktioniert, ist alles in Ordnung.

Wenn Sie jedoch den zweiten EA in einem anderen Diagramm öffnen, erhält das erste Diagramm gleichzeitig Informationen vom ersten und zweiten EA.

Das bedeutet, dass er zu flackern beginnt, weil mehrere Expert Advisors auf ein und demselben Chart arbeiten. In der Init-Funktion erhält jedoch jeder Expert Advisor die Id des Charts, in dem er gestartet wurde. Dann bekomme ich einen Aufruf zum Erstellen.

Bitte helfen Sie mir zu verstehen, was das Problem ist?

In den Namen des Objekts, müssen nicht ChartId hinzufügen? Ich weiß nicht mehr, ob sie innerhalb der Funktion hinzugefügt wird.

Grund der Beschwerde: