trier un tableau à deux dimensions par la deuxième dimension

 

J'ai deux données que je dois mettre dans un tableau, puis trier.

D'abord, je divise les ordres en deux tableaux : le premier tableau est pour les achats, l'autre pour les ventes. Lorsque je fais cela, je collecte le OrderTicket pour pouvoir ensuite exécuter l'ordre. La deuxième chose que je collecte est la valeur OrderClosePrice de l'ordre afin de pouvoir le comparer à une autre liste exactement identique.

Donc le premier tableau que j'ai configuré :

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

AryBuy[1][0] contient le billet, AryBuy[1][1] contient le prix.

Comment trier la deuxième dimension de manière à obtenir un tableau trié par prix décroissant ?

Remarque : avec ArraySort, vous ne pouvez trier que la première dimension. Voici une idée possible : je pourrais créer un tableau temporaire et faire en sorte que le prix soit la première dimension du tableau temporaire, le trier, puis le renvoyer dans le tableau et faire la même chose en sens inverse lorsque j'aurai besoin de le trier par ticket. Cela fonctionnerait-il ?

 

vous ne pouvez pas, malheureusement, mais vous pourriez créer un deuxième tableau avec les données des deux dimensions permutées et trier ce nouveau tableau par prix (la première dimension). Vous pourriez ensuite (si vous le souhaitez toujours) recopier les données dans le tableau d'origine, en intervertissant à nouveau les données dans chaque dimension. Maintenant, votre tableau original contient les données originales mais il est trié par les valeurs de la deuxième dimension.

C'est un peu compliqué, mais c'est le seul moyen pratique (que j'ai pu trouver) d'obtenir des données triées par dimensions >1.

 

C'est ce à quoi j'ai pensé dans mes notes. Ce qui m'inquiète, c'est que si la première dimension est triée, la deuxième dimension de données sera-t-elle également réorganisée lors du tri ? Je suppose que je pourrais mettre en place un test pour essayer cela.

 
LEHayes wrote >>

C'est ce à quoi j'ai pensé dans mes notes. Ce qui m'inquiète, c'est que si la première dimension est triée, la deuxième dimension de données sera-t-elle également réorganisée lors du tri ? Je suppose que je pourrais mettre en place un test pour essayer cela.


Oui, tous les éléments du même indice de base sont déplacés avec le tri de la première dimension. Tout comme le tri d'une feuille de calcul contenant plusieurs colonnes de données, seulement dans MQL vous ne pouvez trier que par la première colonne.
 

Jusqu'à présent, je l'ai mis en place comme discuté. Je suis sûr que je vais résoudre ce problème d'ici à ce que nous terminions la conversation, mais pour l'instant je l'obtiens :
2010.04.15 23:51:01,M1 : position de départ incorrecte 1 pour la fonction ArraySort
Au début, j'ai essayé comme ceci :
ArraySort(AryBuy,WHOLE_ARRAY,0,MODE_DESCEND) ;
et j'ai obtenu le même message, mais la valeur de la position était de 0. J'ai alors changé la valeur de départ (position) à 1 pour voir ce qui pourrait se passer et j'ai obtenu le message ci-dessus.

Les tableaux devraient contenir des données à ce stade. Je vais réinitialiser le test pour voir si le problème persiste.

 
LEHayes:

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

AryBuy[1][0] contient le billet, AryBuy[1][1] contient le prix. ....

Corrigez-moi si je me trompe mais vous semblez définir et adresser le tableau de manière incorrecte. Citation de la référence de la variable:

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

la dernière paire d'accolades est la première dimension du tableau... en supposant que la taille indéfinie du tableau est la première dimension. C'est, selon moi, la bonne définition :

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

AryBuy[0][1] contains the ticket, AryBuy[1][1] contains the price. 
 
cameofx:
la dernière paire d'accolades est la première dimension du tableau... en supposant que la taille indéfinie du tableau est la première dimension. C'est, à mon avis, la bonne solution :

Voir aussi le livre...
Pour info, je suis plus à l'aise pour nommer la dernière paire d'accolades comme "première dimension" parce que la dimension suivante est ajoutée (bien que située plus à gauche) "plus tard".
Je pense que le fait de le considérer comme "taille des colonnes" est également plus pertinent du point de vue du concept.

 
cameofx:

Pour information, je suis plus à l'aise pour nommer la dernière paire d'accolades "première dimension" car la dimension suivante est ajoutée (bien que située plus à gauche) "plus tard".

Peu importe comment vous voulez l'appeler, la première dimension dans un tableau 2D est le vecteur arr_name[0,1,...,n][0], donc techniquement la première parenthèse contient la première dimension ; c'est aussi le vecteur qui sera trié par ArraySort(). Extrait du livre :

Tant que nous sommes sur le sujet de ArraySort(), je vais mentionner 2 particularités non documentées que j'ai trouvées au fil du temps (et je serais heureux si quelqu'un me confirme ou me corrige... ?):

  1. Si certains des éléments de la première dimension sont identiques, ils ne conserveront pas nécessairement leur ordre. Évidemment, cela devrait être documenté si c'est "by-design", sinon je considérerais cela comme un "bug".
  2. OrderSort() ne fonctionne pas avec les tableaux 4D (renvoie l'erreur 4053). Encore une fois, cela devrait être documenté mais ne l'est pas.
 
cameofx wrote >>

Corrigez-moi si je me trompe mais vous semblez définir et adresser le tableau de manière incorrecte. Citation de la référence de la variable:

la dernière paire d'accolades est la première dimension du tableau... en supposant que la taille indéfinie du tableau est la première dimension. Ceci est, selon moi, la bonne solution :



Je considère l'indexation et le dimensionnement des tableaux de la manière standard des tableurs... Row-Column (mnémotechnique "Roman-Catholic").

Tableau 1D : MonTableau[NuméroDeLigne-1]

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

Tableau 3D : Mon tableau [Numéro de rangée-1] [Numéro de colonne-1] [Feuille de calcul-1].

Le jeu de parenthèses le plus à gauche correspond à la première dimension. Tout ce que vous faites qui implique une manipulation de tableau de la première dimension sera fait avec l'index du jeu de parenthèses le plus à gauche. Le redimensionnement d'un tableau (qui ne peut être effectué que sur la première dimension), par exemple, ne modifie que la valeur du jeu de parenthèses le plus à gauche, mais pas la plage d'index des deuxième, troisième ou quatrième dimensions (deuxième, troisième ou quatrième jeu de parenthèses le plus à droite).

Toutes mes lignes de données dans le tableau sont indexées par le premier ensemble de parenthèses, l'ensemble le plus à gauche, et c'est la "première dimension" du tableau.

MyArray[0][ColumnNumber-1] -> première ligne de données

MyArray[1][ColumnNumber-1] -> deuxième ligne de données

MyArray[2][ColumnNumber-1] -> troisième ligne de données

En MQL, je ne peux trier que les données contenues dans la première colonne de données... c'est-à-dire les valeurs trouvées dans MyArray[i][0]. Les valeurs trouvées dans la même ligne (le même "i" dans ce cas) mais dans des colonnes différentes (la valeur dans la deuxième série de parenthèses) ne peuvent pas être utilisées pour le tri/classement.

Voici un exemple de tableau 2D :

3 5
1 9
7 6

Donc, Mon tableau[0][0] = 3, et Mon tableau[0][1] = 5, et Mon tableau[2][1] = 6, etc.

Je peux trier ce tableau :

ArraySort(MyArray,WHOLE_ARRAY,0,MODE_ASCEND) et le résultat sera le suivant :

1 9
3 5
7 6

La première colonne est triée, la deuxième colonne de données (c'est-à-dire toutes les données ayant le même index de première dimension) suit le tri/décalage effectué lors du classement de la première colonne.

Je ne peux pas trier/classer la deuxième colonne de données dans MQL... ce qui signifie que je ne peux pas obtenir ce qui suit (pas directement en tout cas) :

3 5
7 6
1 9

(notez que la deuxième colonne est maintenant triée du plus petit au plus grand)

Pour obtenir un tableau dont la deuxième colonne (ou toute autre colonne que la première) est triée, je dois échanger manuellement les données entre les colonnes (en gardant l'index de la première dimension identique mais en échangeant la valeur de l'index de la deuxième dimension), puis trier et échanger à nouveau les données.

MonNouveauTableau :
5 3
9 1
6 7

Maintenant, triez par la première colonne, ArraySort(MyNewArray,WHOLE_ARRAY,0,MODE_ASCEND) et le résultat sera le suivant :

5 3
6 7
9 1

Puis recopiez les valeurs dans mon tableau d'origine en transposant l'indice de la deuxième dimension tout en conservant la valeur de la première dimension :

3 5
7 6
1 9

J'ai maintenant mon tableau d'origine mais les données sont triées par la deuxième colonne.

 

Toute cette histoire s'est transformée en cauchemar, je ne me souviens même pas si j'ai essayé de la poursuivre. L'idée que j'avais était de prendre la liste des transactions ouvertes, de séparer les achats des ventes dans deux tableaux, chaque tableau contenant le numéro de ticket dans la première colonne, la seconde contenant la valeur du prix de la transaction. En général, l'idée était de faire correspondre toutes les valeurs d'achat à prix élevé avec toutes les valeurs de vente à prix élevé et si la valeur d'achat la plus élevée dépassait la valeur de vente la plus élevée, alors de fermer ces deux transactions et de répéter le processus.

Le dernier point qui m'a fait envisager d'abandonner cette idée est qu'après avoir suivi ce processus, je voulais laisser au moins une transaction d'achat positive et une transaction de vente positive sur la table pour maintenir un système de trading couvert. Il s'agit en fait d'un outil de gestion du drawdown pour une stratégie de couverture. Je veux donc maintenir la couverture, mais retirer les gains de la table. Il m'est apparu que l'utilisation d'un algorythme de tableaux pourrait constituer une solution à ce problème.

Je suis vraiment fatigué et épuisé d'essayer de pousser la sortie d'environ 5 stratégies, donc c'est devenu un peu un plaisir plutôt qu'une nécessité.

Je suis prêt à passer un accord avec toute personne qui peut écrire cette fonction pour moi. Je vous donnerai le produit de votre choix avec une licence d'un an, gratuitement pour m'avoir aidé sur ce point et, en plus, je vous donnerai une copie personnelle de cette stratégie de couverture pour une utilisation gratuite et illimitée à vie. Je suis tout simplement trop débordé pour tout faire et mon équipe de développement est lourdement chargée de publier ce qui est déjà sur nos plaques. Je pense que la durée moyenne de sommeil dans l'équipe est de 4 à 6 heures par jour.

Donc si vous êtes intéressé par un petit troc et un échange, c'est mon offre.

Objectif :
1. Séparer les achats des ventes.
2. trier chacun d'entre eux en fonction de la valeur du prix le plus élevé au plus bas
3. Si l'achat a des prix positifs les plus élevés et la vente a des prix positifs les plus bas, nous voulons clôturer la transaction de vente la plus basse avec la transaction d'achat la plus élevée, la transaction d'achat doit dépasser la dépense de la transaction de vente. Si la vente a des prix positifs plus élevés, nous inversons cette action pour clôturer le prix d'achat le plus bas avec le prix de vente le plus élevé. L'idée est que pour chaque perte, nous la fermons avec un gain à un prix plus élevé, de sorte que les gains dépassent les pertes avec un gain positif moyen.

exemple :
achat vente
$15 $- 12
$5 $ - 6
$ 1.5 $ -1
$ 1 $ - .5

Cela montre un nombre équilibré de transactions ouvertes des deux côtés. Remarquez l'achat de 15 $ et la vente de 12 $, qui peuvent être fermés car l'achat positif dépasse la vente négative. Nous pouvons également fermer les 5 et -6 car il y a suffisamment de gains provenant des deux premières fermetures pour que l'équilibre entre la fermeture des 4 d'entre elles soit positif. Nous pouvons faire de même pour le 1.5 et le -1, mais nous ne voudrions pas fermer le 1 et le -.5 car nous voulons maintenir la situation couverte.

La plupart du temps, les transactions ne seront pas équilibrées de manière égale des deux côtés. C'était la base de la conception pour compenser le côté le plus lourd avec une taille de lot plus élevée et des transactions supplémentaires en faveur du côté gagnant, il est donc possible que vous n'ayez qu'une seule vente, auquel cas, vous ne feriez rien. Si les positions ne sont pas équilibrées mais qu'il y a au moins deux transactions de chaque côté, vous devez vous assurer de laisser une transaction ouverte de chaque côté. Dans le cas où une transaction positive l'emporte sur plus d'une transaction négative, vous pouvez toutes les fermer, à l'exception de la transaction de chaque côté qui est la plus petite.

Il devrait être conçu pour appeler une fonction de fermeture qui fermera un ticketid spécifique, de sorte que vous n'ayez pas à vous soucier de la fermeture, il suffit de passer l'appel pour que les transactions soient fermées en passant le ticketid. Il se peut que vous deviez reconstruire votre liste afin qu'elle ne compare pas les transactions fermées mais les nouvelles transactions qui ont pu se produire pendant le traitement.

Ah oui, encore une chose...
Il ne devrait pas être trop gourmand, vous devriez fournir un utilisateur externe qui dicte la fréquence à laquelle cette fonction doit être déclenchée, il peut être basé sur un compte de bougie ou une heure ou une minute, mais ne devrait pas déclencher chaque tick ou même chaque nouvelle bougie. En l'état actuel des choses, il y a un outil supplémentaire dans lequel il sera intégré et qui nécessitera d'abord que l'autre outil se déclenche afin d'invoquer celui-ci. Ainsi, l'autre outil se déclenchera, et le compte à rebours commencera pour que votre outil se déclenche.

 
Larry, je suis presque sûr que le code pour CloseBy() ici -> https://book.mql4.com/trading/orderclose (c'est environ 2/3 de la page...) peut être étendu pour faire ce que vous voulez (sans utiliser de tableaux)... Juste une pensée pour ton esprit.
Raison: