mql4 zu mql5 umwandlung

 
Habe hier einen indikator, welchen ich in mql5 umwandeln  möchte. (Im Anhang findet sich die mql4 Version).

Fehlermeldungen gibt es keine, trotzdem berechnet der Indikator alles andere, als das was ich möchte..


Mein Ansatz:
#property indicator_separate_window
#property indicator_buffers 7
#property indicator_plots 6

#property indicator_label1  "TSV Strong up"
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrLimeGreen
#property indicator_width1  3

#property indicator_label2  "TSV Weak up"
#property indicator_type2   DRAW_HISTOGRAM
#property indicator_style2  STYLE_DOT
#property indicator_color2  clrLimeGreen
#property indicator_width2  2

#property indicator_label3  "TSV Strong down"
#property indicator_type3   DRAW_HISTOGRAM
#property indicator_color3  clrPaleVioletRed
#property indicator_width3  3

#property indicator_label4  "TSV weak down"
#property indicator_type4   DRAW_HISTOGRAM
#property indicator_color4  clrPaleVioletRed
#property indicator_width4  2


#property indicator_label5  "TSV"
#property indicator_type5   DRAW_LINE
#property indicator_color5  clrDarkGray
#property indicator_style5  STYLE_SOLID
#property indicator_width5  2

#property indicator_label6  "TSV Signal"
#property indicator_type6   DRAW_LINE
#property indicator_style6  STYLE_DOT
#property indicator_color6  clrWhite
#property indicator_width6  1

enum  enMaTypes
      {
         ma_sma,     // Simple moving average
         ma_ema,     // Exponential moving average
         ma_smma,    // Smoothed MA
         ma_lwma,    // Linear weighted MA
      };
      
input int             TsvPeriod = 14; 
input enMaTypes       TsvMaMode = ma_sma;
input int             SigPeriod = 10;
input enMaTypes       SigMaMode = ma_ema;
 
double huu[],hud[],hdd[],hdu[],val[],sig[],valh[]; 


int OnInit()
  {
   SetIndexBuffer(0, huu,INDICATOR_DATA); 
   SetIndexBuffer(1, hud,INDICATOR_DATA); 
   SetIndexBuffer(2, hdd,INDICATOR_DATA);
   SetIndexBuffer(3, hdu,INDICATOR_DATA);
   SetIndexBuffer(4, val,INDICATOR_DATA);
   SetIndexBuffer(5, sig,INDICATOR_DATA);
   SetIndexBuffer(6, valh,INDICATOR_CALCULATIONS);
   
   IndicatorSetString(INDICATOR_SHORTNAME,"Time Segmented Volume");

   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[])
  {
   int i=rates_total-prev_calculated+1; if (i>=rates_total) i=rates_total-1;
  
   //
   //
   //
   
   for (i; i>=0 && !_StopFlag; i--)
   {
       double tem = (close[i]>close[i+1]) ?     tick_volume[i] * (close[i]-close[i+1]) :
                    (close[i]<close[i+1]) ? -1* tick_volume[i] * (close[i+1]-close[i]) : 0;
       val[i]  = iCustomMa(TsvMaMode,tem   ,TsvPeriod,i,rates_total,0)*TsvPeriod;  
       sig[i]  = iCustomMa(SigMaMode,val[i],SigPeriod,i,rates_total,1);  
       valh[i] = (i<rates_total-1) ? (val[i]>0) ? (val[i]>val[i+1]) ? 0 : 1 : (val[i]<val[i+1]) ? 2 : 3 : 0;
       huu[i] = (valh[i] == 0) ? val[i] : EMPTY_VALUE;
       hud[i] = (valh[i] == 1) ? val[i] : EMPTY_VALUE;
       hdd[i] = (valh[i] == 2) ? val[i] : EMPTY_VALUE;
       hdu[i] = (valh[i] == 3) ? val[i] : EMPTY_VALUE;  
   }
return(rates_total);
 }
  



//+------------------------------------------------------------------+
string getAverageName(int method)
{
      switch(method)
      {
         case ma_ema:    return("EMA");
         case ma_lwma:   return("LWMA");
         case ma_sma:    return("SMA");
         case ma_smma:   return("SMMA");
      }
return("");      
}

//------------------------------------------------------------------
//                                                                  
//------------------------------------------------------------------

#define _maInstances 2
#define _maWorkBufferx1 1*_maInstances
#define _maWorkBufferx2 2*_maInstances
#define _maWorkBufferx3 3*_maInstances



double iCustomMa(int mode, double price, double length, int r, int bars, int instanceNo=0)
{
   r = bars-r-1;
   switch (mode)
   {
      case ma_sma   : return(iSma(price,(int)ceil(length),r,bars,instanceNo));
      case ma_ema   : return(iEma(price,length,r,bars,instanceNo));
      case ma_smma  : return(iSmma(price,(int)ceil(length),r,bars,instanceNo));
      case ma_lwma  : return(iLwma(price,(int)ceil(length),r,bars,instanceNo));
      default       : return(price);
   }
}

//
//
//

double workSma[][_maWorkBufferx1];
double iSma(double price, int period, int r, int _bars, int instanceNo=0)
{
   if (ArrayRange(workSma,0)!= _bars) ArrayResize(workSma,_bars);

   workSma[r][instanceNo+0] = price;
   double avg = price; int k=1;  for(; k<period && (r-k)>=0; k++) avg += workSma[r-k][instanceNo+0];  
   return(avg/(double)k);
}

//
//
//

double workEma[][_maWorkBufferx1];
double iEma(double price, double period, int r, int _bars, int instanceNo=0)
{
   if (ArrayRange(workEma,0)!= _bars) ArrayResize(workEma,_bars);

   workEma[r][instanceNo] = price;
   if (r>0 && period>1)
          workEma[r][instanceNo] = workEma[r-1][instanceNo]+(2.0/(1.0+period))*(price-workEma[r-1][instanceNo]);
   return(workEma[r][instanceNo]);
}

//
//
//

double workSmma[][_maWorkBufferx1];
double iSmma(double price, double period, int r, int _bars, int instanceNo=0)
{
   if (ArrayRange(workSmma,0)!= _bars) ArrayResize(workSmma,_bars);

   workSmma[r][instanceNo] = price;
   if (r>1 && period>1)
          workSmma[r][instanceNo] = workSmma[r-1][instanceNo]+(price-workSmma[r-1][instanceNo])/period;
   return(workSmma[r][instanceNo]);
}

//
//
//

double workLwma[][_maWorkBufferx1];
double iLwma(double price, double period, int r, int _bars, int instanceNo=0)
{
   if (ArrayRange(workLwma,0)!= _bars) ArrayResize(workLwma,_bars);
   
   workLwma[r][instanceNo] = price; if (period<=1) return(price);
      double sumw = period;
      double sum  = period*price;

      for(int k=1; k<period && (r-k)>=0; k++)
      {
         double weight = period-k;
                sumw  += weight;
                sum   += weight*workLwma[r-k][instanceNo];  
      }             
      return(sum/sumw);
}



Original Code:
#property indicator_separate_window
#property indicator_buffers 6
#property indicator_label1  "TSV Strong up"
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrLimeGreen
#property indicator_width1  3

#property indicator_label2  "TSV Weak up"
#property indicator_type2   DRAW_HISTOGRAM
#property indicator_color2  clrLimeGreen

#property indicator_label3  "TSV Strong down"
#property indicator_type3   DRAW_HISTOGRAM
#property indicator_color3  clrPaleVioletRed
#property indicator_width3  3

#property indicator_label4  "TSV weak down"
#property indicator_type4   DRAW_HISTOGRAM
#property indicator_color4  clrPaleVioletRed

#property indicator_label5  "TSV"
#property indicator_type5   DRAW_LINE
#property indicator_color5  clrDarkGray
#property indicator_width5  3

#property indicator_label6  "TSV Signal"
#property indicator_type6   DRAW_LINE
#property indicator_style6  STYLE_DOT
#property indicator_color6  clrWhite

 
input int            TsvPeriod = 14; 
enum  enMaTypes
      {
         ma_sma,     // Simple moving average
         ma_ema,     // Exponential moving average
         ma_smma,    // Smoothed MA
         ma_lwma,    // Linear weighted MA
};
input enMaTypes       TsvMaMode = ma_sma;
input int             SigPeriod = 10;
input enMaTypes       SigMaMode = ma_ema;
 
double huu[],hud[],hdd[],hdu[],val[],sig[],valh[]; 

//------------------------------------------------------------------
//
//------------------------------------------------------------------

int OnInit()
{
   IndicatorBuffers(7);
   SetIndexBuffer(0, huu,INDICATOR_DATA); 
   SetIndexBuffer(1, hud,INDICATOR_DATA); 
   SetIndexBuffer(2, hdd,INDICATOR_DATA);
   SetIndexBuffer(3, hdu,INDICATOR_DATA);
   SetIndexBuffer(4, val,INDICATOR_DATA);
   SetIndexBuffer(5, sig,INDICATOR_DATA);
   SetIndexBuffer(6, valh);
   
   IndicatorSetString(INDICATOR_SHORTNAME,"Time Segmented Volume");
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason) {}

//
//
//

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=rates_total-prev_calculated+1; if (i>=rates_total) i=rates_total-1;
  
   //
   //
   //
   
   for (; i>=0 && !_StopFlag; i--)
   {
       double tem = (close[i]>close[i+1]) ?     tick_volume[i] * (close[i]-close[i+1]) :
                    (close[i]<close[i+1]) ? -1* tick_volume[i] * (close[i+1]-close[i]) : 0;
       val[i]  = iCustomMa(TsvMaMode,tem   ,TsvPeriod,i,rates_total,0)*TsvPeriod;  
       sig[i]  = iCustomMa(SigMaMode,val[i],SigPeriod,i,rates_total,1);  
       valh[i] = (i<rates_total-1) ? (val[i]>0) ? (val[i]>val[i+1]) ? 0 : 1 : (val[i]<val[i+1]) ? 2 : 3 : 0;
       huu[i] = (valh[i] == 0) ? val[i] : EMPTY_VALUE;
       hud[i] = (valh[i] == 1) ? val[i] : EMPTY_VALUE;
       hdd[i] = (valh[i] == 2) ? val[i] : EMPTY_VALUE;
       hdu[i] = (valh[i] == 3) ? val[i] : EMPTY_VALUE;  
   }
return(rates_total);
}

//------------------------------------------------------------------
//                                                                  
//------------------------------------------------------------------

string getAverageName(int method)
{
      switch(method)
      {
         case ma_ema:    return("EMA");
         case ma_lwma:   return("LWMA");
         case ma_sma:    return("SMA");
         case ma_smma:   return("SMMA");
      }
return("");      
}

//------------------------------------------------------------------
//                                                                  
//------------------------------------------------------------------

#define _maInstances 2
#define _maWorkBufferx1 1*_maInstances
#define _maWorkBufferx2 2*_maInstances
#define _maWorkBufferx3 3*_maInstances

double iCustomMa(int mode, double price, double length, int r, int bars, int instanceNo=0)
{
   r = bars-r-1;
   switch (mode)
   {
      case ma_sma   : return(iSma(price,(int)ceil(length),r,bars,instanceNo));
      case ma_ema   : return(iEma(price,length,r,bars,instanceNo));
      case ma_smma  : return(iSmma(price,(int)ceil(length),r,bars,instanceNo));
      case ma_lwma  : return(iLwma(price,(int)ceil(length),r,bars,instanceNo));
      default       : return(price);
   }
}

//
//
//

double workSma[][_maWorkBufferx1];
double iSma(double price, int period, int r, int _bars, int instanceNo=0)
{
   if (ArrayRange(workSma,0)!= _bars) ArrayResize(workSma,_bars);

   workSma[r][instanceNo+0] = price;
   double avg = price; int k=1;  for(; k<period && (r-k)>=0; k++) avg += workSma[r-k][instanceNo+0];  
   return(avg/(double)k);
}

//
//
//

double workEma[][_maWorkBufferx1];
double iEma(double price, double period, int r, int _bars, int instanceNo=0)
{
   if (ArrayRange(workEma,0)!= _bars) ArrayResize(workEma,_bars);

   workEma[r][instanceNo] = price;
   if (r>0 && period>1)
          workEma[r][instanceNo] = workEma[r-1][instanceNo]+(2.0/(1.0+period))*(price-workEma[r-1][instanceNo]);
   return(workEma[r][instanceNo]);
}

//
//
//

double workSmma[][_maWorkBufferx1];
double iSmma(double price, double period, int r, int _bars, int instanceNo=0)
{
   if (ArrayRange(workSmma,0)!= _bars) ArrayResize(workSmma,_bars);

   workSmma[r][instanceNo] = price;
   if (r>1 && period>1)
          workSmma[r][instanceNo] = workSmma[r-1][instanceNo]+(price-workSmma[r-1][instanceNo])/period;
   return(workSmma[r][instanceNo]);
}

//
//
//

double workLwma[][_maWorkBufferx1];
double iLwma(double price, double period, int r, int _bars, int instanceNo=0)
{
   if (ArrayRange(workLwma,0)!= _bars) ArrayResize(workLwma,_bars);
   
   workLwma[r][instanceNo] = price; if (period<=1) return(price);
      double sumw = period;
      double sum  = period*price;

      for(int k=1; k<period && (r-k)>=0; k++)
      {
         double weight = period-k;
                sumw  += weight;
                sum   += weight*workLwma[r-k][instanceNo];  
      }             
      return(sum/sumw);
}



Vielen Dank an euch:)
Dateien:
TSV.MQ4  8 kb
 
Geh mit dem Debugge4r durch Deinen MQ5-Code und kontrolliere, wo und was schiefläuft.
 
Carl Schreiber:
Geh mit dem Debugge4r durch Deinen MQ5-Code und kontrolliere, wo und was schiefläuft.
Hab ich, nur leider kommt direkt diese Fehlermedlung. Nicht gerade informativ...

 
Habe den Fehler rausgefunden, indem ich den Debugger mit Live-Daten gefüttert habe. Im Experten journal wurde dann auf die jeweilige (kommentierte) Zeile im Code hingewiesen

Es scheint hier ein einfaches logikproblem vorzuliegen. Nur leider durchschaue ich dies nicht...


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=rates_total-prev_calculated+1; if (i>=rates_total) i=rates_total-1;
  
   //
   //
   //
   
   for (; i>=0 && !_StopFlag; i--)
   {
       double tem = (close[i]>close[i+1]) ?     tick_volume[i] * (close[i]-close[i+1]) :  // auf das Array close[i+1] kann wahrscheinlich nicht zugegriffen werden, da es noch garnicht belegt wurde 
                    (close[i]<close[i+1]) ? -1* tick_volume[i] * (close[i+1]-close[i]) : 0;
       val[i]  = iCustomMa(TsvMaMode,tem   ,TsvPeriod,i,rates_total,0)*TsvPeriod;  
       sig[i]  = iCustomMa(SigMaMode,val[i],SigPeriod,i,rates_total,1);  
       valh[i] = (i<rates_total-1) ? (val[i]>0) ? (val[i]>val[i+1]) ? 0 : 1 : (val[i]<val[i+1]) ? 2 : 3 : 0;
       huu[i] = (valh[i] == 0) ? val[i] : EMPTY_VALUE;
       hud[i] = (valh[i] == 1) ? val[i] : EMPTY_VALUE;
       hdd[i] = (valh[i] == 2) ? val[i] : EMPTY_VALUE;
       hdu[i] = (valh[i] == 3) ? val[i] : EMPTY_VALUE;  
   }
return(rates_total);
}
 

Hast Du die zeitliche Richtung der Array mit den Preisen etc. geprüft? Die hat sich von MQ$ zu MQ5 umgedreht: MQ4: time[0] ist die letzte Zeit, Bar... in MQ5[0] ist die älteste Zeit, Bar ...

Mit ArraySetAsSerie() lässt sich das in MQ5 umdrehen. 

Um das zu verstehen lies das hier: https://www.mql5.com/de/docs/series/bufferdirection.

Ist verwirrend - auch für mich, aber man gewöhnt sich dran.

Liegt es daran?

Übrigens einfach nur zusagen, da gibt's ein Problem ist zu wenig um Dir helfen  zu können. Du musst schon genau sagen, was der Code wo machen soll, aber wo es genau nicht das tut.

Dokumentation zu MQL5: Operationen mit Arrays / ArraySetAsSeries
Dokumentation zu MQL5: Operationen mit Arrays / ArraySetAsSeries
  • www.mql5.com
ArraySetAsSeries - Operationen mit Arrays - Nachschlagewerk MQL5 - Nachschlagewerk über die Sprache des algothitmischen/automatischen Handels für MetaTrader 5
 
Carl Schreiber:

Hast Du die zeitliche Richtung der Array mit den Preisen etc. geprüft? Die hat sich von MQ$ zu MQ5 umgedreht: MQ4: time[0] ist die letzte Zeit, Bar... in MQ5[0] ist die älteste Zeit, Bar ...

Mit ArraySetAsSerie() lässt sich das in MQ5 umdrehen. 

Um das zu verstehen lies das hier: https://www.mql5.com/de/docs/series/bufferdirection.

Ist verwirrend - auch für mich, aber man gewöhnt sich dran.

Liegt es daran?

Übrigens einfach nur zusagen, da gibt's ein Problem ist zu wenig um Dir helfen  zu können. Du musst schon genau sagen, was der Code wo machen soll, aber wo es genau nicht das tut.

Danke dir! ich werde nächstes mal gründlicher an die Sache heran gehen :)


Claudius Marius Walter:
Habe den Fehler rausgefunden, indem ich den Debugger mit Live-Daten gefüttert habe. Im Experten journal wurde dann auf die jeweilige (kommentierte) Zeile im Code hingewiesen

Es scheint hier ein einfaches logikproblem vorzuliegen. Nur leider durchschaue ich dies nicht...


Werde den post löschen. Der indikator in  mql4 war bereits verbugt.
 
Ich versuche gerade die mql4 logik zu verstehen... ziemlich verwirrende Sache

der Debugger lässt sich nicht anhand historischer Daten Starten.
Liegt das am mt4 oder übersehe ich da etwas?


Nochmal fürs Verständnis:

in mq5 iteriere ich mit einer for-Schleife von 0 bis rates_total. Dabei ist 0 die älteste Kerze und die neueste Kerze befindet sich bei rates-total?


in mq4 iteriere ich mit einer for-Schleife von rates_total bis 0. Dabei ist rates total der index für die älteste Kerze und 0 der Index für die neueste Kerze?

Hier ein mq4 Programmschnipsel:

   int counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
           int limit=MathMin(Bars-counted_bars,Bars-1);
  
   for (int i=limit; i>=0; i--)

Ich bin sichtlich überfordert, weshalb meine Problemstellung gerade etwas schwer darzustellen ist. Mich verwirrt vor allem, dass in dem Beispielcode i-- gerechnet wird, statt i++...
 
Claudius Marius Walter:
Ich versuche gerade die mql4 logik zu verstehen... ziemlich verwirrende Sache

der Debugger lässt sich nicht anhand historischer Daten Starten.
Liegt das am mt4 oder übersehe ich da etwas?


Nochmal fürs Verständnis:

in mq5 iteriere ich mit einer for-Schleife von 0 bis rates_total. Dabei ist 0 die älteste Kerze und die neueste Kerze befindet sich bei rates-total?


in mq4 iteriere ich mit einer for-Schleife von rates_total bis 0. Dabei ist rates total der index für die älteste Kerze und 0 der Index für die neueste Kerze?

Hier ein mq4 Programmschnipsel:


Ich bin sichtlich überfordert, weshalb meine Problemstellung gerade etwas schwer darzustellen ist. Mich verwirrt vor allem, dass in dem Beispielcode i-- gerechnet wird, statt i++...

Deswegen kontrolliere ich immer die Indices [i+1],[i],[i-1] über time[..].

Ja Mt4 kann wohl nicht mit hist. Daten debuggen.