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

MQL5 / Funkcje

WebRequest

Pobiera dane z sieci. Wymaga wpisania adresu do ustawień terminala, blokuje wątek na czas odpowiedzi i nie działa ani we wskaźnikach, ani w testerze.

int WebRequest(string metoda, string adres, string naglowki, int limit_ms, const char &dane[], char &wynik[], string &naglowki_odpowiedzi);

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

Co zwraca

Kod odpowiedzi HTTP — na przykład 200 przy powodzeniu — albo -1, gdy zapytanie w ogóle nie wyszło. Rozróżnienie jest istotne: -1 znaczy problem po stronie terminala, każda inna liczba to odpowiedź serwera.

Trzy warunki, bez których nie zadziała

Adres musi być na liście w ustawieniach. Narzędzia → Opcje → Doradcy Ekspert, pole z dozwolonymi adresami URL. Bez tego funkcja zwraca -1 i kod błędu mówiący, że operacja jest niedozwolona. To nie jest błąd w kodzie i żadna zmiana w programie tego nie naprawi.

Adres wpisuje się jako przedrostek, dokładnie w tej postaci, której używasz — https://api.przyklad.pl nie obejmie http://api.przyklad.pl ani innej domeny.

Nie działa we wskaźnikach. W ogóle, niezależnie od ustawień. Wynika to z tego, że wskaźniki jednego symbolu dzielą jeden wątek, a zapytanie sieciowe potrafi trwać sekundy. Właściwym miejscem jest ekspert, skrypt albo usługa.

Nie działa w testerze strategii. Test przebiega bez dostępu do sieci, a wywołanie zwraca błąd. Kod, który pobiera dane z zewnątrz, musi mieć w testerze osobną ścieżkę — na przykład wczytanie zapisanego wcześniej pliku.

Ścieżka zastępcza na czas testu
if(MQLInfoInteger(MQL_TESTER))
  {
   Print("Tester: pomijam zapytanie sieciowe, korzystam z pliku.");
   return;
  }

Wywołanie

Pobranie zawartości adresu metodą GET
char dane[];               // dla GET pusta tablica
char odpowiedz[];
string naglowkiOdpowiedzi;

ResetLastError();

int kod = WebRequest("GET", "https://api.przyklad.pl/dane",
                     "", 5000, dane, odpowiedz, naglowkiOdpowiedzi);

if(kod == -1)
  {
   PrintFormat("Zapytanie nie wyszlo, blad %d. Sprawdz liste adresow "
               "w Narzedzia > Opcje > Doradcy Ekspert.", GetLastError());
   return;
  }

if(kod != 200)
  {
   PrintFormat("Serwer odpowiedzial kodem %d", kod);
   return;
  }

string tresc = CharArrayToString(odpowiedz, 0, WHOLE_ARRAY, CP_UTF8);
PrintFormat("Odebrano %d bajtow", ArraySize(odpowiedz));

Zapytanie blokuje wątek

Funkcja jest synchroniczna. Do czasu odpowiedzi albo upływu limitu ekspert nie robi nic — nie obsługuje ticków, nie zarządza pozycjami, nie reaguje na zdarzenia handlowe.

Konsekwencje są praktyczne:

  • Limit czasu ustawiaj świadomie. Wartość rzędu 5000 milisekund to górna granica rozsądku dla kodu, który przy okazji ma handlować.
  • Nie odpytuj przy każdym ticku. Dane z zewnątrz zmieniają się rzadziej niż cena. Właściwym miejscem jest OnTimer z interwałem liczonym w minutach.
  • Nie odpytuj w OnTradeTransaction. Ta funkcja ma ograniczoną kolejkę zdarzeń i blokowanie jej kończy się gubieniem zdarzeń handlowych.
Odpytywanie z timera, nie z ticku
int OnInit()
  {
   EventSetTimer(300);          // co pięć minut wystarczy
   return INIT_SUCCEEDED;
  }

void OnTimer()
  {
   if(!TerminalInfoInteger(TERMINAL_CONNECTED))
      return;

   //--- tu wywołanie WebRequest i zapis wyniku do zmiennej globalnej
  }

Metoda POST

Przy wysyłaniu danych treść zapytania trafia do tablicy char, a nagłówek z typem zawartości podaje się osobno.

Wysłanie danych metodą POST
string tresc = "{\"symbol\":\"EURUSD\",\"wynik\":123.45}";

char dane[];
StringToCharArray(tresc, dane, 0, StringLen(tresc), CP_UTF8);

char odpowiedz[];
string naglowkiOdpowiedzi;

int kod = WebRequest("POST", "https://api.przyklad.pl/zapis",
                     "Content-Type: application/json\r\n",
                     5000, dane, odpowiedz, naglowkiOdpowiedzi);

Trzeci argument StringToCharArray to długość bez znaku kończącego. Pominięcie go dokleja do treści bajt zerowy, który część serwerów odrzuca jako nieprawidłowy JSON — kolejny przypadek, w którym wina wygląda na leżącą po stronie serwera.

Powiązane