Fragen von Neueinsteigern zu MQL4 und MQL5, Hilfe und Diskussion über Algorithmen und Codes - Seite 248

 
STARIJ:

Das Internet ist wieder da! Kann ich an die Post schreiben?


Ja, ich bleibe in Kontakt. Schicken Sie mir eine SMS.

 

Hilfe zur Verfeinerung der EA Ich bin ein Anfänger Programmierer, Beschreibung:

Der Advisor arbeitet mit den beiden Währungspaaren EURUSD und USDCHF und eröffnet nur dann zwei Kaufgeschäfte, wenn eine Divergenz von 10pp vorliegt (im Wesentlichen ein Standard-Arbitrator).

Hier ist die Bedingung: if ((ind2>ind1+Impuls*Punkt && ind3<ind4-Impuls*Punkt) || (ind2<ind1-Impuls*Punkt && ind3>ind4+Impuls*Punkt))

Und es wird geschlossen, wenn der Gesamtgewinn/-verlust einen bestimmten Wert erreicht: wenn ((Kontoprofit()>=10)||(Kontoprofit()<=-20))


DAS PROBLEM: Es werden nicht immer 2 Geschäfte eröffnet, manchmal sind es 3. Oder es werden zwei Geschäfte in derselben Währung eröffnet. Es müssen immer 2 Transaktionen auf verschiedene Währungen eröffnet werden (eine - auf EURUSD; eine andere - auf USDCHF).



Hier ist der Code selbst:


extern double impulse = 10; // Globale Variablen

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("Output data\nEUR = %G\nCHF =%G",EUR,CHF));

wenn ((Kontoprofit()>=10)||(Kontoprofit()<=-20)) // Bedingung schließen

Alert3();

if ((ind2>ind1+Impuls*Point && ind3<ind4-Impuls*Point) || (ind2<ind1-Impuls*Point && ind3>ind4+Impuls*Point)) //offene Bedingung

if (AufträgeSumme() == 0)

Alert1();

if (AufträgeSumme() == 1)

Alert2();

zurück(0);

}


int Alert1()

{

if (AufträgeSumme() == 0)

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

zurück(0);

}


int Alert2()

{

if(AufträgeSumme() == 1)

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

zurück(0);

}


int Alert3()

{

while (AufträgeSumme()>0)

if (OrderSelect(0, SELECT_BY_POS, MODE_TRADES)) //Schließen

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

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

zurück(0);

}

 

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

Der Server wird angewiesen, den Euro zu öffnen. Bis sie den Server erreicht, bis der Server ... Bislang liegen keine Aufträge vor. Beim nächsten Tick ist die Bedingung erneut erfüllt und wieder wird der Auftrag zum Öffnen des Euro erteilt. Der Server hat die erste Bestellung geöffnet. Da es 1 Auftrag gibt, wird der Befehl zur Eröffnung eines zweiten (und es ist bereits der dritte!) Auftrags gesendet.

Ich habe alle Funktionen ungültig gemacht und die Rückgabe entfernt. Hier ist dieser Teil des Programms (wir haben die Taste SRC gedrückt, um ihn einzufügen)

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

und ersetzte es (etwas grob, aber IMHO besser als das Original) durch

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

Es gibt eine zusätzliche Zeile in der Funktion Alert3

  int cl1=OrderClose (OrderTicket(),OrderLots(),Ask,3);
Anstelle von double CHF=(int)DoubleToStr(oper2*100000,0); versuchen Sie int CHF=oper2/_Point;
 
STARIJ:

ersetzt (grob, aber IMHO besser als das Original) durch

Nicht unhöflich, aber es wird mit Fehlern arbeiten. Schon allein deshalb, weil beide Aufträge von Ask mit demselben Charakter ausgeführt werden.
 
Alexey Kozitsyn:   Nicht unhöflich, aber es wird mit Fehlern arbeiten. Und sei es nur, weil beide Aufträge über Ask desselben Symbols laufen.

Da haben Sie natürlich völlig Recht. Außerdem befand sich dieser Fehler im Quellcode, aber er wurde durch die Verwendung von Funktionen sowohl des Autors als auch von Ihnen und von mir, einem Sünder, verschleiert. Nachdem ich die Funktionen entfernt hatte, war der Fehler offensichtlich geworden. Ich denke, dass Positionen nur von dem Symbol eröffnet werden, auf dessen Chart sich der EA befindet. Richtig?

 
STARIJ:

Da haben Sie natürlich völlig Recht. Und dieser Fehler war im Quellcode enthalten, aber er wurde durch die Verwendung von Funktionen des Autors, von Ihnen und von mir, dem Sünder, verschleiert. Nachdem ich die Funktionen entfernt hatte, war der Fehler offensichtlich geworden. Ich denke, dass Positionen nur von dem Symbol eröffnet werden, auf dessen Chart sich der EA befindet. Oder?

Ja, natürlich, wenn die Voraussetzungen für die Eröffnung erfüllt sind. Das Ask für das zweite Symbol sollte separat angefordert werden.
 
Hallo zusammen. Die Frage ist naiv, sie betrifft die Funktion OrdersTotal(). Es ist klar, dass es die Anzahl der Aufträge zurückgibt, und die Aufträge sind von 0 bis N nummeriert. Wenn die Balken jedoch ab dem neu geöffneten Balken in der Historie nummeriert werden, d. h. der "frische" Balken hat die Nummer 0 und der "alte" Balken die Nummer N. Und in der Funktion OrdersTotal(), verstehe ich, dass alles umgekehrt abläuft - der älteste offene Auftrag wird mit 0 und der "frische" mit N nummeriert. Habe ich es richtig verstanden?
 
Youri Lazurenko:
Hallo zusammen. Die Frage ist naiv, sie betrifft die Funktion OrdersTotal(). Es ist klar, dass es die Anzahl der Aufträge zurückgibt und die Auftragsnummerierung von 0 bis N reicht. Wenn die Takte jedoch ab dem neu geöffneten Takt in der Historie nummeriert werden, d.h. ein "frischer" Takt erhält die Nummer 0 und ein alter Takt - N. Und in der Funktion OrdersTotal(), verstehe ich, dass alles umgekehrt abläuft - der älteste offene Auftrag wird mit 0 und der "frische" mit N nummeriert. Habe ich es richtig verstanden?

Durchaus, aber es gibt Nuancen.

Es gab eine Zeit, in der die Sortierung von der Sortierung im Terminal abhing. Kein Nutzer kann mit Sicherheit sagen, ob diese Zeit "plötzlich" wiederkehren wird, wenn die Sortierung wieder von der Sortierung des Terminals abhängt. Deshalb wäre es viel sicherer, Aufträge in einem Array zu sammeln und sie nach ihrer Öffnungs-/Schließungszeit zu sortieren - dann wüssten Sie mit Sicherheit, dass Ihre Sortierung von der Zeit abhängt und nicht "plötzlich" von der Sortierung im Terminal.

 
Artyom Trishkin:

Durchaus, aber es gibt Nuancen.

Es gab eine Zeit, in der die Sortierung von der Sortierung im Terminal abhing. Kein Nutzer kann mit Sicherheit sagen, ob diese Zeit "plötzlich" wiederkehren wird, wenn die Sortierung wieder von der Sortierung des Terminals abhängt. Deshalb ist es besser, Aufträge in einem Array zu sammeln und sie nach Öffnungs-/Schließungszeit zu sortieren - dann wissen Sie sicher, dass Ihre Sortierung von der Zeit abhängt und nicht "plötzlich" von der Sortierung im Terminal.


Hallo. Ich danke Ihnen für Ihre Antwort. Zunächst möchte ich auf Ihre vorherige Antwort auf meine Frage zum umgekehrten Kreislauf zurückkommen. Gestern, bevor ich zur Arbeit ging, schrieb ich eine Antwort, und heute konnte ich meine (und Ihre) Beiträge überhaupt nicht mehr finden. Soweit ich es verstanden habe, habe ich die Frage in einem falschen Zweig gestellt. Der umgekehrte Zyklus ist i--?

"Deshalb ist es zuverlässiger, Aufträge in einem Array zu sammeln und sie nach Öffnungs-/Schließungszeit zu sortieren" - das ist sehr interessant, und ich denke, dass es zuverlässiger und korrekter ist (und es scheint mir, wenn man den letzten Auftrag definiert, bekommt man nicht immer, was man braucht). Wenn das nicht schwierig ist, wie kann ich es dann tun (ein Array nach Öffnungszeitpunkt erstellen)?

Und noch eine Sache. Ich habe es noch nicht ausprobiert. Wir haben einen gewinnbringenden und einen verlustbringenden (sperrenden) Auftrag. Die Gewinnaufträge werden mit dem Trailing-Stop geschlossen. Ich hätte gerne einen Vermerk, dass die Aufträge geschlossen wurden, um ihren Gesamtgewinn mit dem der Verlustaufträge zu vergleichen und die Verlustaufträge zu schließen, wenn der Saldo positiv ist. Ich bin daran interessiert, welche Aufträge genau abgeschlossen wurden.

 
STARIJ:

Ich gehe davon aus, dass Positionen nur auf dem Symbol geöffnet werden, auf dessen Chart sich der EA befindet. Oder?

Wenn Ihr Expert Advisor auf EURUSD arbeitet, Sie aber eine BUY-Order auf USDCHF platzieren möchten

dann sollten Sie in OrderSend MarketInfo("USDCHF",MODE_ASK); anstelle von Ask (für EURUSD) verwenden