COMMANDE_POSITION_ID - page 21

 
Mikalas:

...

Mais je voulais l'implémenter par le biais d'ordres (il arrive qu'un ordre partiellement exécuté "reste" pendant deux ou trois jours),

...

Michael, tu avais raison ! Pourquoi ne l'avez-vous pas fait ? Vous devez comprendre que lorsque vous traitez des positions nettes, vous serez tôt ou tard confronté au fait que vous ne pouvez pas vous passer de l'analyse des ordres qui y sont inclus. C'est ce que je vous dis en tant que personne qui a passé des mois à étudier cette question, et qui a fait cette erreur de nombreuses fois :) De plus, si vous avez plus d'un robot de trading, vous devez prendre en compte la contribution de chaque robot dans la position commune, et vous ne pouvez pas vous passer des ordres ici aussi. Toutes les informations nécessaires sont contenues dans les ordres et dans les transactions qui en découlent. En transformant les transactions en une position nette unique, ces informations sont irréversiblement supprimées.

Mais si vous basez votre système sur l'analyse des ordres et des transactions, vous devez envisager l'exécution partielle des ordres. Pour ce faire, vous devez créer une version virtuelle de l'ordre et contrôler l'arrivée de nouvelles transactions. Mon algorithme est le suivant :

1. Une nouvelle transaction a été reçue (le compteur HistoryDealsTotal() a changé).

2. Si cette transaction est initiée par un ordre, nous créons un nouvel ordre incluant une seule transaction (COrder* order = new Order(deal)).

3. Ensuite, nous recherchons dans notre liste de commandes virtuelles déjà existantes, une commande avec le même identifiant. Si un tel ordre est trouvé, alors nous fusionnons les transactions de l'ordre créé avec celles de l'ordre trouvé et mettons à jour ses propriétés, et supprimons l'ordre créé. Si le même ordre n'est pas encore dans la liste, nous l'ajoutons simplement à la liste.

De cette façon, le système devient entièrement déterministe. Avec chaque nouvelle transaction, notre ordre virtuel changera d'état, et peu importe que l'ordre réel soit en attente d'exécution ou qu'il ait déjà été déplacé dans l'historique, nous le verrons toujours dans notre système dans le volume réellement exécuté.

 
Contender:
Et si nous fermons la position, et que la partie non exécutée de l'ordre n'est pas supprimée, cela ouvrira (ou changera) une autre position ?

Bonne question !

Si la commande est active, elle n'apparaît pas dans l'historique (cela a été vérifié avec certitude),

Et bien sûr, un ordre actif peut ouvrir une autre position, mais si

il sera à nouveau partiellement exécuté, nous ne lui attribuerons pas ORDER_POSITION_ID.

En d'autrestermes,ORDER_POSITION_ID ne peut être vu que dans l'historique.

 
C-4:

Oui, cela arrive sur le marché boursier et ces situations doivent être prises en compte. C'est l'un des inconvénients fondamentaux des ordres à cours limité.

Dans votre exemple, je pense que nous pouvons le remplacer :

A :

Comme toutes les transactions de type achat et vente sont initiées par une sorte d'ordre.

Non, vous ne pouvez pas, car les transactions ont lieu dans la compensation, mais elles n'ont pas de ticket (ou plutôt ticket = 0),

mais elles ont un prix et un type (BUY et SELL) et bien sûr IN et OUT :(

 
C-4:

Mikhail, et à juste titre ! Pourquoi ne l'avez-vous pas mis en œuvre ? Vous devez comprendre que lorsque vous traitez des positions nettes, vous serez tôt ou tard confronté au fait que vous ne pouvez pas vous passer de l'analyse des ordres qui y sont inclus. C'est ce que je vous dis en tant que personne qui a passé des mois à étudier cette question, et qui a fait cette erreur plusieurs fois :) De plus, si vous avez plus d'un robot de trading, vous devez prendre en compte la contribution de chaque robot dans la position commune, et vous ne pouvez pas vous passer des ordres ici aussi. Toutes les informations nécessaires sont présentes dans les ordres et dans les transactions basées sur ceux-ci, et le fait de regrouper les transactions en une seule position nette supprime au contraire ces informations de manière irréversible.

Mais si vous basez votre système sur l'analyse des ordres et des transactions, vous devez envisager l'exécution partielle des ordres. Pour ce faire, vous devez créer une version virtuelle de l'ordre et contrôler l'arrivée de nouvelles transactions. Mon algorithme est le suivant :

1. Une nouvelle transaction a été reçue (le compteur HistoryDealsTotal() a changé).

2. Si cette transaction est initiée par un ordre, nous créons un nouvel ordre incluant une seule transaction (COrder* order = new Order(deal)).

3. Ensuite, nous recherchons dans notre liste de commandes virtuelles déjà existantes, une commande avec le même identifiant. Si un tel ordre est trouvé, alors nous fusionnons les transactions de l'ordre créé avec celles de l'ordre trouvé et mettons à jour ses propriétés, et supprimons l'ordre créé. Si le même ordre n'est pas encore dans la liste, nous l'ajoutons simplement à la liste.

De cette façon, le système devient entièrement déterministe. L'état de notre ordre virtuel changera à chaque nouvelle transaction et peu importe que l'ordre réel soit en attente d'exécution ou qu'il ait déjà été déplacé dans l'historique, nous le verrons toujours dans notre système dans le volume réellement exécuté.

Vasiliy, j'ai tout implémenté ( pas comme tu l'as fait, mais pas mal non plus ), je voulais juste réduire le temps de recherche...
 
Serj_Che:

Problème résolu, relations réglées :)

J'ai une question connexe :

Il est très peu pratique de sélectionner un ordre par ticket pour voir ses propriétés, car peu importe où se trouve l'ordre dans l'historique ou sur le marché, et le ticket ne change pas.

Nous devons donc chercher l'ordre à la fois ici et là-bas.

Ne serait-il pas plus simple de faire comme dans MT4 : si on sélectionne un ordre, l'endroit où il se trouve n'a pas d'importance.

Je l'ai lu dans l'aide MT4 :

Qu'en pensez-vous ?

P.S. J'espère que Mihail ne voit pas d'inconvénient à ce que nous poursuivions ce fil, afin de ne pas en créer d'autres ?


Mikalas:

C-4, c'est très bien que la discussion soit constructive !

J'ai donc besoin du prix "net" de la position pour savoir (dans un mois, par exemple) quel est mon bénéfice.

...

Dans la fonction (je l'utilise maintenant) :

...

Question pertinente, en général l'API de MetaTrader5 est vraiment très bas niveau. Mais... La négociation en bourse comporte de nombreuses nuances : exécution d'un ordre par des transactions multiples, transactions appariées en une position nette et transfert de celle-ci par compensation, abondance de transactions de courtage et ainsi de suite. L'API de MetaTrader5 (et MT5 lui-même) est donc telle, comme tout terminal d'échange devrait l'être.

De plus, son API peut être enveloppée dans une enveloppe de haut niveau écrite en MQL5 et utiliser à travers elle les fonctions de plus bas niveau de MT5. Si je disposais de l'enveloppe, la tâche de calcul des bénéfices de Mihail ressemblerait à ceci

for(int i = 0; i < TransactionsTotal(); i++)
{
    if(TransactionSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
         ENUM_TRANS_TYPE trans_type = TransactionType();
         if(trans_type == TRANS_HEDGE_POSITION)
         {
              if(HedgePositionGetInteger(HEDGE_POSITION_MAGIC) != myMagic)continue;  // Работаем только со своими позициями.
              if(HedgePositionGetString(HEDGE_POSITION_SYMBOL) != Symbol())continue; // Работаем только с позициями на своем инструменте.
              double profit = HedgePositionGetDouble(HEDGE_POSITION_PROFIT_POINTS); //Профит в пунктах
              double currency = HedgePositionGetDouble(HEDGE_POSITION_PROFIT_CURRENCY); //Профит в валюте депозита.
              double price_open = HedgePositionGetDouble(HEDGE_POSITION_PRICE_OPEN); //Фактическая цена открытия позиции без клирингов и пр. изменений.
              double sl = HedgePositionGetDouble(HEDGE_POSITION_SL); //Узнаем уровень стоп-лосса позиции, если он есть, если нет - вернет нормализованный 0.0.
              if(HedgeOrderSelect(ORDER_SELECTED_INIT)) //Выбираем ордер, открывающий текущую позицию.
              {
                 int deals = HedgeOrderGetInteger(HEDGE_ORDER_DEALS_TOTAL); //Получаем количество сделок, открывающего ордера.
              }
              // Ну и так далее...
         }   
    }
}
 
Mikalas:

Non, vous ne pouvez pas, car les transactions sont compensées, mais elles n'ont pas de ticket (ou plutôt ticket = 0),

mais avoir un prix et un type (BUY et SELL) et bien sûr IN et OUT :(

Merde, c'est vrai :

Alors la tristesse pour vous.

 
Mikalas:
Vasiliy, j'ai tout implémenté ( pas comme tu l'as fait, mais pas mal non plus ), je voulais juste réduire le temps de recherche...
Au fait, comment gérez-vous les entrées multidirectionnelles de vos robots ? Après tout, l'entrée sur le marché d'un conseiller expert peut être la sortie d'un autre robot.
 
Mikalas:

Bonne question !

Si la commande est active, elle n'apparaît pas dans l'historique (cela a été vérifié avec certitude),

Et bien sûr, un ordre actif peut ouvrir une autre position, mais si

il sera à nouveau partiellement exécuté, nous ne lui attribuerons pas ORDER_POSITION_ID.

En d'autrestermes,ORDER_POSITION_ID ne peut être vu que dans l'historique.

Il y a un autre piège ici. Une partie des transactions exécutées par cet ordre appartiendra à une position, et l'autre partie appartiendra déjà à l'autre, nouvelle position. La question est alors de savoir quel identifiant de position lui sera attribué, lorsqu'il arrivera finalement dans l'histoire.
 
C-4:
Au fait, comment gérez-vous les entrées multidirectionnelles de vos robots de trading ? Après tout, l'entrée d'un conseiller expert sur le marché peut correspondre à la sortie de la position d'un autre robot.
Je n'ai pas de chevauchements.
 
C-4:
Le problème est différent ici. Une partie des transactions exécutées de cet ordre appartiendra à une position, et l'autre partie appartiendra déjà à une autre, nouvelle position. La question est alors de savoir quel identifiant de position lui sera attribué lorsqu'il arrivera tôt ou tard dans l'histoire.

Un ordre entièrement exécuté recevra l'ID de la position qu'il a ouverte ou modifiée.

Mais cela ne sera disponible ( ID ) que dans l'historique.