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.
if(MQLInfoInteger(MQL_TESTER))
{
Print("Tester: pomijam zapytanie sieciowe, korzystam z pliku.");
return;
}Wywołanie
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
OnTimerz interwałem liczonym w minutach. - Nie odpytuj w
OnTradeTransaction. Ta funkcja ma ograniczoną kolejkę zdarzeń i blokowanie jej kończy się gubieniem zdarzeń handlowych.
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.
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.