Ti stai perdendo delle opportunità di trading:
- App di trading gratuite
- Oltre 8.000 segnali per il copy trading
- Notizie economiche per esplorare i mercati finanziari
Registrazione
Accedi
Accetti la politica del sito e le condizioni d’uso
Se non hai un account, registrati
È già nell'esempio.
Quando si chiude l'ordine si usa il valore booleano di ritorno della funzione OrderClose(), e se la funzione ha avuto successo, si possono rimuovere gli oggetti relativi all'ordine.
{
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");
}
}
È già nell'esempio.
Quando chiudi l'ordine usi il valore booleano di ritorno della funzione OrderClose(), e se la funzione ha avuto successo, puoi rimuovere gli oggetti relativi all'ordine.
Lo so già, ho già provato. Forse ho fatto qualcosa di sbagliato. Proverò ancora una volta, ma prima di chiedere non vorrei usare OrderClose(). ( a volte chiudo gli ordini manualmente )
D: Quindi, posso cancellare gli oggetti ordine dopo che l'ordine è stato chiuso senza OrderClose()?
Grazie in anticipo.
Bene, il valore di ritorno della funzione Order Close() decide se l'azione ha avuto successo o meno, quindi se chiudi l'ordine manualmente dovrai progettare e usare un meccanismo leggermente diverso.
Puoi fare una copia ombra dell'elenco degli ordini e confrontarla con l'elenco attuale, e ogni volta che qualcosa cambia perché hai chiuso un ordine manualmente, cercare cosa è cambiato e poi rimuovere quegli oggetti.
Ma un modo più semplice potrebbe essere quello di controllare se l'OrderTicket() esiste ancora nel pool degli ordini attivi, così quando sparisce perché hai chiuso l'ordine manualmente, gli oggetti saranno automaticamente rimossi.
Quindi dipende da come vuoi impostare la cosa.
A questo punto direi che dovresti cercare di guardare oltre a ciò che vuoi farci alla fine perché la direzione che prendi è in qualche modo legata a compiti aggiuntivi che potresti voler aggiungere in seguito.
Dato che la creazione degli oggetti è già completamente automatizzata, ti suggerisco di fare lo stesso per la rimozione degli oggetti, così non dovrai preoccupartene in futuro.
Per questo puoi semplicemente usare
E il pool della storia
È semplice, il pool della storia degli ordini viene scansionato, e ad ogni ciclo il codice cercherà di vedere se esiste qualche oggetto collegato al numero OrderTicket(), e se c'è una corrispondenza, gli oggetti vengono automaticamente cancellati.
Per fare questo basta aggiungere un altro ciclo, ma questa volta sul pool della storia.
Vedi esempio.
//| 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
//+------------------------------------------------------------------+
Così ora avete l'aggiunta completamente automatizzata di linee di take profit e stoploss virtuali, e anche la rimozione completamente automatizzata di queste linee.
Naturalmente questo esempio scansiona continuamente lo storico...
Inoltre si potrebbe aggiungere un intero che contiene il numero di ordini, che viene poi confrontato con OrdersTotal(), e ogni volta che qualcosa cambia si esegue il codice di rimozione dell'oggetto.
Oppure, si potrebbe aggiungere un semplice contatore (60) e poi il codice controllerà solo una volta al minuto, se qualcosa deve essere rimosso.
Ehi, amico! Funziona perfettamente! Grazie mille!
Ho solo cambiato un po'. Finora funziona senza problemi.
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
}
}
}
Se c'è qualcosa che non va fammelo sapere.
Ancora una volta grazie mille, amico!
Forse nessuno capisce la mia domanda. Ma ho ancora bisogno di un buon commento per questo. Così ora sto cercando di chiarire la mia domanda con l'immagine.
Domanda: Anche Stop Loss, Take Profit Lines davanti agli oggetti del Trade Panel. So che è stato causato dall'ultima volta che ha creato l'oggetto. Ma se mi capite, per favore fatemi sapere come posso fare l'oggetto Trade Panel dovrebbe essere davanti a tutti gli altri oggetti senza linee "Stop Loss e Take Profit".
So che posso usare OBJPROP_BACK, ma non voglio usarlo. Ho solo bisogno di vedere linea e prezzo come entrambi. Spero di ottenere un buon commento per questo.
Aprire, Stop Loss, Take Profit, linee di prezzo "Crea e cancella" che sono tutte in una funzione. Così ora sto cercando di dividerlo, perché ho bisogno di mettere quella funzione in OnChartEvent(). Ma prima ho bisogno di chiedere.
D: Se metto quella funzione in OnChartEvent() - così quella funzione non potrebbe avere effetti sui miei ordini manualmente?
Ci sto lavorando ora.
Per favore aiutatemi, grazie in anticipo.
No Onchartevent() eseguirà il codice solo quando c'è un evento del grafico, non è come la funzione OnTImer().
Quindi devi sapere esattamente cosa stai facendo.
Per esempio se stai usando il codice di scansione:
Per controllare se il prezzo ha attraversato la vostra linea questo non funzionerà in OnChartEvent().
Anche se vuoi usare l'esempio automatico
{
ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJ_HLINE,0,0,OrderOpenPrice()-takeprofit*Point());
ObjectSet("#"+IntegerToString(OrderTicket())+"-TP",7,3);
}
Questo non funzionerà e non creerà gli oggetti.
Dovrete riscrivere il codice.
Inoltre, puoi impostare gli oggetti H_LINE su OBJPROP_BACK questo non è un problema li vedrai ancora e saranno sotto il tuo pannello.
Commento davvero bello e utile, ora so per certo che dovrei provare almeno una volta per sapere cosa potrei fare in più.
Grazie per la tua rapida risposta e il tuo utile commento.
Dovrete riscrivere il codice.
( Ho già letto attentamente il tuo commento ma volevo solo provare una volta - alla fine come hai detto tu non funziona come OnTimer(). )
Omg! Devo cambiare tutto in quel codice di blocco?
Ora ho quattro funzioni. Cerco solo di metterle in OnChartEvent(). Ho già provato, vedo solo una cosa che si aggiorna questo è solo Print() per i prezzi di stop loss, take profit.
OrderModify() non funziona in esso.
Inizierò a provare di nuovo qualcosa per questo problema in 8 - 10 ore.
Ho solo bisogno di buoni commenti, spero di ottenerli.
Grazie mille in anticipo.
{
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);
}
//+------------------------------------------------------------------+
Queste funzioni saranno eseguite solo quando si verifica un chartevent.
Almeno questo è quello che state mostrando qui.
Il chartevent è solo un trigger per una routine di interrupt quando qualcuno preme un pulsante o qualcos'altro sul grafico.
Ora avete preso l'esempio completamente automatizzato e l'avete messo sotto un pulsante, non succederà nulla se nessuno lo preme.
Queste funzioni saranno eseguite solo quando si verifica un evento grafico.
Almeno questo è quello che state mostrando qui.
Il chartevent è solo un trigger per una routine di interrupt quando qualcuno preme un pulsante o qualcos'altro sul grafico.
Ora avete preso l'esempio completamente automatizzato e l'avete messo sotto un pulsante, non succederà nulla se nessuno lo preme.
È possibile che il tuo ultimo commento sembri così semplice, ma in realtà quel commento mi ha mostrato la strada giusta.
Così ora risolvo il mio problema che cerco di usare il trascinamento.
E ora sto iniziando a fare ricerche su alcuni altri oggetti grafici che si muovono con l'oggetto HLine.
Grazie ancora tanto amico!
Tutto il meglio per te!
Inoltre, pensa a quanto spesso muovi la linea. È una volta al secondo? Probabilmente no.
Mettete il vostro codice in OnChartEvent():
{
if(id==CHARTEVENT_OBJECT_DRAG && sparam=="line") // the chart event of dragging the line