Momentum Volume Indikator

 

Hallo zusammen,

ich wage mich langsam inden Bereich cder Indikator programmierung.
einer meiner ersten Versuche ist der Momentum-volume Indikator, wie er von Gerald apell beschrieben wird.

Dieser setzt sich wie folgt zusammen:

MV = (close - close[n] ) * average(volume,n)

MV: Momentum Volume
close: schlusspreis

close[n]: Schlusspreis nach n Perioden

average(volume,n): durchschnittliches Volumen über n perioden --> (volume[0] + volume[1] + volume[n])  /  n)


Leider zeigt wird nur ein leeres Fenster im Indikator angezeigt... Hab cih da irgendwas in der logik falsch berechnet.  Wie immer wäre ich sehr für eure Hilfe dankbar!:)

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 1
#property indicator_color1 clrRed
#property indicator_width1 1
#property indicator_style1 STYLE_SOLID
#property indicator_type1 DRAW_LINE
#property indicator_label1 "MV"


input int MvPeriods = 10; //Periode 


double Volume[];
double MomentumVolume[];


int OnInit()
  {
   SetIndexBuffer(0,MomentumVolume);
   ArraySetAsSeries(MomentumVolume,true);
   
   SetIndexBuffer(1,Volume);
   ArraySetAsSeries(Volume,true);
   
   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[])
  {
  
  
   ArraySetAsSeries(close,true);
   ArraySetAsSeries(volume,true); 
   
   if(rates_total < MvPeriods) return(rates_total);
   
   int limit = rates_total - prev_calculated;
   if(limit == 0) limit++;
    
    
   for(int i = 0; i < limit; i++)
     {
      if(i > rates_total - MvPeriods) continue; // if to less history data available

     
      Volume[i] = close[i] - close[MvPeriods] ; //price Distance between i and MVPeriods
      
      
      long sumVolume = 0;

      for (int j = 0; j < MvPeriods; j++)
         {
          sumVolume += volume[j];               //calculates the volume of each bar until MVPeriods
         }
      
      MomentumVolume[i] = Volume[i] * (sumVolume/MvPeriods); //the MV formular
      
     }

   return(rates_total);
  }
//+------------------------------------------------------------------+
 

Update:

Habe herausgefunden, dass der const long &volume[] Array leer ist. Kann mir jemand sagen, was es damit auf sich hat?

 

Die Formel im Code scheint zu stimmen, aber es wäre übersichtlicher, eine Preisdifferenz nicht auch noch "Volume" zu nennen, wenn Du gleichzeitig mit Volume rechnest. Nenn sie doch "diff" oder "preisdiff".


Genau, Du musst Tickvolume nehmen. Das andere ist "Real Volume". Das kann man nicht wirklich nutzen. Weiß nicht ob die Broker es nur nicht bereitstellen. Ich glaube, es gibt überall nur tickvolume.

Ich würde da erstmal den umständlichen Weg gehen und noch ein Close[] Array hinzufügen (Bufferzahl natürlich um eins erhöhen) und sowohl Close[] als auch Volume[] in der OnCalculate vor allen anderen Berechnungen mit Hilfe von CopyTickVolume und CopyClose füllen und dann mit denen rechnen. Wenn eine Kurve angezeigt wird kannst Du immer noch ausprobieren, wie Du den Code durch die mitgelieferten Werte aus OnCalculate vereinfachen kannst.

Und ich würde sagen ArraySetAsseries macht man bei Indikatoren nicht.

Außerdem könntest Du noch bei Setindexbuffer wenn du statt die Klammer zu schließen noch ein Komma setzt, einstellen, welchen Buffer du als Kurve anzeigen willst und welcher nur der Berechnung dient mit DATA oder CALCULATIONS. Muss man wohl nicht, ist aber praktisch wenn Du später mehr Buffer hast.


Nachtrag: Ich hab das jetzt mal ausprobiert und stecke fest weil SetIndexBuffer kein long Array mag und CopyTickVolume lässt mich die long Zahlen nicht in ein double Array stecken... Ist schon ne Weile her dass ich was mit Volumen gemacht habe. Ich werds an dieser Stelle auch belassen, das gibt sonst ne riesen Versuchsreihe...

 
Claudius Marius Walter:

Update:

Habe herausgefunden, dass der const long &volume[] Array leer ist. Kann mir jemand sagen, was es damit auf sich hat?

Das vlume gints bei cfd nicht, das ist nur wenn der mt an eine richtige börse angebunden ist. Kenne aber keinen broker der das anbietet ausser einen future broker aus dem amiland

 
Claudius Marius Walter:

Update:

Habe herausgefunden, dass der const long &volume[] Array leer ist. Kann mir jemand sagen, was es damit auf sich hat?

Nimm einen einfachen Indikator aus ..\Indicators\Examples oder der CodeBase mit genauso viel Puffern wie Du es haben willst und auch bezüglich auf'm Chart oder im Extra-Fenster, speicher ihn unter neuen Namen und schreib Stück für Stück Deine Idee darein und überprüfe jeden Schritt, den Du machst im Debugger - das ist der schnellste Weg - nicht nur für einen Neuling, auch mach das auch so. Warum immer wieder alles neu machen, um dann irgendwann etwas zu vergessen und viel Zeit mit der Fehlersuche zu vertrödeln.

 
Vielen Dank euch dreien. Den Debugger hab ich jetzt auch solangsam raus. ziemlich nützlich!

Das probelm lag letztlich darin, dass sich der Indikator im chart nach dem kompilieren nicht aktualisiert hat. Manchmal werd ich einfach nicht schlau aus dem Betatrader...
 
Claudius Marius Walter:
Vielen Dank euch dreien. Den Debugger hab ich jetzt auch solangsam raus. ziemlich nützlich!

Das probelm lag letztlich darin, dass sich der Indikator im chart nach dem kompilieren nicht aktualisiert hat. Manchmal werd ich einfach nicht schlau aus dem Betatrader...
OnCalculate() wird bei jedem neuen Tick aufgerufen. Schau Dir in ..\Indicators\Examples\ an, wie das organisiert ist, dass immer nur die neuen bzw. aktuellen Kerzen/Balken berechnet werden und nicht immer alles. Da kann man falsch liegen und es passiert nix mehr.
Grund der Beschwerde: