Tutte le domande dei nuovi arrivati su MQL4 e MQL5, aiuto e discussione su algoritmi e codici - pagina 248

 
STARIJ:

Internet è di nuovo attivo! Posso scrivere all'ufficio postale?


Sì, sono in contatto. Mandami un messaggio.

 

Aiuto per perfezionare l'EA Sono un programmatore principiante, descrizione:

Il consulente lavora su due coppie di valute EURUSD e USDCHF, apre due operazioni di acquisto solo quando c'è una divergenza di 10pp (essenzialmente un arbitro standard).

Ecco la condizione: if ((ind2>ind1+impulso*Point && ind3<ind4-impulso*Point) || (ind2<ind1-impulso*Point && ind3>ind4+impulso*Point))

E si chiude quando il profitto/perdita totale raggiunge un certo valore: se ((AccountProfit()>=10)||(AccountProfit()<=-20))


IL PROBLEMA: Non sempre apre 2 trade, a volte ne apre 3. Oppure apre due accordi della stessa valuta. Ha bisogno di: apre sempre 2 transazioni su valute diverse (una - su EURUSD; un'altra - su USDCHF).



Ecco il codice stesso:


extern double impulse = 10; // Variabili globali

extern double Lots = 1;


int start()

{

double ind2=iClose("EURUSD",PERIOD_M1,0);

double ind1=iOpen("EURUSD",PERIOD_M1,0);


double ind3=iClose("USDCHF",PERIOD_M1,0);

double ind4=iOpen("USDCHF",PERIOD_M1,0);


doppio oper1=ind2-ind1;

double EUR=(int)DoubleToStr(oper1*100000,0);


doppio oper2=ind3-ind4;

double CHF=(int)DoubleToStr(oper2*100000,0);


Comment(StringFormat("Output data\nEUR = %G\nCHF =%G",EUR,CHF));

se ((AccountProfit()>=10)||(AccountProfit()<=-20)) // Condizione di chiusura

Alert3();

if ((ind2>ind1+impulso*Point && ind3<ind4-impulso*Point) || (ind2<ind1-impulso*Point && ind3>ind4+impulso*Point)) //condizione aperta

se (Totale ordini() == 0)

Alert1();

se (Totale ordini() == 1)

Allarme2();

ritorno(0);

}


int Alert1()

{

se (Totale ordini() == 0)

int send1=OrderSend("EURUSD",OP_BUY,Lots,Ask,3,0,0);

ritorno(0);

}


int Alert2()

{

se(OrdiniTotali() == 1)

int send2=OrderSend("USDCHF",OP_BUY,Lots,Ask,3,0,0);

ritorno(0);

}


int Alert3()

{

mentre (OrdiniTotali()>0)

se (OrderSelect(0, SELECT_BY_POS, MODE_TRADES)) //Chiusura

int cl1=OrderClose (OrderTicket(),OrderLots(),Bid,3);

int cl1=OrderClose (OrderTicket(),OrderLots(),Ask,3);

ritorno(0);

}

 

Alexey Belyakov:  CУТЬ ПРОБЛЕММЫ: Не всегда открывает 2 сделки, а бывает открывает 3. Или открывает две сделки по одной валюте. Нужно чтобы: открывал всегда 2 сделки по разным валютам ( одна - по EURUSD; другая- по USDCHF)

Si ordina al server di aprire l'Euro. Nel momento in cui raggiunge il server, nel momento in cui il server ... Finora non ci sono ordini. Al prossimo tick la condizione è soddisfatta di nuovo e di nuovo l'ordine di aprire l'Euro. Il server ha aperto il primo ordine. Dato che c'è 1 ordine, viene inviato il comando per aprire un secondo (ed è già il terzo!) ordine.

Ho reso nulle tutte le funzioni e rimosso il ritorno. Ecco questa parte del programma (abbiamo premuto il tasto SRC per inserirla)

  if((ind2>ind1+impulse*Point && ind3<ind4-impulse*Point) ||
     (ind2<ind1-impulse*Point && ind3>ind4+impulse*Point))   // Условие открытия
     if(OrdersTotal() == 0) Alert1();
     if(OrdersTotal() == 1) Alert2();
}

void Alert1()
{
  if (OrdersTotal() == 0)  // Перед вызовом этой функции уже проверялось количество ордеров
  int send1=OrderSend("EURUSD",OP_BUY,Lots,Ask,3,0,0);
}

void Alert2()
{
  if(OrdersTotal() == 1)  // Перед вызовом этой функции уже проверялось количество ордеров
  int send2=OrderSend("USDCHF",OP_BUY,Lots,Ask,3,0,0);
}

e l'ho sostituito (un po' grezzo, ma IMHO è meglio dell'originale) con

  if((ind2>ind1+impulse*Point && ind3<ind4-impulse*Point) ||
     (ind2<ind1-impulse*Point && ind3>ind4+impulse*Point))   // Условие открытия
     if(OrdersTotal() == 0)
  {
    int send1=OrderSend("EURUSD",OP_BUY,Lots,Ask,3,0,0); 
    int send2=OrderSend("USDCHF",OP_BUY,Lots,Ask,3,0,0);
    Sleep(60); // Дождаться следующего бара, а то еще пооткрывает
  }
}

C'è una linea in più nella funzione Alert3

  int cl1=OrderClose (OrderTicket(),OrderLots(),Ask,3);
Invece di double CHF=(int)DoubleToStr(oper2*100000,0); prova int CHF=oper2/_Point;
 
STARIJ:

sostituito (grezzo, ma IMHO meglio dell'originale) con

Non è scortese, ma funziona con gli errori. Se non altro perché entrambi gli ordini vanno da Ask dello stesso carattere.
 
Alexey Kozitsyn:   Non è scortese, ma funziona con gli errori. Se non altro perché entrambi gli ordini vanno per Ask dello stesso simbolo.

Naturalmente, avete assolutamente ragione. Inoltre, questo errore era nel codice sorgente, ma è stato mascherato utilizzando funzioni sia dell'autore che di voi, oltre che di me, un peccatore. Dopo aver rimosso le funzioni, l'errore era diventato evidente. Penso che le posizioni saranno aperte solo dal simbolo sul cui grafico si trova l'EA. Giusto?

 
STARIJ:

Naturalmente, avete assolutamente ragione. E questo errore era contenuto nel codice sorgente, ma è stato mascherato dall'uso di funzioni dell'autore, da voi e da me peccatore. Dopo aver rimosso le funzioni, l'errore era diventato evidente. Penso che le posizioni saranno aperte solo dal simbolo sul cui grafico si trova l'EA. Giusto?

Sì, certo, se le condizioni per l'apertura sono soddisfatte. L'Ask per il secondo simbolo deve essere ottenuto separatamente.
 
Ciao a tutti. La domanda è ingenua, riguarda la funzione OrdersTotal(). È chiaro che restituisce il numero di ordini, e gli ordini sono numerati da 0 a N. Ma se le barre sono numerate a partire da quella appena aperta nella storia, cioè la barra "fresca" è numerata 0 e quella "vecchia" è numerata N. E nella funzione OrdersTotal(), capisco che tutto avviene al contrario - l'ordine aperto più vecchio è numerato 0 e quello "fresco" è numerato come N. Ho capito bene?
 
Youri Lazurenko:
Ciao a tutti. La domanda è ingenua, riguarda la funzione OrdersTotal(). È chiaro che restituisce il numero di ordini e la numerazione degli ordini è da 0 a N. Ma se le barre sono numerate a partire da quella appena aperta nella storia, cioè una barra "fresca" è numerata 0 e una vecchia - N. E nella funzione OrdersTotal(), capisco che tutto avviene al contrario - l'ordine aperto più vecchio è numerato 0 e quello "fresco" è numerato come N. Ho capito bene?

Abbastanza, ma ci sono delle sfumature.

C'è stato un tempo in cui lo smistamento dipendeva dallo smistamento nel terminale. Nessun utente può dire con certezza se quel tempo tornerà "improvvisamente" quando l'ordinamento dipenderà nuovamente dall'ordinamento del terminale. Ecco perché è più affidabile raccogliere gli ordini in un array e ordinarli in base al loro tempo di apertura/chiusura - allora saprai con certezza che il tuo ordinamento dipende dal tempo e non "improvvisamente" dall'ordinamento nel terminale.

 
Artyom Trishkin:

Abbastanza, ma ci sono delle sfumature.

C'è stato un tempo in cui lo smistamento dipendeva dallo smistamento nel terminale. Nessun utente può dire con certezza se quel tempo tornerà "improvvisamente" quando l'ordinamento dipenderà nuovamente dall'ordinamento del terminale. Ecco perché è meglio raccogliere gli ordini in array e ordinarli per tempo di apertura/chiusura - allora saprai con certezza che il tuo ordinamento dipende dal tempo e non "improvvisamente" dall'ordinamento nel terminale.


Salve. Grazie per la vostra risposta. Per prima cosa voglio tornare alla tua precedente risposta alla mia domanda, sul ciclo inverso. Ieri, prima di uscire per lavoro, ho scritto una risposta, e oggi, non ho potuto trovare il mio (e il tuo) post. Per quanto ho capito, l'ho chiesto in un ramo sbagliato. Il ciclo inverso è...?

"Ecco perché è più affidabile raccogliere gli ordini in un array e ordinarli per tempo di apertura/chiusura" - questo è molto interessante, e penso che sia più affidabile e corretto (e mi sembra che, quando si definisce l'ultimo ordine, non sempre si ottiene ciò di cui si ha bisogno). Se non è difficile, come posso farlo (creare un array per tempo aperto)?

E un'altra cosa. Non l'ho ancora provato. Abbiamo un ordine redditizio e uno perdente (bloccante). Gli ordini di profitto vengono chiusi utilizzando il trailing stop. Vorrei avere una nota che gli ordini sono stati chiusi in modo da confrontare il loro profitto totale con quello degli ordini perdenti e chiudere quelli perdenti, se il saldo è positivo. Mi interessa esattamente quali ordini sono stati chiusi.

 
STARIJ:

Presumo che le posizioni si aprano solo sul simbolo sul cui grafico si trova l'EA. Giusto?

Se il tuo Expert Advisor sta lavorando su EURUSD, ma vuoi piazzare un ordine BUY su USDCHF

allora dovreste usare MarketInfo("USDCHF",MODE_ASK); invece di Ask (sarà per EURUSD) in OrderSend