Frage zu Arrays

 

Hallo an die Spezialisten,


ich hab da mal eine Frage, hab mich ja immer gewundert wofür mehrdimensionale Arrays gut sind, aber kommt die Zeit findet sich das von selbst.

Was ich bei mql5 nicht gefunden habe, darf ich Array mit verschiedenen typen befüllen?

lt. Doku kann ich ja nur ein mehrdimensionales Array mit dem gleichen Zahlentyp machen


double xxx[],[10],[10];


jetzt hätte ich aber gerne string und long Werte gemischt in einem Array was mir ein solches Ergebnis bringen sollte

Pair ChartID

EURUSD 12345

USDJPY 23456

....


ich hab das mal über 2 Arrays gelöst


  int count=0;
   long chartID[];                           // Array für die Chart ID
   string symbol[];                          // Array für das symbol
   ArrayResize(chartID,128,0 );
   ArrayResize(symbol,128,0);
   for(long chartid=ChartFirst(); chartid!=-1; chartid=ChartNext(chartid))
     {
      count++;// ab hier werden die Symbole abgefragt und die weiteren Schritte über alle Symbole durchgeführt.
      chartID[count] = chartid;              // chart ID in den Array schreiben
      symbol[count] = ChartSymbol(chartid);  // Symbol in den Array Schreiben
     }    
     ArrayResize(chartID,count,0);
     ArrayResize(symbol,count,0);

ginge das mit einem auch?

darf ich long und string in einem Array zusammenfassen?



dann gleich noch eine Frage, ich gehe ja davon aus, wenn ich ein Chart öffne, das die Chart ID fix bleibt.

Kann es sein, das Arrays mit String sich umgekehrt füllen als Arrays mit long?


da mein Debugger ja nicht funktioniert, startet aber beendet sich gleich hab ich das mal auf Print gegeben

    for(int i=0;i<ArraySize(chartID);i++)
    {
    Print(symbol[i]," = ",chartID[i]);
    } 

hier mal der Ausdruck mit 3 offenen Fenstern, wobei mich das erste ja eigentlich nicht wirklich interessiert



und dann mit 4


wo auffällig ist, die Chart ID mit der Endung 664 bekommt immer das neueste Fenster

 

hi amando,

nur kurz zur ersten Frage: Du könntest das mit einer Struktur lösen, also mit dem Befehl struct eine Struktur der gewünschten gemischten Variblentypen erzeugen (reicht 1x auf globaler Ebene) und dann machst Du danach ein Array dieser Strukur und liest die Daten dann aus nach dem Motto Struktur[n].ChartID, Struktur[n].Symbolstring usw.; frag nach falls unklar ist, was ich meine.

Gruß

 
amando:

Hallo an die Spezialisten,


darf ich long und string in einem Array zusammenfassen?


Nein da ein Array Typbezogen ist. Kombination geht aber wie Chris schon sagte....

//+------------------------------------------------------------------+
//|                                                   amando_323.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
struct  Charts
   {
     string   Name ; 
     long     ID ;
   };


void OnStart()
  {
//---
  Charts chart[100];
  
  
  chart[1].Name = "EURUSD";
  chart[1].ID   = 23211233222;
  
  chart[2].Name = "EURCHF";
  chart[2].ID   = 2321121223222; 
  
  chart[3].Name = "EURGBP";
  chart[3].ID   = 212232112332;
  
  for (uint idx=1;idx < 4; idx++)
    {
      Print(chart[idx].ID);
      Print(chart[idx].Name);
    }
  }
//+------------------------------------------------------------------+
 
Christian:

Nein da ein Array Typbezogen ist. Kombination geht aber wie Chris schon sagte....

danke für die Antworten,

das bedeutet ja, das ich eine struct auch dynamisch befüllen kann oder seh ich das falsch?

 
amando:

danke für die Antworten,

das bedeutet ja, das ich eine struct auch dynamisch befüllen kann oder seh ich das falsch?

Da musst du unterscheiden.

Ein array aus einem struct kannst du nicht mit den typischen Befehlen wie

ArrayCopy()
ArrayFill()
ArrayFree()

bearbeiten. Der Compiler meckert weil der Typ nicht passt.

Im Grunde hast du nur wie in meinem Beispiel 100 Objecte erstellt aber kein arrray in dem klassischen Sinn.

Sieht zwar so aus ist es aber nicht.


Tipp:

Bevor du dir da irgendwas bastelst , lies dich in die Welt der Container ein.

Es gibt unter MQL5 schon Container in OOP für double,string ect.

Dort kannst du eine ganze Liste verwalten mit Funktionen wie suchen , hinzufügen, löschen..etc.

Dann baust du dir einfach einen art Super-Container in dem du die gewünschten Datentypen zusammenfügst und einen gemeinsamen Index anlegst.

Ich hatte schon mal eine vertige Include von so einem Objekt. Finde das aber nicht mehr . Geisterte hier uaf der Webseite rum.


Gibt aber noch andere Arten sowas zu verwalten.

Container sind aber mitlerweise auch hier in MQL5 auf breiter Front eingezogen.

Mach dich vertraut mit:

Daten-Arrays

Mit den Klassen von dynamischen Daten-Arrays sparen Sie Zeit bei der Entwicklung von verschiedenen benutzerdefinierten Data-Warehouses (mehrdimensionale Arrays).

Die Standardbibliothek MQL5 (in Bezug auf Daten-Arrays) befindet sich im Arbeitsverzeichnis des Terminals im Ordner Include\Arrays.

Klasse

Beschreibung

CArray

Die Basisklasse des dynamischen Daten-Arrays

CArrayChar

Ein dynamisches Array von Variablen vom Typ char oder uchar

CArrayShort

Ein dynamisches Array von Variablen vom Typ short har oder ushort

CArrayInt

Ein dynamisches Array von Variablen vom Typ int oder uint

CArrayLong

Ein dynamisches Array von Variablen vom Typ long oder ulong

CArrayFloat

Ein dynamisches Array von Variablen vom Typ float

CArrayDouble

Ein dynamisches Array von Variablen vom Typ double

CArrayString

Ein dynamisches Array von Variablen vom Typ string

Die Basisklasse der Objekten CArrayObj

Ein dynamisches Array von Zeigern CObject

Die Basisklasse der Liste CList

Bietet die Möglichkeit, mit einer Liste der Instanzen der CObject-Klasse und ihrer Nachfolger zu arbeiten

CTreeNode

Bietet die Möglichkeit, mit den Knoten eines binären Baums CTree zu arbeiten

CTree

Bietet die Möglichkeit, mit dem binären Baum der Instanzen der CTreeNode-Klasse und ihrer Nachfolger zu arbeiten


https://www.mql5.com/de/docs/standardlibrary/datastructures


Es gibt hierzu auch Artikel ...alles schon fertig was du brauchst oder Carl ?   .. :-)

Dokumentation zu MQL5: Standardbibliothek / Datensammlungen
Dokumentation zu MQL5: Standardbibliothek / Datensammlungen
  • www.mql5.com
Dieser Abschnitt enthält die technischen Details der Arbeit mit verschiedenen Datenstrukturen (Arrays, verkettete Listen, etc.) und die Beschreibungen der Komponenten der Standardbibliothek MQL5. Durch die Verwendung der Klassen von Datenstrukturen, sparen Sie Zeit bei der Entwicklung von verschiedenen benutzerdefinierten...
 

Hab das Ding dann doch noch gefunden :

The Table  ....die Eierlegede Vollmilchsau :-)


Artikel durchlesen und dann hast du eine Art von Super-Container der viele Arten von Datentypen komfortabel verwalten kann.

Aber immer bedenken: Je mehr Komfort desto langsamer der Code

Periodische Berechnungen würde ich mit der Table nur mit Timer machen .

Alles was in OnTick()  so schlank wie möglich.

https://www.mql5.com/de/articles/228

Elektronische Tabellen in MQL5
Elektronische Tabellen in MQL5
  • www.mql5.com
Elektronische Tabellen beziehen sich meist auf Tabellen-Verarbeiter (also Anwendungen zur Speicherung und Verarbeitung von Daten), wie z.B. EXCEL. Der in diesem Beitrag gezeigte Code ist zwar nicht so leistungsfähig, doch kann er als eine Basisklasse für eine voll-funktionsfähige Implementierung eines Tabelle-Verarbeiters verwendet werden. Ich...
 
Christian:

Hab das Ding dann doch noch gefunden :

The Table  ....die Eierlegede Vollmilchsau :-)


Artikel durchlesen und dann hast du eine Art von Super-Container der viele Arten von Datentypen komfortabel verwalten kann.

Aber immer bedenken: Je mehr Komfort desto langsamer der Code

Periodische Berechnungen würde ich mit der Table nur mit Timer machen .

Alles was in OnTick()  so schlank wie möglich.

https://www.mql5.com/de/articles/228

das hab ich befürchtet, das die OnTick da zu langsam wird ;-)

ich les mir das mal durch und schau mal ob das meine Lösung ist


danke @Christian

 

gar nicht so einfach wenn man sich erstmals mit dem befasst.

nun gut, ich hab mir das alles mal durchgelesen, und das mit dem CArray ist so eine sache, soviel brauch ich ja gar nicht ;-)


unter der Annahme, es gibt max 64 offene Charts

  int count=0;
   long chartID[];                           // Array für die Chart ID
   string symbol[];                          // Array für das symbol
   ArrayFree(chartID);
   ArrayFree(symbol);
   ArrayResize(chartID,64,0);
   ArrayResize(symbol,64,0);

   for(long chartid=ChartFirst(); chartid!=-1; chartid=ChartNext(chartid))
     {
      count++;// ab hier werden die Symbole abgefragt und die weiteren Schritte über alle Symbole durchgeführt.
      chartID[count] = chartid;              // chart ID in den Array schreiben
      symbol[count] = ChartSymbol(chartid);  // Symbol in den Array Schreiben
      Print(symbol[count]," ", chartID[count]);
     }

   ArrayResize(chartID,count+1,0);
   ArrayResize(symbol,count+1,0);

   
   ArrayPrint(chartID,0,NULL,1,WHOLE_ARRAY,ARRAYPRINT_INDEX);
   ArrayPrint(symbol,0,NULL,1,WHOLE_ARRAY,ARRAYPRINT_INDEX);

funktioniert das.


Ich hab da nur eine Frage zum Array Generell,

nachdem ich den Array befülle und anschließend den resize mache auf die echte größe

   ArrayResize(chartID,count+1,0);
   ArrayResize(symbol,count+1,0);

muss ich zur count +1 hinzuzählen.

das ist mir soweit klar, da ich ja in der for schleife bei 0 beginne und raufzähle. sieht etwas ünschön aus, kann ich lösen indem ich

count = 1;

definiere und dann hochzähle.


aber im Array, gibts keinen keinen Index 0? beginnt der immer mit 1?


also wenn ich habe

double Array[10];

kann ich den nicht von 0-9 auslesen sondern von 1-10

 
amando:

gar nicht so einfach wenn man sich erstmals mit dem befasst.

nun gut, ich hab mir das alles mal durchgelesen, und das mit dem CArray ist so eine sache, soviel brauch ich ja gar nicht ;-)


unter der Annahme, es gibt max 64 offene Charts

funktioniert das.


Ich hab da nur eine Frage zum Array Generell,

nachdem ich den Array befülle und anschließend den resize mache auf die echte größe

muss ich zur count +1 hinzuzählen.

das ist mir soweit klar, da ich ja in der for schleife bei 0 beginne und raufzähle. sieht etwas ünschön aus, kann ich lösen indem ich

definiere und dann hochzähle.


aber im Array, gibts keinen keinen Index 0? beginnt der immer mit 1?


also wenn ich habe

kann ich den nicht von 0-9 auslesen sondern von 1-10

Also ....dynamische Arrays verwendet man nur wenn zur Compilezeit (sprich wenn der Compiler gestartet wird) NICHT weis wie groß das Array werden wird.

In deinem Falle sind die Grenzen ja gesteckt.

64 Charts.


Dann reicht das

//+------------------------------------------------------------------+
//|                                    forum_amando_array_charts.mq5 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
  
   int count=0;                                // Zähler für Charts
   long chartID[63];                           // Array für die Chart ID 64 Stück von 0-63
   string symbol[63];                          // Array für das symbol   64 Stück von 0-63
  
  // Wichtig // Immer erst initialisieren sonst sind mit Pech schon "krumme" Werte drin
   ArrayFill(chartID,0,63,0);  // Jeden Wert im Array mit 0 speichern 
   // leider funktioniert ArrayFill nicht für Strings 
   // Hab aber auch noch nie "wirre" strings gesehen  
   

   
   for(long chartid=ChartFirst(); chartid!=-1; chartid=ChartNext(chartid))
     {
      
      chartID[count] = chartid;              // chart ID in den Array schreiben
      symbol[count] = ChartSymbol(chartid);  // Symbol in den Array Schreiben
      Print(symbol[count]," ", chartID[count]);
      count++;
     }

  // ArrayResize(chartID,count+1,0);    // Resize ist ein "teuerer" Befehl . Hier wird das Array immer kopiert = Laufzeitverluste
  // ArrayResize(symbol,count+1,0);     // die Anzahl der Charts wird in count gezählt, das soll reichen

   // Index 0 geht siehe hier
   for (int idx=0;idx != count ; idx++ )
    {
     printf("Wert = %s aus Index %d",symbol[idx],idx);
    }
     
   ArrayPrint(chartID,0,NULL,0,count);
   ArrayPrint(symbol,0,NULL,0,count);
  }
//+------------------------------------------------------------------+

Mann muss selber abwägen , am schnellsten ist diese Version. Komfortabel ist vielleicht deine mit Resize.

Index 0 geht ...siehe Code

 
amando:


nun gut, ich hab mir das alles mal durchgelesen, und das mit dem CArray ist so eine sache, soviel brauch ich ja gar nicht ;-)

Da hst du vollkommen Recht , das war etwas mit Kanonnen auf Spatzen... :-)

Aber deine Projekte werden größer so oder so.

Und da ist es gut zu Wissen was möglich ist.

Bleib erstmal bei der schlanken Version

Ich baue dein Code aber mal zum Lernzweck auf CArrayLong und CArrayString um .

 

Nun schau was komfortabler ist.

Hier die Lösung mit Containern CArrayString und CArrayLong

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
#include <Arrays\ArrayLong.mqh>
#include <Arrays\ArrayString.mqh>
 
CArrayString caStrSymbol;
CArrayLong caLChartID;


void OnStart()
  {
  
  
     
   for(long chartid=ChartFirst(); chartid!=-1; chartid=ChartNext(chartid))
     {    
      caLChartID.Add(chartid);              // chart ID in das Object schreiben
      caStrSymbol.Add(ChartSymbol(chartid));  // Symbol in das Object Schreiben
      Print("Count = ",caStrSymbol.Total());  // Anzahl der gepeicherten Elemente ausgeben     
      Print(caStrSymbol.At(caStrSymbol.Total()-1), " <--> " , caLChartID.At(caLChartID.Total()-1));    
     }
     
   for( int idx = 1;idx < caLChartID.Total();idx++)
      {
        Print(caLChartID.At(idx));
        Print(caStrSymbol.At(idx));
      }
   
   caStrSymbol.Sort();     
   Print("Chart EURUSD hat den Index = ",caStrSymbol.Search("EURUSD"));
   
   Print("Zeige die ID vom EURUSD Chart = ",caLChartID.At(caStrSymbol.Search("EURUSD")));
   
  }
//+------------------------------------------------------------------+
Grund der Beschwerde: