Sie verpassen Handelsmöglichkeiten:
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Registrierung
Einloggen
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
Wenn Sie kein Benutzerkonto haben, registrieren Sie sich
Das ist bereits im Beispiel enthalten.
Wenn Sie den Auftrag schließen, verwenden Sie den booleschen Rückgabewert der Funktion OrderClose(), und wenn die Funktion erfolgreich war, können Sie die mit dem Auftrag verbundenen Objekte entfernen.
{
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");
}
}
Das ist bereits im Beispiel enthalten.
Wenn Sie den Auftrag schließen, verwenden Sie den booleschen Rückgabewert der Funktion OrderClose(), und wenn die Funktion erfolgreich war, können Sie die mit dem Auftrag verbundenen Objekte entfernen.
Ich weiß es schon, ich habe es schon versucht. Vielleicht habe ich etwas falsch gemacht. Ich werde es noch einmal versuchen, aber vorher möchte ich fragen, ob ich OrderClose() verwenden möchte. (manchmal schließe ich Aufträge manuell)
F: Also, kann ich Order-Objekte löschen, nachdem die Order ohne OrderClose() geschlossen wurde?
Vielen Dank im Voraus.
Nun, der Rückgabewert der Funktion Order Close() entscheidet, ob die Aktion erfolgreich war oder nicht. Wenn Sie also die Bestellung manuell schließen, müssen Sie einen etwas anderen Mechanismus entwickeln und verwenden.
Sie können eine Schattenkopie der Auftragsliste erstellen und diese mit der aktuellen Liste vergleichen. Wenn sich etwas ändert, weil Sie einen Auftrag manuell geschlossen haben, suchen Sie nach den Änderungen und entfernen Sie diese Objekte.
Einfacher ist es jedoch, zu prüfen, ob das OrderTicket() noch im aktiven Auftragspool vorhanden ist, so dass die Objekte automatisch entfernt werden, wenn es verschwindet, weil Sie den Auftrag manuell geschlossen haben.
Es hängt also davon ab, wie Sie es einrichten wollen.
An diesem Punkt würde ich sagen, dass Sie versuchen sollten, darüber hinaus zu schauen, was Sie letztendlich damit machen wollen, weil die Richtung, die Sie einschlagen, etwas mit zusätzlichen Aufgaben zu tun hat, die Sie vielleicht später hinzufügen wollen.
Da die Erstellung von Objekten bereits vollständig automatisiert ist, schlage ich vor, dass Sie das Gleiche für das Entfernen von Objekten tun, damit Sie sich in Zukunft nicht mehr darum kümmern müssen.
Hierfür können Sie einfach die Funktion
Und der Historienpool
Es ist ganz einfach, der Auftragshistorien-Pool wird gescannt, und bei jedem Zyklus wird der Code nachsehen, ob irgendwelche Objekte mit Bezug zur OrderTicket()-Nummer existieren, und wenn es eine Übereinstimmung gibt, werden die Objekte automatisch gelöscht.
Dazu müssen Sie nur eine weitere Schleife hinzufügen, diesmal aber über den History-Pool.
Siehe Beispiel.
//| 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
//+------------------------------------------------------------------+
So haben Sie nun das vollautomatische Hinzufügen von virtuellen Take-Profit- und Stop-Loss-Linien und auch das vollautomatische Entfernen dieser Linien.
Natürlich wird in diesem Beispiel der History-Pool kontinuierlich durchsucht...
Zusätzlich könnten Sie einen Integer hinzufügen, der die Anzahl der Orders enthält, die dann mit OrdersTotal() verglichen wird, und wann immer sich etwas ändert, führen Sie den Code zum Entfernen der Objekte aus.
Oder Sie könnten einen einfachen Zähler (60) hinzufügen, dann wird das Codestück nur einmal pro Minute prüfen, ob etwas entfernt werden muss.
Hey Mann! Das funktioniert perfekt! Vielen Dank an dieser Stelle!
Ich habe nur wenig geändert. Bis jetzt funktioniert es ohne Probleme.
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
}
}
}
Sollte etwas nicht stimmen, bitte ich um Rückmeldung.
Nochmals vielen Dank Mann!
Vielleicht versteht niemand meine Frage. Aber ich brauche trotzdem einen guten Kommentar dafür. Deshalb versuche ich jetzt, meine Frage mit einem Bild zu verdeutlichen.
Frage: Auch Stop Loss, Take Profit Linien vor den Trade Panel Objekten. Ich weiß, dass dies durch das letzte Mal erstellte Objekt verursacht wurde. Aber wenn Sie mich verstehen, lassen Sie mich bitte wissen, wie ich Trade Panel Objekt sollte vor allen anderen Objekten ohne "Stop Loss und Take Profit" Linien sein.
Ich weiß, dass ich OBJPROP_BACK verwenden kann, aber ich möchte es nicht verwenden. Ich muss nur Zeile und Preis wie beide sehen. Ich hoffe, dass ich dafür gute Kommentare bekomme.
Öffnen, Stop Loss, Take Profit, Preislinien "Erstellen und Löschen", dass alle von ihnen in einer Funktion. So gerade jetzt versuche ich, es zu teilen, weil ich diese Funktion in OnChartEvent() setzen müssen. Aber bevor ich fragen muss.
F: Wenn ich diese Funktion in OnChartEvent() - so dass die Funktion konnte nicht Auswirkungen auf meine manuell Bestellungen?
Ich arbeite jetzt daran.
Bitte helfen Sie mir, vielen Dank im Voraus.
Nein, Onchartevent() führt den Code nur aus, wenn ein Diagrammereignis eintritt, nicht so wie die Funktion OnTImer().
Sie müssen also genau wissen, was Sie tun.
Wenn Sie zum Beispiel den Scan-Code verwenden:
Um zu prüfen, ob der Preis Ihre Linie überschritten hat, wird dies nicht in OnChartEvent() funktionieren.
Auch wenn Sie das automatisierte Beispiel verwenden möchten
{
ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJ_HLINE,0,0,OrderOpenPrice()-takeprofit*Point());
ObjectSet("#"+IntegerToString(OrderTicket())+"-TP",7,3);
}
Dies wird nicht funktionieren oder die Objekte erstellen.
Sie werden den Code neu schreiben müssen.
Sie können auch die H_LINE-Objekte auf OBJPROP_BACK setzen. Das ist kein Problem, Sie werden sie immer noch sehen und sie werden unter Ihrem Panel sein.
Wirklich netter und nützlicher Kommentar, jetzt weiß ich sicher, dass ich es zumindest einmal versuchen sollte, um zu wissen, was ich zusätzlich tun könnte.
Danke für Ihre schnelle Antwort und Ihren hilfreichen Kommentar.
Du wirst den Code neu schreiben müssen.
(Ich habe Ihren Kommentar schon aufmerksam gelesen, aber ich wollte es nur einmal versuchen - schließlich funktioniert es, wie Sie sagten, nicht wie der OnTimer(). )
Omg! Soll ich alles in diesem Code des Blocks ändern?
Jetzt habe ich vier Funktionen. Ich versuche gerade, sie in OnChartEvent() einzufügen. Ich habe bereits versucht, ich sehe nur eine Sache aktualisiert dies ist nur Print() für Stop Loss, Take Profit Preise.
OrderModify() funktioniert nicht in ihm.
Ich werde beginnen, etwas zu versuchen, wieder für dieses Problem in 8 - 10 Stunden.
Ich brauche nur wirklich gute Kommentare, ich hoffe, ich werde es bekommen.
Vielen Dank im Voraus.
{
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);
}
//+------------------------------------------------------------------+
Diese Funktionen werden nur ausgeführt, wenn ein Zeichenereignis eintritt.
Zumindest ist es das, was Sie hier zeigen.
Chartevent ist nur ein Auslöser für eine Unterbrechungsroutine, wenn jemand eine Schaltfläche oder etwas anderes auf dem Diagramm drückt.
Jetzt haben Sie das vollautomatische Beispiel genommen und unter eine Schaltfläche gelegt, es wird nichts passieren, wenn niemand die Schaltfläche drückt.
Diese Funktionen werden nur ausgeführt, wenn ein Zeichenereignis eintritt.
Zumindest ist es das, was Sie hier zeigen.
Ein Chart-Ereignis ist nur ein Auslöser für eine Interrupt-Routine, wenn jemand eine Schaltfläche oder etwas anderes auf dem Chart drückt.
Jetzt haben Sie das vollautomatische Beispiel unter eine Schaltfläche gelegt, und wenn niemand auf die Schaltfläche drückt, wird nichts passieren.
Es ist möglich, dass Ihr letzter Kommentar sieht aus wie so einfach, aber eigentlich, dass Kommentar zeigte mir den richtigen Weg.
So jetzt löse ich mein Problem, die ich versuchen, ziehen zu verwenden.
Und jetzt fange ich an, über einige andere grafische Objekte zu recherchieren, die sich mit diesem HLine-Objekt bewegen.
Vielen Dank mehr Mann!
Alles Gute für Sie!
Überlegen Sie auch, wie oft Sie die Linie bewegen. Ist es einmal pro Sekunde? Wahrscheinlich nicht.
Fügen Sie Ihren Code in OnChartEvent() ein:
{
if(id==CHARTEVENT_OBJECT_DRAG && sparam=="line") // the chart event of dragging the line