Diskussion zum Artikel "Wie man den Berechnungsblock eines Indikators in den Code eines Expert Advisors überträgt" - Seite 3

 

Ich habe beschlossen, Indicator.mqh, die für mich modifiziert wurde, mit anderen zu teilen. Vielleicht spart es jemandem Zeit, wenn er den Indikator in eine Klasse übersetzt.

Dateien:
 
MetaQuotes:

Der neue Artikel Implementierung von Indikatorberechnungen in den Code eines Expert Advisors wurde veröffentlicht:

Autor: Dmitriy Gizlyk

Ein Blick in die Vergangenheit.

In der Tat ein sehr interessanter Artikel! Solides und nettes Konzept... aber ich fürchte, es gibt einen Fehler in der verteilten Software, und es ist nicht gut, Fehler zu hinterlassen.


Methode GetData. Verteilter Code ist:

double CIndicator::GetData(const uint buffer_num,const uint shift)
  {
   if(!Calculate())
      return EMPTY_VALUE;
//---
   if((int)buffer_num>=m_buffers)
      return EMPTY_VALUE;
//---
   return ar_IndBuffers[buffer_num].At(m_data_len-shift);
  }

Korrigierter Code sollte sein:

double CIndicator::GetData(const uint buffer_num,const uint shift)
  {
   if(!Calculate())
      return EMPTY_VALUE;
//---
   if((int)buffer_num>=m_buffers)
      return EMPTY_VALUE;
//---
   return ar_IndBuffers[buffer_num].At(m_data_len-shift - 1);
  }

Array-Index beginnt bei 0 und letztes Element hat Index (m_data_len - 1) statt m_data_len, nicht wahr?

 

rf, Abschnitt Arbeiten mit benutzerdefinierten Indikatoren von https://www.mql5.com/de/articles/261

Use of Resources in MQL5
Use of Resources in MQL5
  • www.mql5.com
MQL5 programs not only automate routine calculations, but also can create a full-featured graphical environment. The functions for creating truly interactive controls are now virtually the same rich, as those in classical programming languages. If you want to write a full-fledged stand-alone program in MQL5, use resources in them. Programs with resources are easier to maintain and distribute.
 
Hallo und vielen Dank
 

Vielen Dank für diesen Artikel! Ich studiere ihn, um von instabilen konventionellen Indikatoren wegzukommen.

Aber es ist wichtig für mich, Indikatoren auf einem Diagramm visualisieren zu können. Hat es jemand implementiert?

 

Warum muss man überhaupt Berechnungen aus einem Indikator in einen Expert Advisor übertragen?

Viele Leute verwenden Indikatoren ganz ohne EA.

Sie können die Berechnungen einfach in Stufen aufteilen.

Zum Beispiel so:

//+------------------------------------------------------------------+
//|FutData.mq5 |
//|Copyright 2020 - 2021, prostotrader |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020-2021, prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.001"
//---
#property indicator_separate_window
#property indicator_plots   1
#property indicator_buffers 1
//---
enum IND_STAGE
{
  LOAD_TICKS = 0,
  READ_TICKS = 1,
  READ_DEALS = 2,
  FILL_DATA = 3
} stage;
//+------------------------------------------------------------------+
//| OnInit-Funktion für benutzerdefinierte Indikatoren|
//+------------------------------------------------------------------+
int OnInit()
{
  stage = LOAD_TICKS;  
//---
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Benutzerdefinierter Indikator Funktion "Zecken laden" |
//+------------------------------------------------------------------+
bool LoadTicks(const datetime &a_times[])
{
  return(false);
}
//+------------------------------------------------------------------+
//| Benutzerdefinierter Indikator Funktion "Primäre Ticks lesen" |
//+------------------------------------------------------------------+
bool ReadTicks()
{
  return(false);
}
//+------------------------------------------------------------------+
//| Benutzerdefinierter Indikator Funktion "Sekundäre Ticks lesen" |
//+------------------------------------------------------------------+
bool ReadDeals()
{
  return(false);
}
//+------------------------------------------------------------------+
//| Benutzerdefinierter Indikator Fülldatenfunktion |
//+------------------------------------------------------------------+
void FillData()
{
//---
}
//+------------------------------------------------------------------+
//| Benutzerdefinierter Indikator für die Funktion Berechnen |
//+------------------------------------------------------------------+
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[]  
)
{
    
  if(prev_calculated == 0)
  {
      switch (stage)
      {
        case LOAD_TICKS:
          if(LoadTicks(time) == true)
          {
            stage = READ_TICKS;
          }
          return(0);
        break;
        case READ_TICKS:
          if(ReadTicks() == true)
          {
            stage = READ_DEALS;
          }  
          return(0);
        break;
        case READ_DEALS:
          if(ReadDeals() == true)
          {
            stage = FILL_DATA;
          }  
          return(0);
        break;
        case FILL_DATA:
          stage = LOAD_TICKS;
        break;
      }
  }
  else
  {
    //
  }    
  //---
  return(rates_total);
}
//+------------------------------------------------------------------+
 
prostotrader #:

Warum muss ich Berechnungen aus einem Indikator in einen Expert Advisor übertragen?

Viele Leute verwenden Indikatoren, ohne einen Expert Advisor zu haben.

Sie können die Berechnungen einfach in Stufen unterteilen.

Zum Beispiel so:

Aufgrund der Tatsache, dass der reguläre Mechanismus der Indikatoren arbeitet durch einen Stumpf, zum Beispiel: https://www.mql5.com/ru/forum/372612 und dies ist aufgrund ihrer Umsetzung.

Mit der zunehmenden Komplexität der Indikatoren, mein Expert Advisor "verzettelt". Im Tester habe ich viele andere Fehler in der Arbeit der Indikatoren gefangen, aber ich habe sie nicht beschrieben, weil es nutzlos ist.

Ich habe Ihre Idee nicht verstanden.

Некорректная инициализация индикаторов в визуальном тестере
Некорректная инициализация индикаторов в визуальном тестере
  • 2021.07.04
  • www.mql5.com
Если делаю инициализацию индикаторов в OnInit() { } эксперта, то в визуальном тестере индикатор обычно не появляется и не отрисовывается...
 
Sunriser #:

Da der reguläre Indikatormechanismus über den Stumpf funktioniert, z.B.: https://www.mql5.com/ru/forum/372612 und dies ist auf ihre Umsetzung zurückzuführen.

Mit der zunehmenden Komplexität der Indikatoren hat sich mein Expert Advisor "verzettelt". Im Tester habe ich viele andere Fehler in der Arbeit der Indikatoren gefunden, aber ich habe sie nicht beschrieben, weil es nutzlos ist.

Ich habe Ihre Idee nicht verstanden.

Zunächst einmal ist Ihr Code nicht ganz korrekt.

Ich würde ihn so schreiben:

int OnInit()
  {int  TicksTesterIndicatorHandle = INVALID_HANDLE;
   bool InitComplite=false;
   if(IndicatorInitialization() == false) return(INIT_FAILED);
    return(INIT_SUCCEEDED);
 }
void OnDeinit(const int reason)
{
     if(TicksTesterIndicatorHandle != INVALID_HANDLE) IndicatorRelease(TicksTesterIndicatorHandle);
}
void OnTick()   { //if(!InitComplite)
 // { // IndicatorInitialisation();
 // }   } //+------------------------------------------------------------------+
bool IndicatorInitialization()
   { //---Get TicksTesterIndicator Indikator-Handle
    TicksTesterIndicatorHandle=iCustom(NULL, _Period, "OnInit_TestIndicator");
 //--- Es muss geprüft werden, ob ungültige Handle-Werte zurückgegeben wurden 
  if(TicksTesterIndicatorHandle == INVALID_HANDLE)
      {       Print("Fehler beim Erstellen des TicksTesterIndicator-Indikators - Fehlernummer: ",GetLastError(),"!!!");
      
   }
    else
      { 
      Print("TicksTesterIndicator initialisiert, Handle: ", TicksTesterIndicatorHandle);
       ArraySetAsSeries(Buf, true);
     InitComplite=true;
     return(true);
   }
    return(false);  
 }

Da die Funktionen in Indikatoren mit minimalen Verzögerungen ausgeführt werden sollen, werden komplexe Prozesse (Laden der Historie, komplexe Berechnungen usw.)

in mehrere Teile aufgeteilt werden, die zum

OnCalculate

Nullwert (return(0) ), d.h. der Indikator befindet sich in der Anfangsphase, bis wir alle notwendigen Aktionen mit minimalen Verzögerungen in jeder Phase durchführen.

 
В архитектуре MetaTrader 5 организован асинхронный доступ к значениям индикаторов. Иными словами, при получении хэндла индикатора он прикрепляется к графику. Далее этот индикатор производит свои расчеты вне потока советника. Они взаимодействуют лишь на этапе передачи данных, аналогично получению данных тайм-серий. Поэтому и время на выполнение этих операций сопоставимо.

Sie sagen also, dass es im wirklichen Leben schneller sein wird?! -Denn in Wirklichkeit wird es so sein. Experte in einer Spur, Indikator in einer anderen (und vielleicht sogar auf verschiedenen Kernen). Nur wenn man es in die serielle Verarbeitung steckt, wird es langsamer - aber das ist nur eine künstliche Einschränkung durch den Strategietester.

 
Ich habe nicht verstanden, aus dem Artikel, hat die Klasse-Indikator Schutz gegen fehlende Bars? Zum Beispiel gab es eine Verbindung Pause für 5 Bars, und dann die Geschichte geladen wurde, wird die Klasse-Indikator füllen nur den letzten Wert in der Bohrmaschine oder wird es eine vollständige Neuberechnung tun?