[SOLVED] Indikatoren werden nicht richtig instanziiert, wenn sie von einem Indikator mit einem anderen Zeitrahmen aufgerufen/erzeugt werden. - Seite 3

 
Stanislav Korotky:
Stellen Sie eine spezifischere Frage mit einem Beispielcode. Es kann fehlerhaft sein. Der Ansatz funktioniert für mich.

Hier ein Codebeispiel für einen fehlgeschlagenen Indikatorzugriff. Selbst nach einer Schleife, einem Refreshing und einer Wartezeit (zwei verschiedene Methoden des Wartens).

//+------------------------------------------------------------------+
//|                                                    THROWAWAY.mq5 |
//|                                                      nicholishen |
//|                                   www.reddit.com/u/nicholishenFX |
//+------------------------------------------------------------------+
#property copyright "nicholishen"
#property link      "www.reddit.com/u/nicholishenFX"
#property version   "1.00"
#property indicator_chart_window

#include <Indicators\Trend.mqh>
#include <errordescription.mqh>

CiMA ima;
int m_bufferSize = -1;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   static int iCnt = 0;
//--- indicator buffers mapping
      Print("-----------------------",TimeCurrent(),"--------------------------");
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
   static int tickCnt = 0;
   tickCnt++;
//---
   if(rates_total != prev_calculated || m_bufferSize < 1 ){
      ResetLastError();
      datetime createTime = TimeCurrent();
      ima.Create(_Symbol,PERIOD_H1,20,0,MODE_SMA,PRICE_CLOSE);
      ima.Refresh(); //no wait time!
          
      CIndicatorBuffer *buff = ima.At(0);
      m_bufferSize = buff.Total();
      int call = 0;
      int sleep = 200;
      // try with Sleep function ...
      while(buff.Total() <= 0 && call < 10){
         Sleep(sleep);
         ima.Refresh(); // Refreshed 10x since create
         m_bufferSize = buff.Total();
         call++;
         Print(__LINE__," ",__FUNCTION__," ",buff.Name(),
               " Buffer size = ",m_bufferSize," | Call (",
               call,")"," Sleep(",sleep,")"
               );
         sleep+=100;
        
      }
      // try wait with looping  
      if(buff.Total() <=0){
         datetime waitTime = timeLoop(createTime);
         Print("Time Between Create and Refresh() = ",TimeToString(waitTime,TIME_SECONDS));
         ima.Refresh();
         m_bufferSize = buff.Total();
      }
      if(m_bufferSize < 1){
         Print(ErrorDescription(GetLastError()));
         return(rates_total);
      } else {
         for(int i=0;i<m_bufferSize;i++){
            if(i>2return(rates_total);
            else{
               Print(__LINE__," ",__FUNCTION__,buff.Name(),
                     " Buffer size = ",m_bufferSize,
                     " | ",ima.PeriodDescription()," iMA(",i,") value = ",
                     DoubleToString(ima.Main(i),_Digits),
                     " | Tick-count = ",tickCnt
                     );  
            }
         }
      }
   }
//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason){

}

datetime timeLoop(datetime timeIn){
   int cnt = 0;
   while(TimeCurrent() - timeIn < 10 && !IsStopped()){
      Comment("Time looping i = ",cnt);
      cnt++;
   }
   return TimeCurrent() - timeIn;
}

Und hier ist die Ausgabe:

-----------------------2017.01.31 23:48:03--------------------------


60 OnCalculate MAIN_LINE Puffergröße = -1 | Call (1) Sleep(200)

60 OnCalculate MAIN_LINE Puffergröße = -1 | Aufruf (2) Sleep(300)

60 OnCalculate MAIN_LINE Puffergröße = -1 | Aufruf (3) Sleep(400)

60 OnCalculate MAIN_LINE Puffergröße = -1 | Aufruf (4) Sleep(500)

60 OnCalculate MAIN_LINE Puffergröße = -1 | Aufruf (5) Sleep(600)

60 OnCalculate MAIN_LINE Puffergröße = -1 | Aufruf (6) Sleep(700)

60 OnCalculate MAIN_LINE Puffergröße = -1 | Aufruf (7) Sleep(800)

60 OnCalculate MAIN_LINE Puffergröße = -1 | Aufruf (8) Sleep(900)

60 OnCalculate MAIN_LINE Puffergröße = -1 | Aufruf (9) Sleep(1000)

60 OnCalculate MAIN_LINE Puffergröße = -1 | Aufruf (10) Sleep(1100)

Zeit zwischen Erstellen und Aktualisieren() = 00:00:11

Angeforderte Daten nicht gefunden

81 OnCalculateMAIN_LINE Puffergröße = 1024 | H1 iMA(0) Wert = 113.227 | Tick-Zahl = 2

81 OnCalculateMAIN_LINE Puffergröße = 1024 | H1 iMA(1) Wert = 113.269 | Tick-Zahl = 2

81 OnCalculateMAIN_LINE Puffergröße = 1024 | H1 iMA(2) Wert = 113.313 | Tick-Zahl = 2

















 
nicholishen:

Hier ein Codebeispiel für einen fehlgeschlagenen Indikatorzugriff. Selbst nach einer Schleife, einem Refreshing und einer Wartezeit (zwei verschiedene Methoden des Wartens).

         Sleep(sleep);


Sleep wird bei einem Indikator nicht funktionieren; Sie können den Schnittstellen-Thread nicht unterbrechen.

Versuchen Sie es stattdessen mit OnTimer().

 
honest_knave:

Sleep wird bei einem Indikator nicht funktionieren; Sie können den Schnittstellen-Thread nicht unterbrechen.

Versuchen Sie es stattdessen mit OnTimer().

Das war's! Das ist der Workaround! Ich könnte dich küssen, Mann!

Dadurch kann OnInit() zur Plattform zurückkehren und OnTimer() übergehen und den zweiten Durchlauf aufrufen. Ich habe EventSetMillisecondTimer auf nur 1ms gesetzt und nur einmal aufgerufen und jetzt funktioniert es.

//+------------------------------------------------------------------+
//|                                                    THROWAWAY.mq5 |
//|                                                      nicholishen |
//|                                   www.reddit.com/u/nicholishenFX |
//+------------------------------------------------------------------+
#property copyright "nicholishen"
#property link      "www.reddit.com/u/nicholishenFX"
#property version   "1.00"
#property indicator_chart_window

#include <Indicators\Trend.mqh>
#include <errordescription.mqh>

CiMA ima;
int m_bufferSize = -1;
bool timedEvent = false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
      int waitMS = 1;
      Print("-----------------------",TimeCurrent(),"--------------------------");
  
      ima.Create(_Symbol,PERIOD_H1,20,0,MODE_SMA,PRICE_CLOSE);
      EventSetMillisecondTimer(waitMS);
      Print("OnTimer set to ",waitMS," ms");
      
//---
   return(INIT_SUCCEEDED);
  }

void OnTimer()
  {
//---
   ima.Refresh();
   EventKillTimer();
   timedEvent = true;
  
  }
//+------------------------------------------------------------------+
//| 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[])
  {

   static int tickCnt = 0;
   tickCnt++;
  
   if(!timedEvent)return rates_total;
//---
   if(rates_total != prev_calculated || m_bufferSize < 1 ){
      ResetLastError();
      CIndicatorBuffer *buff = ima.At(0);
      m_bufferSize = buff.Total();
      if(m_bufferSize <=0) ima.Refresh();
      // try wait with looping  
      
      if(m_bufferSize < 1){
         Print(ErrorDescription(GetLastError()));
        
      } else {
         for(int i=0;i<m_bufferSize;i++){
            if(i>2) break;
            else{
               Print(__LINE__," ",__FUNCTION__,buff.Name(),
                     " Buffer size = ",m_bufferSize,
                     " | ",ima.PeriodDescription()," iMA(",i,") value = ",
                     DoubleToString(ima.Main(i),_Digits),
                     " | Tick-count = ",tickCnt
                     );  
            }
         }
      }
   }
//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+


Ausgabe:

-----------------------2017.02.01 01:31:01--------------------------

OnTimer auf 1 ms eingestellt

75 OnCalculateMAIN_LINE Puffergröße = 1024 | H1 iMA(0) Wert = 113.142 | Tick-Zahl = 2

75 OnCalculateMAIN_LINE Puffergröße = 1024 | H1 iMA(1) Wert = 113.181 | Tick-Zählung = 2

 
nicholishen:

Das war's! Das ist die Abhilfe! Ich könnte dich küssen, Mann!

Kein Problem, ich akzeptiere Banküberweisungen und alle gängigen Kreditkarten... 100 Dollar waren es doch, oder?
 
nicholishen:

Das war's! Das ist die Abhilfe! Ich könnte dich küssen, Mann!

Cool!

Ich habe dir vorgeschlagen, einen Timer zu benutzen. Du hast geantwortet, dass das bei dir nicht funktioniert hat. Ich habe dich um ein Beispiel gebeten, was du ausprobiert hast. Aber du sagtest, du kannst nicht mehr Details posten, als du bereits getan hast.

Jetzt hat dir ein anderer Mann den Timer vorgeschlagen und du scheinst damit zufrieden zu sein ;-)

 
Stanislav Korotky:

Super!

Ich habe dir vorgeschlagen, einen Timer zu benutzen. Du hast geantwortet, dass das bei dir nicht funktioniert hat. Ich habe dich um ein Beispiel gebeten, was du ausprobiert hast. Aber du sagtest, du kannst nicht mehr Details posten, als du schon getan hast.

Jetzt hat dir ein anderer Mann den Timer vorgeschlagen und du scheinst damit zufrieden zu sein ;-)

Hey! Hören Sie auf, sich in meine 150 Dollar einzumischen!
 
Stanislav Korotky:

Super!

Ich habe dir vorgeschlagen, einen Timer zu benutzen. Du hast geantwortet, dass das bei dir nicht funktioniert hat. Ich habe dich um ein Beispiel gebeten, was du ausprobiert hast. Aber du sagtest, du kannst nicht mehr Details posten, als du schon getan hast.

Jetzt hat dir ein anderer Mann den Timer vorgeschlagen und du scheinst damit zufrieden zu sein ;-)

Und wir haben jetzt einen MT5-Fehler behoben...
 
honest_knave:
Kein Problem, ich akzeptiere Banküberweisungen und alle gängigen Kreditkarten... $100 war es nicht?

$100?! ...Ich dachte, ich biete mehr...

Forum über Handel, automatisierte Handelssysteme und das Testen von Handelsstrategien

[MQL5 BUG] [SOLVED]Indikatoren werden nicht richtig instanziiert, wenn sie von einem Indikator eines anderen Zeitrahmens aufgerufen/erzeugt werden.

Stanislav Korotky, 2017.02.01 09:27

Cool!

Ich habe Ihnen vorgeschlagen, einen Timer zu verwenden. Sie haben mir geantwortet, dass es bei Ihnen nicht funktioniert hat. Ich habe Sie um ein Beispiel gebeten, das Sie ausprobiert haben. Aber du hast gesagt, du kannst nicht mehr Details posten, als du schon getan hast.

Jetzt hat dir ein anderer Mann den Timer vorgeschlagen und du scheinst damit zufrieden zu sein ;-)


Tut mir leid, dass ich bis jetzt nicht verstanden habe, was du damit meinst. Ich betrachte euch als Partner von knave, und da niemand ein funktionierendes Modell gepostet hat, werde ich entscheiden, dass das Kopfgeld 50% betragen wird - geteilt durch zwei: Das heißt also... hm... die beiden tragen... Wie wäre es, wenn ich euch beiden ein Bier spendiere? Im Ernst: Schickt mir eine BTC-Adresse und ich sorge dafür, dass ihr beide entschädigt werdet :)

Ich möchte mich ganz besonders bei Ihnen für Ihre Hilfe bedanken... wenn Sie nicht so herablassend wären, wüsste ich nicht, woher ich die Motivation zum Weitermachen genommen hätte! /s

 
nicholishen:

Im Ernst, PM mir eine BTC-Adresse und ich werde sicherstellen, dass Sie beide entschädigt werden :)

ein großzügiges Angebot, aber unnötig. Schön, dass Sie es geregelt haben.
 
Ich schließe die Sache mit dem Service Desk ab, aber falls MetaQuotes dies liest, halte ich dies immer noch für einen großen Fehler in der Plattform. Wenn dies ein Problem mit dem Threading ist, sollte es einen besseren Weg geben, diese Art von Ereignissen zu behandeln, als willkürlich eine (geschätzte) Wartezeit in den Code einzubauen.
Grund der Beschwerde: