Sortierung eines 2-dimensionalen Arrays nach der zweiten Dimension

 

Ich habe 2 Stücke von Daten, die ich in ein Array setzen müssen, dann sortieren Sie es.

Zuerst teile ich die Aufträge in zwei Arrays, das erste Array ist für Käufe, das andere für Verkäufe. Wenn ich dies tue, sammle ich das OrderTicket, damit ich später eine Ausführung für die Bestellung durchführen kann. Die zweite Sache, die ich sammle, ist der OrderClosePrice-Wert der Bestellung, damit ich sie mit einer anderen Liste vergleichen kann, die genau dieselbe ist.

Das erste Array habe ich also eingerichtet:

double AryBuys[][2];
double ArySells[][2];

AryBuy[1][0] enthält das Ticket, AryBuy[1][1] enthält den Preis.

Wie sortiere ich die zweite Dimension, so dass das Array nach dem Preis absteigend sortiert ist?

Hinweis: Mit ArraySort können Sie nur die erste Dimension sortieren. Hier ist ein möglicher Gedanke, ich könnte ein temporäres Array erstellen und den Preis zur ersten Dimension im temporären Array machen, es sortieren, dann zurück zum Array leiten und das Gleiche in umgekehrter Richtung tun, wenn ich es später nach Ticket sortieren muss. Würde das funktionieren?

 

Das geht leider nicht, aber Sie könnten ein zweites Array erstellen, in dem die Daten aus den beiden Dimensionen vertauscht werden, und dieses neue Array nach dem Preis (der ersten Dimension) sortieren. Sie könnten dann (wenn Sie das immer noch wollten) die Daten zurück in das ursprüngliche Array kopieren und die Daten in jeder Dimension erneut vertauschen. Jetzt enthält Ihr ursprüngliches Array die ursprünglichen Daten, ist aber nach den Werten der zweiten Dimension sortiert.

Das ist zwar etwas umständlich, aber es ist der einzige praktische Weg (den ich bisher herausgefunden habe), um die Daten nach Dimensionen >1 zu sortieren.

 

Daran habe ich in meinen Notizen gedacht. Meine Sorge war, dass die erste Dimension sortiert werden würde, würde es auch neu anordnen die zweite Dimension der Daten als auch, wenn die Sortierung stattgefunden hat? Ich denke, ich könnte einen Test einrichten, um dies auszuprobieren.

 
LEHayes wrote >>

Daran habe ich in meinen Notizen gedacht. Meine Sorge war, dass die erste Dimension sortiert werden würde, würde es auch neu anordnen die zweite Dimension der Daten als auch, wenn die Sortierung stattgefunden hat? Ich denke, ich könnte einen Test einrichten, um das auszuprobieren.


Ja, alle Elemente mit demselben Basisindex werden bei der Sortierung nach der ersten Dimension verschoben. Genau wie beim Sortieren einer Tabellenkalkulation, die mehrere Spalten mit Daten enthält, nur dass man in MQL nur nach der ersten Spalte sortieren kann.
 

Bis jetzt habe ich es wie besprochen eingerichtet. Ich bin mir sicher, dass ich das bis zum Ende der Konversation hinbekomme, aber momentan bekomme ich:
2010.04.15 23:51:01,M1: falsche Startposition 1 für ArraySort Funktion
Zuerst habe ich es so versucht:
ArraySort(AryBuy,WHOLE_ARRAY,0,MODE_DESCEND);
und erhielt die gleiche Meldung nur der Positionswert war 0, dann änderte ich den Start (Positionswert) auf 1, um zu sehen, was passieren könnte, und ich erhielt die oben genannten.

Die Arrays sollten zu diesem Zeitpunkt Daten in ihnen haben. Ich werde den Test zurücksetzen, um zu sehen, ob das Problem weiterhin besteht.

 
LEHayes:

.....
double AryBuys[][2];
double ArySells[][2];

AryBuy[1][0] enthält das Ticket, AryBuy[1][1] enthält den Preis. ....

Korrigieren Sie mich, wenn ich falsch liege, aber Sie scheinen das Array falsch zu definieren und anzusprechen. Zitiert aus der Variablenreferenz:

int    a[50];       // A one-dimensional array of 50 integers.
double m[7][50];    // Two-dimensional array of seven arrays,
                    //each of them consisting of 50 integers

das letzte Paar geschweifter Klammern ist die erste Dimension des Arrays... unter der Annahme, dass die unbestimmte Größe des Arrays die erste Dimension ist. Dies ist IMO die richtige Definition:

double AryBuys[2][];
double ArySells[2][];

AryBuy[0][1] contains the ticket, AryBuy[1][1] contains the price. 
 
cameofx:
das letzte Paar geschweifter Klammern ist die erste Dimension des Arrays... unter der Annahme, dass die unbestimmte Größe des Arrays die erste Dimension ist. Dies ist IMO die richtige Variante:

Siehe auch Buch...
Zu Ihrer Information: Ich finde es besser, das letzte Paar geschweifter Klammern als "erste Dimension" zu bezeichnen, da die nächste Dimension "später" hinzugefügt wird (obwohl sie weiter links steht).
IMHO ist die Bezeichnung "Größe der Spalten" auch konzeptionell besser.

 
cameofx:

Zu Ihrer Information: Ich finde es besser, das letzte Paar geschweifter Klammern als 'erste Dimension' zu bezeichnen, weil die nächste Dimension 'später' hinzugefügt wird (obwohl sie weiter links liegt).

Unabhängig davon, wie Sie es nennen möchten, ist die erste Dimension in einem 2D-Array der Vektor arr_name[0,1,...,n][0], so dass technisch gesehen die erste Klammer die erste Dimension enthält; dies ist auch der Vektor, der von ArraySort() sortiert wird. Aus dem Buch:

Wenn wir schon beim Thema ArraySort() sind, möchte ich noch 2 undokumentierte Besonderheiten erwähnen, die ich im Laufe der Zeit gefunden habe (und würde mich freuen, wenn mich jemand bestätigt oder korrigiert...?):

  1. Wenn einige der Elemente in der ersten Dimension identisch sind, behalten sie nicht unbedingt ihre Reihenfolge bei. Offensichtlich sollte dies dokumentiert werden, wenn es 'by-design' ist, andernfalls würde ich dies als 'Bug' betrachten.
  2. OrderSort() funktioniert nicht mit 4D-Arrays (gibt Fehler 4053 zurück). Auch dies sollte dokumentiert sein, ist es aber nicht.
 
cameofx wrote >>

Korrigieren Sie mich, wenn ich falsch liege, aber Sie scheinen das Array falsch zu definieren und zu adressieren. Aus der Variablenreferenz zitiert:

das letzte Paar geschweifter Klammern ist die erste Dimension des Arrays... unter der Annahme, dass die unbestimmte Größe des Arrays die erste Dimension ist. Dies ist IMO die korrekte Variante:



Ich betrachte die Indizierung und Dimensionierung von Arrays in der Standard-Tabellenkalkulation...Zeile-Spalte (Eselsbrücke "römisch-katholisch").

1D-Array: MeinArray[Zeilennummer-1]

2D-Array: MyArray[RowNumber-1][ColumnNumber-1]

3D-Array: MyArray[RowNumber-1][ColumnNumber-1][Worksheet-1]

Die Klammer ganz links ist die erste Dimension. Alles, was Sie mit der Array-Manipulation der ersten Dimension zu tun haben, wird mit dem Index der Klammer ganz links durchgeführt. Eine Größenänderung des Arrays (die nur für die erste Dimension möglich ist) ändert beispielsweise nur den Wert der ganz linken Klammer, nicht aber den Indexbereich der zweiten, dritten oder vierten Dimension (zweite, dritte oder vierte Klammer ganz rechts).

Alle meine Datenzeilen im Array werden durch den ersten Satz von Klammern indiziert, den ganz linken Satz, und dies ist die "erste Dimension" des Arrays.

MyArray[0][ColumnNumber-1] -> erste Zeile der Daten

MyArray[1][SpaltenNummer-1] -> zweite Datenreihe

MyArray[2][ColumnNumber-1] -> dritte Zeile der Daten

In MQL kann ich nur nach Daten sortieren, die in der ersten Datenspalte enthalten sind, d. h. nach den Werten in MyArray[i][0]. Werte, die sich in derselben Zeile (in diesem Fall dasselbe "i"), aber in verschiedenen Spalten (der Wert in der zweiten Klammer) befinden, können nicht zum Sortieren/Rangieren verwendet werden.

Hier ist ein Beispiel für ein 2D-Array:

3 5
1 9
7 6

Also MyArray[0][0] = 3, und MyArray[0][1] = 5, und MyArray[2][1] = 6, usw.

Ich kann dieses Array sortieren:

ArraySort(MeinArray,WHOLE_ARRAY,0,MODE_ASCEND) und das Ergebnis wird das folgende sein:

1 9
3 5
7 6

Die erste Spalte ist sortiert, die zweite Datenspalte (d.h. alle Daten mit dem gleichen Index der ersten Dimension) wird mit der Sortierung/Verschiebung der ersten Spalte mitgeführt.

Ich kann die zweite Datenspalte in MQL nicht sortieren/einordnen...d.h. ich kann das Folgende NICHT erhalten (jedenfalls nicht direkt):

3 5
7 6
1 9

(Hinweis: Die zweite Spalte ist jetzt von der kleinsten zur größten Spalte sortiert)

Um ein Array zu erhalten, in dem die zweite Spalte (oder eine andere Spalte als die erste Spalte) sortiert ist, muss ich die Daten manuell zwischen den Spalten austauschen (wobei der Index der ersten Dimension gleich bleibt, aber der Wert des Index der zweiten Dimension ausgetauscht wird), dann sortieren und dann die Daten wieder austauschen.

MeinNeuesArray:
5 3
9 1
6 7

Sortieren Sie nun nach der ersten Spalte, ArraySort(MyNewArray,WHOLE_ARRAY,0,MODE_ASCEND) und das Ergebnis wird wie folgt aussehen:

5 3
6 7
9 1

Kopieren Sie dann die Werte zurück in mein ursprüngliches Array, wobei Sie den Index der zweiten Dimension transponieren und den Wert der ersten Dimension beibehalten:

3 5
7 6
1 9

Jetzt habe ich mein ursprüngliches Array, aber die Daten sind nach der zweiten Spalte sortiert.

 

Diese ganze Sache verwandelte sich in einen Albtraum, ich weiß nicht einmal mehr, ob ich versucht habe, es weiter zu verfolgen. Die Idee, die ich hatte, war, die Liste der offenen Trades zu nehmen, die Käufe von den Verkäufen in 2 Arrays zu trennen, jedes Array enthielt die Ticketnummer in der ersten Spalte, die zweite enthielt den Preiswert des Trades. Im Allgemeinen war die Idee, alle großen Kaufwerte mit allen großen Verkaufswerten abzugleichen, und wenn der höchste Kaufwert den höchsten Verkaufswert überstieg, dann beide Geschäfte zu schließen und den Prozess zu wiederholen.

Der letzte Haken, der mich von dieser Idee abkommen ließ, war, dass ich, nachdem ich diesen Prozess durchlaufen hatte, mindestens einen positiven Kauf- und einen positiven Verkaufshandel auf dem Tisch lassen wollte, um ein abgesichertes Handelssystem in Gang zu halten. Dies ist im Grunde als Drawdown-Management-Tool für eine Absicherungsstrategie konzipiert. Ich möchte also die Absicherung beibehalten, aber die Erträge vom Tisch nehmen. Mir kam der Gedanke, dass die Verwendung eines Array-Algorithmus eine Lösung für dieses Problem darstellen könnte.

Ich bin wirklich müde und erschöpft von dem Versuch, die Veröffentlichung von etwa 5 Strategien voranzutreiben, so dass dies eher eine nette Kleinigkeit als eine Notwendigkeit ist.

Ich bin bereit, mit jedem, der diese Funktion für mich schreiben kann, einen Deal zu machen. Ich überlasse Ihnen ein Produkt Ihrer Wahl mit einer Jahreslizenz, wenn Sie mir dabei helfen, und außerdem gebe ich Ihnen eine persönliche Kopie dieser Hedging-Strategie zur kostenlosen, unbegrenzten Nutzung auf Lebenszeit. Ich bin einfach zu überlastet, um das alles zu tun, und mein Entwicklungsteam ist mit der Freigabe dessen, was wir bereits auf unseren Tellern haben, stark belastet. Ich glaube, der durchschnittliche Schlafwert im Team liegt bei 4 bis 6 Stunden pro Tag.

Wenn Sie also an einem kleinen Tauschhandel interessiert sind, ist das mein Angebot.

Zielsetzung:
1. Trenne die Käufe von den Verkäufen
2. Sortieren nach höchstem und niedrigstem Preiswert
3. Wenn der Kaufkurs den höchsten positiven Wert und der Verkaufskurs den niedrigsten positiven Wert hat, wollen wir den niedrigsten Verkaufskurs mit dem höchsten Kaufkurs abschließen, wobei der Kaufkurs die Kosten für den Verkaufskurs übersteigen muss. Wenn der Verkaufspreis höher ist, kehren wir diesen Vorgang um und schließen den niedrigsten Kaufkurs mit dem höchsten Verkaufskurs ab. Die Idee ist, dass wir jeden Verlust mit einem Gewinn zu einem höheren Preis abschließen, so dass die Gewinne die Verluste mit einem durchschnittlichen positiven Gewinn übersteigen.

Beispiel:
kaufen verkaufen
$15 $- 12
$5 $ - 6
$ 1.5 $ -1
$ 1 $ - .5

Dies zeigt eine ausgewogene Anzahl von offenen Geschäften auf beiden Seiten. Beachten Sie die $15-Käufe und $-12-Verkäufe, die geschlossen werden können, weil die positiven Käufe die negativen Verkäufe übersteigen. Wir können auch die 5 und die -6 schließen, weil die ersten beiden Schließungen so viel Gewinn abwerfen, dass das Gleichgewicht zwischen der Schließung der 4 Geschäfte zu einem positiven Ergebnis führen würde. Das Gleiche können wir für die 1,5 und die -1 tun, aber wir würden die 1 und die -,5 nicht schließen wollen, weil wir die abgesicherte Situation beibehalten wollen.

In der Mehrzahl der Fälle werden die Geschäfte nicht auf beiden Seiten ausgeglichen sein. Dies war die Grundlage für das Design, um die schwerste Seite mit einer höheren Losgröße und zusätzlichen Geschäften zugunsten der Gewinnerseite auszugleichen, so dass es möglich ist, dass Sie nur 1 Verkauf haben, in diesem Fall würden Sie nichts tun. Falls die beiden Seiten nicht ausgeglichen sind, aber mindestens 2 Geschäfte auf jeder Seite stehen, müssen Sie sicherstellen, dass Sie auf jeder Seite ein Geschäft offen lassen. Überwiegt ein positiver Handel mehr als ein negativer Handel, können Sie alle schließen, bis auf den einen Handel auf jeder Seite, der im Verhältnis zu den anderen am kleinsten ist.

Die Funktion sollte so konzipiert sein, dass sie eine Schließungsfunktion aufruft, die eine bestimmte ticketid schließt, so dass Sie sich nicht um die Schließung kümmern müssen, sondern nur den Aufruf tätigen müssen, damit die Geschäfte unter Übergabe der ticketid geschlossen werden. Möglicherweise müssen Sie Ihre Liste neu erstellen, damit sie nicht die geschlossenen Geschäfte vergleicht, sondern alle neuen Geschäfte, die während der Verarbeitung aufgetreten sind.

Ach ja, eine Sache noch...
Es sollte nicht zu gierig sein, Sie sollten ein externes Tool zur Verfügung stellen, das vorgibt, wie oft diese Funktion ausgelöst werden soll, es kann auf einer Kerzenanzahl oder einer Stunden- oder Minutenbasis basieren, sollte aber nicht jeden Tick oder sogar jede neue Kerze auslösen. So wie es ist, gibt es ein zusätzliches Tool, in das es eingebettet wird, das zuerst erfordert, dass das andere Tool ausgelöst wird, um dieses aufzurufen. Das andere Tool wird also ausgelöst, und der Countdown beginnt, bis Ihr Tool ausgelöst wird.

 
Larry, ich bin ziemlich sicher, dass der Code für CloseBy() hier -> https://book.mql4.com/trading/orderclose (es ist etwa 2/3 unten auf der Seite...) kann erweitert werden, um zu tun, was u wollen (ohne Verwendung von Arrays)... Nur ein Gedanke für dich.