Download MetaTrader 5

On the Strategy Tester, I need to read the values of one Indicator inside another Indicator, both loaded within an Expert Advisor

To add comments, please log in or register
Do you need a programmer? Make an order to let the developer find you!
cyberglassed
611
cyberglassed 2016.07.11 08:14 

Hello again folks.

I have one Expert Advisor (EA) which loads 2 indicators. Indicator 1 is a moving average (IND_MA / top indicator) and Indicator 2 is a custom indicator (IND_CUSTOM / bottom indicator) which reads the information from the moving average indicator on every tick and output the values of IND_MA rounded to the third digit after the floating point, producing what you can see on the following image:


The EA needs the IND_CUSTOM for it's own functionality. So that's a requirement for it.

My problem is that the EA works OK on the terminal but on the Strategy Tester (ST) the IND_CUSTOM doesn't get any value. as you can see on the following image:

Any idea on how to make the IND_CUSTOM gets the values on the ST, so I can backtesting?

Below you have the code of the IND_CUSTOM and the EA...

// File: ProblemIndicator.mq5

#property indicator_separate_window
#property indicator_buffers            1
#property indicator_plots              1
#property indicator_type1              DRAW_LINE
#property indicator_color1             clrBlue
#property indicator_style1             STYLE_SOLID
#property indicator_width1             1

input int handle_base;                  // Handle of the base indicator
input int handle_base_buffer;   // Buffer index of the base indicator

double buffer[];
double data_base[];

int OnInit() {

        be_aware_of_indicators_available();     // needed here at the beginning

        if (!is_valid_indicator_handle(handle_base)) {
                printf("The handle of the base indicator: %d, is invalid", handle_base);
                return -1;
        }

        ArraySetAsSeries(buffer, true);
        ArraySetAsSeries(data_base, true);

        IndicatorSetInteger(INDICATOR_DIGITS, _Digits + 1);

        PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 0);
        SetIndexBuffer(0, buffer, INDICATOR_DATA);

        return 0;
}

int OnCalculate(
            const int rates_total,     // number of bars in history at the current tick
                                const int prev_calculated,      // number of bars calculated at previous call
                                const int begin, const double &price[]
) {
        int count = rates_total - prev_calculated;
        CopyBuffer(handle_base, handle_base_buffer, 0, count, data_base);

        for (int i = count - 1; i >= 0; i--)
                buffer[i] = MathRoundDecimals(data_base[i], 3);

        return rates_total;
}

void get_chart_indicators_handle(int &handles[]) {
        ArrayResize(handles, 0);
        int total = (int) ChartGetInteger(0, CHART_WINDOWS_TOTAL);
        for (int w = 0; w < total; w++) {
                for (int i = 0; i < ChartIndicatorsTotal(0, w); i++) {
                        string name = ChartIndicatorName(0, w, i);
                        ArrayResize(handles, ArraySize(handles) + 1);
                        handles[ArraySize(handles) - 1] = ChartIndicatorGet(0, w, name);
                }
        }
}

void be_aware_of_indicators_available() {
        int handles[];
        get_chart_indicators_handle(handles);
}

bool is_valid_indicator_handle(int handle) {
        ENUM_INDICATOR type;
        MqlParam parameters[];
        int result = IndicatorParameters(handle, type, parameters);
        if (GetLastError() == ERR_FUNCTION_NOT_ALLOWED)
                return true;
        else
                return (result != -1);
}

double MathRoundDecimals(double num, int decimals) {
        return MathRound(num * MathPow(10, decimals)) / MathPow(10, decimals);
}
// File: ProblemEA.mq5

int OnInit() {

        ChartSetInteger(0, CHART_SCALE, 3);
        ChartSetInteger(0, CHART_MODE, CHART_CANDLES);

        int handle_1, handle_2;

        int i = 0;

        MqlParam params_1[4];
        params_1[0].type = TYPE_INT;
        params_1[0].integer_value = 20;
        params_1[1].type = TYPE_INT;
        params_1[1].integer_value = 0;
        params_1[2].type = TYPE_INT;
        params_1[2].integer_value = MODE_SMA;
        params_1[3].type = TYPE_INT;
        params_1[3].integer_value = PRICE_CLOSE;
        handle_1 = IndicatorCreate(_Symbol, PERIOD_CURRENT, IND_MA, ArraySize(params_1), params_1);
        ChartIndicatorAdd(0, i, handle_1);

        MqlParam params_2[3];
        params_2[0].type = TYPE_STRING;
        params_2[0].string_value = "ProblemIndicator";
        params_2[1].type = TYPE_INT;
        params_2[1].integer_value = handle_1;
        params_2[2].type = TYPE_INT;
        params_2[2].integer_value = 0;
        handle_2 = IndicatorCreate(_Symbol, PERIOD_CURRENT, IND_CUSTOM, ArraySize(params_2), params_2);
        ChartIndicatorAdd(0, ++i, handle_2);

        return (INIT_SUCCEEDED);
}

Important:

// on the following value you have to specify the Indicator path
// starting from the "Indicators" directory without the extension

params_2[0].string_value = "ProblemIndicator";

Regards, Cyberglassed.

Stanislav Korotky
17942
Stanislav Korotky 2016.09.07 21:27  

To use your custom indicator in the tester your should use directive #property tester_indicator.

But I'm not sure your method of binding indicators by passing handle via inputs is the best. I'd create MA from your custom indicator. Because the parameters is the same, MT5 will actually create the only one copy of the MA, and both EA and the custom indicator can use it.

Alain Verleyen
Moderator
30775
Alain Verleyen 2016.09.08 16:12  
cyberglassed:

Hello again folks.

I have one Expert Advisor (EA) which loads 2 indicators. Indicator 1 is a moving average (IND_MA / top indicator) and Indicator 2 is a custom indicator (IND_CUSTOM / bottom indicator) which reads the information from the moving average indicator on every tick and output the values of IND_MA rounded to the third digit after the floating point, producing what you can see on the following image:


The EA needs the IND_CUSTOM for it's own functionality. So that's a requirement for it.

My problem is that the EA works OK on the terminal but on the Strategy Tester (ST) the IND_CUSTOM doesn't get any value. as you can see on the following image:

Any idea on how to make the IND_CUSTOM gets the values on the ST, so I can backtesting?

Below you have the code of the IND_CUSTOM and the EA...

Important:


Regards, Cyberglassed.

  • What you are doing is weird.
  • That's a Strategy Tester bug (limitation ?). You should ask to ServiceDesk.
  • You should take the habits to add error checking (most mql5 functions return a value). There is some "hidden" bugs in your code as you don't have sufficient error checking.
  • If you have a Tester.tpl template (attached example), it "works".
Files:
Tester.tpl 4 kb
To add comments, please log in or register