How to fix this Indicator that i converted from MT4,

 

I converted this from MT4, but it is showing some errors,  it is showing errors on this  lines, 
 ')' - open parenthesis expected DSS_Bressert_MA.mq5 99 34
')' - open parenthesis expected DSS_Bressert_MA.mq5 100 33
'-' - open parenthesis expected DSS_Bressert_MA.mq5 102 17

appreciate if anyone can help me with this, thanks in advance



//+------------------------------------------------------------------+

//|                                                                                 |

//+------------------------------------------------------------------+

#property indicator_separate_window

#property indicator_buffers 3

#property indicator_color1  clrGreen

#property indicator_color2  clrRed

#property indicator_color3  clrRed

#property indicator_width1  2

#property indicator_width2  2

#property indicator_width3  2

#property indicator_minimum 0

#property indicator_maximum 100



input int MaPeriod          = 5;

input ENUM_APPLIED_PRICE MaPrice = PRICE_CLOSE;

input ENUM_MA_METHOD MaType = MODE_EMA;

input int StochasticLength = 15;

input int SmoothEMA        = 5;



double dssBuffer[];

double dssBufferda[];

double dssBufferdb[];

double slope[];



//+------------------------------------------------------------------+

//| Custom indicator initialization function                         |

//+------------------------------------------------------------------+

int OnInit()

{

   SetIndexBuffer(0, dssBuffer);

   SetIndexBuffer(1, dssBufferda);

   SetIndexBuffer(2, dssBufferdb);

   SetIndexBuffer(3, slope);



   IndicatorSetString(INDICATOR_SHORTNAME, "DSS Bressert of MA (" + IntegerToString(MaPeriod) + "," + IntegerToString(StochasticLength) + "," + IntegerToString(SmoothEMA) + ")");

   

   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 counted_bars = prev_calculated;

   if(counted_bars < 0)

      return(-1);



   if(counted_bars > 0)

      counted_bars--;



   int limit = MathMin(rates_total - counted_bars, rates_total - 1);



   if (slope[limit] == -1)

      CleanPoint(limit, dssBufferda, dssBufferdb);



   for(int i = limit; i >= 0; i--)

   {

      double price = iMA(_Symbol, _Period, MaPeriod, 0, MaType, MaPrice);

      dssBuffer[i] = iDss(price, high[i], low[i], StochasticLength, SmoothEMA, i);

      dssBufferda[i] = EMPTY_VALUE;

      dssBufferdb[i] = EMPTY_VALUE;

      slope[i] = slope[i + 1];

      

      if (dssBuffer[i] > dssBuffer[i + 1])

         slope[i] =  1;



      if (dssBuffer[i] < dssBuffer[i + 1])

         slope[i] = -1;



      if (slope[i] == -1)

         PlotPoint(i, dssBufferda, dssBufferdb, dssBuffer);

   }



   return(rates_total);

}



//+------------------------------------------------------------------+

double workDss[][5];

#define _st1    0

#define _ss1    1

#define _pHigh  2

#define _pLow   3

#define _dss    4



double iDss(double close, double high, double low, int length, double smooth, int local_r)

{

   // Check and resize array if necessary

   if (ArraySize(workDss) != Bars) {

       ArrayResize(workDss, Bars);

   }



   // Calculate 'r' based on local_r and adjust for indexing

   int r = Bars - local_r - 1;



   // Calculate alpha

   double alpha = 2.0 / (1.0 + smooth);



   // Update workDss arrays

   workDss[r][_pHigh] = high;

   workDss[r][_pLow] = low;



   // Find min and max over specified length

   double min = workDss[r][_pLow];

   double max = workDss[r][_pHigh];

   for (int k = 1; k < length && (r - k) >= 0; k++) {

       min = MathMin(min, workDss[r - k][_pLow]);

       max = MathMax(max, workDss[r - k][_pHigh]);

   }



   // Calculate _st1 value

   workDss[r][_st1] = 0;

   if (min != max) {

       workDss[r][_st1] = 100 * (close - min) / (max - min);

   }



   // Calculate _ss1 value

   workDss[r][_ss1] = workDss[r - 1][_ss1] + alpha * (workDss[r][_st1] - workDss[r - 1][_ss1]);



   // Find min and max of _ss1 over specified length

   min = workDss[r][_ss1];

   max = workDss[r][_ss1];

   for (int k = 1; k < length && (r - k) >= 0; k++) {

       min = MathMin(min, workDss[r - k][_ss1]);

       max = MathMax(max, workDss[r - k][_ss1]);

   }



   // Calculate stoch value

   double stoch = 0;

   if (min != max) {

       stoch = 100 * (workDss[r][_ss1] - min) / (max - min);

   }



   // Calculate _dss value

   workDss[r][_dss] = workDss[r - 1][_dss] + alpha * (stoch - workDss[r - 1][_dss]);



   return workDss[r][_dss];

}



//+------------------------------------------------------------------+

void CleanPoint(int i, double& first[], double& second[])

{

   if ((second[i]  != EMPTY_VALUE) && (second[i + 1] != EMPTY_VALUE)) {

      second[i + 1] = EMPTY_VALUE;

   } else if ((first[i] != EMPTY_VALUE) && (first[i + 1] != EMPTY_VALUE) && (first[i + 2] == EMPTY_VALUE)) {

      first[i + 1] = EMPTY_VALUE;

   }

}



//+------------------------------------------------------------------+

void PlotPoint(int i, double& first[], double& second[], double& from[])

{

   if (first[i + 1] == EMPTY_VALUE) {

      if (first[i + 2] == EMPTY_VALUE) {

         first[i]   = from[i];

         first[i + 1] = from[i + 1];

         second[i]  = EMPTY_VALUE;

      } else {

         second[i]   =  from[i];

         second[i + 1] =  from[i + 1];

         first[i]    = EMPTY_VALUE;

      }

   } else {

      first[i]  = from[i];

      second[i] = EMPTY_VALUE;

   }

}


 

When you post code please use the CODE button (Alt-S)!

Use the CODE button

 
You need to replace "Bars" with 
"Bars(_Symbol, _Period)" 
or else replace "Bars" with "rates_total"

Get used to highlighting a function name and pressing F1 key so it will open the api documentation.

Your properties are wrong. You need:

#property indicator_buffers 4

#property indicator_plots 3

#property indicator_type1 DRAW_LINE

#property indicator_type2 DRAW_LINE

#property indicator_type3 DRAW_LINE


and leave the rest of your properties there 

Also..because it's an MT4 conversion and your loop is counting down to 0, that means it expects 0 to be the newest element..so you have to use ArraySetAsSeries on all the buffers in the initializer.


 
//+------------------------------------------------------------------+
//|                                                      DSS_Bressert_MA.mq5 |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots 3
#property indicator_type1 DRAW_LINEw
#property indicator_type2 DRAW_LINE
#property indicator_type3 DRAW_LINE
#property indicator_color1 clrGreen
#property indicator_color2 clrRed
#property indicator_color3 clrRed
#property indicator_width1 2
#property indicator_width2 2
#property indicator_width3 2
#property indicator_minimum 0
#property indicator_maximum 100

input int MaPeriod = 5;
input ENUM_APPLIED_PRICE MaPrice = PRICE_CLOSE;
input ENUM_MA_METHOD MaType = MODE_EMA;
input int StochasticLength = 15;
input int SmoothEMA = 5;

double dssBuffer[];
double dssBufferda[];
double dssBufferdb[];
double slope[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
    SetIndexBuffer(0, dssBuffer);
    SetIndexBuffer(1, dssBufferda);
    SetIndexBuffer(2, dssBufferdb);
    SetIndexBuffer(3, slope);

    ArraySetAsSeries(dssBuffer, true);
    ArraySetAsSeries(dssBufferda, true);
    ArraySetAsSeries(dssBufferdb, true);
    ArraySetAsSeries(slope, true);

    IndicatorSetString(INDICATOR_SHORTNAME, "DSS Bressert of MA (" + IntegerToString(MaPeriod) + "," + IntegerToString(StochasticLength) + "," + IntegerToString(SmoothEMA) + ")");

    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 counted_bars = prev_calculated;
    if(counted_bars < 0) return(-1);
    if(counted_bars > 0) counted_bars--;

    int limit = rates_total - counted_bars;
    if (limit < 0) return(-1);

    if (slope[limit] == -1) CleanPoint(limit, dssBufferda, dssBufferdb);

    for(int i = limit - 1; i >= 0; i--)
    {
        double price = iMA(_Symbol, _Period, MaPeriod, 0, MaType, MaPrice);
        dssBuffer[i] = iDss(price, high[i], low[i], StochasticLength, SmoothEMA, i);
        dssBufferda[i] = EMPTY_VALUE;
        dssBufferdb[i] = EMPTY_VALUE;
        slope[i] = slope[i + 1];

        if (dssBuffer[i] > dssBuffer[i + 1]) slope[i] = 1;
        if (dssBuffer[i] < dssBuffer[i + 1]) slope[i] = -1;

        if (slope[i] == -1) PlotPoint(i, dssBufferda, dssBufferdb, dssBuffer);
    }
    return(rates_total);
}

//+------------------------------------------------------------------+
double workDss[][5];
#define _st1    0
#define _ss1    1
#define _pHigh  2
#define _pLow   3
#define _dss    4

double iDss(double close, double high, double low, int length, double smooth, int local_r)
{
    int bars_count = Bars(_Symbol, _Period);

    // Check and resize array if necessary
    if (ArraySize(workDss) != bars_count) {
        ArrayResize(workDss, bars_count);
    }

    // Calculate 'r' based on local_r and adjust for indexing
    int r = bars_count - local_r - 1;

    if (r < 0 || r >= bars_count) return EMPTY_VALUE;

    // Calculate alpha
    double alpha = 2.0 / (1.0 + smooth);

    // Update workDss arrays
    workDss[r][_pHigh] = high;
    workDss[r][_pLow] = low;

    // Find min and max over specified length
    double min = workDss[r][_pLow];
    double max = workDss[r][_pHigh];
    for (int k = 1; k < length && (r - k) >= 0; k++) {
        min = MathMin(min, workDss[r - k][_pLow]);
        max = MathMax(max, workDss[r - k][_pHigh]);
    }

    // Calculate _st1 value
    workDss[r][_st1] = 0;
    if (min != max) {
        workDss[r][_st1] = 100 * (close - min) / (max - min);
    }

    // Calculate _ss1 value
    if (r - 1 >= 0)
    {
        workDss[r][_ss1] = workDss[r - 1][_ss1] + alpha * (workDss[r][_st1] - workDss[r - 1][_ss1]);
    }
    else
    {
        workDss[r][_ss1] = workDss[r][_st1]; // Initialize the first value
    }

    // Find min and max of _ss1 over specified length
    min = workDss[r][_ss1];
    max = workDss[r][_ss1];
    for (int k = 1; k < length && (r - k) >= 0; k++) {
        min = MathMin(min, workDss[r - k][_ss1]);
        max = MathMax(max, workDss[r - k][_ss1]);
    }

    // Calculate stoch value
    double stoch = 0;
    if (min != max) {
        stoch = 100 * (workDss[r][_ss1] - min) / (max - min);
    }

    // Calculate _dss value
    if (r - 1 >= 0)
    {
        workDss[r][_dss] = workDss[r - 1][_dss] + alpha * (stoch - workDss[r - 1][_dss]);
    }
    else
    {
        workDss[r][_dss] = stoch; // Initialize the first value
    }

    return workDss[r][_dss];
}

//+------------------------------------------------------------------+
void CleanPoint(int i, double& first[], double& second[])
{
    if ((second[i] != EMPTY_VALUE) && (second[i + 1] != EMPTY_VALUE)) {
        second[i + 1] = EMPTY_VALUE;
    } else if ((first[i] != EMPTY_VALUE) && (first[i + 1] != EMPTY_VALUE) && (first[i + 2] == EMPTY_VALUE)) {
        first[i + 1] = EMPTY_VALUE;
    }
}

//+------------------------------------------------------------------+
void PlotPoint(int i, double& first[], double& second[], double& from[])
{
    if (first[i + 1] == EMPTY_VALUE) {
        if (first[i + 2] == EMPTY_VALUE) {
            first[i] = from[i];
            first[i + 1] = from[i + 1];
            second[i] = EMPTY_VALUE;
        } else {
            second[i] = from[i];
            second[i + 1] = from[i + 1];
            first[i] = EMPTY_VALUE;
        }
    } else {
        first[i] = from[i];
        second[i] = EMPTY_VALUE;
    }
}


I compile with the above code, everything is good, but when i run it , it shows "critical error occurred, and debugging is stopped", 

i changed this line to get it to passed,


double price = iMA(_Symbol, _Period, MaPeriod, 0, MaType, MaPrice, 1);

to

double price = iMA(_Symbol, _Period, MaPeriod, 0, MaType, MaPrice);


wonder if i did it right

 
  1. Please edit your post and use the CODE button (or Alt+S)! (For large amounts of code, attach it.)
          General rules and best pratices of the Forum. - General - MQL5 programming forum #25 (2019)
              Messages Editor
          Forum rules and recommendations - General - MQL5 programming forum (2023)

  2.         double price = iMA(_Symbol, _Period, MaPeriod, 0, MaType, MaPrice);
    

    Perhaps you should read the manual, especially the examples.
       How To Ask Questions The Smart Way. (2004)
          How To Interpret Answers.
             RTFM and STFW: How To Tell You've Seriously Screwed Up.

    They all (including iCustom) return a handle (an int). You get that in OnInit. In OnTick/OnCalculate (after the indicator has updated its buffers), you use the handle, shift and count to get the data.
              Technical Indicators - Reference on algorithmic/automated trading language for MetaTrader 5
              Timeseries and Indicators Access / CopyBuffer - Reference on algorithmic/automated trading language for MetaTrader 5
              How to start with MQL5 - General - MQL5 programming forum - Page 3 #22 (2020)
              How to start with MQL5 - MetaTrader 5 - General - MQL5 programming forum - Page 7 #61 (2020)
              MQL5 for Newbies: Guide to Using Technical Indicators in Expert Advisors - MQL5 Articles (2010)
              How to call indicators in MQL5 - MQL5 Articles (2010)

 
mrprofit88 #:


I compile with the above code, everything is good, but when i run it , it shows "critical error occurred, and debugging is stopped", 

i changed this line to get it to passed,


double price = iMA(_Symbol, _Period, MaPeriod, 0, MaType, MaPrice, 1);

to

double price = iMA(_Symbol, _Period, MaPeriod, 0, MaType, MaPrice);


wonder if i did it right


yes that change is right, but you don't have to wonder, see MQL5 documentation for iMA

https://www.mql5.com/en/docs/indicators/ima

int  iMA(
   string               symbol,            // symbol name
   ENUM_TIMEFRAMES      period,            // period
   int                  ma_period,         // averaging period
   int                  ma_shift,          // horizontal shift
   ENUM_MA_METHOD       ma_method,         // smoothing type
   ENUM_APPLIED_PRICE   applied_price      // type of price or handle
   );


but you can't call it like that in OnCalculate, you have to define the handle in OnInit and use CopyBuffer in OnCalculate

Please check codebase. I know that you were using AI because I can see the mistakes that AI will do. Haha

The codebase will be much better help to you.

https://www.mql5.com/en/code/viewcode/46924/291559/cci_withshift.mq5


Remember that you make the iMA handle, define the handle in OnInit, and use CopyBuffer in OnCalculate to copy all the bars/rates.

Documentation on MQL5: Technical Indicators / iMA
Documentation on MQL5: Technical Indicators / iMA
  • www.mql5.com
The function returns the handle of the Moving Average indicator. It has only one buffer. Parameters symbol [in] The symbol name of the security...
 
Conor Mcnamara #: yes that change is right, but you don't have to wonder, see MQL5 documentation for iMA

Not right, iMA does not return a double. See #4

 
William Roeder #:

Not right, iMA does not return a double. See #4

I know, but I just meant that the parameters passed are now corrected