-->

How to read a JSON from a URL in MQL5?

2020-06-29 07:58发布

问题:

How can I read JSON from a url in MQL5?

For example this simple JSON from: https://api.myjson.com/bins/56z28

{ "employees": [ { "firstName": "John",
                   "lastName":  "Doe"
                   },
                 { "firstName": "Anna",
                   "lastName":  "Smith"
                   },
                 { "firstName": "Peter",
                   "lastName":  "Jones"
                   }
                 ]
  }

回答1:

Simple, but restrictions apply.

MetaTrader Terminal 5 is a code-execution environment, that can communicate with an external URL target (if explicitly configured as a permitted URL) via both HTTP/HTTPS protocols over port 80/443 respectively.

   string aCookieHOLDER = NULL,
          aHttpHEADERs;

   char   postBYTEs[],
          replBYTEs[];    
   int    aRetCODE;
   string aTargetURL = "https://api.myjson.com/bins/56z28";

                    /*  to enable access to the URL-> pointed server,
                        you should append "https://api.myjson.com/bins/56z28"
                        to the list of allowed URLs in
                        ( Main Menu -> Tools -> Options, tab "Expert Advisors" ):
                        */
   ResetLastError();                     // Reset the last error code
   int    aTIMEOUT = 5000;               // less than 1 sec. is NOT
                                         // enough for slow Internet connection
   aRetCODE = WebRequest( "GET",
                          aTargetURL,
                          aCookieHOLDER,
                          NULL,
                          aTIMEOUT,
                          postBYTEs,
                          0,
                          replBYTEs,
                          aHttpHEADERs
                          );
   if ( aRetCODE == EMPTY )             // Check errors
   {    Print( "Error in WebRequest(). Error code  = ", GetLastError() );    
     }
   else
   {    // Load was successfull, PROCESS THE STRING ... assumed to be a JSON
   }

As noted in code, to use the WebRequest() function, one has to add the addresses of all the required URLs (servers) a-priori in the list of allowed URLs in the "Expert Advisors" tab of the "Options" window. Server port is automatically selected on the basis of the specified protocol - 80 for "http://" and 443 for "https://" (not a free option...).

The WebRequest() function is synchronous, which means its breaks/blocks(!) the program execution and waits for the response from the requested URL. Since the delays in receiving a response can be large, the function is not available for calls from the indicators, because indicators run in a common thread shared by all indicators and charts on one symbol. Indicator performance delay on one of the charts of a symbol may stop updating of all charts of the same symbol(!!!!).

The function can be called only from Expert Advisors and scripts, as they run in their own execution threads. If you try to call the function from a Custom Indicator, GetLastError() will return error 4060"Function is not allowed for call".

WebRequest() cannot be executed in the Strategy Tester.


Bad news?

If all this sounds as a bad news to your Project, do not give up. MQL code can call DLL-functions, so one can integrate a fair, distributed, non-blocking communicator, that cooperates with MQL code smoothly and does not include any of the above listed limitations in a production system.