Discussione sull’articolo "Visualizza questo! Libreria grafica di MQL5 simile a 'plot' del linguaggio R"

 

Il nuovo articolo Visualizza questo! Libreria grafica di MQL5 simile a 'plot' del linguaggio R è stato pubblicato:

Quando si studia la logica del trading, la rappresentazione visiva sotto forma di grafici è di grande importanza. Alcuni linguaggi di programmazione popolari tra la comunità scientifica (come R e Python) dispongono della speciale funzione "plot" utilizzata per la visualizzazione. Permette di disegnare linee, distribuzioni di punti e istogrammi per visualizzare i modelli. In MQL5, è possibile fare lo stesso utilizzando la classe CGraphics.

Durante l'utilizzo delle funzioni potrebbe verificarsi un errore di divisione per zero. Ci sono due modi per gestire questo problema:

  • disabilitare il controllo della divisione per zero in metaeditor.ini
    [Experts]
    FpNoZeroCheckOnDivision=1
  • o analizzare un'equazione utilizzata in una funzione e restituire un valore valido per questi casi. Un esempio di questa gestione tramite macro si trova nei file 3Functions.mq5 e bat.mq5 allegati.



Autore: MetaQuotes

 
Ottimo lavoro! Grazie. Avevo già intenzione di correggere l'algoritmo CircleAA
A proposito, la funzione CircleWu può essere semplificata e accelerata:

void CCanvas::CircleWu(const int x,const int y,const double r,const uint clr,const uint style=UINT_MAX)
  {
   if(r<=0)
      return;
//--- calcoli preliminari
   double r2=r*r;
   double quarter=round(r*M_SQRT1_2);
//--- impostare lo stile della linea
   uint prev_style=m_style;
   if(style!=UINT_MAX)
      LineStyleSet(style);
   uint mask=1<<m_style_idx;
//--- disegnare
   for(int dx=0; dx<=quarter; dx++)
     {
      double dy=sqrt(r2-dx*dx);
      double alpha1=dy-floor(dy);
      double alpha2=1-alpha1;
      if((m_style&mask)==mask)
        {
         PixelTransform4(x,y,dx,(int)(dy)+1,clr,alpha1);
         PixelTransform4(x,y,dx,(int)(dy),clr,alpha2);
         PixelTransform4(x,y,(int)dy+1,dx,clr,alpha1);
         PixelTransform4(x,y,(int)dy,dx,clr,alpha2);
        }
      mask<<=1;
      if(mask==0x1000000)
         mask=1;
     }
  
//--- impostare lo stile della riga precedente
   if(style!=UINT_MAX)
      m_style=prev_style;
  }
 
Nikolai Semko:
Ottimo lavoro! Grazie. Avevo già intenzione di sistemare l'algoritmo CircleAA
A proposito, la funzione CircleWu può essere semplificata e accelerata:
Grazie per l'idea, le modifiche saranno apportate!
 

È possibile modificare le proprietà del grafico stesso e di ciascuna delle sue funzioni in qualsiasi momento. Ad esempio, aggiungiamo le didascalie agli assi del grafico, cambiamo il nome della curva e attiviamo la modalità di approssimazione spline:

#include <Graphics\Graphic.mqh>
//+------------------------------------------------------------------+
//| Funzione di avvio del programma di script|
//+------------------------------------------------------------------+
void OnStart()
  {
   CGraphic graphic;
   graphic.Create(0,"Graphic",0,30,30,780,380);
   double x[]={-10,-4,-1,2,3,4,5,6,7,8};
   double y[]={-5,4,-10,23,17,18,-9,13,17,4};
   CCurve *curve=graphic.CurveAdd(x,y,CURVE_LINES);
   curve.Name("Example");                 
   curve.LinesIsSmooth(true);             
   graphic.XAxis().Name("X - axis");      
   graphic.XAxis().NameSize(12);          
   graphic.YAxis().Name("Y - axis");      
   graphic.YAxis().NameSize(12);
   graphic.YAxis().ValuesWidth(15);
   graphic.CurvePlotAll();
   graphic.Update();
   DebugBreak();
  }

 У меня метод называется LinesSmooth LineIsSmooth нету. Продолжаю изучать дальше :)

 

 
Orangetree:

È possibile modificare le proprietà del grafico stesso e di ciascuna delle sue funzioni in qualsiasi momento. Ad esempio, aggiungiamo le didascalie agli assi del grafico, cambiamo il nome della curva e attiviamo la modalità di approssimazione spline:

  {
   curve.LinesIsSmooth(true);             

 У меня метод называется LinesSmooth LineIsSmooth нету. Продолжаю изучать дальше :)

 

Il metodo è stato rinominato in seguito. Grazie, corretto nell'articolo
 

Come posso fare in modo che quando una curva viene ridisegnata sul grafico, anche la scala venga aggiornata?

curve5.Update(resultPrices);
    
graphicfirst.Redraw(); и Update()


la curva stessa viene aggiornata, ma la scala con i vecchi prezzi rimane e il grafico si sposta al di fuori dei confini dell'area di disegno.

L'ho trovato, devo fare CalculateMaxMinValues() :)

 
Maxim Dmitrievsky:
Potreste dirmi come ridisegnare correttamente un grafico già creato, ad esempio quando si cambiano i valori negli array? Redraw() e Update() non hanno alcun effetto.

Buon pomeriggio, come ha provato a ridisegnare il grafico?

Se deve solo cambiare i dati di una particolare curva, ecco un esempio funzionante:

#include <Graphics\Graphic.mqh>
//+------------------------------------------------------------------+
//| Funzione di avvio del programma di script|
//+------------------------------------------------------------------+
void OnStart()
  {
//--- dati 1
   double x1[]={-10,-4,-1,2,3,4,5,6,7,8};
   double y1[]={-5,4,-10,23,17,18,-9,13,17,4};
//--- dati 2
   double x2[]={-10,-10,10,10};
   double y2[]={-10,10,-10,10};
//--- grafico
   CGraphic graph;
   graph.HistoryNameWidth(80);
   graph.Create(0,"Graph",0,30,30,830,430);
//--- Punti
   CCurve *curve=graph.CurveAdd(x1,y1,CURVE_LINES);
   graph.CurvePlot(0);
   graph.Update();
   Sleep(1000);
   curve.Update(x2,y2);
   graph.Redraw(true);
   graph.Update();
   Sleep(1000);
  }
P.S. C'è una discussione sul forum riguardante la libreria Graphics, dove questo problema è già stato sollevato.
 
Roman Konopelko:

Buon pomeriggio, in che modo esattamente stavate cercando di ridisegnare il grafico?

Se deve solo cambiare i dati di una particolare curva, ecco un esempio funzionante:

P.S. C'è un thread sul forum riguardante la libreria Graphics, in cui questa domanda è già stata sollevata.
Grazie, l'ho già capito, stavo facendo esattamente la stessa cosa, solo su un array... è sufficiente ricalcolare graph.CalculateMaxMinValues() anche per il grafico, quindi la scala viene aggiornata.
 
Maxim Dmitrievsky:
Grazie, l'ho già capito, ho fatto esattamente la stessa cosa, solo su un array. è sufficiente ricalcolare graph.CalculateMaxMinValues() anche per il grafico, quindi la scala viene aggiornata
Se si chiama il metodo CGraphic::Redraw(const bool rescale=false) con il parametro true, le scale verranno ricalcolate automaticamente (non è necessario chiamare CalculateMaxMinValues separatamente).
 
Roman Konopelko:
Se si chiama il metodo CGraphic::Redraw(const bool rescale=false) con il parametro true, le scale saranno ricalcolate automaticamente (non è necessario chiamare CalculateMaxMinValues separatamente).

Giusto, capito. Grazie)
 

È possibile creare due o più scale sul grafico, in modo simile a un righello, dove le divisioni sono indicate come centimetri e pollici, con i valori indicati solo se il punto è stato utilizzato per tracciare il grafico?