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

MQL5 / Funkcje

HistorySelect

Bez tego wywołania wszystkie funkcje historii zwracają zero. Wyjaśniamy też różnicę między zleceniem, transakcją a pozycją w historii.

bool HistorySelect(datetime od, datetime do);

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

Zawsze najpierw

Funkcje HistoryDealsTotal, HistoryOrdersTotal i wszystkie HistoryXxxGet działają na wcześniej wczytanym zakresie. Bez HistorySelect licznik zwraca zero i wygląda to jak pusty rachunek.

Wczytanie zakresu przed czytaniem historii
if(!HistorySelect(TimeCurrent() - 30 * 24 * 3600, TimeCurrent()))
  {
   Print("Nie udało się wczytać historii.");
   return;
  }

PrintFormat("Transakcji w zakresie: %d", HistoryDealsTotal());

Trzy pojęcia, które łatwo pomylić

PojęcieCzym jest w historii
Zlecenie (order)polecenie, które zostało wykonane lub anulowane
Transakcja (deal)faktyczne wykonanie: wejście, wyjście albo odwrócenie
Pozycja (position)nie istnieje w historii jako osobny obiekt

Pozycji w historii nie ma. Jest tylko zbiór transakcji o wspólnym DEAL_POSITION_ID. Jeśli chcesz wiedzieć, ile zarobiła konkretna pozycja, musisz zsumować transakcje z tym samym identyfikatorem.

Zysk zamkniętych pozycji

Suma wyniku z transakcji zamykających
double PolicZysk(const ulong magic)
  {
   if(!HistorySelect(TimeCurrent() - 30 * 24 * 3600, TimeCurrent()))
      return 0.0;

   double suma = 0.0;

   for(int i = HistoryDealsTotal() - 1; i >= 0; i--)
     {
      ulong bilet = HistoryDealGetTicket(i);
      if(bilet == 0)
         continue;

      if(HistoryDealGetInteger(bilet, DEAL_MAGIC) != (long)magic)
         continue;

      //--- zysk niosą wyłącznie transakcje wyjścia
      if(HistoryDealGetInteger(bilet, DEAL_ENTRY) != DEAL_ENTRY_OUT)
         continue;

      suma += HistoryDealGetDouble(bilet, DEAL_PROFIT)
            + HistoryDealGetDouble(bilet, DEAL_SWAP)
            + HistoryDealGetDouble(bilet, DEAL_COMMISSION);
     }

   return suma;
  }

Dwie rzeczy, które łatwo pominąć: swap i prowizja to osobne pola, a DEAL_PROFIT przy transakcji wejścia zawsze wynosi zero. Sumowanie samego zysku bez kosztów daje wynik ładniejszy od prawdziwego — dokładnie ten sam błąd, który sprawia, że backtesty wyglądają lepiej niż rachunek.

Historia jednej pozycji

Gdy znasz identyfikator pozycji, jest krótsza droga:

Transakcje należące do jednej pozycji
if(HistorySelectByPosition(identyfikator))
   PrintFormat("Transakcji w tej pozycji: %d", HistoryDealsTotal());

Identyfikator bierze się z POSITION_IDENTIFIER otwartej pozycji albo z DEAL_POSITION_ID dowolnej jej transakcji. Nie jest tym samym co bilet pozycji, choć przy prostych rachunkach obie liczby bywają identyczne.

Wydajność

HistorySelect na zakresie „od początku rachunku" przy kilkudziesięciu tysiącach transakcji potrafi zauważalnie spowolnić każde wywołanie OnTick. Wczytuj najkrótszy zakres, który wystarcza, i rób to tylko wtedy, gdy dane są naprawdę potrzebne — nie przy każdym ticku.

Powiązane