Grundsätzliche Fragen zur MT5 Programmierung im Zusammenhand mit Indikatoren

 

Ich habe das Buch "Expert Advisor - Programming for MetaTrader 5" vor mir liegen und bei Durchsicht kommen mir einige Verständnisfragen:

   // Moving average
   double ma[];
   ArraySetAsSeries(ma,true);
        
   int maHandle=iMA(_Symbol,0,MAPeriod,MODE_SMA,0,PRICE_CLOSE);
   CopyBuffer(maHandle,0,0,1,ma);
   
   
   // Close price
   double close[];
   ArraySetAsSeries(close,true);
   CopyClose(_Symbol,0,0,1,close);
   
   double macurrent = ma[0];
   double maprevious = ma[1];

Dieser Teil steht innerhalb der OnTick-Funktion und ich frage mich Folgendes:

-Kann ich die Arrays nicht global anlegen?

-Brauche ich den Aufruf "ArraySetAsSeries(ma,true);" oder ist es nicht per default der Fall ist?

-Warum werden beide Aufrufe ArraySetAsSeries(... und maHandle = iMA( ....   in der OnTick() gemacht? Reicht es nicht einmalig zum Programmstart in der OnInit()?

-Warum wird häufig der Arraywert ma[0] noch in eine double-Variable, hier macucrrent gespeichert? Macht es hier einen Unterschied, ob ich auf den Array-Wert oder auf die Double-Variable zugreife?

-Laut meinem Verständnis, würde ich doch bei jedem Tick nur die Funktion CopyBuffer(... ausführen müssen, oder?

 
sunshineh:

Ich habe das Buch "Expert Advisor - Programming for MetaTrader 5" vor mir liegen und bei Durchsicht kommen mir einige Verständnisfragen:

Dieser Teil steht innerhalb der OnTick-Funktion und ich frage mich Folgendes:

-Kann ich die Arrays nicht global anlegen?

-Brauche ich den Aufruf "ArraySetAsSeries(ma,true);" oder ist es nicht per default der Fall ist?

-Warum werden beide Aufrufe ArraySetAsSeries(... und maHandle = iMA( ....   in der OnTick() gemacht? Reicht es nicht einmalig zum Programmstart in der OnInit()?

-Warum wird häufig der Arraywert ma[0] noch in eine double-Variable, hier macucrrent gespeichert? Macht es hier einen Unterschied, ob ich auf den Array-Wert oder auf die Double-Variable zugreife?

-Laut meinem Verständnis, würde ich doch bei jedem Tick nur die Funktion CopyBuffer(... ausführen müssen, oder?

   

Hallo, natürlich geht das.

Hier Ein Beispiel:

//+------------------------------------------------------------------+
//|              Globale Variablen                                         |
//+------------------------------------------------------------------+

input ENUM_TIMEFRAMES Timeframes       = PERIOD_H1;               // Timeframe
input int  MAPeriod                    = 100;                     // Movingperiod

int    ma=0;

int OnInit() { // OnInit Funktion

//--- Moving Average indicator

   ma=iMA(_Symbol,Timeframes,MAPeriod,0,MODE_SMA,PRICE_CLOSE);
   if(MA==INVALID_HANDLE) {
      printf("Error creating MA indicator");
      return(INIT_FAILED);
   }

return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() {

// Create an Array
   MqlRates PriceInformation[];

// Sort current to oldest candle
   ArraySetAsSeries(PriceInformation,true);

// Copy price
   int Data = CopyRates(Symbol(),Period(),0,Bars(Symbol(),Period()),PriceInformation);

//--- get current Moving Average
   double   mawert[1];

   if(CopyBuffer(ma,0,0,1,mawert)!=1) {
      Print("CopyBuffer from iMA failed, no data");
      return;
   }

// Funktion für Handelsbedinnungen 
     
    if(mawert[0] > Ihre Eingaben){
     
    // Send Order oder so

     }else if(mawert[0] < Ihre Eingaben){

      // Send Order oder so

     }

} // OnTick Funktion ende

Gruß Igor

 
Arraysetasseries gehört aber auch in die oninit
 

Hallo Igor, herzlichen Dank für deine Antwort

Ich habe nun einige Tests durchgeführt kann aber komischerweise in den Buffern selbst, nicht den aktuellen Wert abrufen:

input int Sto_KPeriod = 5;             // Stochastik K-Period
input int Sto_DPeriod = 3;             // Stochastik D-Period
input int Sto_Slowing = 3;             // Stochastik Slowing

int handle_STO;

double STO_MAIN[3];
double STO_SIGNAL[3];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
      handle_STO = iStochastic(_Symbol,_Period,Sto_KPeriod,Sto_DPeriod,Sto_Slowing,MODE_SMA,STO_LOWHIGH);
      
      if(handle_STO == INVALID_HANDLE)
         Alert("Fehler beim Erstellen der Indikator-Handles");
      ChartIndicatorAdd(0,1,handle_STO);
//---
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   ArraySetAsSeries(STO_MAIN,true);
   ArraySetAsSeries(STO_SIGNAL,true);

   CopyBuffer(handle_STO,0,0,3,STO_MAIN);
   CopyBuffer(handle_STO,1,0,3,STO_SIGNAL); 
   
   Print("STO_MAIN[1]="+DoubleToString(STO_MAIN[1],5)+" STO_SIGNAL[1]="+DoubleToString(STO_SIGNAL[1],5)+" STO_MAIN[0]="+DoubleToString(STO_MAIN[0],5)+" STO_SIGNAL[0]="+DoubleToString(STO_SIGNAL[0],5) );   
  }
//+------------------------------------------------------------------+

Hier das entsprechende Bild dazu:

Die ausgelesenen Werte stimmen nicht überein - auch wenn ich die Funktion "ArraySetAsSeries(" entferne. 

Ich habe nun gemerkt, dass es funktioniert, wenn ich statt

double STO_MAIN[3];
double STO_SIGNAL[3];

die Arrays so deklariere 

double STO_MAIN[];
double STO_SIGNAL[];

dann klappt es.  Ich kann nur noch nicht verstehen, warum das so ist. 

 
sunshineh #:

Ich habe nun gemerkt, dass es funktioniert, wenn ich statt

die Arrays so deklariere 

dann klappt es.  Ich kann nur noch nicht verstehen, warum das so ist. 

Einmal [] deklarierst Du ein Array mit veränderbarer Größe (die CopyBuffer anpasst) das andere Mal [3] mit einer fixen Größe von 3: [0], [1], [2] (vielleicht mag CopyBuffer das nicht?) Siehe Code-Beispiel von CopyBuffer (Kursor drauf + F1)

 
sunshineh #:

Hallo Igor, herzlichen Dank für deine Antwort

Ich habe nun einige Tests durchgeführt kann aber komischerweise in den Buffern selbst, nicht den aktuellen Wert abrufen:

Hier das entsprechende Bild dazu:

Die ausgelesenen Werte stimmen nicht überein - auch wenn ich die Funktion "ArraySetAsSeries(" entferne. 

Ich habe nun gemerkt, dass es funktioniert, wenn ich statt

die Arrays so deklariere 

dann klappt es.  Ich kann nur noch nicht verstehen, warum das so ist. 

Hallo,

du hast Buffer 

CopyBuffer(handle_STO,0,0,3,STO_MAIN);

und 

CopyBuffer(handle_STO,1,0,3,STO_SIGNAL);

mit dem Wert 3 deklariert.

Wie schon Carl Schreiber beschrieben hat, Buffer zählt die Kerzen von 0, ... u.s.w. 

Wenn du aber 3 eingibst, nimmt der Buffer den Wert von der vierte Kerze.


Und bei Arrays

double STO_MAIN[3];
double STO_SIGNAL[3];

verstehe ich den Sinn nicht.

Gruß Igor

 
amando #:
Arraysetasseries gehört aber auch in die oninit

Hier handelt es sich um einen EA und nicht Indikator.

Der Preis verändert sich mit jedem Tick.

Und OnInit wird nur beim laden des EAs oder wechseln von Timeframes aufgerufen.

 
Igor Widiger #:

Hier handelt es sich um einen EA und nicht Indikator.

Der Preis verändert sich mit jedem Tick.

Und OnInit wird nur beim laden des EAs oder wechseln von Timeframes aufgerufen.

Das reicht ja auch, da gehts ja nur darum in welcher Richtung der Bluffer aufgebaut wird