Weiß jemand, wie man einen Multicurrency-Indikator entwickelt? - Seite 3

 
4x_Gypsy:

Großer Hinweis war "Aber ich weiß nicht, wie man das macht.".

Das Ausbleiben jeglicher Reaktion seitens des Auftraggebers ist ein Hinweis darauf, dass etwas nicht stimmt. Meine "Vermutung" ist, dass der Betreiber aufgrund des mangelnden Verständnisses frustriert war und den Thread aufgegeben hat. Es gab eine Zeit, vor Jahren, als ich das Gleiche tat. Ich habe auf anderen Websites/Foren mehr gelernt als in diesem Forum, weil sich niemand die Zeit nahm, zu erkennen, wie neu ich war, und ständig Beispiele gepostet und Diskussionen geführt hat, die über mein damaliges Verständnis hinausgingen.

Aus deiner Sicht magst du Recht haben, andererseits habe ich viele viele Fragen gesehen, die einfach beantwortet wurden, wenn man nur einen kurzen Blick in die Dokumentationen riskiert und man fühlt sich wirklich wie ein Narr, wenn man diese Fragen immer wieder beantwortet.

Außerdem gibt es hier google und eine Suchoption. Wenn ich nicht weiß, wie man etwas macht, ist das mein nächster Schritt, das Problem selbst zu lösen.

Im Falle des Themas dieses Threads, dass ich nicht weiß, wie man ein Mehrwährungssystem programmiert, hätte ich auf google geantwortet oder hier nach bereits existierendem Code gesucht.

 
gooly:

Aus deiner Sicht magst du Recht haben, andererseits habe ich viele Fragen gesehen, die einfach beantwortet wurden, wenn man nur einen kurzen Blick in die Dokumentationen riskiert und man fühlt sich wirklich wie ein Narr, wenn man diese Fragen immer wieder beantwortet.

Außerdem gibt es hier google und eine Suchoption. Wenn ich nicht weiß, wie man etwas macht, ist das mein nächster Schritt, das Problem selbst zu lösen.

Im Falle des Themas dieses Threads weiß ich nicht, wie man ein Mehrwährungssystem programmiert, ich hätte auf Google geantwortet oder hier nach bereits vorhandenem Code gesucht.

Vielen Dank für das Feedback, und schön, dass es positiv war. lol

Ich entschuldige mich bei allen, die es betrifft, für die Art und Weise, wie ich in dieser Situation rüberkam. Ich bin wirklich eine friedliebende, dramafreie Person, die normalerweise die meisten Dinge ignoriert, mit denen ich nicht einverstanden bin.

 

Hallo Leute,

Sorry für die lange Zeit ohne Aktivität hier. Ich war auf der Reise zur Arbeit und auch mit einigen Projekten beschäftigt und musste das Projekt für eine Weile beiseite lassen ...

Nachdem ich die Post Updates gelesen habe, habe ich einige Punkte zu klären:

  1. Ich möchte nicht, dass jemand alles für mich programmiert, ich brauche nur die richtige Richtung zu zeigen und ich mache den Rest. Nun... ich werde die WHRoeder Lösung jetzt testen und meine Sachen machen und später das Ergebnis hier posten. WHRoeder-Vorschlag:https://www.mql5.com/en/forum/158938
  2. Bevor ich dieses Thema erstellt habe, habe ich nach ähnlichen Beiträgen gesucht, aber nichts gefunden... dann habe ich es erstellt
  3. Es tut mir leid, dass ich so lange gebraucht habe, um zu antworten, aber ich war wirklich überarbeitet, aber jetzt arbeite ich weiter an dem Indikator.
  4. Sorry für mein schlechtes Englisch! meine Sprache ist Portugiesisch und wenn ich Englisch posten, müssen Google Übersetzer verwenden und es ist nicht perfekt.


 
Hier mein Test.

Erlauben Sie einfach Benutzern, ihre Vermögenswerte zu informieren, und nach, zeigen die alle Paare High/Low-Werte.

Wenn eines der ausgewählten Paare mit dem aktiven Fenster übereinstimmt, werden die Kurse problemlos aktualisiert. Aber andere Paare zeigen nur die Kurse, wenn der Indikator hinzugefügt wurde... und nicht mehr aktualisiert...

Wie Sie auf dem Bild unten sehen können, wurde der Indikator im GBPUSD-Fenster hinzugefügt... und die GBPUSD-Kurse wurden problemlos Tick für Tick aktualisiert. Aber EURUSD wird nicht aktualisiert und hat immer noch den gleichen Wert.

Preise kopiert


Unten, der Indikator-Code:

//+------------------------------------------------------------------+
//|                                                MultiCurrency.mq4 |
//|                         Copyright 2016, Wemerson Couto Guimarães |
//|                  https://www.mql5.com/pt/users/wemersonrv/seller |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Wemerson Couto Guimarães"
#property link      "https://www.mql5.com/pt/users/wemersonrv/seller"
#property version   "1.00"
#property strict
#property indicator_separate_window

input string UsePairs="EURUSD,GBPUSD"; // Pares separados por vírgula.

struct pair_struct{
   string symbol;
   MqlRates rates[];
};
pair_struct pairs[];
bool initial;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(){
   int i=0, j=0, c;
   string _pairs[], msg="";
   bool pairok=false;
   initial = true;
   ENUM_INIT_RETCODE result = INIT_SUCCEEDED;
   
   StringSplit(UsePairs, StringGetCharacter(",",0), _pairs);
   
   for( i=0; i< ArraySize(_pairs); i++){
      pairok=false;
      
      for( j=0; j<SymbolsTotal(true); j++){
         if( SymbolName(j, true) == _pairs[i]){
            pairok=true;
            break;
         }
      }
      if( pairok ){
         c=ArraySize(pairs);
         ArrayResize(pairs, c+1);
         pairs[c].symbol = _pairs[i];
      }else{
         msg += _pairs[i] + ", ";
      }
   }
   if( msg != "" ){
      string invalids = ArraySize(pairs)== 1?"Invalid Pair: ": "Invalid Pairs: ";
      msg = invalids +  StringSubstr(msg,0,StringLen(msg)-2) + ". Please Check!";
      Alert(msg);
      result = INIT_PARAMETERS_INCORRECT;
   }else{
      for(i=0; i<ArraySize(pairs); i++){
         ArrayCopyRates( pairs[i].rates, pairs[i].symbol, PERIOD_CURRENT );
      }
   }   
   
   return(result);

}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason){
   
   Comment("");
   
}

//+------------------------------------------------------------------+
//| 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[])
  {

   int i=0;
   if( initial ){
      for( i=0; i<ArraySize(pairs); i++){
         if(pairs[i].rates[0].time == 0) return(rates_total);
      }
      initial=false;
   }
   
   string log="";
   
   for(i=0; i<ArraySize(pairs); i++){
      log += "\nPair: " + pairs[i].symbol + 
             " - High: "+ DoubleToStr(pairs[i].rates[0].high, Digits()) + 
             " - Low: "+ DoubleToStr(pairs[i].rates[0].low, Digits());
   }

   Comment( "\n\n*** Pair Rates***\n" + log );
   return(rates_total);
   
}
//+------------------------------------------------------------------+

 
Ich versuche, RefreshRates() zu verwenden, aber immer noch mit dem gleichen Ergebnis... nur das Paar am gleichen Fenster funktioniert, andere Paare nicht aktualisiert.
 
wemersonrv:
Ich habe versucht, RefreshRates() zu verwenden, aber immer noch mit dem gleichen Ergebnis... nur das Paar am gleichen Fenster funktioniert, andere Paare werden nicht aktualisiert.

RefreshRates() hat nichts mit den MqlRates-Daten zu tun. Der Beispielcode von WHRoeder ist nur für die Pre-600-Builds gültig. Für die neuesten Builds müssen Sie die verschiedenen in meinem Beitrag erwähnten Punkte überprüfen, z. B. die Rückgabewerte von ArrayCopyRates() sowie die Fehlercodes, die Größe des Raten-Arrays und - als zusätzliche Vorsichtsmaßnahme, auf die WHRoeder hingewiesen hat - die Gültigkeit des Zeitattributs.

PS! Wenn Sie Schwierigkeiten mit Englisch haben, schicken Sie mir eine PM. Ich bin Portugiese (Portugal)

 

Hallo Leute.

Testen, ich enthalten eine "recopy" von Raten in OnCalculate Funktion... durch das Hinzufügen einer Schleife, die erste FREE das Array von Paar in allen Iterationen, dann kopieren Sie die Preise wieder. Das scheint zu funktionieren und gibt keinen Fehler zurück.

Ich weiß nicht, ob dies der beste Weg, um zu tun, was ich brauche, aber anscheinend ist es funktioniert und ohne erros.


   int i=0;
   if( initial ){
      for( i=0; i<ArraySize(pairs); i++){
         if(pairs[i].rates[0].time == 0) return(rates_total);
      }
      initial=false;
   }

   // My change to recopy rates every tick by adding a loop at starting of OnCalculate() to do this
   // AS FMIC says, ArrayCopyRates needs the array without content, 
   // then before recopy, free the array.
   for(i=0; i<ArraySize(pairs); i++){
      ArrayFree(pairs[i].rates);
      ArrayCopyRates(pairs[i].rates, pairs[i].symbol, PERIOD_CURRENT);
   }
 
wemersonrv: Beim Testen habe ich eine "erneute Kopie" der Raten in die OnCalculate-Funktion eingefügt... indem ich eine Schleife hinzugefügt habe, die zuerst das Array der Paare in allen Iterationen FREI macht und dann die Raten erneut kopiert. Scheint zu funktionieren und gibt keinen Fehler zurück.
  1. Wie in der Dokumentation angegeben.
    Wenn Daten (Symbolname und/oder Zeitrahmen unterscheiden sich von den aktuellen) von einem anderen Diagramm angefordert werden, ist es möglich, dass das entsprechende Diagramm nicht im Client-Terminal geöffnet wurde und die erforderlichen Daten vom Server angefordert werden müssen. In diesem Fall wird der Fehler ERR_HISTORY_WILL_UPDATED (4066 - die angeforderten History-Daten werden gerade aktualisiert) in der last_error-Variable abgelegt, und man muss die Daten erneut anfordern.
    Und hier verifiziert
    ArrayCopyRates gibt einen Fehler zurück, wenn keine History-Daten vorhanden sind (ERR_NO_HISTORY_DATA = 4073.) Wiederholte Aufrufe schlagen ebenfalls fehl, bis der Download abgeschlossen ist. Wenn es eine Historie gibt, die aber nicht aktuell ist, gibt ArrayCopyRates einen gültigen Wert zurück und setzt außerdem `_LastError` auf ERR_HISTORY_WILL_UPDATED (= 4066.)
  2. Testen Sie Ihren Rückgabewert, schlafen Sie und versuchen Sie es erneut, wenn nötig. Was sind Funktionsrückgabewerte? Wie verwende ich sie? - MQL4-Forum und häufige Fehler in MQL4-Programmen und wie man sie vermeidet - MQL4-Artikel
 

Ein Update für alle, die diesen Thread verfolgen!

Ich habe dem OP per PM geholfen, seinen Code zu korrigieren, da er Schwierigkeiten mit Englisch hat und wir beide Portugiesisch sprechen. Bei unseren Tests sind wir auf ein weiteres "komisches" Problem gestoßen, das mit der Funktion"ArrayCopyRates()" auftritt. Wenn man ein MqlRates-Array mit"ArrayCopyRates()" in einem EA verwendet, ist das Daten-Array ein virtuelles Array, das immer den aktuellen Stand der Dinge meldet, so dass die Daten immer frisch sind.

In einem Indicator scheint dies jedoch nicht der Fall zu sein. Das Array ist keine virtuelle Kopie, sondern eine statische Kopie, die zum Zeitpunkt des Aufrufs von"ArrayCopyRates()" festgelegt wurde. Die Daten werden nicht aktualisiert, wenn das Symbol nicht mit dem Diagrammsymbol übereinstimmt. Wenn es sich um dasselbe Symbol wie das Diagramm handelt, dann sind die Array-Daten "live" und werden wie erwartet aktualisiert, aber wenn es sich um ein anderes Symbol handelt, ist es eine statische Kopie.

Damit dies in einem Indikator funktioniert, muss die Funktion "ArrayCopyRates()" bei jedem Aufruf des Ereignisses OnCalculate() aufgerufen werden, wenn neue Daten benötigt werden.

 

Hallo zusammen.

  • FMIC, danke für deine Unterstützung !
  • WHRoeder, auch Dir vielen Dank... Du bist immer für uns alle da!
  • Danke an alle Forumsmitglieder für eure Überlegungen und auch für die ganze Debatte, die in diesem Thread entstanden ist. Es war sehr interessant!

Das ist (fast) das Gleiche, was ich später mache, aber der Unterschied ist, dass ich ein ArrayFree vor ArrayCopyRates laufen lasse... und ich mache nicht die Überprüfungen, bei denen Sie mir geholfen haben.

Hier der endgültige Code, bei dem mir FMIC geholfen hat. Es funktioniert jetzt normal in einem Indikator-Code..:

input string UsePairs="NZDCAD,EURUSD,GBPUSD,USDJPY"; // pairs separated by commas
struct pair_struct{
   string symbol;
   MqlRates rates[];
   bool valid;
};
pair_struct pairs[];
bool initial;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(){
   
   int i=0, j=0, c;
   string _pairs[], msg="";
   bool pairok=false;
   initial = true;
   ENUM_INIT_RETCODE result = INIT_SUCCEEDED;
   
   StringSplit(UsePairs, StringGetCharacter(",",0), _pairs);
   
   for( i=0; i< ArraySize(_pairs); i++){
      pairok=false;
      
      for( j=0; j<SymbolsTotal(true); j++){
         if( SymbolName(j, true) == _pairs[i] ){
            pairok=true;
            break;
         }
      }
      if( pairok ){
         c=ArraySize(pairs);
         ArrayResize(pairs, c+1);
         pairs[c].symbol = _pairs[i];
         pairs[c].valid = false;
      }else{
         msg += _pairs[i] + ", ";
      }
   }
   if( msg != "" ){
      string invalids = ArraySize(pairs)== 1?"Invalid Pair: ": "Invalid Pairs: ";
      msg = invalids +  StringSubstr(msg,0,StringLen(msg)-2) + ". Please Check!";
      Alert(msg);
      result = INIT_PARAMETERS_INCORRECT;
   }
   return(result);

}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason){
   
   Comment("");
   
}

//+------------------------------------------------------------------+
//| 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[])
  {

   InitializeRates();
   
   int i=0;
   string log="";
   for(i=0; i<ArraySize(pairs); i++){
      log += "\nPar: " + pairs[i].symbol;
      if( pairs[i].valid ){
         log += " - Time: "+ TimeToString( pairs[i].rates[0].time ) + 
                " - Open: "+ DoubleToString( pairs[i].rates[0].open, (int)MarketInfo( pairs[i].symbol, MODE_DIGITS ) ) +
                " - Close: "+ DoubleToString( pairs[i].rates[0].close, (int)MarketInfo( pairs[i].symbol, MODE_DIGITS ) ) +
                " - High: "+ DoubleToString( pairs[i].rates[0].high, (int)MarketInfo( pairs[i].symbol, MODE_DIGITS ) ) +
                " - Low: "+ DoubleToString( pairs[i].rates[0].low, (int)MarketInfo( pairs[i].symbol, MODE_DIGITS ) );
      }else{
         log += " - Currently not valid!";
      }
   }

   Comment( "\n\n*** Pair Rates***\n" + log );
   return(rates_total);
   
}
//+------------------------------------------------------------------+

void InitializeRates(){
 
   for( int i=0; i<ArraySize( pairs ); i++ ){
      pairs[i].valid = false;
      ResetLastError();
      if( ArrayCopyRates(pairs[i].rates, pairs[i].symbol, PERIOD_CURRENT) > 0 ){
         if( _LastError == 0 ){
            if( ArraySize(pairs[i].rates) > 0 ){
               if( pairs[i].rates[0].time > 0 )
                  pairs[i].valid = true;
            }
         }
      }
   }

}
Grund der Beschwerde: