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

MQL5 / Pułapki

Iluzja czasu: strefy czasowe i zmiana czasu

Czas brokera nie jest czasem londyńskim ani twoim. Dlaczego strategia oparta na godzinach działa przez pół roku i jak liczyć czas od GMT.

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

Początkujący programiści MQL5 rzadko zastanawiają się nad czasem, dopóki nie napiszą strategii opartej na konkretnych godzinach (np. "Otwórz pozycję o 8:00 rano" lub "Zamknij wszystko o 17:00"). Wtedy zazwyczaj używają funkcji TimeCurrent() i na początek wszystko działa idealnie w Testerze Strategii. Problemy zaczynają się, gdy EA zostanie wdrożone na konto rzeczywiste na VPS, a po kilku tygodniach nagle przestaje otwierać zlecenia albo robi to o godzinę za wcześnie. Winowajcą jest najczęściej nieodpowiednie zrozumienie stref czasowych i zjawiska DST (Daylight Saving Time - czas letni/zimowy).

W tym artykule przeprowadzimy dogłębną analizę tego, jak MQL5 zarządza czasem, dlaczego czas brokera nie jest czasem uniwersalnym i jak napisać kod odporny na zmiany czasu.

1. Czas Serwera (TimeCurrent) vs Czas Lokalny (TimeLocal)

MQL5 posiada trzy główne funkcje czasowe. Zrozumienie różnic między nimi to absolutny fundament:

  • TimeCurrent(): Zwraca czas serwera brokera. To ten czas widzisz na osi X wykresu. Zależy wyłącznie od tego, gdzie fizycznie stoi serwer brokera i jaką strefę ma ustawioną w konfiguracji MT5.
  • TimeLocal(): Zwraca czas lokalny komputera (lub VPS), na którym uruchomiony jest terminal. Zależy od ustawień systemu operacyjnego.
  • TimeGMT(): Zwraca uniwersalny czas Greenwich (UTC). Obliczany na podstawie TimeLocal() i ustawień strefy czasowej systemu operacyjnego.
Iluzja czasu: strefy czasowe i zmiana czasuCzas brokera nie jest czasem londyńskim ani twoim. Dlaczego strategia oparta na godzinach działa przez pół roku i jak liczyć czas od GMT. Trzy wymiary czasu w MQL5 TimeGMT() Uniwersalny Baza do obliczeń np. 12:00 UTC TimeLocal() Czas Twojego VPS Zależny od Windowsa np. 14:00 (CEST) TimeCurrent() Czas Brokera Oś wykresu np. 15:00 (EET)

2. Pułapka Zmiany Czasu (DST - Daylight Saving Time)

Rynki finansowe mają swoją geometrię. Otwarcie giełdy w Londynie zawsze odbywa się o 8:00 czasu lokalnego. Jednak dla reszty świata ta godzina przesuwa się dwa razy w roku. Pod koniec marca Europa przechodzi na czas letni (CEST, UTC+2), a pod koniec października na zimowy (CET, UTC+1). Ameryka również zmienia czas, ale w inne dni niż Europa! Powstaje tzw. "Okno asymetrii" (zwykle przez 2 tygodnie w roku), gdzie różnica czasu między Londynem a Nowym Jorkem wynosi 4 godziny zamiast standardowych 5.

Jeśli Twój EA hardcoduje (na sztywno wpisuje) np. if(Hour() == 8) bazując na czasie TimeCurrent(), strategia ta będzie działać źle przez połowę roku. Co gorsza, jeśli przeniesiesz EA do brokera z innej strefy czasowej, przestanie działać w ogóle.

3. Wzorzec "Safe Time": Liczenie od GMT

Jedynym profesjonalnym sposobem radzenia sobie z czasem w tradingu algorytmicznym jest sprowadzenie wszystkiego do czasu GMT (UTC). Sesja londyńska w czasie zimowym zaczyna się o 8:00 GMT, a w letnim o 7:00 GMT. Zamiast zgadywać, jaki jest stan DST w Londynie, użyjmy prostej matematyki.

// Sprawdza czy obecny czas przypada w sesji londyńskiej
// bazując na uniwersalnym czasie GMT
bool IsLondonSession() {
    // Zawsze używamy TimeGMT(). Zwraca uwagę na wielkość liter!
    datetime gmtTime = TimeGMT();
    MqlDateTime dt;
    TimeToStruct(gmtTime, dt);
    
    // Sesja londyńska: 8:00 - 16:00 czasu lokalnego Londynu.
    // Londyn zimą: UTC+1 -> Sesja 7:00 - 15:00 UTC
    // Londyn latem: UTC+0 -> Sesja 8:00 - 16:00 UTC
    
    // Aby uniknąć skomplikowanego sprawdzania dat zmiany czasu,
    // można przyjąć uproszczony model: lato = kwiecień-październik
    bool isSummerTime = (dt.mon >= 4 && dt.mon <= 10);
    
    int startHour = isSummerTime ? 8 : 7; // GMT godziny
    int endHour = isSummerTime ? 16 : 15;
    
    if(dt.hour >= startHour && dt.hour < endHour) {
        return true;
    }
    
    return false;
}

void OnTick() {
    if(IsLondonSession()) {
        // Logika handlowa
    }
}

4. Pułapka Tester Strategii: Oszustwo TimeTradeServer()

W MQL5 wprowadzono funkcję TimeTradeServer(). Według dokumentacji ma ona zwracać "obliczony czas serwera". Niestety, jest to funkcja, która polega na zgraniu TimeLocal() z ostatnio znanym offsetem serwera. W środowisku rzeczywistym potrafi ona zwracać dziwne wartości, jeśli połączenie z serwerem zostało zerwane.

Jednak prawdziwym problemem jest to, że Tester Strategii w MQL5 nie symuluje czasu lokalnego ani GMT!. W Testerze TimeLocal() i TimeGMT() zwracają dokładnie to samo co TimeCurrent() (czyli czas brokera ustawiony w teście). Oznacza to, że jeśli Twój kod opiera się na strefach czasowych (jak w powyższym przykładzie z sesją londyńską), Tester Strategii daje fałszywe poczucie bezpieczeństwa. Backtest może pokazać zysk, ponieważ Tester założył, że czas brokera to czas GMT, podczas gdy na koncie rzeczywistym offset będzie zupełnie inny.

5. Pobieranie czasu świecy na wyższym interwale

Częstym błędem przy sprawdzaniu, czy minął dany dzień, jest odpytywanie funkcji TimeCurrent(). Pamiętaj, że ticki mogą nie przychodzić przez kilka sekund (lub minut na mało płynnych parach). Zawsze sprawdzaj czas otwarcia świecy D1, jeśli chcesz wiedzieć, czy "rozpoczął się nowy dzień handlowy".

datetime lastCheckedDay = 0;

void OnTick() {
    // Pobieramy czas otwarcia dzisiejszej świecy D1
    // To jest niezależne od płynności i ticków. D1 świeca powstaje na serwerze.
    datetime today = iTime(_Symbol, PERIOD_D1, 0);
    
    if(today != lastCheckedDay) {
        lastCheckedDay = today;
        Print("Nowy dzień handlowy! Czas serwera: ", TimeToString(today));
        // Tu wykonujemy logikę dzienną (np. przesuwanie stopów, przeliczanie wskaźników D1)
    }
}

Podsumowanie

Czas w algorytmicznym tradingu to zmienna, która wydaje się trywialna, dopóki nie zderzy się z realiami globalnego rynku. Nigdy nie ufaj czasowi serwera (TimeCurrent) jako punktowi odniesienia dla zdarzeń geograficznych. Zawsze sprowadzaj logikę do czasu UTC/GMT używając TimeGMT(), pamiętając o jego zależności od systemu operacyjnego. Zrozumienie, że tester MT5 "fałszuje" strefy czasowe na potrzeby uproszczenia symulacji, uchroni Cię przed katastrofalnymi błędami wdrożeniowymi. Czas to nie tylko liczba na osi wykresu, to architektura synchronizacji Twojego algorytmu ze światem.

Powiązane