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.
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ęcie | Czym 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
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:
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.