Indikator Grundlagen

 

Hallo @all,


muss ja gestehen, ich habe noch nie einen Indicator geschrieben, das war mir bisher ja immer ein wenig zu hoch. 

Aber da ich ja neugierig bin, hab ich jetzt mal ein paar Grundlegende Fragen dazu.


#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot Diff
#property indicator_label1  "Diff LMA-SMA"  
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

#property indicator_color2  clrGreen
#property indicator_type2   DRAW_LINE
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

seh ich das richtig, bei den Buffern,

ich muss für jede Linie die ich Zeichnen will im Indikator einen Buffer verwenden.

im allgemeinen Teil, definiere ich die Buffer, in dem Fall 2, und anschliessend sage ich dem Indicator, wie er die jeweiligen Buffer darstellen soll. ACHTUNG: wenn ich das richtig verstanden habe, beginnen hier die Buffer bei 1


So, dann gehen wir in die OnInit weiter

   SetIndexBuffer(0,DiffBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,TestProzent,INDICATOR_DATA);

in der OnInit, lege ich den Buffer fest, für was ich diesen verwenden will

Hier beginnen die Buffer bei 0 zu zählen?????? was ja auch logisch ist. Das heist, der indicator_style1 gilt für den Buffer 0? nehme ich zumindest an

INDICATOR_DATA

benötige ich für alle Buffer welche angezeigt werden sollen

INDICATOR_CALCULATIONS

benötige ich für alle Buffer welche nur zum zwischenspeichern dienen.

denke ich halt mal oder? sollte so sein


und dann mein größtes rätsel

was bitte ist der Unterschied zwischen 

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[])

und 


int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])

die im &price[]  auszulesenden Werte sind ja oben nur einzeln dargestellt oder?


weitere fragen kommen.

;-)

 

Alles sehr richtig erkannt.

Den Unterschied bei den 2 Versionen der OnInit() siehst du an den Parametern.

Die Variante die du wählst hat Einfluss auf den Aufruf des Indikators (Startbildschirm).

Bei der kurzen Variante

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])

erscheint dort ein zusätzlicher Tab 'Parameters' in dem die Preisart ausgewält werden kann.

Den dort erscheinenden Wert kannst du mit

#property indicator_applied_price PRICE_TYPICAL // oder andere Vorgabe

voreinstellen.

Dlle Arrays die du in der OnCalculate() verwendest lönnen als Series eingestellt werden, falls du mit index 0 auf die aktuelle Kerze zugreifen willst.
Das ist nicht immer der Fall.

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[])
{
   //ArraySetAsSeries(high, true);
   //ArraySetAsSeries(low, true);
      
   int start=(prev_calculated==0)?0:prev_calculated-1;   // kompakteste definition die ich kenne
   
   for(int i=start; i<rates_total; i++)
      {
         // falls du hier auf [i-1] zugreifen willst muss die start angepasst werden
         // int start=(prev_calculated==0)?1:prev_calculated-1;
         // zB. um Steigungen zu berechnen
         double slope=close[i]-close[i-1]; // wird hier einen Indexfehler produzieren
      }

   return(rates_total);
}

// die parametername konnen auch anders lauten, der Compiler meckert nicht!
// ist aber unüblich und nicht zu empfehlen
int OnCalculate(const int total, const int previ, const int begin, const double& price[])
{
   //ArraySetAsSeries(price, true);


   return(total);
}

Es braucht Jahre um die tiefen Geheimnisse zu lüften ;)

edit: Ich war jetzt geistig noch bei den EAs, da ist das mit dem ArraySetAsSeries sehr wichtig.
Bei der Indikatoren ist es eher nicht üblich.

 

Danke Otto,


was sagt diese Zeile eigentlich aus?

Vor allem der teil  ?0: ist mir nicht klar
int start=(prev_calculated==0)?0:prev_calculated-1;   // kompakteste definition die ich kenne
 

Amando, F1?

=>

int OnCalculate (const int rates_total,      // Feldgroesse price[] 
                 const int prev_calculated,  // verarbeitete Bars im früheren Aufruf  
                 ...
    );

Also Anzahl und bereits berechnete Bars auf dem Chart.

 
Carl Schreiber:

Amando, F1?

=>

Also Anzahl und bereits berechnete Bars auf dem Chart.

Carl, 

was bedeutet ?0: ?


das ist die grosse frage

 
amando:

Carl, 

was bedeutet ?0: ?


das ist die grosse frage

Das ist nur eine kompakte schreibweise für

int start;

if(prev_calculated==0)
   start=0;
else
   start=prev_calculated-1; 

oder

   int start=prev_calculated-1;
   if(start<0)
      start=0;

viele Wege führen nach Rom.

 
Otto Pauser:

Das ist nur eine kompakte schreibweise für

oder

viele Wege führen nach Rom.

Danke, jetzt ist mir das klar

 

Wann muss ich bei einem Indicator einen Hilfsbuffer setzen?

in der OnInit initialisiere ich ja die Buffer für den Indikator


   SetIndexBuffer(0,buffer1,INDICATOR_DATA); 
   SetIndexBuffer(1,buffer2,INDICATOR_DATA);

   SetIndexBuffer(4,sum,INDICATOR_CALCULATIONS);
   SetIndexBuffer(5,MA_Buffer,INDICATOR_CALCULATIONS); 

bei dein INDICATOR_DATA, das sind die Buffer welche anschliessend als Line geplottet werden

bei INDICATOR_CALCULATION das sind ja nur hilfsbuffer,

die Frage ist, 

wann muss ich einen Buffer in der OnInit() initialisieren, und wann reicht es, wenn ich einen Buffer einfach mit

double Buffer1[];

definiere?

diese definition kann ich ja global durchführen, bzw diese erst in der OnCalculation laufen lassen?

 
amando: wann muss ich einen Buffer in der OnInit() initialisieren?

Im Debugger siehst du kleine Geheimzeichen hinter dem buffer wie S oder I oder beides.

Zuerst wird 'dynamic array[0]' angezeigt.

Nach SetIndexBuffer 'dynamic array[xxx],I -> die Arraygröße und shift wird vom System automatisch angepasst.

Nach ArraySetAsSeries() kommt ein S dazu:  'dynamic array[0],S -> AsSeries aber kein Buffer

'dynamic array[xxx],IS -> Buffer und Timeseries

 

Danke@Otto,

das verseh ich soweit, aber wann muss ich initialisieren in der OnInit() und wann nicht?


dann hab ich da nochwas

kann da mal wer drüberschauen?

irgendwie krieg ich das nicht so ganz hin

Der Indikator soll 2 MA einzeichnen und dann für den einen MA die %Fibo Werte.

Das Funktioniert so weit so gut, mit dem initialisieren seh ich den Indicator. Jedoch, wenn eine neue Kerze kommt, dann zeichnet er sich nicht weiter, bzw, irgendwann verschwindet er ganz vom Chart.


und zwar stoßt er sich das dieser Zeile


if(use_Fibo_MA) MA_Buffer[i]= MA[i]; 

irgendwie will er das MA[i] nicht

hat jemand eine Idee?

#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 10
#property indicator_plots   10
//--- 

// MA Fibo
#property indicator_label1  "MA_Fibo"   
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed, clrBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

// Trend MA
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrGreenYellow
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

// Fibo Levels
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrGray
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1

#property indicator_type4   DRAW_LINE
#property indicator_color4  clrGray
#property indicator_type4   DRAW_LINE
#property indicator_style4  STYLE_SOLID
#property indicator_width4  1

#property indicator_type5   DRAW_LINE
#property indicator_color5  clrGray
#property indicator_style5  STYLE_SOLID
#property indicator_width5  1

#property indicator_type6   DRAW_LINE
#property indicator_color6  clrGray
#property indicator_style6  STYLE_SOLID
#property indicator_width6  1

#property indicator_type7   DRAW_LINE
#property indicator_color7  clrGray
#property indicator_style7  STYLE_SOLID
#property indicator_width7  1

#property indicator_type8   DRAW_LINE
#property indicator_color8  clrGray
#property indicator_type8   DRAW_LINE
#property indicator_style8  STYLE_SOLID
#property indicator_width8  1

#property indicator_type9   DRAW_LINE
#property indicator_color9  clrGray
#property indicator_style9  STYLE_SOLID
#property indicator_width9  1

#property indicator_type10   DRAW_LINE
#property indicator_color10  clrGray
#property indicator_style10  STYLE_SOLID
#property indicator_width10  1



input int Periode_Short_MA = 14;
input int Periode_Trend_MA = 50;

input bool use_Fibo_MA = true;
input bool use_Trend_MA = true;
input bool use_SechsunzwanzigProzent = false;
input bool use_SiebenundDreisigProzent= true;
input bool use_EinundSechzigProzent= false;
input bool use_HundertProzent= false;

input ENUM_APPLIED_PRICE Price_Short_MA = PRICE_CLOSE;
input ENUM_MA_METHOD Mode_Short_MA = MODE_LWMA;

input ENUM_APPLIED_PRICE Price_Trend_MA = PRICE_CLOSE;
input ENUM_MA_METHOD Mode_Trend_MA = MODE_LWMA;






double   MA_Buffer[];  // Fibo Ma
double   MA_Trend_Buffer[];  // Trend MA
// Fibo Levels
double   EinundSechzigProzent_oben[];
double   EinundSechzigProzent_unten[];
double   SiebenundDreisigProzent_oben[];
double   SiebenundDreisigProzent_unten[];
double   Dreiundzwanzig_oben[];
double   Dreiundzwanzig_unten[];
double   HundertProzent_oben[];
double   HundertProzent_unten[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int MA_Handle, MATrend_Handle;


int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,MA_Buffer,INDICATOR_DATA);
   SetIndexBuffer(1,MA_Trend_Buffer,INDICATOR_DATA);
   SetIndexBuffer(2,EinundSechzigProzent_oben,INDICATOR_DATA);
   SetIndexBuffer(3,EinundSechzigProzent_unten,INDICATOR_DATA);
   SetIndexBuffer(4,SiebenundDreisigProzent_oben,INDICATOR_DATA);
   SetIndexBuffer(5,SiebenundDreisigProzent_unten,INDICATOR_DATA);
   SetIndexBuffer(6,HundertProzent_oben,INDICATOR_DATA);
   SetIndexBuffer(7,HundertProzent_unten,INDICATOR_DATA);
   SetIndexBuffer(8,Dreiundzwanzig_oben,INDICATOR_DATA);
   SetIndexBuffer(9,Dreiundzwanzig_unten,INDICATOR_DATA);
   
      
   MA_Handle      = iMA(_Symbol,_Period,Periode_Short_MA,0,Mode_Short_MA,Price_Short_MA);
   MATrend_Handle = iMA(_Symbol,_Period,Periode_Trend_MA,0,Mode_Trend_MA,Price_Trend_MA);
//---
   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[])
  {
//---
   double MA[], TrendMA[];
   
   int limit=rates_total-prev_calculated,
       count=(limit>1 ? rates_total : 1), 
        cop2=0, cop1 = 0;

   cop2 = CopyBuffer(MA_Handle,0,0,count,MA);   // Fibo MA = kurzer MA
   cop1 = CopyBuffer(MATrend_Handle,0,0,count,TrendMA); // Buffer für Trend MA
   
   
   // definieren der ragene für die Bars (kurze Schreibweise)
   int start=(prev_calculated==0)?0:prev_calculated-1; 

   for(int i=start; i<rates_total; i++)
      {
      if(use_Fibo_MA) MA_Buffer[i]= MA[i]; 
      
      if(use_Trend_MA) MA_Trend_Buffer[i] = TrendMA[i];
      
      if (use_EinundSechzigProzent)
      {
      EinundSechzigProzent_oben[i]     =  MA[i] - (MA[i] / 100 * 0.618);
      EinundSechzigProzent_unten[i]    =  MA[i] - (MA[i] / 100 * 0.618)*-1;
      }
      if(use_SiebenundDreisigProzent)
      {
      SiebenundDreisigProzent_oben[i]  =  MA[i] - (MA[i] / 100 * 0.382);
      SiebenundDreisigProzent_unten[i] =  MA[i] - (MA[i] / 100 * 0.382)*-1;
      }
      if(use_HundertProzent)
      {
      HundertProzent_oben[i]           =  MA[i] - (MA[i] / 100 * 1.000);
      HundertProzent_unten[i]          =  MA[i] - (MA[i] / 100 * 1.000)*-1;
      }
      if(use_SechsunzwanzigProzent)
      {
      Dreiundzwanzig_oben[i]           =  MA[i] - (MA[i] / 100 * 0.236);
      Dreiundzwanzig_unten[i]          =  MA[i] - (MA[i] / 100 * 0.236)*-1;
      }
      
      }
   
  
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+


Edit:

da hab ich auch den Hinweis dazu

wenn ich das ganze im Debugger laufen lasse dann bekomme ich für die MA[i] und MATrend[i] ewig 0 heraus, erst nach gefühlten 100 mal F5 drücken kommen da Werte, genau sind es die Perioden der MA. Also der 14er kommt nach 14 x F5, der 50er nach 50x F5


Edit2:

das Problem mit den Werten im Debugger hab ich gelöst

dazu musste ich 

   ArraySetAsSeries(MA,true);
   ArraySetAsSeries(TrendMA,true);

einfügen, das ist mir zwar nicht wirklich verständlich in einem Indicator, da sollte ein Array ja automatisch richtig initialisiert sein, aber gut, ist halt so

das Problem, das mit dem arrayoutofrange in der selben Zeile hab ich noch immer

 

Überprüf den Index:

if ( idx<0 || idx>=ArraySize(arr) ) { Print(idx,"  sz: ",ArraySize(arr)); Print(1.0/(sqrt(1)-1)); } // crash, den der Compiler nicht erkennt ;)
Grund der Beschwerde: