Diskussion zum Artikel "Die Erstellung der benutzerdefinierten Indikatoren unter Verwendung der Klasse CCanvas"

 

Neuer Artikel Die Erstellung der benutzerdefinierten Indikatoren unter Verwendung der Klasse CCanvas :

Im Artikel wurde das Beispiel der Erstellung der gezeichneten benutzerdefinierten Indikatoren mit Hilfe der graphischen Ringpuffer der Klasse CCanvas.

Im Unterschied zur einfachen Bogenindikation, die Sektionsindikation sieht so optisch aus, als ob auf sie die Zeichen aufgetragen würden, die die gleichen Abstände der Werte teilen. Beim Aufbau des Modelles des Indikators dieses Typs wurde es entschieden, zehn Sektionen zu machen, es wird dabei ein neues Element hinzugefügt: der innere Rahmen. Die grundlegende Struktur mit der Bogensektionsindikation wurde auf der Abb. 5 dargestellt.


Die Abb. 5 die grundlegende Struktur des kreisförmigen Indikators mit der Bogen-Indikation.

Autor: Alexander Fedosov

 

Vielen Dank an den Autor für diesen Artikel. Ich habe viele einfache (aber gleichzeitig elegante) Lösungen für mich notiert, die ich definitiv in meinen Programmen verwenden werde.

 
MetaQuotes Software Corp.:

Veröffentlichter Artikel Erstellen von benutzerdefinierten Indikatoren mit der CCanvas-Klasse:

Autor: Alexander Fedosov


Oh, was für eine Schönheit! Ich füge es zu meinem Denkmal hinzu ;)
 

Ich möchte Sie noch einmal darauf aufmerksam machen, dass bei der Anwendung mehrerer Kopien desselben Indikators, der mit CustomGUI-Klassen implementiert wurde, die Namen in der Create() -Methode unterschiedlich sein müssen. Als Beispiel dient die unten stehende Implementierung.

#property version   "1.00"
#property indicator_chart_window
#property indicator_plots 0
//---
#include <CustomGUI\CustomGUI.mqh>
CCircleSection ind;
//+------------------------------------------------------------------+
//| Eingabeparameter des Indikators|
//+------------------------------------------------------------------+
input ENUM_TIMEFRAMES   tf=PERIOD_CURRENT;
input int               period=10;
input int               indsize=50;
input ENUM_ORIENTATION  orient=VERTICAL;
input int               X=100;
input int               Y=100;
//---
int      IndHandle;
double   rsi[];
//+------------------------------------------------------------------+
//| Benutzerdefinierte Initialisierungsfunktion für Indikatoren |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Indikator-Handle holen
   IndHandle=iRSI(Symbol(),tf,period,PRICE_CLOSE);
   if(IndHandle==INVALID_HANDLE)
     {
      Print("Failed to get indicator handle");
      return(INIT_FAILED);
     }
   ArraySetAsSeries(rsi,true);
//---
   ind.Radius(indsize);
   ind.LabelSize(15);
   ind.LabelValue("RSI "+"("+IntegerToString(period)+")");
   ind.Orientation(orient);
   ind.Create("rsi_custom"+IntegerToString(MathRand()),X,Y);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Benutzerdefinierte Indikator-Iterationsfunktion |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   if(CopyBuffer(IndHandle,0,0,1,rsi)<1)
      return(0);
   ind.NewValue(rsi[0]);
//--- Rückgabe des Wertes von prev_calculated für den nächsten Aufruf
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Benutzerdefinierte Indikator-Deinitialisierungsfunktion |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ind.Delete();
   ChartRedraw();
  }
//+------------------------------------------------------------------+

Die Create() -Methode hat einen eindeutigen Namen.

Dateien:
 

Vielen Dank.

Ist es möglich, in MT4 oder MT5 die Funktion der Auswahl eines Indikatorobjekts zu implementieren? (zum Beispiel, eine Linie).

Zum Beispiel, Doppelklick auf eine Linie und es wird mit einer fetten Linie hervorgehoben, die Beschreibung der Linie erscheint, und umgekehrt.

 
Ilmir Galiev:

Vielen Dank.

Ist es möglich, in MT4 oder MT5 die Funktion der Auswahl eines Indikatorobjekts zu implementieren? (zum Beispiel, eine Linie).

Wenn Sie z.B. auf eine Linie doppelklicken, wird diese mit einer fetten Linie hervorgehoben und die Beschreibung der Linie erscheint und umgekehrt.

Nein. Das Wesen dieser Methode besteht darin, dass es sich um ein Bild handelt, das neu gezeichnet wird, wenn sich irgendwelche Bedingungen ändern. Sie reagiert nicht auf Hotkey- oder Mausklick-Ereignisse.
 
Alexander Fedosov:
Nein. Das Wesentliche dieser Methode ist, dass es sich um ein Bild handelt, das neu gezeichnet wird, wenn sich irgendwelche Bedingungen ändern. Es reagiert nicht auf Hotkey- oder Mausklick-Ereignisse.

Ach, kommen Sie. Was sind Mausklicks? Keine "Änderung irgendwelcher Bedingungen". Es wird ein Ereignis erzeugt, mit dem die Leinwand neu gezeichnet wird, wie es sein sollte. Ilmir, die richtige Antwort auf deine Frage lautet: Natürlich kannst du das.

 

Gutes Thema. Vielen Dank an den Autor, wird ein Tick-Indikator auf Leinwand machen.....

Mir ist folgendes aufgefallen.

//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
class CCanvasBase
  {
private:
   //--- Name der Leinwand
   string            m_canvas_name;
   //--- Koordinaten für die Leinwand
   int               m_x;
   int               m_y;
   //--- Leinwandgröße
   int               m_x_size;
   int               m_y_size;
protected:
   CCanvas           m_canvas;
   //--- Erzeugt eine grafische Ressource für das Objekt
   bool              CreateCanvas(void);
   //--- Löscht die Grafikressource
   bool              DeleteCanvas(void);
public:
                     CCanvasBase(void);
                    ~CCanvasBase(void);
   //--- Koordinaten festlegen und zurückgeben
   void              X(const int x)                         { m_x=x;                      }
   void              Y(const int y)                         { m_y=y;                      }
   int               X(void)                                { return(m_x);                }
   int               Y(void)                                { return(m_y);                }
   //--- Dimensionen festlegen und zurückgeben
   void              XSize(const int x_size)                { m_x_size=x_size;            }
   void              YSize(const int y_size)                { m_y_size=y_size;            }
   int               XSize(void)                            { return(m_x_size);           }
   int               YSize(void)                            { return(m_y_size);           }
   //--- Legt den Indikatornamen bei der Erstellung fest
   void              Name(const string canvas_name) { m_canvas_name=canvas_name;  }
  };

Es gibt ein privates Datenmitglied m_canvas_name, aber die Methode, die seinen Wert setzt - Name() - ist öffentlich. Imho wird das Prinzip der Kapselung verletzt. Ich werde diese Methode privat machen.

 
Dennis Kirichenko:

Gutes Thema. Vielen Dank an den Autor, wird ein Tick-Indikator auf Leinwand machen....

Da Sie Skizzen haben, senden Sie bitte Screenshots/Video. Ich habe selbst einen solchen Indikator gepostet, aber er ist nicht unter die Leute gegangen. Obwohl ich keine bessere Lösung gefunden habe. Es ist interessant, andere Lösungen auf der Leinwand zu sehen.

 
fxsaber:

Ich habe selbst einen solchen Hinweis gegeben, aber er ging nicht an die Leute.

Doch, das ist er.

Ich versuche sogar, auf dieser Grundlage einen Indikator für die Tickgeschwindigkeit zu erstellen.

 
Andrey Khatimlianskii:
Los, los, los.

Ich versuche sogar, einen Tick-Rate-Indikator daraus zu machen.

Das ist eine gute Nachricht! Was ist die Idee? Anstelle der Tick-Historie eine benutzerdefinierte Zeitreihe zu ersetzen?