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

 
Hallo zusammen.
Dies ist mein erstes Mal im Forum, wenn ich etwas falsch mache, bitte ich um Verzeihung im Voraus.
Ich betrachte Charts mit Indikatoren für eine lange Zeit. Vor kurzem habe ich 2 Einlagen verloren. Bevor ich ein neues Konto eröffne, möchte ich die Rentabilität der Strategie anhand der Historie überprüfen. Ich verwende ein Demokonto in MT4.
Ich bin überhaupt kein Programmierer. Ich bin nur in der Lage, den Indikator auf MT4 zu installieren und vielleicht die Dicke der Indikatorlinie in MetaEditor zu ändern (ich werde wahrscheinlich nicht in der Lage sein, die Farbe im Indikatorcode zu ändern, nur im Terminal).
Haben Sie eine klare Information für jemanden mit meinen Kenntnissen, wo man mit dem Testen Schritt für Schritt beginnen kann (in einfachem Englisch "Anleitung für die Neger, wie man die Toilette benutzt")? Die Strategie verfügt über 3 Indikatoren: MA (3 einfache), Stochastik mit Standardwerten und CCI mit 5 Werten. Eröffnung von Short-Geschäften nach Überschreiten der Indikatorenlevels von oben nach unten, Long-Geschäfte umgekehrt (ich denke, das ist klar...). Festlegung von Einnahmen und Verlusten.
Ich möchte die Strategie sowohl im Auto-Modus als auch ohne Visualisierung visuell verfolgen können, um Parameter von Indikatoren und Aufträgen auszuwählen.
 
ZebStamp:
Hallo zusammen.
Dies ist mein erstes Mal im Forum, wenn ich etwas falsch mache, bitte ich um Verzeihung im Voraus.
Ich betrachte Charts mit Indikatoren für eine lange Zeit. Vor kurzem habe ich 2 Einlagen verloren. Ich möchte die Rentabilität der Strategie anhand der Historie überprüfen, bevor ich ein neues Konto eröffne. Ich verwende ein Demokonto in MT4.
Ich bin überhaupt kein Programmierer. Ich bin nur in der Lage, den Indikator auf MT4 zu installieren und vielleicht die Dicke der Indikatorlinie in MetaEditor zu ändern (ich werde wahrscheinlich nicht in der Lage sein, die Farbe im Indikatorcode zu ändern, nur im Terminal).
Haben Sie klare Informationen für jemanden mit meinen Kenntnissen, wo man mit dem Testen Schritt für Schritt beginnen kann (in einfachem Englisch "Anleitung für die Neger, wie man die Toilette benutzt")? Die Strategie verfügt über 3 Indikatoren: MA (3 einfache), Stochastik mit Standardwerten und CCI mit 5 Werten. Eröffnung von Short-Geschäften nach Überschreiten der Indikatorenlevels von oben nach unten, Long-Geschäfte umgekehrt (ich denke, das ist klar...). Festlegung von Einnahmen und Verlusten.
Ich möchte die Strategie im Auto-Modus visuell verfolgen können, aber auch ohne Visualisierung, um Parameter von Indikatoren und Orders auszuwählen.

Beim Erstellen eines grafischen Objekts (GO), z. B. einer Trendlinie, wählen Sie die Farbe aus. Wenn Sie die Trendlinie neu erstellen, wird sie mit der gleichen Farbe erstellt. Bei Hline wählt man eine Farbe - und die nächste ist so. Nehmen Sie gelb, blau, ...

Wenn CS erstellt Expert Advisor, Indikator, Skript - dann, wie Sie in dem Programm zu schreiben. Manchmal ist die Wahl der Parameter

 
STARIJ:

Wenn Sie glauben, dass jemand, der sich Ihren Code ansieht, schnell einen Fehler finden kann, irren Sie sich. Der Compiler sucht nach Fehlern. Der Programmtext sollte formatiert werden - MetaEditor verfügt über ein Styling-Tool für diesen Zweck. Wenn Sie einen anderen Stil bevorzugen, verwenden Sie z. B. das Programm AStyle.exe. Nach dem Styling werden Sie schnell feststellen, dass das Programm 1) eine zusätzliche schließende Klammer hat. 2) Deklarierte Variable: datetime date_Buf_1; // Indikator Datums-Array - damit dies ein Array ist, muss es [size] oder [] für ein dynamisches Array sein und dann muss die Größe auf ArrayResize gesetzt werden, wie es scheint. Und Sie müssen es tun, bevor Sie ein Array verwenden - siehe oben Beiträge darüber. 3) FileOpen(InpDirectoryName+"//"+InpFileName - scheint, als ob die Sticks in die andere Richtung gekippt werden sollten. Und es ist besser, auf InpDirectoryName+"//" zu verzichten - Sie finden die Datei ohnehin im Ordner "Files".

in der Zeile: int copied=CopyTime(NULL,0,0,0,date_Buf_1); der Compiler wird böse, start=0=0


Danke. Es ist mir gelungen, etwas zu reparieren, aber mehr intuitiv als durch Verstehen. Aber wir haben immer noch 3 Fehler bezüglich des Arrays:

'Buf_1' - Array erforderlich 111.mq4 93 21

'date_Buf_1' - Array erforderlich 111.mq4 94 21

'Buf_1' - Array erforderlich 111.mq4 100 16


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
input string             InpFileName="111.csv";      // Имя файла 
input string             InpDirectoryName="Data";     // Имя каталога 

datetime Время=0;   // Время прошлого бара
double Bid1;
double   Buf_1[];
// double ExtBuffer;
long V1; // объем для текущего тика вверх
long V2; // накопленный объем для всех тиков вверх текущего бара
long V3; // объем текущего тика вниз
long V4; // накопленный объем для всех тиков вниз для текущего бара
long V5;  // отрицательные и положительные iVolume нарастающим итогом
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnInit()
  {
   IndicatorDigits(0);
   SetIndexBuffer(0,Buf_1);
//SetIndexBuffer(1,Buf_2);
   Bid1=Bid;
   V5=0;

  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   datetime Вр=Time[0];   // Время текущего бара
   if(Вр>Время)           // Если новый бар
     {
      Время=Вр;           // Запомнить
                          //      Buf_1[0]=0;         // и обнулить последний элемент буфера
     }

   datetime date_Buf_1[]; // массив дат индикатора 
   datetime time_Buf_1[]; // массив времени 
                          // --- считаю объем для положительных и отрицательных тиков      
   if(Bid>=Bid1)
     {
      if(Bid>Bid1) // если тик положительный..
        {
         V1=iVolume(NULL,0,0); // если повышающий цену тик, то находим его объем
         V2= V1 + V2;
        }
      else
        {
         V1=0;                // если Bid1 = Bid2, т.е. изменение цены = 0, то iVolume этого тика присваиваем 0;
         V2= V1 + V2;
        }
     }
   else
     {
      V3 = iVolume(NULL, 0, 0); // если понижающий цену тик 
      V4 = V3 + V4;             // то находим его объем  
     }

   V5=V2-V4;               // определяем разницу (дельту) между объемами положительных и отрицательных тиков
   Bid1=Bid;
   Buf_1[0]=V5; // в буфер сгружаем  дельту

                //   ExtBuffer = Buf_1 [0];
//   double macurrent=iMAOnArray(ExtBuffer,0,5,0,MODE_LWMA,0); 

// запись в файл данных буфера


//--- установим для массивов признак таймсерии 
   ArraySetAsSeries(Buf_1[0],true);
   ArraySetAsSeries(date_Buf_1[0],true);

//--- скопируем таймсерию 
   int copied=CopyTime(NULL,0,10000,0,date_Buf_1);

//--- подготовим массив Buf_1 
   ArrayResize(Buf_1[0],copied);

//--- скопируем значения линии индикатора  
   for(int i=0;i<copied;i++)
     {
      Buf_1[i]=V5;
     }
//--- откроем файл для записи значений индикатора 
   ResetLastError();
   int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_CSV);
   if(file_handle!=INVALID_HANDLE)
     {
      PrintFormat("Файл %s открыт для записи",InpFileName);
      PrintFormat("Путь к файлу: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
      //--- сначала запишем значения индикатора 
      FileWrite(file_handle,Buf_1[0]);
      //--- запишем время и значения в файл 
      for(int i=0;i<Buf_1[0];i++)
         FileWrite(file_handle,time_Buf_1[0],Buf_1[0]);
      //--- закрываем файл 
      FileClose(file_handle);
      PrintFormat("Данные записаны, файл %s закрыт",InpFileName);
     }
   else
      PrintFormat("Не удалось открыть файл %s, Код ошибки = %d",InpFileName,GetLastError());

   return(rates_total);
  }
//+------------------------------------------------------------------+


Ich verstehe nicht, wie ich Ihre Bemerkungen umsetzen soll. Aber ich habe eine zusätzliche Heftklammer gefunden :)
 
YarTrade:

Ich danke Ihnen. Es ist mir gelungen, etwas zu reparieren, aber mehr intuitiv als durch Verstehen. Aber ich habe immer noch 3 Fehler bezüglich des Arrays:

'Buf_1' - Array erforderlich 111.mq4 93 21

'date_Buf_1' - Array erforderlich 111.mq4 94 21

'Buf_1' - Array erforderlich 111.mq4 100 16



Ich verstehe nicht, wie ich Ihre Bemerkungen umsetzen soll. Aber ich habe eine zusätzliche Klammer gefunden :)
Lassen Sie nur Namen von Array-Variablen stehen. Entfernen Sie "[]" in den Codezeilen, auf die der Compiler Sie hinweist.
 
Artyom Trishkin:
Lassen Sie nur die Namen der variablen Arrays stehen. Entfernen Sie "[]" in den Codezeilen, auf die der Compiler Sie hinweist.

Ich danke Ihnen. Ich werde sehen, was im wirklichen Leben passiert. Ich habe große Zweifel daran, dass etwas in die Datei geschrieben wird :)

 

Es haben sich eine Reihe von Fragen ergeben, ich hoffe sehr auf Ihre Hilfe. Ich habe die traurige Erfahrung gemacht, dass die Leistung von EA während der Tests und in Echtzeit sehr unterschiedlich ist, daher möchte ich die häufigsten und typischen Fehler analysieren. Ich würde mich freuen, wenn Sie Ihre Erfahrungen mit dem Programmierer teilen könnten, der weiß, was er beachten und was er in seinem Code behalten sollte.

1. Der Fehler der Division durch Null trat im realen Handelsmodus auf, obwohl die Division durch Null im Code nicht vorhanden war und bei Backtests nicht auftrat. Der Programmierer löste das Problem, indem er jeden Divisor als NormalizeDouble(x,Digits) schrieb;

2. Das Geschäft wurde nicht eröffnet. Am Freitag wurde das Geschäft eröffnet, als der Backtest lief, aber während des echten Handels wurde kein Geschäft eröffnet. Außerdem hat das Journal des Expert Advisors keine Fehler gezeigt. Ich weiß nicht, woran es liegen könnte, aber ich habe da ein paar Dinge. Zunächst erhielt ich Warnungen wie "Rückgabewert von 'ordersend' sollte überprüft werden", aber wenn ich richtig verstehe, sollte dies keinen Einfluss auf die Codeausführung haben? Oder geht es nur um Schlupf? Mein Wert ist 1, was nicht zu klein ist. Und der Balken, bei dem ich einen Einstieg vornehmen sollte, öffnete sich ohne Gap.

Ich habe die Zeile "if(Volume[0]>1) return;" aus dem Standardbeispiel mit Slips genommen und am Anfang des Codes eingefügt. Das heißt, mein Code wird nur während des ersten Ticks ausgeführt, wenn ein neuer Balken erscheint. Kann es sein, dass ein Bar mit einem Volumen eröffnet und mein Code nicht ausgeführt wird?

4. Bitte geben Sie Hinweise auf Dinge, die zu beachten sind, oder auf typische Fehler bei der Arbeit mit EA mit Historie und Echtzeit.


 
LuckySith:

Es haben sich eine Reihe von Fragen ergeben, ich hoffe sehr auf Ihre Hilfe. Ich habe die traurige Erfahrung gemacht, dass die Leistung von EA während der Tests und in Echtzeit sehr unterschiedlich ist, daher möchte ich die häufigsten und typischen Fehler analysieren. Ich würde mich freuen, wenn Sie Ihre Erfahrungen mit dem Programmierer teilen könnten, der weiß, worauf er achten muss und was er in seinem Code beibehalten sollte.

1. Der Fehler der Division durch Null trat im realen Handelsmodus auf, obwohl die Division durch Null im Code nicht vorhanden war und bei Backtests nicht auftrat. Der Programmierer löste das Problem, indem er jeden Divisor als NormalizeDouble(x,Digits) schrieb;

2. Das Geschäft wurde nicht eröffnet. Am Freitag wurde das Geschäft eröffnet, als der Backtest lief, aber während des echten Handels wurde kein Geschäft eröffnet. Außerdem hat das Journal des Expert Advisors keine Fehler gezeigt. Ich weiß nicht, woran es liegen könnte, aber ich habe da ein paar Dinge. Zunächst erhielt ich Warnungen wie "Rückgabewert von 'ordersend' sollte überprüft werden", aber wenn ich richtig verstehe, sollte dies keinen Einfluss auf die Codeausführung haben? Oder geht es nur um Schlupf? Mein Wert ist 1, was nicht zu klein ist. Und der Balken, bei dem ich einen Einstieg vornehmen sollte, öffnete sich ohne Gap.

Ich habe die Zeile "if(Volume[0]>1) return;" aus dem Standardbeispiel mit Slips genommen und am Anfang des Codes eingefügt. Das heißt, mein Code wird nur während des ersten Ticks ausgeführt, wenn ein neuer Balken erscheint. Kann es sein, dass ein Bar mit einem Volumen eröffnet und mein Code nicht ausgeführt wird?

4. Bitte geben Sie Hinweise auf Dinge, die zu beachten sind, oder auf typische Fehler bei der Arbeit mit EA mit Historie und Echtzeit, bitte

Ersetzen Sie dieses wilde Konstrukt "if(Volume[0]>1) return;" durch eine normale "New Bar"-Prüfung, das Forum ist voll davon.

Warnungen der Art "Rückgabewert von 'ordersend' sollte geprüft werden" sind noch keine Fehler, sondern potentielle Fehler für die Zukunft. Es sollte keine Warnungen im Code geben, schon gar nicht, wenn man online arbeitet.

"Ich habe 1, das ist nicht zu wenig" - das kann sehr wenig sein bei der Eröffnung eines neuen Taktes, und besonders bei der Eröffnung einer halben Stunde oder einer Stunde, zu dieser Zeit weitet sich der Spread stark aus.

Was wir brauchen: eine Überprüfung der neuen Bar zu tun, und wenn es neu ist, dann beobachten Sie die Bedingungen für die Einreise, wenn sie übereinstimmten - ein Geschäft machen. Danach müssen wir festhalten, dass die Leiste funktioniert hat und auf die neue warten.

Was wir jetzt haben: if(Volume[0]>1) return; = wenn es einen neuen Balken gibt, suchen wir nach Bedingungen, die Bedingung hat nicht gepasst == großer Spread = Exit wieder in OnTick(), beim nächsten Tick if(Volume[0]>1) return; es geht nicht weiter, also ist der Trade schon verpasst, auch wenn der Spread 0.0001 ist

 

Hallo. Können Sie mir bitte sagen, wie ich das Folgende mit dem Code beschreiben kann? Es gibt eine Ebene, die von einer oberen und einer unteren horizontalen Linie begrenzt wird. Der Expert Advisor erkennt und setzt sie selbst.

Der EA muss erkennen, wenn der Preis die flache Zone verlässt und dann in diese Zone zurückkehrt. Und erst danach wird eine Position eröffnet.

Um das Rauschen zu filtern, verwende ich ein bewegliches Ziel mit dem Parameter 2 oder 3

 
Vitaly Muzichenko:

Ersetzen Sie solche wilden Konstruktionen "if(Volume[0]>1) return;" durch normale "New Bar"-Prüfungen, davon gibt es hier im Forum genug.

Warnungen wie "Rückgabewert von 'ordersend' sollte geprüft werden" - dies ist noch kein Fehler, sondern ein potenzieller Fehler für die Zukunft. Es sollte keine Warnungen im Code geben, schon gar nicht, wenn man online arbeitet.

"Ich habe 1, das ist nicht zu wenig" - das kann sehr wenig sein bei der Eröffnung eines neuen Taktes, und vor allem bei der Eröffnung einer halben Stunde oder einer Stunde, zu diesem Zeitpunkt weitet sich der Spread stark aus.

Was wir brauchen: eine Überprüfung der neuen Bar zu tun, und wenn es neu ist, dann beobachten Sie die Bedingungen für die Einreise, wenn sie übereinstimmten - ein Geschäft machen. Danach müssen wir festhalten, dass die Leiste funktioniert hat und auf die neue warten.

Was wir jetzt haben: if(Volume[0]>1) return; = wenn es einen neuen Balken gibt, dann schauen Sie sich die Bedingungen an, die Bedingung passt nicht == großer Spread = Exit wieder in OnTick(), auf dem nächsten Tick if(Volume[0]>1) return; es wird nicht weiter verpassen, so wird der Handel verpasst werden, auch wenn der Spread 0,0001 ist


Über die Eröffnung einer neuen Bar. Wäre das gut? :

datetime counted_bar = 0;

int OnInit()
{
   counted_bar = 0; // если нужно, чтоб при перезапуске последний бар был проанализирован
   ...

void OnTick()
{
   // Если появился новый бар
   if ( iTime( _Symbol, _Period, 0 ) > counted_bar )
   {
      counted_bar = iTime( _Symbol, _Period, 0 );

      // Анализируем индикаторы
      ...
   }
 
LuckySith:

Über die Eröffnung einer neuen Bar. Wäre das eine gute Option? :

So soll es zunächst sein.

Als Nächstes müssen wir eine ordnungsgemäße Fixierung, dass die Bar ausgearbeitet ist, aber hier müssen wir die gesamte Annäherung an die TOR zu berechnen.

Soweit ich aus Ihrem Beitrag ersehen kann, müssen wir es so machen:

void OnTick()
{
   // Если появился новый бар
   if ( iTime( _Symbol, _Period, 0 ) > counted_bar )
   {
      // Анализируем индикаторы
      if(SpreadMax > текущий спред) return;

      counted_bar = iTime( _Symbol, _Period, 0 );
      ...
   }

Die Essenz ist folgende: Wenn der Spread höher als normal ist, dann gehen wir wieder zuOnTick, und bei einem neuen Tick überprüfen wir den Spread, wenn er normal ist - senden wir einen Auftrag und erinnern uns, dass es einen Handel auf diesem Balken gab.

Es gibt auch einen zweiten Weg:

void OnTick()
{
   // Если появился новый бар
   if ( iTime( _Symbol, _Period, 0 ) > counted_bar )
   {
      if(SpreadMax > текущий спред) return;
      // Анализируем индикаторы
      ...
      result = OrderSend(...);
      // если открылась позиция, то result будет тикет позиции
       if(result>0) counted_bar = iTime( _Symbol, _Period, 0 );
   }

Im Allgemeinen müssen Sie die Logik definieren, wann sie aufzeichnen soll, und nicht vor der Bildung eines "Neuen Balkens" erneut prüfen.

Grund der Beschwerde: