Signalrechner

Vladimir Karputov | 24 Juni, 2016

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 

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:

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.