Hilfe zu Ermittlung Bandbreite High-Low für EA

 

Hallo zusammen,

nach längerer Pause habe ich begonnen, meinen MT5 anzuwerfen und meine EAs zu verbessern. Meine bisherigen Kenntnisse habe ich aus dem Buch „Expert Advisor Programming for MetaTrader 5“ und bin damit bisher ganz gut zurecht gekommen, bin aber eher ein Programmierlaie.

Nun möchte ich eine Funktion erstellen, um für einen Zeitraum von n Bars die maximale Bandbreite zwischen dem jeweiligen Hoch und dem Tief pro Bar zu ermitteln.

Also nicht das Maximale Hoch für n Bars und das minimale Tief für n Bars.

Hat jemand einen Tip, wie ich das anstellen oder einen Link, den ich mir ansehen kann ? Ich vermute (bzw. befürchte), dass ein Array dafür erforderlich ist, habe aber keine Ahnung, wie das gehen könnte, da die mir bekannten „copy“ Funktionen jeweils nur die Hoch bzw. Tiefkurse verfügbar machen, nicht aber die Differenz, bzw. habe es bisher nicht gefunden.  

Vielen Dank für Eure Unterstützung !

 

ich bin mir nicht sicher ob du das meinst, aber die Bandbreite einer Kerze ist doch

Hoch[i] - Tief[i]

Du brauchst ja nur x Kerzen das hoch und tief nehmen und schauen wo es am weitestens auseinanderliegt

 
amando:

ich bin mir nicht sicher ob du das meinst, aber die Bandbreite einer Kerze ist doch

Hoch[i] - Tief[i]

Du brauchst ja nur x Kerzen das hoch und tief nehmen und schauen wo es am weitestens auseinanderliegt

Hallo amando,

sorry für die verspätete Antwort.

Das ist richtig. Aber angenommen,Bandbreite [i] = Hoch[i]-Tief[i], wie ermittle ich die maximale Bandbreite, wenn [i] = 10, ohne über "if" die jeweiligen Werte miteinander zu vergleichen. 

Ich denke also an eine Funktion "HighestRange()", mir ist aber unklar, wie ich das hinbekommen kann. MathMax lässt z.B. nur den Vergleich von zwei Werten zu.

 

Du kannst eine schleife nehmen, und schreibst den höchsten wert weiter

Zuerst definierst du eine Variable für die range

double range =0;

dann die schleife

for(int i=0;...

{

If high-low > range

  range = high-low

}


mehr ist es eigentlich nicht.

da ich am tablett schreibe musst den code selbst vervollständigten

 
amando:

Du kannst eine schleife nehmen, und schreibst den höchsten wert weiter

Zuerst definierst du eine Variable für die range

double range =0;

dann die schleife

for(int i=0;...

{

If high-low > range

  range = high-low

}


mehr ist es eigentlich nicht.

da ich am tablett schreibe musst den code selbst vervollständigten

Hallo amando,

danke, das ist eine gute Anregung.

Ich habe es versucht, scheitere aber kläglich:

double range =0; 
int Anzahl;
double high;
double low;

for(Anzahl=1;Anzahl<=10;Anzahl++) //Range über Anzahl = 10 Bars
{
  if (high(Anzahl)-low(Anzahl) > range)
   {
   range = high(Anzahl)-low(Anzahl);
   }
}
Print("Die max. Bandbreite beträgt "+range); //Zur Kontrolle

Fehlermeldungen: "Unbalanced left parenthesis", "Anzahl: Some operator expected", " ')' Unexpected token etc.

Es ist sicher nur eine Kleinigkeit wg. unzutreffender Variablendeklaration...

Für einen kleinen Hinweis, wo der Fehler liegt, bin ich dankbar !

 
TraderMQL:

Hallo amando,

danke, das ist eine gute Anregung.

Ich habe es versucht, scheitere aber kläglich:

Fehlermeldungen: "Unbalanced left parenthesis", "Anzahl: Some operator expected", " ')' Unexpected token etc.

Es ist sicher nur eine Kleinigkeit wg. unzutreffender Variablendeklaration...

Für einen kleinen Hinweis, wo der Fehler liegt, bin ich dankbar !

Ja du hast die variablen high und low deklariert, aber wo bekommen die den wert her?

die musst du dir zuerst mit MqlRates erzeugen

 
amando:

Ja du hast die variablen high und low deklariert, aber wo bekommen die den wert her?

die musst du dir zuerst mit MqlRates erzeugen


Sie müssten den Wert aus dem Include-File "price.mqh" beziehen, welcher meinem "Muster-" EA zugrundeliegt:

#define MAX_BARS 100                    // Max bars of rate data to retrieve

{
        public:
                CBars(void);
                MqlRates bar[];
                void Update(string pSymbol, ENUM_TIMEFRAMES pPeriod);
                double Close(int pShift);
                double High(int pShift);
                double Low(int pShift);
                double Open(int pShift);
                datetime Time(int pShift);
                long TickVolume(int pShift);
                long Volume(int pShift);
};

CBars::CBars(void)
{
        ArraySetAsSeries(bar,true);
}

void CBars::Update(string pSymbol,ENUM_TIMEFRAMES pPeriod)
{
        CopyRates(pSymbol,pPeriod,0,MAX_BARS,bar);
}

double CBars::High(int pShift=0)
{
        return(bar[pShift].high);
}
double CBars::Low(int pShift=0)
{
        return(bar[pShift].low);
}

Eigentlich müsste es funktionieren, auch die Anzahl 100 ist ausreichen.

Der Fehler liegt vermutlich darin, dass ich als Newbie "High" und "Low" auf dieser Basis nicht richtig deklariert habe....
 
TraderMQL:


Sie müssten den Wert aus dem Include-File "price.mqh" beziehen, welcher meinem "Muster-" EA zugrundeliegt:

Eigentlich müsste es funktionieren, auch die Anzahl 100 ist ausreichen.

Der Fehler liegt vermutlich darin, dass ich als Newbie "High" und "Low" auf dieser Basis nicht richtig deklariert habe....

Dasist aber schon mit kanonen auf spatzen schiessenum die paar werte zu bekommen.

ich würde MqlRates verwenden, die 10 Werte in die ausgabe und das dann wirklich nur durchlaufen lassen. Das include ist ja schön, aber für die Anwendung etwas zu weit gegriffen in meinen augen

 
amando:

Dasist aber schon mit kanonen auf spatzen schiessenum die paar werte zu bekommen.

ich würde MqlRates verwenden, die 10 Werte in die ausgabe und das dann wirklich nur durchlaufen lassen. Das include ist ja schön, aber für die Anwendung etwas zu weit gegriffen in meinen augen

Hallo amando,


das mag sein, aber ich möchte gerne in den bereits vorhandenen Strukturen arbeiten, um es -für mich- "einfach" zu halten. Die Daten sind ja bereits vorhanden und werden an anderer Stelle (EA) auch zutreffend verwendet. Sie kommen doch auch aus einer MQlRates-Funktion ... ?

MqlRates bar[];

Ich schaffe es nur nicht, diese Werte in Deinem Vorschlag mit dem Loop auch zu verwenden.

Was mache ich da falsch ?

Ich wäre Dir dankbar, wenn Du mir als Hilfestellung den richtigstellenden Codeschnipsel für meinen Transfer zur Verfügung stellen könntest.

 
TraderMQL:

Hallo amando,


das mag sein, aber ich möchte gerne in den bereits vorhandenen Strukturen arbeiten, um es -für mich- "einfach" zu halten. Die Daten sind ja bereits vorhanden und werden an anderer Stelle (EA) auch zutreffend verwendet. Sie kommen doch auch aus einer MQlRates-Funktion ... ?

Ich schaffe es nur nicht, diese Werte in Deinem Vorschlag mit dem Loop auch zu verwenden.

Was mache ich da falsch ?

Ich wäre Dir dankbar, wenn Du mir als Hilfestellung den richtigstellenden Codeschnipsel für meinen Transfer zur Verfügung stellen könntest.

Ich schicks dir sobald ich mal wieder am pc bin

am tablett zu proggen ist immer ein wenig mühsam, mach ich nur zur fehlerkorrektur im livebetrieb

 
amando:

Ich schicks dir sobald ich mal wieder am pc bin

am tablett zu proggen ist immer ein wenig mühsam, mach ich nur zur fehlerkorrektur im livebetrieb

bitte sehr, denke das ist selbsterklärend

 MqlRates rates[];							// MqlRates und copied direkt aus der Doku kopiert
   int copied=CopyRates(NULL,0,0,100,rates);
   if(copied<=0)
      Print("Fehler des Kopieren von Preisdaten ",GetLastError());

   ArraySetAsSeries(rates,true);					// ArraySetAsSeries muss auf true gesetzt werden, in der Doku findet man den Grund, sonst zählt er von hinten

   double spanne=0;


   for(int i = 0; i<10; i++)
     {
      if(rates[i].high - rates[i].low > spanne)
        {
         spanne = rates[i].high - rates[i].low;
         Print("high: ", rates[i].high," low: ",rates[i].low);  // hier sieht man welcher Werte er nimmt
         Print(i);                                              // die die Kerze dazu;
        }

     }

   Print(spanne);                                               // hier die ausgegebene Spanne, die kann natürlich noch normalisiert werden
   Print(spanne*MathPow(10,_Digits));                           // Spanne in Points
   Print(NormalizeDouble(spanne*MathPow(10,_Digits)/10,0));     // in Pips
Grund der Beschwerde: