Przejdź do treści
MQL5 · MetaTrader 5 · po polsku
kod odczarowany

MQL5 / Z MQL4 na MQL5

IndicatorCounted — z MQL4 na MQL5

Funkcji IndicatorCounted nie ma. Jej rolę przejął argument prev_calculated, ale liczy się inaczej i to jest źródło błędów przy przepisywaniu wskaźników.

2 fragmenty kodu z tej strony przeszły przez kompilator MetaEditor build 6090, 2026-08-05.

Stara postać

MQL4
int start()
  {
   int policzone = IndicatorCounted();
   int limit = Bars - policzone - 1;

   for(int i = limit; i >= 0; i--)
      Bufor[i] = (High[i] + Low[i]) / 2;

   return(0);
  }

IndicatorCounted() zwracało liczbę słupków policzonych przy poprzednim wywołaniu, a zero przy pierwszym.

Nowa postać

Szkielet wskaźnika w MQL5
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1

double Bufor[];

int OnInit()
  {
   SetIndexBuffer(0, Bufor, INDICATOR_DATA);
   return(INIT_SUCCEEDED);
  }

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[])
  {
   //--- od której świecy liczyć
   int start = (prev_calculated > 0) ? prev_calculated - 1 : 0;

   for(int i = start; i < rates_total; i++)
      Bufor[i] = (high[i] + low[i]) / 2.0;

   //--- zwracana wartość trafi do prev_calculated przy następnym wywołaniu
   return(rates_total);
  }

Trzy różnice, które psują przepisany kod

1. Kierunek pętli jest odwrotny. Tablice w OnCalculate domyślnie nie są szeregami — indeks 0 to najstarsza świeca, a rates_total - 1 to bieżąca. W MQL4 było odwrotnie. Pętla for(i = limit; i >= 0; i--) przepisana bez zmian liczy wtedy nie to, co trzeba.

Można to odwrócić i pracować po staremu:

Praca w konwencji MQL4
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(Bufor, true);

Wtedy indeks 0 znów oznacza świecę bieżącą. Wybierz jedną konwencję i trzymaj się jej w całym wskaźniku — mieszanie obu to najpewniejsza droga do wykresu, który wygląda prawie dobrze.

2. prev_calculated to nie to samo co IndicatorCounted. Zwraca wartość, którą ty zwróciłeś przy poprzednim wywołaniu. Jeśli zwrócisz zero, następnym razem wskaźnik przeliczy wszystko od nowa. To bywa użyteczne, gdy wykryjesz, że dane się zmieniły.

3. Ostatnią świecę trzeba przeliczyć ponownie. Przy kolejnym ticku prev_calculated równa się rates_total, ale ostatnia świeca wciąż się zmienia. Stąd prev_calculated - 1 jako punkt startu. Pominięcie tego minus jeden daje wskaźnik, który nie aktualizuje bieżącej świecy.

Tabela zamian

MQL4MQL5
int start()int OnCalculate(...)
IndicatorCounted()argument prev_calculated
Barsargument rates_total
SetIndexBuffer(0, Bufor)SetIndexBuffer(0, Bufor, INDICATOR_DATA)
SetIndexStyle(...)PlotIndexSetInteger(0, PLOT_DRAW_TYPE, ...)
SetIndexLabel(...)PlotIndexSetString(0, PLOT_LABEL, ...)
IndicatorShortName(...)IndicatorSetString(INDICATOR_SHORTNAME, ...)
IndicatorDigits(...)IndicatorSetInteger(INDICATOR_DIGITS, ...)

Powiązane