Eseguire un solo ordine nella candela

Sezione dedicata a metatrader (ed altre piattaforme) ed al suo linguaggio di programmazione per il trading automatico
rob80
Messaggi: 9
Iscritto il: 07/10/2014, 16:58

Eseguire un solo ordine nella candela

Messaggio da rob80 »

Buongiorno a tutti, volevo chiedervi se esiste una funzione per mql4 per far si che in una determinata candela possa aprirsi una sola posizione? ...alla chiusura per tp o sl sulla stessa candela non possono aprirsi altre posizioni....grazie per il vostro aiuto!!
Avatar utente
carlo10
Messaggi: 4261
Iscritto il: 08/05/2014, 21:17

Re: Eseguire un solo ordine nella candela

Messaggio da carlo10 »

Ciao rob80, benvenuto.

Non esiste una funzione built-in di metatrader per fare quello che chiedi ma si può chiaramente inserire un controllo di questo tipo nel tuo expert advisor.

Non mi è però chiaro dal tuo messaggio se te ne intendi di programmazione e ti serve solo uno spunto su come fare e se devi inserire questa logica all'interno di qualcosa di già esistente.
rob80
Messaggi: 9
Iscritto il: 07/10/2014, 16:58

Re: Eseguire un solo ordine nella candela

Messaggio da rob80 »

Ciao Carlo, grazie per la risposta!
non sono un programmatore nato ma è da un pò che sviluppo per me stesso qualche EA, ho creato un sistema con due medie mobili ma non riesco a trovare una funzione che mi permetta di aprire una sola ed unica posizione su una candela: una funzione che riconosca che su quella candela è già stato eseguito un trade e non deve eseguirne altri...ho trovato e provato in rete un pò di tutto ma non riesco a capire dove sbaglio o se non esiste soluzione, con la ricerca in google: "one trade per bar" si trovano una marea di informazioni ma non ne ho trovato uno che mi permetta di fare quello che cerco...molti dicono che la bar è inaffidabile e bisognerebbe affidarsi ad una funzione di tempo tipo:

static int order_time

int start()

{

if(order_time ==0 || TimeHour(TimeCurrent()) >= order_time + x )
{
if(condition1= true)
{
OrderSend();
order_time = TimeHour(TimeCurrent());
}
}
return(0);
}


oppure ho trovato anche questa con la funzione islastordercandle ma non riesco ad inserirla forse io correttamente :

bool isLastOrderCandle(){
//TRUE è già stato aperto un ordine su questa candela
//FALSE non sono stati aperti ordini su questa candela

int v_LastOrderHistory = OrdersHistoryTotal() - 1;

if (OrderSelect(v_LastOrderHistory, SELECT_BY_POS, MODE_HISTORY) && (OrderMagicNumber() == e_MagicID))
if (iBarShift(NULL, 0, OrderOpenTime(), true) == 0)
return(True);

return(False);
}
Avatar utente
carlo10
Messaggi: 4261
Iscritto il: 08/05/2014, 21:17

Re: Eseguire un solo ordine nella candela

Messaggio da carlo10 »

Ottimo in questo caso ti aiuto volentieri!

Partirei dalla isLastOrderCandle dato che è un articolo che avevo pubblicato io diversi anni fa.

Prova ad inserirla all'interno del tuo expert advisor e poi prova ad inserire qui il codice completo che cerco di capire il problema.
Avatar utente
Dainesi
Messaggi: 457
Iscritto il: 12/05/2014, 12:10
Località: Castellanza (VA)

Re: Eseguire un solo ordine nella candela

Messaggio da Dainesi »

Ciò che hai trovato in rete è, scusa il termine, ciarpame!

Per sapere se hai già aperto un ordine sulla candela attuale (ed eventualmente già chiuso), non devi fare altro che ciclare i due insiemi del portafoglio ordini e storico ordini, controllando che non ci siano ordini la cui data di apertura (OrderOpenTime()) sia uguale o maggiore dell'orario di inizio candela (Time[0]), lo stesso per le chiusure, utilizzando per il confronto la OrderCloseTime() (sempre che il tipo sia OP_BUY o OP_SELL). Se una di queste due condizioni viene trovata su un oggetto dell'insieme hai la certezza di aver avuto un apertura o chiusura sulla barra.

P.S. Verifica sempre la corrispondenza di strumento tradato e Magic Number
rob80
Messaggi: 9
Iscritto il: 07/10/2014, 16:58

Re: Eseguire un solo ordine nella candela

Messaggio da rob80 »

Ciao, eccomi!

xCarlo:
non sapevo fosse tuo l'articolo! ti scrivo il codice completo del mio EA con l'inserimento della formula isLastOrderCandle, il problema è che addirittura mi apre a raffica ordini senza nemmeno aver aspettato la chiusura di uno, non capisco dove sia l'errore...

extern int MagicNumber=100077;
extern double Lots =0.1;
extern double StopLoss=50;
extern double TakeProfit=150;
extern int TrailingStop=50;
extern int Slippage=3;
//+------------------------------------------------------------------+
// start function
//+------------------------------------------------------------------+
int start()
{
double MyPoint=Point;
if(Digits==3 || Digits==5) MyPoint=Point*10;

double TheStopLoss=0;
double TheTakeProfit=0;
if (isLastOrderCandle())
{
int result=0;
if((iMA(NULL,0,14,0,MODE_EMA,PRICE_CLOSE,2)<iMA(NULL,0,28,0,MODE_EMA,PRICE_CLOSE,2))&&(iMA(NULL,0,14,0,MODE_EMA,PRICE_CLOSE,1)>iMA(NULL,0,28,0,MODE_EMA,PRICE_CLOSE,1))) // condizioni buy
{
result=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,0,0,"commento",MagicNumber,0,Blue);
if(result>0)
{
TheStopLoss=0;
TheTakeProfit=0;
if(TakeProfit>0) TheTakeProfit=Ask+TakeProfit*MyPoint;
if(StopLoss>0) TheStopLoss=Ask-StopLoss*MyPoint;

}
return(0);
}
if((iMA(NULL,0,14,0,MODE_EMA,PRICE_CLOSE,2)>iMA(NULL,0,28,0,MODE_EMA,PRICE_CLOSE,2))&&(iMA(NULL,0,14,0,MODE_EMA,PRICE_CLOSE,1)<iMA(NULL,0,28,0,MODE_EMA,PRICE_CLOSE,1))) // condizioni sell
{
result=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,0,0,"commento",MagicNumber,0,Red);
if(result>0)
{
TheStopLoss=0;
TheTakeProfit=0;
if(TakeProfit>0) TheTakeProfit=Bid-TakeProfit*MyPoint;
if(StopLoss>0) TheStopLoss=Bid+StopLoss*MyPoint;

}
return(0);
}
}


}


bool isLastOrderCandle(){
//TRUE è già stato aperto un ordine su questa candela
//FALSE non sono stati aperti ordini su questa candela

int v_LastOrderHistory = OrdersHistoryTotal() - 1;

if (OrderSelect(v_LastOrderHistory, SELECT_BY_POS, MODE_HISTORY) && (OrderMagicNumber() ==MagicNumber))
if (iBarShift(NULL, 0, OrderOpenTime(), true) == 0)
return(True);

return(False);
}


xDainesi:
cavolo....mi sa che ne sai un bel pò....solo che per me detta così non è semplice, immagino che per te sia molto più facile applicare questi concetti...comunque ho visto che sei di castellanza, io di saronno! :)
Avatar utente
carlo10
Messaggi: 4261
Iscritto il: 08/05/2014, 21:17

Re: Eseguire un solo ordine nella candela

Messaggio da carlo10 »

Eh si, Dainesi è un'autorità nel campo.

Da quanto vedo il problema del codice che hai postato sopra è che non verifichi se ci sono attualmente ordini aperti su quella candela. La funzione isLastOrderCandle ti verifica solo se l'ultimo ordine è stato chiuso sulla candela attuale.

Per capire che tipo di controllo inserire volevo prima sapere se la tua strategia prevede di aprire anche più ordini contemporaneamente (ad esempio sulle candele successive a quella in cui hai aperto l'ordine) oppure se vuoi attendere che tutti gli ordini siano chiusi prima di aprire una nuova posizione.
rob80
Messaggi: 9
Iscritto il: 07/10/2014, 16:58

Re: Eseguire un solo ordine nella candela

Messaggio da rob80 »

Ciao Carlo!
ho provato anche inserendo la funzione con TotalOrderCount:
int TotalOrdersCount()
{
int result=0;
for(int i=0;i<OrdersTotal();i++)
{
OrderSelect(i,SELECT_BY_POS ,MODE_TRADES);
if (OrderMagicNumber()==MagicNumber) result++;

}
return (result);


in questo caso non apre ordini a raffica ma (quando sono verificate le condizioni) apre un ordine per volta sulla candela di riferimento fino a che la candela non si chiude, ma il mio obiettivo sarebbe questo: quando le condizioni si sono verificate su quella candela apri solo una posizione e quando si chiude non se ne possono aprire più....fino a che non si verificano nuovamente le condizioni (nuovo incrocio delle medie).

Grazie infinite per la tua disponibilità!
Avatar utente
carlo10
Messaggi: 4261
Iscritto il: 08/05/2014, 21:17

Re: Eseguire un solo ordine nella candela

Messaggio da carlo10 »

L'ultima funzione che hai aggiunto ti dice solo se ci sono ordini attualmente aperti con quel magic number quindi non può essere che gli ordini siano stati aperti anche su candele più vecchie di quella attuale.

A questo punto come suggerito da Dainesi possiamo fare una funzione che cicli su ordini aperti e chiusi e verifichi se ci sono ordini (aperti o chiusi) sulla candela attuale. Questa prende in considerazione solo la data di apertura dell'ordine:

Codice: Seleziona tutto

bool candleHasOrders(int magic){

   //ciclo sugli ordini aperti
   for(int i = 0; i < OrdersTotal(); i++)
      if(OrderSelect(i, SELECT_BY_POS) && OrderSymbol() == Symbol() && OrderMagicNumber() == magic)
         if (iBarShift(NULL, 0, OrderOpenTime(), true) == 0)
            return TRUE;
   
   //ciclo sugli ordini chiusi
   for(int i = 0; i < OrdersHistoryTotal(); i++)
      if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && OrderSymbol() == Symbol() && OrderMagicNumber() == magic)
         if (iBarShift(NULL, 0, OrderOpenTime(), true) == 0)
            return TRUE;   

   return FALSE;

}  
A questo punto nella all'interno del tuo start inserirai il seguente controllo:

Codice: Seleziona tutto

if (candleHasOrders(magic_id) == FALSE){
   ....
   ....
}
L'ho buttato giù al volo senza provarlo, verifica se effettivamente fa ciò che ti aspetti e facci sapere.
rob80
Messaggi: 9
Iscritto il: 07/10/2014, 16:58

Re: Eseguire un solo ordine nella candela

Messaggio da rob80 »

Grazie infinite Carlo....appena riesco a verificarlo ti faccio sapere!!
a presto e grazie ancora!!
Rispondi

Chi c’è in linea

Visitano il forum: Nessuno e 2 ospiti