Vous manquez des opportunités de trading :
- Applications de trading gratuites
- Plus de 8 000 signaux à copier
- Actualités économiques pour explorer les marchés financiers
Inscription
Se connecter
Vous acceptez la politique du site Web et les conditions d'utilisation
Si vous n'avez pas de compte, veuillez vous inscrire
C'est déjà dans l'exemple.
Lorsque vous fermez l'ordre, vous utilisez la valeur de retour booléenne de la fonction OrderClose(), et si la fonction a réussi, vous pouvez supprimer les objets liés à l'ordre.
{
if(close==0)
{
Alert(" Order Close Error! # "+IntegerToString(OrderTicket()));
}
if(close==1)
{
Alert(" Order: "+IntegerToString(OrderTicket())+" Closed due to TP Profit = "+DoubleToString(OrderProfit(),2));
ObjectDelete(0,"#"+IntegerToString(OrderTicket())+"-TP");
ObjectDelete(0,"#"+IntegerToString(OrderTicket())+"-SL");
}
}
C'est déjà dans l'exemple.
Lorsque vous fermez l'ordre, vous utilisez la valeur de retour booléenne de la fonction OrderClose(), et si la fonction a réussi, vous pouvez supprimer les objets liés à l'ordre.
Je le sais déjà, je l'ai déjà essayé. Peut-être ai-je fait quelque chose de mal. Je vais essayer encore une fois, mais avant de demander, je ne voudrais pas utiliser OrderClose(). ( parfois je ferme les ordres manuellement )
Q : Donc, puis-je supprimer les objets d'ordre après la fermeture de l'ordre sans OrderClose() ?
Merci d'avance.
C'est la valeur de retour de la fonction Order Close() qui détermine si l'action a réussi ou non. Si vous fermez l'ordre manuellement, vous devrez concevoir et utiliser un mécanisme légèrement différent.
Vous pouvez faire une copie cachée de la liste des ordres et la comparer à la liste actuelle, et chaque fois que quelque chose change parce que vous avez fermé un ordre manuellement, recherchez ce qui a changé et supprimez ces objets.
Mais un moyen plus simple pourrait être de vérifier si l'OrderTicket() existe toujours dans le pool d'ordres actifs, de sorte que lorsqu'il disparaît parce que vous avez fermé l'ordre manuellement, les objets seront automatiquement supprimés.
Tout dépend donc de la façon dont vous voulez le mettre en place.
À ce stade, je dirais que vous devez essayer de voir au-delà de ce que vous voulez faire avec ce système, car la direction que vous prenez est quelque peu liée à des tâches supplémentaires que vous pourriez vouloir ajouter plus tard.
Puisque la création des objets est déjà entièrement automatisée, je vous suggère de faire de même pour la suppression des objets afin de ne pas avoir à vous en soucier à l'avenir.
Pour cela, vous pouvez simplement utiliser
Et le pool d'historique
C'est simple, le pool d'historique de commande est scanné, et à chaque cycle le code va regarder si des objets liés au numéro OrderTicket() existent, et s'il y a une correspondance, les objets sont automatiquement supprimés.
Pour ce faire, il suffit d'ajouter une autre boucle, mais cette fois sur le pool d'historique.
Voir l'exemple.
//| ObjectsRemove.mq4 |
//| Copyright 2017, Marco vd Heijden, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, Marco vd Heijden, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
static input int takeprofit=500;// Take Profit
static input int stoploss=500; // Stop Loss
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- create timer
EventSetTimer(1);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- destroy timer
EventKillTimer();
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
}
//+------------------------------------------------------------------+
//| Timer function |
//+------------------------------------------------------------------+
void OnTimer()
{
for(int order=OrdersTotal(); order>=0; order--)
{
bool selected=OrderSelect(order,SELECT_BY_POS);
{
if(selected==1)
{
if(Symbol()==OrderSymbol()) // only for current chart symbol
{
switch(OrderType())
{
case OP_BUY: // for buy order
{
// if objects not found - create them
if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")<0)
{
ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJ_HLINE,0,0,OrderOpenPrice()+takeprofit*Point());
ObjectSet("#"+IntegerToString(OrderTicket())+"-TP",7,3);
}
if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-SL")<0)
{
ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-SL",OBJ_HLINE,0,0,OrderOpenPrice()-stoploss*Point());
ObjectSet("#"+IntegerToString(OrderTicket())+"-SL",7,3);
}
// if objects exist
if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")>=0)
{
if(Bid>ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJPROP_PRICE,0))
{
PlaySound("alert2.wav"); // OrderClose now removed...
}
}
if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-SL")>=0)
{
if(Ask<ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-SL",OBJPROP_PRICE,0))
{
PlaySound("alert2.wav"); // OrderClose now removed...
}
}
}
break;
case OP_SELL: // for sell order
{
// if objects not found - create them
if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")<0)
{
ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJ_HLINE,0,0,OrderOpenPrice()-takeprofit*Point());
ObjectSet("#"+IntegerToString(OrderTicket())+"-TP",7,3);
}
if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-SL")<0)
{
ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-SL",OBJ_HLINE,0,0,OrderOpenPrice()+stoploss*Point());
ObjectSet("#"+IntegerToString(OrderTicket())+"-SL",7,3);
}
// if objects exist
if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")>=0)
{
if(Ask<ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJPROP_PRICE,0))
{
PlaySound("alert2.wav"); // OrderClose now removed...
}
}
if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-SL")>=0)
{
if(Bid>ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-SL",OBJPROP_PRICE,0))
{
PlaySound("alert2.wav"); // OrderClose now removed...
}
}
}
break;
}
}
}
}
}
//+------------------------------------------------------------------+
//--- delete objects when order is closed
for(int order=OrdersHistoryTotal()-1; order>=0; order--)
{
bool selected=OrderSelect(order,SELECT_BY_POS,MODE_HISTORY);
{
if(selected==1)
{
// if objects are still found - Delete them
if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")>=0)
{
ObjectDelete(0,"#"+IntegerToString(OrderTicket())+"-TP");
}
if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-SL")>=0)
{
ObjectDelete(0,"#"+IntegerToString(OrderTicket())+"-SL");
}
}
}
}
//+------------------------------------------------------------------+
} // end OnTimer() function
//+------------------------------------------------------------------+
Vous avez donc maintenant l'ajout entièrement automatisé de lignes virtuelles de prise de profit et de perte, ainsi que la suppression entièrement automatisée de ces lignes.
Bien sûr, cet exemple scanne continuellement le pool d'historique...
En outre, vous pourriez ajouter un nombre entier qui contient le nombre d'ordres, qui est ensuite comparé à OrdersTotal(), et chaque fois que quelque chose change, vous exécutez le code de suppression d'objet.
Ou bien, vous pourriez ajouter un simple compteur (60), puis le morceau de code ne vérifiera qu'une fois par minute, si quelque chose doit être retiré.
Hé mec ! Cela fonctionne parfaitement ! Merci beaucoup !
J'ai juste un peu changé. Jusqu'à présent, il fonctionne sans problème.
for(int order=OrdersHistoryTotal()-1; order>=0; order--)
{
bool selected=OrderSelect(order,SELECT_BY_POS,MODE_HISTORY);
{
if(selected==1)
{
// if objects are still found - Delete them
ObjectsDeleteAll( 0, "#" + IntegerToString( OrderTicket() ) ); // for arrows
ObjectsDeleteAll( 0, _prefix + " #" + IntegerToString( OrderTicket() ) ); // order, sl, tp, price objects
}
}
}
Si quelque chose de mal s'il vous plaît laissez-moi savoir à ce sujet.
Encore une fois, merci beaucoup !
Peut-être que personne ne comprend ma question. Mais j'ai toujours besoin d'un bon commentaire à ce sujet. J'essaie donc maintenant de clarifier ma question à l'aide d'une image.
Question : Les lignes Stop Loss et Take Profit sont également situées devant les objets du Trade Panel. Je sais que cela a été causé par la dernière fois que l'objet a été créé. Mais si vous me comprenez, dites-moi comment faire pour que l'objet Trade Panel soit devant tous les autres objets sans les lignes " Stop Loss and Take Profit ".
Je sais que je peux utiliser OBJPROP_BACK, mais je ne veux pas l'utiliser. J'ai juste besoin de voir la ligne et le prix comme les deux. J'espère que j'obtiendrai de bons commentaires à ce sujet.
Ouvrir, Stop Loss, Take Profit, lignes de prix " Create and Delete " que tous dans une fonction. C'est pourquoi j'essaie maintenant de la diviser, car je dois mettre cette fonction dans OnChartEvent(). Mais avant, je dois demander.
Q : Si je mets cette fonction dans OnChartEvent() - alors cette fonction ne pourrait pas avoir d'effets sur mes ordres manuels ?
Je suis en train de travailler dessus.
S'il vous plaît, aidez-moi, merci d'avance.
Non, Onchartevent() n'exécute le code que lorsqu'il y a un événement graphique, ce n'est pas comme la fonction OnTImer().
Vous devez donc savoir exactement ce que vous faites.
Par exemple, si vous utilisez le code de balayage :
Pour vérifier si le prix a franchi votre ligne, cela ne fonctionnera pas dans OnChartEvent().
Aussi, si vous voulez utiliser l'exemple automatisé
{
ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJ_HLINE,0,0,OrderOpenPrice()-takeprofit*Point());
ObjectSet("#"+IntegerToString(OrderTicket())+"-TP",7,3);
}
Cela ne fonctionnera pas ou ne créera pas les objets.
Vous devrez réécrire le code.
Aussi, vous pouvez définir les objets H_LINE à OBJPROP_BACK, ce n'est pas un problème, vous les verrez toujours et ils seront sous votre panneau.
Je sais maintenant que je devrais essayer au moins une fois pour savoir ce que je pourrais faire de plus.
Merci pour votre réponse rapide et votre commentaire utile.
Vous devrez réécrire le code.
( J'ai déjà lu attentivement votre commentaire mais je voulais juste essayer une fois - finalement comme vous l'avez dit cela ne fonctionne pas comme le OnTimer(). )
Omg ! Je dois tout changer dans ce code de bloc ?
Maintenant, j'ai quatre fonctions. J'essaie juste de les mettre dans OnChartEvent(). J'ai déjà essayé, je vois juste une mise à jour des choses, c'est juste Print() pour les prix de stop loss, take profit.
OrderModify() ne fonctionne pas là-dedans.
Je vais commencer à essayer de nouveau quelque chose pour ce problème dans 8 - 10 heures.
J'ai juste vraiment besoin de bons commentaires, j'espère que je vais l'obtenir.
Merci beaucoup par avance.
{
if(id==CHARTEVENT_OBJECT_DRAG) // I already tried with take profit object - there was not any effects
{
SL_TPcreateobjects();
SL_TPdrags();
SL_TPmodify();
deleteobjs();
}
}
// if objects not found - create them
SL_TPcreateobjects()
{
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
if(Symbol()!=OrderSymbol()) continue;
if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")<0)
{
ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJ_HLINE,0,0,takeprofit);
}
}
}
// if objects exist
SL_TPdrags()
{
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
if(Symbol()!=OrderSymbol()) continue;
if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")>=0)
{
if(TP_Price!=ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJPROP_PRICE,0))
{
TP_drag=1;
TP_Price=ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJPROP_PRICE,0);
}
if(TP_drag==1)
{
if(TP_Price==ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJPROP_PRICE,0))
{
Print("Take Profit Price:",DoubleToString(TP_Price,Digits));
TP_drag=0;
}
}
}
}
}
// order closed - delete junks
deleteobjs()
{
for(int i=OrdersHistoryTotal()-1; i>=0; i--)
{
bool Selected=OrderSelect(i,SELECT_BY_POS,MODE_HISTORY);
if(Selected==1)
{
ObjectsDeleteAll(0,"#"+IntegerToString(OrderTicket())+"-TP");
}
}
}
// ordermodify()
SL_TPmodify()
{
Order_Modify=OrderModify(OrderTicket(),OrderOpenPrice(),SL_Price,TP_Price,0,CLR_NONE);
}
//+------------------------------------------------------------------+
Ces fonctions ne seront exécutées que lorsqu'un événement de charte se produit.
C'est du moins ce que vous montrez ici.
Le chartevent est juste un déclencheur d'une routine d'interruption lorsque quelqu'un appuie sur un bouton ou quelque chose d'autre sur le graphique.
Vous avez pris l'exemple entièrement automatisé et l'avez placé sous un bouton, rien ne se produira si personne n'appuie dessus.
Ces fonctions ne sont exécutées que lorsqu'un événement de charte se produit.
Du moins, c'est ce que vous montrez ici.
Un chartevent est juste un déclencheur d'une routine d'interruption lorsque quelqu'un appuie sur un bouton ou autre chose sur le graphique.
Maintenant que vous avez pris l'exemple entièrement automatisé et que vous l'avez placé sous un bouton, rien ne se passera si personne n'appuie dessus.
Il est possible que votre dernier commentaire semble si simple, mais en fait ce commentaire m'a montré la bonne voie.
Donc maintenant, je résous mon problème qui j'essaie d'utiliser drag.
Et maintenant je commence à faire des recherches sur d'autres objets graphiques qui se déplacent avec cet objet HLine.
Merci beaucoup plus homme !
Tous les meilleurs à vous !
Pensez également à la fréquence à laquelle vous déplacez la ligne. Est-ce une fois par seconde ? Probablement pas.
Placez votre code dans OnChartEvent() :
{
if(id==CHARTEVENT_OBJECT_DRAG && sparam=="line") // the chart event of dragging the line