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

MQL5 / Funkcje

OrderSendAsync

Zlecenie wysłane asynchronicznie wraca natychmiast, zanim serwer cokolwiek zrobi. Jak śledzić jego stan i dlaczego lokalna baza bywa nieaktualna.

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

Jednym z najbardziej bolesnych doświadczeń dla programistów przechodzących z MQL4 do MQL5 (lub z języków skryptowych takich jak Python do algorytmicznego tradingu) jest zderzenie z asynchroniczną naturą wysyłania zleceń. W MQL4 funkcja OrderSend była blokująca – program czekał na odpowiedź serwera, a po jej zakończeniu zlecenie było już w systemie. W MQL5 ten paradygmat uległ drastycznej zmianie.

Wielu początkujących programistów pisze kod, który wysyła zlecenie, a w kolejnej linijce sprawdza, czy pozycja została otwarta, używając do tego np. PositionsTotal(). Prowadzi to do katastrofalnych w skutkach błędów logicznych: zlecenia nie ma, bo serwer jeszcze go nie przetworzył, a EA uznaje, że wystąpił błąd i próbuje wysłać je ponownie, zazwyczaj kończąc z dziesiątkami duplikatów.

Podział ról: Wątek Klienta a Wątek Sieciowy

Terminal MetaTrader 5 zarządza komunikacją sieciową w osobnym wątku. Kiedy wywołujesz OrderSend() (wersja synchroniczna w MQL5), terminal w rzeczywistości oddaje żądanie do wątku sieciowego i czeka na wynik. To "czekanie" jest w MQL5 często przerywane przez timeouty. Jednak prawdziwa moc (i problematyczność) leży w funkcji OrderSendAsync().

OrderSendAsyncZlecenie wysłane asynchronicznie wraca natychmiast, zanim serwer cokolwiek zrobi. Jak śledzić jego stan i dlaczego lokalna baza bywa nieaktualna. Porównanie: Synchroniczne vs Asynchroniczne OrderSend OrderSend() (Synchroniczne) EA: Wysyła żądanie BLOKUJE wątek EA... Sieć: Oczekuje na serwer EA: Wznawia pracę OrderSendAsync() EA: Wysyła żądanie Natychmiast! EA: Dalsza logika Sieć: W tle OnTradeTransaction(): Potwierdzenie

Stan Transakcji: Maszyna Stanów (State Machine)

W MQL5 zlecenie przechodzi przez wiele etapów: ORDER_STATE_STARTED, ORDER_STATE_PLACED, ORDER_STATE_PARTIAL, ORDER_STATE_FILLED itd. Aby bezpiecznie zarządzać asynchronicznymi zleceniami, musisz zaimplementować maszynę stanów opartą na zdarzeniach. Służy do tego funkcja OnTradeTransaction().

// Zmienna globalna śledząca stan naszego oczekującego zlecenia
ulong pendingOrderTicket = 0;

void OpenPositionAsync() {
    MqlTradeRequest request = {};
    MqlTradeResult result = {};
    
    request.action = TRADE_ACTION_DEAL;
    request.symbol = _Symbol;
    request.volume = 0.1;
    request.type = ORDER_TYPE_BUY;
    request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
    request.deviation = 20;
    request.magic = 12345;
    
    // Wysyłamy asynchronicznie. Funkcja wraca natychmiast.
    if(OrderSendAsync(request, result)) {
        if(result.retcode == TRADE_RETCODE_PLACED || result.retcode == TRADE_RETCODE_DONE) {
            pendingOrderTicket = result.order;
            Print("Zlecenie wysłane, czekam na potwierdzenie. Ticket: ", pendingOrderTicket);
        }
    } else {
        Print("Błąd wysyłania asynchronicznego: ", GetLastError());
    }
}

// To jest nasz "wywoływacz zwrotny" (callback) z wątku sieciowego
void OnTradeTransaction(const MqlTradeTransaction& trans, const MqlTradeRequest& request, const MqlTradeResult& result) {
    // Interesują nas tylko zdarzenia dotyczące zleceń
    if(trans.type == TRADE_TRANSACTION_ORDER_ADD ||
       trans.type == TRADE_TRANSACTION_ORDER_UPDATE) {
        if(trans.order == pendingOrderTicket) {
            // Sprawdzamy aktualny stan zlecenia na serwerze
            if(trans.order_state == ORDER_STATE_FILLED) {
                Print("Zlecenie zrealizowane! Pozycja otwarta.");
                pendingOrderTicket = 0; // Resetujemy
            } else if(trans.order_state == ORDER_STATE_REJECTED) {
                Print("Zlecenie odrzucone przez serwer! Kod: ", result.retcode);
                pendingOrderTicket = 0;
            }
        }
    }
}

Zrozumienie asynchroniczności to nie tylko kwestia uniknięcia błędów, ale przede wszystkim optymalizacji HFT (High-Frequency Trading). Wykorzystując OrderSendAsync w połączeniu z OnTradeTransaction, EA może wysyłać setki zleceń na sekundę bez blokowania głównego wątku przetwarzającego ticki.