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

MQL5 / Pułapki

OnTick nie przychodzi, choć rynek się rusza

Brak ticków w weekend, luki cenowe i instrumenty o niskiej płynności. Dlaczego wykrywanie nowej świecy wyłącznie w OnTick bywa zawodne.

1 fragment kodu z tej strony przeszedł przez kompilator MetaEditor build 6090, 2026-08-05.

Funkcja OnTick() to serce każdego Eksperta (EA). Początkujący programiści często zakładają, że kod wewnątrz tej funkcji wykona się dokładnie raz dla każdej zmiany ceny. Niestety, rzeczywistość rynkowa i architektura MT5 bywają bezlitosne. Niezrozumienie modelu zdarzeń prowadzi do gubienia zleceń i błędów w zarządzaniu pozycjami.

Brak Ticków w Weekendy i Gapsy

OnTick() nie wywoła się, jeśli nie ma nowych kwotowań. Jeśli rynek otworzy się z luką (gap) w poniedziałek, Twój EA może zostać zmuszony do obsługi ogromnego ruchu z opóźnieniem. Co gorsza, jeśli używasz wewnętrznych zmiennych statycznych do śledzenia poprzedniej ceny, mogą one być całkowicie nieaktualne po weekendzie.

OnTick nie przychodzi, choć rynek się ruszaBrak ticków w weekend, luki cenowe i instrumenty o niskiej płynności. Dlaczego wykrywanie nowej świecy wyłącznie w OnTick bywa zawodne. Czas Tick BRAK ONTICK (Weekend) Gap & Pierwszy Tick! Tutaj ratuje OnTimer()

Paradoks OnTick vs OnTimer

Częstym błędem jest umieszczanie logiki wysyłającej zlecenia (np. sprawdzanie warunków wejścia na rynek) wewnątrz OnTimer(), podczas gdy logika zarządzania pozycjami (Trailing Stop) znajduje się w OnTick(). To prowadzi do problemów z synchronizacją. OnTimer() powinien być używany do odświeżania interfejsu, wykrywania nowych świec na wyższych interwałach lub jako "watchdog" dla OnTick(), gdy kwotowania są rzadkie.

datetime lastBarTime;

void OnInit() {
    // Ustawiamy timer na 1 sekundę jako mechanizm zapasowy
    EventSetTimer(1);
    lastBarTime = iTime(_Symbol, PERIOD_M1, 0);
}

void OnTick() {
    // Główna logika handlowa - działa przy każdej zmianie ceny
    CheckForEntry();
}

void OnTimer() {
    // Wykrywanie nowej świecy, gdy rynek jest bardzo płaski
    // i OnTick() nie wywołuje się przez długi czas
    datetime currentBarTime = iTime(_Symbol, PERIOD_M1, 0);
    if(currentBarTime != lastBarTime) {
        lastBarTime = currentBarTime;
        Print("Wykryto nową świecę w OnTimer (rynek może być wolny)");
        ManageOpenPositions();
    }
}
    

Zauważ, że poleganie wyłącznie na OnTick() do wykrywania zamknięcia świecy jest niebezpieczne na instrumentach o niskiej płynności. Może dojść do sytuacji, w której świeca M1 zamknie się, ale nowy tick pojawi się dopiero po 2 sekundach. Wtedy EA wykona akcję z opóźnieniem, co przy ustawieniach typu "Execute on Close" może skutkować gorszą ceną wejścia (slippage).