English Русский 中文 Español 日本語 Português
Signalrechner

Signalrechner

MetaTrader 5Integration | 24 Juni 2016, 12:57
870 0
Vladimir Karputov
Vladimir Karputov

Inhaltsverzeichnis

Einführung

Die häufigste Frage von Abonnenten: "Kann ich auf das NNN-Signal abonnieren, und welches Volumen wird auf mein Trading-Konto kopiert?". Dieser Artikel ermöglicht einen Signalrechner zu erstellen - einen Assistenten für diejenigen, die Signale abonnieren wollen. Es wird in diesem Artikel auch eine kurze Anleitung aufgeführt, um den Signalrechner zu verwenden.

Der Rechner selbst ist ein Feld auf der Basis der Klasse CDialog. In diesem Feld werden die folgenden Elemente verwendet:

Der Signalrechner arbeitet mit den Signalen, die im Terminal zur Verfügung stellen. Dadurch wird die maximale Kompatibilität zwischen dem Signal und Ihrem Trading-Konto gewährleistet, da das Terminal eine zusätzliche Filterung der Signale durch mehrere Indikatoren durchführt. Die Hauptaufgabe einer Filtration - Die Signale mit absichtlich schlechter Leistung des Kopierens aus der Sicht des Benutzers zu entfernen oder die Signale zu entfernen, die nicht kopiert werden können.

In diesem Artikel präsentierte Rechner kann kostenlos aus dem Markt für MetaTrader 5 und für MetaTrader 4 heruntergeladen werden:

1. Nutzungsbeschränkungen

Man muss sich klar vorstellen, dass es im Terminal im Titel "Signale" nur die Signale angezeigt werden, die meisten mit dem Trading-Konto des Benutzers kompatibel sind. Mit anderen Worten, im Terminal werden Sie nicht alle Signale sehen, die online im Fenster Signale auf der Web-Seite sind. Darüber hinaus werden Sie beim Umschalten von einem Terminal-Server zu einem anderen Terminal-Server (Trading-Konto) jedes Mal sehen, dass die Liste von Signalen im Terminal sich ändert.


2. Die Anleitung für die Arbeit mit dem Signalrechner

2.1. Der Arbeitsanfang

Für die Funktionalität des Rechners wird eine aktuelle Datenbank von Handelssignalen im Terminal benötigt. Um dies zu tun, müssen Sie den aktiven Titel "Signale" in "Extras" (klicken Sie auf den Titel "Signale") machen:

Abb. 1. Aktivieren Sie den Titel "Signale" 

Wenn es Änderungen in der Datenbank von Handelssignalen gibt, werden sie innerhalb von drei bis fünf Sekunden geladen.

Der Titel "Signale" muss nach der Verbindung zum Trading-Konto aktiv gemacht werden, auch falls es zu einem anderen Trading-Konto verbunden wird.


2.2. Benutzer-Interface

Die Interface des Signalrechners enthält die folgenden Elemente:

Abb. 2. Die Interface des Signalrechners 

  • Die Balance des Handelskontos — die Balance des momentan verbundenen Trading-Kontos — das editierbare Feld. Nach dem Hinzufügen des Signalrechners zum Chart oder nach dem Wechsel der Periode wird im editierbaren Feld "Handelsbilanz" die Balance des momentan verbundenen Trading-Kontos enthalten. In diesem Feld ist nur die Ziffern von 0 bis 9 erlaubt, einzugeben.
  • Die Währung des Trading-Kontos — die Währung des des momentan verbundenen Trading-Kontos — eine Drop-Down-Liste der am häufigsten verwendeten Währungen. Nach dem Hinzufügen des Signalrechners zum Chart oder nach dem Wechsel der Periode wird der Signalrechner versuchen, in der Liste den Währung-Namen des momentan verbundenen Trading-Kontos zu finden. Wenn es keine Übereinstimmung gefunden wird, wird eine Währung standardmäßig ausgewählt — "USD".
  • Der Hebel des Trading-Kontos — Der Hebel des momentan verbundenen Trading-Kontos — eine Drop-Down-Liste der am häufigsten getroffenen Hebels. Nach dem Hinzufügen des Signalrechners zum Chart oder nach dem Wechsel der Periode wird der Signalrechner versuchen, in der Liste den Hebel des momentan verbundenen Trading-Kontos zu finden. Wenn es keine Übereinstimmung gefunden wird, wird ein Hebel standardmäßig ausgewählt — "1:100".
  • Die Belastung auf das Deposite beim Sifnal-Kopieren — eine Drop-Down-Liste aus dem Menü des Terminals "Service" - "Einstellungen" - "Alarme". Nach dem Hinzufügen des Signalrechners zum Chart oder nach dem Wechsel der Periode wird der Signalrechner versuchen, in der Liste die Belastung auf das Deposite des momentan verbundenen Trading-Kontos zu finden. Wenn es keine Übereinstimmung gefunden wird, wird eine Belastung standardmäßig ausgewählt — "95%".
  • Die Tabelle aus den verfügbaren Signale im Terminal — - die Tabelle mit den Signalen von dem "Alarme". Die Tabelle wird automatisch in absteigender Reihenfolge in der Spalte sortiert "Das Verhältnis. der Abbildung". Die Spalten der Tabelle:
    • Die Spalte "Der Zuwachs, %" — bedeutet den Prozentsatz des Wachstums als Ergebnis der Handels-Operationen.
    • Die Spalte "Alarm" — der Name des Handelssignals.
    • Die Spalte "Tools" — die Anzahl der Eigenmittel auf dem Konto des Signalanbieters, unter Berücksichtigung aller Verpflichtungen.
    • Die Spalte "Währung" — die Währung des Handelskontos vom Signalanbieter.
    • Die Spalte "Hebel" — Der Hebel des Trading-Kontos vom Signalanbieter.
    • Die Spalte "Der Preis, $" — Der Preis des Trading-Kontos, in $.
    • Die Spalte "Das Verhältnis. der Abbildung" — Das berechnete Abbildungsverhältnis für jedes Signal bei den gewählten Einstellungen: "Die Balance des Handelskontos", "Die Währung des Trading-Kontos", "Der Hebel des Trading-Kontos" und "Die Belastung auf das Deposite beim Signal-Kopieren".
    • Die Spalte "Min. Das Deposit *" — Das benötigte Deposit für das Kopieren 1:1 bei der Verwendung des Deposites 95%. Das heisst, das ist ein Deposit, bei dem die Trades vom Signalanbieter im Verhältnis 1:1 zu Ihrem Trading-Konto kopiert werden, unter der Bedingung, dass die gewählte Belastung auf das Deposit "95%" ist.
  • Die Detaillierung der Berechnungen des Abbildungsverhältnis — Schritt um Schritt, eine detaillierte Berechnung des Abbildungsverhältnis beim ausgewählten Signal.
    • K1 — Der Korrelationskoeffizient Ihrer Trading-Kontos Währung und Trading-Kontos vom Signalanbieter.
    • K2 — Der Korrelationskoeffizient der Balancen vom Trading-Konto und vom Trading-Konto des Signalanbieters.
    • K3 — Der Nutzungskoeffizient des Deposites. Die Berechnung der Prozente in Koeffizient.
    • K4 — Der Korrekturskoeffizient für die Differenz der Hebels.
    • K — Der endgültige Koeffizient. Es wird folgenderweise K1*K2*K3*K4 berechnet.
    • Der endgültige Abbildungskoeffizient - Der Koeffizient K, ist abgerundet über dem Schema.

2.3. Die Erhaltung des Abbildungsverhältnis

In der Signale-Tabelle für jedes Signal in der Spalte " Abbilgungsverhältnis" kann man den berechneten Abbilgungsverhältnis für jedes Signal bei ausgewählten Einstellungen sehen: "Die Balance des Handelskontos", "Die Währung des Trading-Kontos", "Der Hebel des Trading-Kontos" und "Die Belastung auf das Deposite beim Signal-Kopieren". 

Nach freiem Ermessen kann man Einstellungen ändern: "Die Balance des Handelskontos", "Die Währung des Trading-Kontos", "Der Hebel des Trading-Kontos" oder "Die Belastung auf das Deposite beim Signal-Kopieren". Eine Änderung einer von diesen Einstellungen führt zur Neuberechnung des Abbildungsverhältnis und Aktualisierung der Tabelle, und es ist nicht sicher, dass die Handelssignale an seinen Orten in der Tabelle weiter bleiben, nach der Sortierung in absteigender Reihenfolge in der Spalte "Minimales Deposite*". Somit ist es möglich, online zu sehen, wie das Abbildungsverhältnis des Handelssignals sich bei verschiedenen Einstellungen des Trading-Kontos ändert.

2.4. Die Detaillierung der Berechnung des Abbildungsverhältnis

Um eine detaillierte Berechnung des Abbildungsverhältnisses für ein bestimmtes Signal zu erhalten, müssen Sie in der Signaltabelle auf die interessierten Zeile klicken (Aktion 1). Danach erscheint unter der Signaltabelle eine detaillierte Berechnung des Abbildungsverhältnisses für das ausgewählte Signal(Aktion 2):

 

Abb. 3. Die Detaillierung der Berechnung des Abbildungsverhältnis  

2.5. Die Mapping ist unmöglich

Nachdem Sie eine andere Währung von der Dropdown-Liste der "Die Währung des Trading-Kontos" ausgewählt haben, der Signalrechner wird versuchen, um das Abbildungsverhältnis zu berechnen, ein Symbol im Fenster "Market Watch" zu finden, das zur gleichen Zeit auch die Währung Ihres Trading-Kontos enthält (oder die ausgewählte Währung aus der Dropdown-Liste im Titel "Die Währung des Trading-Kontos"). Zum Beispiel ist die Währung Ihres Trading-Kontos — "USD", und die Währung des Handelskontos vom Signalanbieter — ist "EUR". In diesem Fall wird der Rechner versuchen, im "Market Watch" das Symbol "USDEUR" und "EURUSD" zu finden.  Wenn das Symbol nicht gefunden wird, wird eine Fehlermeldung im Tab-Terminal "Experten" angezeigt.

Ein Beispiel für eine Fehlermeldung, nachdem Sie aus der Dropdown-Liste "Die Währung des Handelskontos" die Währung "SGD" ausgewählt haben:

Calculator for signals (EURUSD,M5)      Error find symbols: (Account currency SGD, Signal currency RUB)
Calculator for signals (EURUSD,M5)      Error find symbols: (Account currency SGD, Signal currency EUR)
Calculator for signals (EURUSD,M5)      Error find symbols: (Account currency SGD, Signal currency EUR)

Diese Meldung bedeutet, dass im Fenster "Market Watch" keine Symbole "SGDRUB", "SGDEUR", "RUBSGD", "EURSGD" gibt. Überprüfen wir, ob das so ist: im Fenster "Market Watch" werden versuchen, ein Symbol zu finden, deren Name "SGD" enthält. Um dies zu tun, im Fenster "Market Watch" müssen Sie auf die Schaltfläche "+ Add" klicken:

Abb. 4. Das "Hinzufügen" im Fenster "Market Watch"   

und im aufgetauchten Feld "SGD" eingeben:

Abb. 5. Eine Liste der verfügbaren Symbole im Fenster "Market Watch", unter denen mit dem Namen "SGD" gibt   

Wie Sie sehen können, im Fenster "Market Watch" gibt es bereits ein Symbol "USDSGD" und noch eins - "SGDJPY" kann hinzugefügt werden, aber die Symbole "SGDRUB", "SGDEUR", "RUBSGD", "EURSGD" gibt es nicht. 

Wenn die Mapping nicht möglich ist, in der Signale-Tabelle in der Spalte ". das Abbildungsverhältnis" wird "n/d" gegeben, was bedeutet, "keine Daten".

Ein kurzes Video über den Signalrechner:



3. Die Entwicklung des Signalrechners

3.1. Wir gestalten die Interface

Die Bedienelemente im Signalrechner wurden folgendermaßen zugeordnet:

Die Positionen der Bedienelemente  

Abb. 6. Die Positionen der Bedienelemente 

Für die Positionen, die Größe und für die Erstellung der Bedienelemente ist die hinzufügbare Datei "Calculator for signals Dialog.mqh" verantwortlich. Die grundlegende Größe der Bedienelemente und der Margen werden mit dem Block Makrosubstitution eingestellt:

//+------------------------------------------------------------------+
//| defines                                                          |
//+------------------------------------------------------------------+
//--- indents and gaps
#define INDENT_LEFT                         (11)      // indent from left (with allowance for border width)
#define INDENT_TOP                          (11)      // indent from top (with allowance for border width)
#define CONTROLS_GAP_Y                      (5)       // gap by Y coordinate
//--- for combo boxes
#define COMBOBOX_WIDTH                      (60)      // size by X coordinate
#define COMBOBOX_HEIGHT                     (20)      // size by Y coordinate
//--- for list view
#define LIST_HEIGHT                         (102)     // size by Y coordinate
//--- for buttons
#define BUTTON_WIDTH                        (72)      // size by X coordinate
#define BUTTON_HEIGHT                       (20)      // size by Y coordinate
//--- for the indication area
#define EDIT_WIDTH                          (60)      // size by X coordinate
#define EDIT_HEIGHT                         (20)      // size by Y coordinate

Schematisch wurden die Bedienelemente auf dem Feld in fünf Zeilen angeordnet:

  1. Die erste Zeile — Label1, Edit1, ComboBox1, Label2, ComboBox2, Label3, ComboBox2
  2. Die zweite Zeile — Label 4
  3. Die dritte Zeile — Die Schaltfläche von Button1 bis Button8 einschließlich
  4. Die vierte Zeile — ein neues Bedienelement — die Tabelle TableListView1
  5. Die fünfte Zeile — das Objekt BmpButton1, dem als bmp-Datei eine Grafik-Ressource basierend auf CCanvas zugeordnet wurde, um das Element im Online-Zustand anzuzeigen.
Die Hauptsache - Denken Sie daran, dass alle Steuerungsobjekte auf dem Dialog-Feld sind ( Das Hauptfeld wird wiederum hier erstellt):

//+------------------------------------------------------------------+
//| Create                                                           |
//+------------------------------------------------------------------+
bool CoSDialog::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
  {
//---
   m_error=true;
   if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2))
      return(false);
//---

Das bedeutet, dass jedes Steuerungsobjekt nach dem Erstellen durch das Verfahren Add der Klasse CDialog zum Client-Bereich hinzugefügt werden muss. So sieht es im Beispiel mit Label4 aus:

//+------------------------------------------------------------------+
//| Create the "Signals" Label                                       |
//+------------------------------------------------------------------+
bool CoSDialog::CreateLabel4(void)
  {
//--- coordinates
   int x1=INDENT_LEFT;
   int y1=INDENT_TOP+COMBOBOX_HEIGHT+CONTROLS_GAP_Y;
   int x2=x1+100;
   int y2=y1+COMBOBOX_HEIGHT;
//--- create
   if(!m_label4.Create(m_chart_id,m_name+"Label4",m_subwin,x1,y1,x2,y2))
      return(false);
   if(!m_label4.Text(m_languages.GetText(3)))
      return(false);
   if(!Add(m_label4))
      return(false);
//--- succeed
   return(true);
  }

Erstellen wir zunächst das Objekt Label4:

   if(!m_label4.Create(m_chart_id,m_name+"Label4",m_subwin,x1,y1,x2,y2))
      return(false);

und bevor wir die Funktion verlassen, hinzufügen wir unbedingt das wieder erstelltes Objekt Label4 zum Client-Bereich durch das Verfahren Add:

   if(!Add(m_label4))
      return(false);

Im Allgemeinen ist der Erstellungsprozess des Feldes und Bedienelementes in diesem Feld, kann man im Beispiel der Erstellung des Signalrechnersfeldes in Form von Schema darstellen:

Das Schema der Feldesobjekte-Erstellung

Abb. 7. Das Schema der Feldesobjekte-Erstellung 

Ziehe ich Schlüsse. In der Regel wird die Erstellung des Feldes im folgenden Plan gehen:

  • Die Erstellung des Feldes (CAppDialog::Create)
  • die reihenfolgende Erstellung der Bedienelemente, dabei wird jedes Bedienelement in dieser Reihenfolge erstellt:
    • Die Erstellung des Elementes (element_N.Create)
    • Die Änderung der Elemente-Eigenschaften
    • Das nötige Hinzufügen des Elementes zum Feld (Add(elenemt_N))

3.2. Erstellen Leinwand auf dem Panel

Die Leinwand wird in CoSDialog::CreateBmpButton1 erstellt.

Erstmal kurz, in ein paar Schritten:

Schritt 1: Erstellen wir eine Grafik-Ressource ohne Verweis zum Chartobjekt (wir verwenden die Methode Create der Klasse CCanvas)

Schritt 2: Erstellen wir ein Steuerungselement m_bmp_button1 der Klasse CBmpButton (eine einfache Klasse des Steuerungselements basierend auf dem Objekt 'Grafik Marke')

Schritt 3: für das Steuerungselement m_bmp_button1, als bmp-Datei im Online-Zustand ON (die Methode BmpOnName), stellen wir Canvas ein

Schritt 4: Fügen wir das Steuerungselement m_bmp_button1 zum Feld hinzu (die Methode Add der Klasse CDialog)

Jetzt mehr Informationen über jeden Schritt.

Schritt 1

//--- create canvas
   if(!m_canvas1.Create("Canvas1",x2,y2,COLOR_FORMAT_XRGB_NOALPHA))
     {
      Print("Error creating canvas: ",GetLastError());
      return(false);
     }
   m_canvas1.FontSet("Trebuchet MS",-100,FW_THIN);
   m_canvas1.Erase(ColorToARGB(C'0xF7,0xF7,0xF7',255));
   m_canvas1.Update(true);

Bitte beachten Sie, dass bei der Erstellung des Canvases (m_canvas1.Create) die Breite x2 und die Höhe y2 gegeben wird — in der Tat sind es die Größe des Bildes, die nicht geändert werden:

Die Größe des Canvases  

Abb. 8. Die Größe des Canvases 

Weiter wird die Schriftart für die Canvas (m_canvas1.FontSet) gegeben, die Canvas wird mit der Farbe der Innenseite des Feldes (m_canvas1.Erase) gefüllt und notwendigerweise wird die Änderung auf dem Bildschirm (m_canvas1.Update) angezeigt.

Schritt 2.

//--- create
   if(!m_bmp_button1.Create(m_chart_id,m_name+"BmpButton1",m_subwin,x1,y1,x1+10,y1+10))
      return(false);

Die Erstellung des Steuerungselementes m_bmp_button1 die Größe 10*10 Pixel. Eine kleine Größe des Steuerungselementes spielt keine Rolle. Hier ist die Hauptsache - selbst Koordinaten x1 und y1. Das ist der Ankerpunkt. Das heißt, wenn die Größe des Steuerungselementes sich auf die Größe des Bildes anpassen wird, wird der Winkel mit den Koordinaten (x1; y1) stehen bleiben.

Schritt 3.

//--- sets the name of bmp files of the control CBmpButton
   if(!m_bmp_button1.BmpOnName(m_canvas1.ResourceName()))
      return(false);

Wir bekommen den Ressource-Name (m_canvas1.ResourceName())und stellen als bmp-Datei im Online-Zustand ON (m_bmp_button1.BmpOnName) ein. Eben in diesem Stadium wird das Steuerungselement m_bmp_button1 auf die Größe des Canvases gestreckt.

Schritt 4.

Nach dem Erstellen des Steuerungselementes, vergessen wir nicht, dieses Steuerungselement zu dem Feld hinzuzufügen: 

   if(!Add(m_bmp_button1))
      return(false);

3.3. Das 2D-Array. Sortierung

Die Arbeit mit der Sortierung wird in der Datei "Calculator for signals Dialog.mqh" der Methode CoSDialog::InitStructurs durchgeführt. 

Der Signalrechner wurden Daten in der Tabelle durch den berechneten Index sortiert - Das Abbildungsverhältnis. Aber wenn man im Prozess das Abbildungsverhältnis erhalten wird, welches aus der Liste von Namen und dem berechneten Abbildungsverhältnis besteht, er ist nicht sortiert, sieht folgendermaßen aus:

Name Copy ratio
TestUSD 15.0
TradeLargeVolumes 120.0
Zeus PRO 15.0
CS Trading Co Beta Free Provider 1510.0
Mint blueberry ice cream 8.0
MT5Hedging 7.0
Forex Leos Trading 160.0
Hedge 1.0
Siksikawa 8770.0
Week H4 15.0
WGT Live Signal 45.0
Atrader 30.0
Trajecta Advisor FX491 30.0
MOsg style 6.0 

Für die Sortierung wurde die Lösung angewendet, die vom Vasiliy Sokolov mitgeteilt wurde: jede Zeile muss als CObject vorgestellt werden, und die ganze Tabelle — als Objekt CArrayObj. Diese Tabelle wurde linear genannt, die lineare virtuelle Tabellenklasse (virtuell, denn die Tabelle hat keine visuelle Interface) wurde in der Datei  "LineTable.mqh" gesetzt.

Im Folgenden finden Sie eine lineare Tabelle mit dem Sortierungsergebnis (Das Beispiel wird für die einigen ersten Zeilen von Einsätzen in der Tabelle gezeigt). Zunächst werden die Parameter angezeigt, die in die lineare Tabelle eingefügt werden (Insert : ), unten wird eine Liste nach allen Elementen der linearen Tabelle (Zeile #) angezeigt:

name rate  min_deposit
 Insert : MyCorrelation EURUSD XAUUSD  7  133134.7143
 row #0: MyCorrelation EURUSD XAUUSD  7  133134.7143
 Insert : EA microPatience AvzPrecio v6 HG 10  7  133134.7143
 row #0: MyCorrelation EURUSD XAUUSD  7  133134.7143
 row #1: EA microPatience AvzPrecio v6 HG 10  7  133134.7143
 Insert : EURUSD Daytrade  170  5482.017647
 row #0: EURUSD Daytrade  170  5482.017647
 row #1: MyCorrelation EURUSD XAUUSD  7   133134.7143
 row #2: EA microPatience AvzPrecio v6 HG 10  7  133134.7143
 Insert : Exp TickSniper PRO FULL MT5  50  18638.86
 row #0: EURUSD Daytrade  170  5482.017647
 row #1: Exp TickSniper PRO FULL MT5  50  18638.86
 row #2: MyCorrelation EURUSD XAUUSD  7  133134.7143
 row #3: EA microPatience AvzPrecio v6 HG 10  7  133134.7143
 Insert : Example1  3  310647.6667
 row #0: EURUSD Daytrade  170  5482.017647
 row #1: Exp TickSniper PRO FULL MT5  50  18638.86
 row #2: MyCorrelation EURUSD XAUUSD  7  133134.7143
 row #3: EA microPatience AvzPrecio v6 HG 10  7  133134.7143
 row #4: Example1  3  310647.6667
 Insert : Big sale  80  11649.2875
 row #0: EURUSD Daytrade  170  5482.017647
 row #1: Big sale  80  11649.2875
 row #2: Exp TickSniper PRO FULL MT5  50  18638.86
 row #3: MyCorrelation EURUSD XAUUSD  7  133134.7143
 row #4: EA microPatience AvzPrecio v6 HG 10  7  133134.7143
 row #5: Example1  3  310647.6667

Im Bild ist es gut zu sehen, dass die Sortierung nach dem Hinzufügen der linearen Tabelle über das Feld"rate" durchgeführt wird — das ist eben der Lauf, den wir brauchen. Später, wohl wissend, dass alle Elemente in einer linearen Tabelle sortiert sind, können Sie diese Werte auf das neue Steuerungselement kopieren,auf die Tabelle CTableListView, und sicher sein, dass die Daten in sortierter Reihenfolge präsentiert werden.

Für das Drücken der rundenbasierten Sortierung und der gleichen Tabelle kommentieren Sie einfach die Zeile in der Datei "Calculator for signals Dialog.mqh" der Methode CoSDialog :: InitStructurs: 

         else
           {
            min_deposit=AccInfo.balance/rate*100.0;
           }
         //Print("Insert : ",name,"; ",rate,"; ",min_deposit); 
         m_table.InsertSort(new CLineTable(name,rate,min_deposit));
         //for(int m=0;m<m_table.Total();m++)
         //  {
         //   CLineTable *line=m_table.At(m);
         //   Print("row #",m,": ",line.Text(),"; ",line.Number(),"; ",line.Number1());
         //  }
        }
      else PrintFormat("Error in call of SignalBaseSelect. Error code=%d",GetLastError());
     }
//---
   return(true);
  }

3.4. Ein neues Steuerungselement - die Tabelle CTableListView

Um Signale anzuzeigen, deren Eigenschaften und berechneten Daten, werden wir ein visuelles Steuerungselement erstellen - eine Tabelle, die einige Zeilen und Spalten anzeigen kann. Zur gleichen Zeit, wenn die Anzahl der Zeilen höher ist, als die Höhe der Tabelle, dann muss unbedingt eine vertikale Bildlaufleiste erscheinen. Nach der Suche wurde beschlossen, das Steuerungselement der Klasse CListView als Basis zu nutzen und ihn wesentlich zu modernisieren.

Das Steuerungselement, die Tabelle  CTableListView hat zwei Teile — einen sichtbaren Teil, den ein Benutzer sehen kann und mit ihm ein physisches Kontakt haben kann, und einen unsichtbaren Teil, in der die Daten der Tabelle-Zelle gespeichert sind.

Der sichtbare Teil der Tabelle wird durch die Größe des Steuerungselementes festgelegt. Er ist mit einem Rechteck mit den Koordinaten (x1; y1) beschränkt und (x2; y2) mit der Anzahl der Spalten columns, die bei der Erstellung des Steuerungselementes in der Methode Create gesetzt werden:

   virtual bool      Create(const long chart,const string name,const int subwin,const int x1,
                            const int y1,const int x2,const int y2,const uchar columns,const ushort &columns_size[]);

Der sichtbare Teil besteht aus den Steuerungselementen CEdit

Die Erstellung eines sichtbaren Teiles der Tabelle CTableListView

Abb. 9. Die Erstellung eines sichtbaren Teiles der Tabelle CTableListView

Die Steuerungselemente CEdit des sichtbaren Teiles werden durch das dynamische Zeigers-Array erstellt und gesteuert m_arr_rows  — das Objekt der Klasse CArrayObj:

   CArrayObj         m_arr_rows;             // array of pointer to objects-rows (CEdit) 

(Der Artikel über die Anwendung der Anzeiger Verwendung von Objektzeigern in MQL5)

Das Zeigers-Array m_arr_rows arbeitet nach dem Prinzip einer zweistufigen russischen Matreschka. Auf der ersten Stufe werden die Zeiger auf die Zeilenobjekte gespeichert row, und die haben row die Zeiger auf die Zellenobjekte (die Elemente CEdit) der Tabelle gespeichert:

Die Zeiger auf die sichtbaren Objekte

Abb. 10. Die Zeiger auf die sichtbaren Objekte 

Der unsichtbare Teil wird auch durch die Klasse CArrayObj realisiert. Für den unsichtbaren Teil sind zwei dynamischen Zeigers-Arrays m_arr_rows_str und m_arr_rows_val , verantwortlich

   CArrayObj         m_arr_rows_str;         // array of pointer to objects-rows (CArrayString) 
   CArrayObj         m_arr_rows_val;         // array of pointer to objects-rows (CArrayLong) 

in den der Text der Zellen und die Werte gespeichert sind.

Die Struktur der Zeigers-Arrays m_arr_rows_str und m_arr_rows_val sind ähnlich mit der Struktur der Zeigers-Arrays m_arr_rows, mit einem Unterschied, dass die Klasse der Arrays  CArrayString und CArrayLong als Zeilen verwendet werden.

3.4.1. Ein Beispiel für die Arbeit mit dem dynamischen Zeigers-Array

Betrachten wir die Arbeit mit dem dynamischen Zeigers-Array im Beispiel der Objekterstellung - Tabelle:

//+------------------------------------------------------------------+
//| Create a control                                                 |
//+------------------------------------------------------------------+
bool CTableListView::Create(const long chart,const string name,const int subwin,const int x1,
                            const int y1,const int x2,const int y2,const uchar columns,const ushort &columns_size[])
  {
   m_columns=columns;
   ArrayResize(m_columns_size,m_columns);
   if(ArraySize(columns_size)!=m_columns)
      return(false);
   ArrayCopy(m_columns_size,columns_size,0,0,WHOLE_ARRAY);
   m_columns_size[0]-=1;
   m_columns_size[m_columns-1]-=1;
   int y=y2;
//--- if the number of visible rows is previously determined, adjust the vertical size
   if(!TotalView((y2-y1)/m_item_height))
      y=m_item_height+y1+2*CONTROLS_BORDER_WIDTH;
//--- check the number of visible rows
   if(m_total_view<1)
      return(false);
//--- call method of the parent class
   if(!CWndClient::Create(chart,name,subwin,x1,y1,x2,y))
      return(false);
//--- set up
   if(!m_background.ColorBackground(CONTROLS_LIST_COLOR_BG))
      return(false);
   if(!m_background.ColorBorder(CONTROLS_LIST_COLOR_BORDER))
      return(false);
//--- create dependent controls
   CArrayObj *m_arr_cells;
   for(int i=0;i<m_total_view;i++)
     {
      m_arr_cells=new CArrayObj;
      if(CheckPointer(m_arr_cells)==POINTER_INVALID)
         return(false);
      for(int j=0;j<m_columns;j++)
        {
         CEdit *m_cell;
         m_cell=new CEdit;
         if(CheckPointer(m_cell)==POINTER_INVALID)
            return(false);
         m_arr_cells.Add(m_cell);
        }
      m_arr_rows.Add(m_arr_cells);
     }
//---
   for(int i=0;i<m_total_view;i++)
     {
      if(!CreateRow(i))
         return(false);
      if(m_height_variable && i>0)
        {
         // m_rows[i].Hide(); ///
         CArrayObj *m_arr_cells_i=m_arr_rows.At(i);
         if(CheckPointer(m_arr_cells_i)==POINTER_INVALID)
            return(false);
         for(int j=0;j<m_arr_cells_i.Total();j++)
           {
            CEdit *m_cell=m_arr_cells_i.At(j);
            if(CheckPointer(m_cell)==POINTER_INVALID)
               return(false);
            if(!m_cell.Hide())
               return(false);
           }
        }
     }
//--- succeed
   return(true);
  }

Im Code

//--- if the number of visible rows is previously determined, adjust the vertical size
   if(!TotalView((y2-y1)/m_item_height))
      y=m_item_height+y1+2*CONTROLS_BORDER_WIDTH;

Es wird TotalView aufgerufen, wo die die Anzahl der sichtbaren Zeilen berechnet wird. Die Anzahl wird in der Variable m_total_view gespeichert.

Weiter in der Loop for(int i=0;i<m_total_view;i++) werden die Zeilen m_arr_cells erstellt, und in der Loop for(int j=0;j<m_columns;j++) werden Zeilen mit den Zellen m_cell gefüllt:

//--- create dependent controls
   CArrayObj *m_arr_cells;
   for(int i=0;i<m_total_view;i++)
     {
      m_arr_cells=new CArrayObj;
      if(CheckPointer(m_arr_cells)==POINTER_INVALID)
         return(false);
      for(int j=0;j<m_columns;j++)
        {
         CEdit *m_cell;
         m_cell=new CEdit;
         if(CheckPointer(m_cell)==POINTER_INVALID)
            return(false);
         m_arr_cells.Add(m_cell);
        }
      m_arr_rows.Add(m_arr_cells);
     }
//---

Nach der vollständigen Überbrückung der Loop for(int j=0;j<m_columns;j++) wird jeder gefüllte Zeile zum Hauptarray m_arr_rows hinzugefügt:

      m_arr_rows.Add(m_arr_cells);

Auf diese Weise, nach der vollständigen Überbrückung der Loop for(int i=0;i<m_total_view;i++) haben wir ein gefülltes Zeigers-Array m_arr_rows, welches in seiner Struktur dem sichtbaren Teil der Tabelle entspricht (siehe. in Abb. 9).

Nach dem Füllen des Zeigers-Arrays in der zweiten Schleife for(int i=0;i<m_total_view;i++) wird die Tabelle durch den Aufruf (die Erstellung des sichtbaren Teiles der Tabelle) CreateRow visualisiert:

//---
   for(int i=0;i<m_total_view;i++)
     {
      if(!CreateRow(i))
         return(false);
      .
      .
      .
     }
//--- succeed
   return(true);

Die Methode CreateRow:

//+------------------------------------------------------------------+
//| Create "row"                                                     |
//+------------------------------------------------------------------+
bool CTableListView::CreateRow(const int index)
  {
   .
   .
   .
//--- create
   CArrayObj *m_arr_cells=m_arr_rows.At(index);
   if(CheckPointer(m_arr_cells)==POINTER_INVALID)
      return(false);
   for(int i=0;i<m_arr_cells.Total();i++)
     {
      CEdit *m_cell=m_arr_cells.At(i);
      if(CheckPointer(m_cell)==POINTER_INVALID)
         return(false);
      x1+=x2;
      x2=m_columns_size[i];
      if(!m_cell.Create(m_chart_id,m_name+"_"+IntegerToString(index)+"_"+IntegerToString(i),
         m_subwin,x1,y1,x1+x2,y2))
         return(false);
      if(!m_cell.Text(""))
         return(false);
      if(!m_cell.ReadOnly(true))
         return(false);
      if(!Add(m_cell))
         return(false);
     }
   .
   .
   .
   return(true);
  }

Im Block des Codes erhalten wir aus dem Zeigers-Array m_arr_rows den Zeiger auf das Element m_arr_cells (Das Element m_arr_cells  hat den Typ CArrayObj), der auf der Position index ist. Das Element m_arr_cells - ist eben die Zeile der Tabellerow (siehe. in Abb. 10). Wir verwenden die Methode At der KLasse CArrayObj:

   .
//--- create
   CArrayObj *m_arr_cells=m_arr_rows.At(index);
   if(CheckPointer(m_arr_cells)==POINTER_INVALID)
      return(false);
   for(int i=0;i<m_arr_cells.Total();i++)

Weiter in der Loop for(int i=0;i<m_arr_cells.Total();i++) arbeiten wir schon mit dem Element m_arr_cells (das Zeigers-Array): erhalten wir aus dem Zeigers-Array m_arr_cells den Zeiger auf das Element m_cell (Das Element m_cell hat den Typ CEdit),  der auf der Position i ist:

      CEdit *m_cell=m_arr_cells.At(i);
      if(CheckPointer(m_cell)==POINTER_INVALID)
         return(false);

Dann erstellen wir Zellen (Die Steuerungselemente CEdit) mit einem eindeutigen Namen:

      if(!m_cell.Create(m_chart_id,m_name+"_"+IntegerToString(index)+"_"+IntegerToString(i),
         m_subwin,x1,y1,x1+x2,y2))
         return(false);

ändern einige Eigenschaften der erstellten Steuerungselemente (entfernen wir den ganzen Text des Steuerungselementes und machen das Steuerungselement nicht mehr editierbar):

      if(!m_cell.Text(""))
         return(false);
      if(!m_cell.ReadOnly(true))
         return(false);

Und der letzte Schritt, aber nicht zuletzt - wir fügen das neu erstellte Steuerungselement zu unserem Feld:

      if(!Add(m_cell))
         return(false);
     }

 

Fazit

Ich hoffe, dass der Signalrechner Ihnen bei der Signale-Auswahl nützlich sein wird, und was am wichtigsten ist, es wird Ihnen helfen, zu sehen, wie das Abbildungsverhältnis sich ändert, wenn Sie (im Rechner) die Größe des Deposites und / oder des Hebels von Ihrem Trading-Konto ändern.


Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/2329

Beigefügte Dateien |
Die Erstellung des Bots für Telegram in der Sprache MQL5 Die Erstellung des Bots für Telegram in der Sprache MQL5
Dieser Artikel ist eine Anleitung, um Schritt um Schritt Bots für Telegramm in MQL5 zu erstellen. Dieses Material wird für diejenigen interessant sein, die ihre Traiding-Bots mit ihrem mobilen Gerät verknüpfen möchten. Der Artikel gibt Beispiele für Bots, die Trading-Signale senden, die Suche nach Informationen auf der Web-Seite durchführen, Informationen über den Status des Trading-Kontos senden, Notierungen und Screenshots der Charts auf Ihr Smartphone senden.
Rezepte MQL5 - Programmierung der gleitenden Kanäle Rezepte MQL5 - Programmierung der gleitenden Kanäle
In diesem Artikel wird eine Weise angeboten, das System der gleich entfernten Kanäle zu programmieren. Es werden einige Nuancen des Zeichens der Kanäle betrachtet. Es wird eine Typisierung der Kanäle durchgeführt, eine Weise des universellen Typs von Gleitkanälen angeboten. Es werden bei der Realisierung des Codes die OOP-Werkzeuge verwendet.
Reguläre Ausdrücke für Trader Reguläre Ausdrücke für Trader
Reguläre Ausdrücke (eng. regular expressions) stellen eine spezielle Sprache für die Textverarbeitung nach einer vorbestimmten Regel dar, die auch als Muster bezeichnet wird oder die Maske eines regulären Ausdrucks. In diesem Artikel zeigen wir Ihnen, wie Sie den Handelsbericht mit Hilfe von der Bibliothek RegularExpressions für MQL5 verarbeiten können, auch werden die Ergebnisse der Optimierung mit ihrer Anwendung demonstriert.
Tipps für eine effektive Produktpräsentation auf dem Market Tipps für eine effektive Produktpräsentation auf dem Market
Der Verkauf von Programmen an Händler erfordert effektiv nicht nur das Schreiben eines effizienten und nützlichen Produkts und dessen anschließende Veröffentlichung auf dem Market. Es ist äußerst wichtig, eine umfassende, detaillierte Beschreibung und gute Illustrationen bereitzustellen. Ein hochwertiges Logo und korrekte Screenshots sind genauso wichtig wie das Schreiben eines richtigen Codes. Denken Sie an eine simple Formel: keine Downloads = keine Verkäufe.