Работа завершена
Техническое задание
MetaTrader 5, Version: 5.00 build 1375, 15 Jul 2016
Hello, 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. It outputs the following on the Toolbox / Experts window:
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:
I need the IND_CUSTOM gets the values on the ST, so I can do backtesting.
Below you have the code of the IND_CUSTOM and the EA. Please, try it on the terminal first to see how it works, then try it on the ST.
// 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 (MQL_TESTER && GetLastError() == ERR_FUNCTION_NOT_ALLOWED) // on ST "IndicatorParameters" is 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 handle_1, handle_2; int OnInit() { ChartSetInteger(0, CHART_SCALE, 3); ChartSetInteger(0, CHART_MODE, CHART_CANDLES); 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; // buffer index to use handle_2 = IndicatorCreate(_Symbol, PERIOD_CURRENT, IND_CUSTOM, ArraySize(params_2), params_2); ChartIndicatorAdd(0, ++i, handle_2); return (INIT_SUCCEEDED); } void OnTick() { double last_1 = get_last_indicator_value(handle_1); double last_2 = get_last_indicator_value(handle_2); printf("values: %f %f", last_1, last_2); } double get_last_indicator_value(int handle) { // just first buffer double values[1]; int result = CopyBuffer(handle, 0, TimeCurrent(), 1, values); return values[0]; }
Any question, please let me know.
Regards, Cyberglassed.