Rejoindre la communauté
banner_forum
Devenez membre de la plus grande
communauté francophone sur le Forex
Partagez, échangez et apprenez en gagnant des crédits sur votre compte de trading

Créer un TS caché ?

  • Nicolab

    Bonjour,

    je cherche à créer un trailing stop qui est connu que dans l'EA (donc pas envoyé au broker).
    Cela évite les erreurs 130 et permet d'être entièrement libre au niveau du TS :)

    Je pense que pour réaliser ça il faut stocker tous les trades dans un tableau (indexé par le numéro de ticket) pour y placer le TS et pourquoi pas d'autres infos. Le problème c'est que j'ai du mal avec les tableaux MQL. Peut être qu'il y a une autre façon de faire, je ne sais pas je débute en MQL.

    Peut être qu'un pro pourra m'aider, mon code est faux mais c'est pour montrer la logique :
    Code
    // Le stop loss initial sl = 40; // La limite de pip à laquelle on envoi le stop loss au broker (par prudence au cas où la connexion entre l'EA et le broker plante, on sécurise de temps en temps) ts_hidden_limit_pip = 40; // Le TS ts = 20; // Ouverture de l'ordre ticket = OrderSend(Symbol(),OP_BUY,lotSize,Ask,slippage,0,0,tradeComment,MagicNumber,Orange); Sleep(400); // Je lui laisse le temps d'être traité par le broker // Place TS et TP OrderModify(ticket, 0, Bid - (sl * Point), OrderOpenPrice() + (tp * Point), 0, Orange); // Ajoute le trade à notre tableau // Je ne connais pas la syntaxe mais la logique est là trades[ticket] = array('ts_hidden_value' => '', // la valeur du TS caché // ... puis d'autres valeurs, pourquoi pas un TP caché, etc ); // Liste les positions ouvertes for (int i = 0; i < OrdersTotal(); i++) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (MagicNumber == OrderMagicNumber()) { RefreshRates(); if (OrderType() == OP_BUY) { ts_tmp = Bid-(Point*ts); // calcul trailing stop (achat) // Si le cours est égal ou supérieur à notre TS caché if(Bid >= trades[OrderTicket()]["ts_hidden_value"]) { trades[OrderTicket()]["ts_hidden_value"] = ts_tmp; // On fait suivre le TS // Si il est temps d'envoyer notre nouveau stop loss au broker if(OrderStopLoss()+ts_hidden_limit_pip < trades[OrderTicket()]["ts_hidden_value"] ) OrderModify(OrderTicket(), 0, trades[OrderTicket()]["ts_hidden_value"] , OrderTakeProfit(), 0, White); }else{ OrderClose( OrderTicket()); // Si le TS caché est touché on ferme la position unset(trades[OrderTicket()]); // On retire le trade du tableau (connait pas la façon de faire) } } // Si le cours est inférieur au prix d'aquisition, bingo on passe à la phase suivante if (OrderType() == OP_SELL) { // ... idem pour les OP_SELL } } } }
  • furynick

    Mes tableaux en MQL sont un vrai problème car ils sont statico-dynamiques (j'ai pas trouvé mieux pour les qualifier).

    Ils sont statiques dans la mesure où tu ne peux pas utiliser un index en dehors de la taille du tableau
    Ils sont dynamiques dans la mesure où tu peux les redimensionner

    Par ex.
    Code
    double tstops[]; tstops[OrderTicket()]=Ask - TSpoints;

    ne fonctionnera pas car le tableau n'a pas la taille OrderTicket()+1

    Pour stocker ton TS tu as deux possibilités :
    - soit tu retailles ton tableau en fonction du ticket id ce qui est ultra simple mais extrêmement gourmand en mémoire car tu consommes (OrderTicket()+1) * sizeof(double) octets en mémoire. Par ex. sur Alpari le ticket id en démo est 257421630, un double faisant une taille de 8 octets tu vas consommer près de 2Go de RAM, ton PC ou ton VPS qui vont très vite crier famine.
    - soit tu construis deux tableaux, l'un contenant les n° de tickets, l'autre les TS associés et tu fais la liaison avec le n° d'id de chacun des tableaux.

    Bon courage ;)
  • jal_fr

    Salut nico, attention aux SL caches, car tu ne seras pas protéger en cas de coupure. Cela peut être catastrophique ! Cependant la bonne façon pour moi est quand même d'initialiser un SL a deux fois ton vrai SL par sécurité.
    Contact moi si tu veux un coup de mains ;)
  • Nicolab

    Merci pour votre aide :)

    @furynick : j'ai peut être mal compris mais pour arriver à 2 Go il faut des milliers de positions ouvertes non ?
    En faisant 2 tableaux, c'est pareil j'aurais le même nombre de données sauf que divisé dans 2 tableaux ? Il y a une subtilité avec les tableaux MQL que je n'ai pas saisi, peut être le * sizeof(double) que je sous-estime.

    @Jal_fr : effectivement, dans l'EA je place un SL puis quand le 1er TS est atteins c'est le TS caché qui prend le relais. Tous les x pips le TS caché est placé en SL. Les x pips sont défini dans ts_hidden_limit_pip.

    Code
    // Si il est temps d'envoyer notre nouveau stop loss au broker if(OrderStopLoss()+ts_hidden_limit_pip < trades[OrderTicket()]["ts_hidden_value"] )

    Citation :
    Contact moi si tu veux un coup de mains ;)

    Avec plaisir ! :) Par contre je ne crois pas avoir ton email, voici le miens diegy laposte.net


  • furynick

    Et non Nico, c'est bien là le problème, il suffit d'une seule position pour consommer les 2Go de RAM. C'est pourquoi je les qualifie de statico-dynamiques, ont peut changer leur taille mais ils sont créés statiquement.

    Par exemple, si j'ouvre un seul et unique ordre dont le ticket est 262143, pour pouvoir utiliser un tableau avec cet index je dois créer un tableau de 262144 éléments (1er élément = index 0) comme ceci :
    Code
    double stops[]; int ticket = OrderSend(x, y, z ...); ArrayResize(stops, ticket + 1); stops[ticket] = Ask - TSpoints;

    La commande ArrayResize va créer 262144 éléments de type double en mémoire soit une consommation de 2Mo
    Si le ticket obtenu avait été 268435455 j'aurais créé un tableau occupant 2Go en mémoire pour stocker une seule et unique valeur.

    En utilisant deux tableaux tu ne consommes que ce dont tu as besoin, dans le 1er tableau tu stockes un seul élément contenant le n° de ticket (4 octets) et dans l'autre tu stockes le stop (8 octets) soit un total de 12 octets.
    Code
    // variables gloables int count = 0; double stops[]; int tickets[]; // code ArrayResize(stops, count + 1); ArrayResize(stops, count + 1); tickets[count] = OrderSend(x, y, z ...); stops[count] = Ask - TSpoints; count++;

    Ceci étant dit, il est fort possible que le stockage de tels tableaux soit optimisé par MT4 et ne consomme pas réellement les 2 Go, ce serait un point à vérifier.
  • Nicolab

    Ah d'accord je comprends ! Je n'avais pas saisi que ça créait autant d'index que nécessaire pour arriver à une somme, je voyais un peu ça comme un index associatif.
    Qu'on est bien dans les langages de haut niveau, ou tout est dynamique, même le typage ^^
    Merci pour cette explication, il faudra que je vérifie si le MQL4 est potentiellement optimisé au niveau de ce type de stockage comme tu le suggères.
  • Nicolab

    Je n'ai rien trouvé du genre unset(tickets[count]);
    Pour l'instant je mets tickets[count] = null; mais ça va fausser le ArraySize()

    Comment on fait pour supprimer une valeur d'un tableau ?
  • furynick

    Tu ne peux supprimer que le dernier élément avec un ArrayResize(tableau, ArraySize(tableau) - 1);
  • Nicolab

    Ok merci.