Toute question des nouveaux arrivants sur MQL4 et MQL5, aide et discussion sur les algorithmes et les codes. - page 248

 
STARIJ:

Internet est de retour ! Puis-je écrire à la poste ?


Oui, je suis en contact. Envoyez-moi un SMS.

 

Aide pour affiner le conseiller Je suis un programmeur novice, description :

Le conseiller travaille sur deux paires de devises EURUSD et USDCHF, il n'ouvre deux trades d'achat que lorsqu'il y a une divergence de 10pp (essentiellement un arbitre standard).

Voici la condition : si ((ind2>ind1+impulse*Point && ind3<ind4-impulse*Point) || (ind2<ind1-impulse*Point && ind3>ind4+impulse*Point))

Et il se ferme lorsque le total des profits/pertes atteint une certaine valeur : si ((AccountProfit()>=10)||(AccountProfit()<=-20))


LE PROBLÈME : Il n'ouvre pas toujours 2 transactions, parfois il en ouvre 3. Ou bien il ouvre deux transactions de la même devise. Il faut : toujours ouvrir 2 transactions sur des devises différentes (une - sur EURUSD ; une autre - sur USDCHF).



Voici le code lui-même :


extern double impulse = 10 ; // Variables globales

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) ;


double oper1=ind2-ind1 ;

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


double oper2=ind3-ind4 ;

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


Comment(StringFormat("Données de sortie -EUR = %G -CHF =%G",EUR,CHF)) ;

si ((AccountProfit()>=10)||(AccountProfit()<=-20)) // Condition de fermeture

Alert3() ;

if ((ind2>ind1+impulse*Point && ind3<ind4-impulse*Point) || (ind2<ind1-impulse*Point && ind3>ind4+impulse*Point)) //condition ouverte

si (OrdersTotal() == 0)

Alert1() ;

si (OrdersTotal() == 1)

Alert2() ;

retour(0) ;

}


int Alerte1()

{

si (OrdersTotal() == 0)

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

retour(0) ;

}


int Alert2()

{

si(OrdersTotal() == 1)

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

retour(0) ;

}


int Alerte3()

{

while (OrdersTotal()>0)

si (OrderSelect(0, SELECT_BY_POS, MODE_TRADES)) //Fermeture

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

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

retour(0) ;

}

 

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

Le serveur reçoit l'ordre d'ouvrir l'euro. Le temps qu'il atteigne le serveur, le temps que le serveur ... Pour l'instant, il n'y a pas de commande. Au tick suivant, la condition est à nouveau remplie et l'ordre d'ouvrir l'Euro est à nouveau donné. Le serveur a ouvert la première commande. Comme il y a 1 commande, la commande pour ouvrir une deuxième (et c'est déjà la troisième !) commande est envoyée.

J'ai annulé toutes les fonctions et supprimé le retour. Voici cette partie du programme (nous avons appuyé sur le bouton SRC pour l'insérer)

  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);
}

et l'a remplacé (un peu brut, mais IMHO il est mieux que l'original) avec

  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); // Дождаться следующего бара, а то еще пооткрывает
  }
}

Il y a une ligne supplémentaire dans la fonction Alert3

  int cl1=OrderClose (OrderTicket(),OrderLots(),Ask,3);
Au lieu de double CHF=(int)DoubleToStr(oper2*100000,0) ; essayez int CHF=oper2/_Point ;
 
STARIJ:

remplacé (grossièrement, mais à mon avis mieux que l'original) par

Ce n'est pas impoli, mais cela fonctionnera avec des erreurs. Ne serait-ce que parce que les deux ordres passent par une demande du même caractère.
 
Alexey Kozitsyn:   Ce n'est pas impoli, mais cela fonctionnera avec des erreurs. Ne serait-ce que parce que les deux ordres passent par Ask du même symbole.

Bien sûr, vous avez tout à fait raison. De plus, cette erreur se trouvait dans le code source, mais elle a été déguisée en utilisant des fonctions de l'auteur et de vous, ainsi que de moi, un pécheur. Après avoir retiré les fonctions, l'erreur était devenue évidente. Je pense que les positions seront ouvertes uniquement par le symbole sur le graphique duquel se trouve l'EA. N'est-ce pas ?

 
STARIJ:

Bien sûr, vous avez tout à fait raison. Et cette erreur était contenue dans le code source, mais elle était masquée par l'utilisation de fonctions de l'auteur, de vous et de mon péché. Après avoir retiré les fonctions, l'erreur était devenue évidente. Je pense que les positions seront ouvertes uniquement par le symbole sur le graphique duquel se trouve l'EA. N'est-ce pas ?

Oui, bien sûr, si les conditions d'ouverture sont remplies. La demande pour le deuxième symbole doit être obtenue séparément.
 
Bonjour à tous. La question est naïve, elle concerne la fonction OrdersTotal(). Il est clair qu'elle renvoie le nombre de commandes, et les commandes sont numérotées de 0 à N. Mais si les barres sont numérotées en commençant par celle qui vient d'être ouverte dans l'historique, c'est-à-dire que la barre "fraîche" est numérotée 0 et l'"ancienne" est numérotée N. Et dans la fonction OrdersTotal(), je comprends que tout se passe à l'inverse - l'ordre ouvert le plus ancien est numéroté 0 et le " nouveau " est numéroté N. Est-ce que j'ai bien compris ?
 
Youri Lazurenko:
Bonjour à tous. La question est naïve, elle concerne la fonction OrdersTotal(). Il est clair qu'il renvoie le nombre de commandes et que la numérotation des commandes est de 0 à N. Mais si les barres sont numérotées à partir de la nouvelle barre ouverte dans l'historique, c'est-à-dire qu'une barre "fraîche" est numérotée 0 et une ancienne - N. Et dans la fonction OrdersTotal(), je comprends que tout se passe à l'inverse - l'ordre ouvert le plus ancien est numéroté 0 et le " nouveau " est numéroté N. Est-ce que j'ai bien compris ?

Tout à fait, mais il y a des nuances.

Il fut un temps où le tri dépendait du tri dans le terminal. Aucun utilisateur ne peut dire avec certitude si ce moment reviendra "soudainement" lorsque le tri dépendra à nouveau du tri du terminal. C'est pourquoi il est plus fiable de rassembler les ordres dans un tableau et de les trier en fonction de leur heure d'ouverture/de fermeture - vous saurez alors avec certitude que votre tri dépend du temps et non pas "soudainement" du tri dans le terminal.

 
Artyom Trishkin:

Tout à fait, mais il y a des nuances.

Il fut un temps où le tri dépendait du tri dans le terminal. Aucun utilisateur ne peut dire avec certitude si ce moment reviendra "soudainement" lorsque le tri dépendra à nouveau du tri du terminal. C'est pourquoi il est préférable de collecter les ordres dans un tableau et de les trier par heure d'ouverture/de fermeture - vous serez alors certain que votre tri dépend de l'heure et non pas "soudainement" du tri dans le terminal.


Bonjour. Je vous remercie de votre réponse. Je voudrais d'abord revenir sur votre réponse précédente à ma question, concernant le cycle inverse. Hier, avant de partir au travail, j'ai écrit une réponse, et aujourd'hui, je n'ai pas trouvé mes (et vos) messages du tout. D'après ce que j'ai compris, j'ai posé la question dans une mauvaise branche. Le cycle inverse est...

"C'est pourquoi il est plus fiable de rassembler les ordres dans un tableau et de les trier par heure d'ouverture/fermeture" - c'est très intéressant, et je pense que c'est plus fiable et correct (et il me semble que, lorsque vous définissez le dernier ordre, cela ne donne pas toujours ce dont vous avez besoin). Si ce n'est pas difficile, comment dois-je faire (créer un tableau par heure d'ouverture) ?

Et encore une chose. Je ne l'ai pas encore essayé. Nous avons un ordre rentable et un ordre perdant (verrouillage). Les ordres de profit sont fermés en utilisant le stop suiveur. J'aimerais avoir une note indiquant que les ordres ont été fermés afin de pouvoir comparer leur profit total avec celui des ordres perdants et fermer les ordres perdants si nous avons un solde positif. Je suis intéressé de savoir exactement quelles commandes ont été fermées.

 
STARIJ:

Je suppose que les positions ne s'ouvriront que sur le symbole sur le graphique duquel se trouve l'EA. N'est-ce pas ?

Si votre conseiller expert travaille sur l'EURUSD, mais que vous voulez placer un ordre d'achat sur l'USDCHF.

alors vous devez utiliser MarketInfo("USDCHF",MODE_ASK) ; au lieu de Ask (ce sera pour EURUSD) dans OrderSend.

Raison: