MQL4:如何从URL读取CSV

时间:2016-09-07 10:19:47

标签: algorithmic-trading mql4 metatrader4 quandl

我正在使用 URL 从Quandl网站上获取一些内容:

https://www.quandl.com/api/v3/datasets/FRED/PAYEMS.csv?exclude_column_names=true&rows=1&api_key=my_api_key

Quandl服务器返回以响应上述请求的值:

2016-08-01, 144598.0

我需要在144598.0 MQL4 中使用 Script , :

Q1。如何从上面的URL中获取内容以在MQL4脚本中使用?

来自SO(https://stackoverflow.com/users/3666197/user3666197)的一位非常有用的用户提供了以下scriptMQL4: Read single value from CSV的原文)(我自己添加了几个部分)来帮助我实现这一目标, ,我无法让它发挥作用:

// Code created with the help of Stack Overflow question
// https://stackoverflow.com/questions/39279634/mql4-read-single-value-from-csv/39284875#39284875
// Question by p.luck:
// https://stackoverflow.com/users/5551849/p-luck
// Answer by user3666197:
// https://stackoverflow.com/users/3666197/user3666197

void OnStart()
{    
     string cookie = NULL,
            headers; 
     char   post[],
            result[]; 
     int    res; 

/*   TODO:                                                                             *
 *   Must allow MT4 to access the server URL,                                          *
 *   you should add URL "https://www.quandl.com/api/v3/datasets/FRED/PAYEMS.csv" *
 *   in the list of allowed URLs                                                       *
 *   ( MT4 -> Tools -> Options -> [Tab]: "Expert Advisors" ):                          */

     string aDataSOURCE_URL = "https://www.quandl.com/api/v3/datasets/FRED/PAYEMS.csv";
     string aDataSOURCE_API = "?exclude_column_names=true&rows=1&api_key=my_api_key";

     //-- Create the body of the POST request for API specifications and API-authorization
     ArrayResize( post,
                  StringToCharArray( aDataSOURCE_API, // string   text             |--> [in]  String to copy.
                                     post,            // uchar   &array[]       <--|    [out] Array of uchar type.
                                     0,               // int      start =  0       |--> [in]  Position from which copying starts. Default - 0. 
                                     WHOLE_ARRAY,     // int      count = -1       |--> [in]  Number of array elements to copy. Defines length of a resulting string. Default value is -1, which means copying up to the array end, or till terminating '\0'. Terminating zero will also be copied to the recipient array, in this case the size of a dynamic array can be increased if necessary to the size of the string. If the size of the dynamic array exceeds the length of the string, the size of the array will not be reduced.
                                     CP_UTF8          // uint     cp    = CP_ACP   |--> [in]  The value of the code page. For the most-used code pages provide appropriate constants.
                                     )
                  - 1
                  );

//-- Reset the last error code
     ResetLastError();

//-- Loading a html page from Quandl
     int timeout = 5000;                                                //-- Timeout below 1000 (1 sec.) is not enough for slow Internet connection

     res = WebRequest( "POST",              // const string  method            |--> [in]  HTTP method.
                        aDataSOURCE_URL,    // const string  URL               |--> [in]  URL.
                        cookie,             // const string  cookie            |--> [in]  Cookie value.
                        NULL,               // const string  referrer          |--> [in]  Value of the Referer header of the HTTP request.
                        timeout,            //       int     timeout           |--> [in]  Timeout in milliseconds.
                        post,               // const char   &data              |--> [in]  Data array of the HTTP message body
                        ArraySize( post ),  //       int     data_size         |--> [in]  Size of the data[] array.
                        result,             //       char   &result         <--|    [out] An array containing server response data.
                        headers             //       string &result_headers <--|    [out] Server response headers.
                        );
//-- Check errors
     if ( res == -1 )
     {    Print( "WebRequest Error. Error code  = ", GetLastError() );  //-- Perhaps the URL is not listed, display a message about the necessity to add the address
          MessageBox( "Add the address '" + aDataSOURCE_URL + "' in the list of allowed URLs on tab 'Expert Advisors'", "Error", MB_ICONINFORMATION );
          }
     else //-- Load was successfull
     {    
          PrintFormat( "The data has been successfully loaded, size = %d bytes.", ArraySize( result ) );

          //-- parse the content ---------------------------------------
          /*
              "2016-08-01, 144598.0"

          */
          //-- consume the content -------------------------------------
          //...


          }
     }

我已将URL的{​​{1}}添加到https://www.quandl.com/api/v3/datasets/FRED/PAYEMS.csv的{​​{1}}列表中。

如果我启用allowed URLs并将名为(MT4)的AutoTrading拖至script tutorial7,我会得到chart USDCAD,M1中的这些消息:

  • Experts
  • tab
  • Script tutorial7 USDCAD,M1: loaded successfuly
  • tutorial7 USDCAD,M1: initialized

当然,如果&#34; tutorial7 USDCAD,M1: The data has been successfully loaded, size = 0 bytes&#34;它不应该说&#34; tutorial7 USDCAD,M1: uninit reason 0&#34;?

如果我将The data has successfully loaded直接复制并粘贴到size = 0 bytesscript,这个MetaQuotes Language Editor是否正常工作?

除了将compile添加到URL中的allowed URLs并将此代码复制并粘贴到MT4之外,还有什么我必须做的吗?

若然,怎么样?

我将上述代码作为script 而不是Script运行;这没关系吗?

Q2。我可以将获取的值144598.0设置为我脚本中的变量吗?

我需要将Expert Advisor value作为变量,以便将其与另一个144598.0进行比较。

这样的事情会起作用吗?

value

1 个答案:

答案 0 :(得分:1)

A2:是的! 这是旅程中最简单的部分。
A1:但是!如何在实践中发挥作用?
MetaTrader终端< / kbd>实际上和Quandl说话,所以要得到它?

首先让我说明远程HttpServer - 侧处理的问题。

有一个简单的原型程序 curl (可用的Linux和DOS版本)将显示在终端窗口(或Windows cmd窗口)Quandl上的远程HttpServer如何响应通过HTTP协议传送的本地组合请求的各种组合。

请注意,刚刚重新输入的URL会生成要传递的整个历史记录。

C:\>curl https://www.quandl.com/api/v3/datasets/FRED/PAYEMS.csv
DATE,VALUE
2016-08-01,144598.0
2016-07-01,144447.0
...
..
.
1939-03-01,30280.0
1939-02-01,30101.0
1939-01-01,29923.0

一旦我们向普通URL添加了更多参数,远程端(HttpServer)会将回复更改为我们感兴趣的一行:

C:\>curl -G --data rows=1 --data exclude_column_names=true https://www.quandl.com/api/v3/datasets/FRED/PAYEMS.csv
2016-08-01,144598.0

酷,看起来很棒,几乎是我们想要的单一价值!

但魔法来了。

本地流程(现在curl,但稍后MetaTrader终端)之间的真实交换(对话)看起来是这样的(使用--verbose中的 curl 选项}命令行):

C:\>curl --verbose -G --data rows=1 --data exclude_column_names=true https://www.quandl.com/api/v3/datasets/FRED/PAYEMS.csv
*   Trying 54.174.87.84...
* Connected to www.quandl.com (54.174.87.84) port 443 (#0)
* schannel: SSL/TLS connection with www.quandl.com port 443 (step 1/3)
* schannel: checking server certificate revocation
* schannel: sending initial handshake data: sending 70 bytes...
* schannel: sent initial handshake data: sent 70 bytes
* schannel: SSL/TLS connection with www.quandl.com port 443 (step 2/3)
* schannel: failed to receive handshake, need more data
* schannel: SSL/TLS connection with www.quandl.com port 443 (step 2/3)
* schannel: encrypted data buffer: offset 4096 length 4096
* schannel: encrypted data length: 4017
* schannel: encrypted data buffer: offset 4017 length 4096
* schannel: received incomplete message, need more data
* schannel: SSL/TLS connection with www.quandl.com port 443 (step 2/3)
* schannel: encrypted data buffer: offset 4569 length 5041
* schannel: sending next handshake data: sending 318 bytes...
* schannel: SSL/TLS connection with www.quandl.com port 443 (step 2/3)
* schannel: encrypted data buffer: offset 51 length 5041
* schannel: SSL/TLS handshake complete
* schannel: SSL/TLS connection with www.quandl.com port 443 (step 3/3)
* schannel: incremented credential handle refcount = 1
* schannel: stored credential handle in session cache
> GET /api/v3/datasets/FRED/PAYEMS.csv?rows=1&exclude_column_names=true HTTP/1.1
> Host: www.quandl.com
> User-Agent: curl/7.45.0
> Accept: */*
>
* schannel: client wants to read 16384 bytes
* schannel: encdata_buffer resized 17408
* schannel: encrypted data buffer: offset 0 length 17408
* schannel: encrypted data got 653
* schannel: encrypted data buffer: offset 653 length 17408
* schannel: decrypted data length: 623
* schannel: decrypted data added: 623
* schannel: decrypted data cached: offset 623 length 16384
* schannel: encrypted data buffer: offset 0 length 17408
* schannel: decrypted data buffer: offset 623 length 16384
* schannel: schannel_recv cleanup
* schannel: decrypted data returned 623
* schannel: decrypted data buffer: offset 0 length 16384
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Disposition: attachment; filename=FRED-PAYEMS.csv
< Content-Transfer-Encoding: binary
< Content-Type: text/csv
< Date: Wed, 07 Sep 2016 12:47:20 GMT
< ETag: W/"adfdb97850c493cdd03e2036574bc404"
< Server: openresty
< Vary: Origin
< X-API-Version: 2015-04-09
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< X-Rack-CORS: preflight-hit; no-origin
< X-RateLimit-Limit: 50
< X-RateLimit-Remaining: 42
< X-Request-Id: c609e92d-22d2-40e7-b7d4-cacb07467c76
< X-Runtime: 0.023534
< X-XSS-Protection: 1; mode=block
< Content-Length: 20
< Connection: keep-alive
<
2016-08-01,144598.0
* Connection #0 to host www.quandl.com left intact

注意 GET /api/v3/datasets/FRED/PAYEMS.csv?rows=1&exclude_column_names=true

所以神奇的是让MetaTrader终端组装相同的东西,同时允许配置中允许列表中的URL(你已经在另一篇文章中已经完成)。

也可能已经注意到, HTTP GET 仅发送<HttpServer_relative_part_of_the.URL>

神奇的做法是让 MQL4 代码发送与上面相同的请求并获取数据。

由于Quandl WebRequest()未对 HTTP GET 版本的相同的请求示例,返回0个字节(只省略上面HttpServer示例中的HTTP POST开关。)

一次满足所有条件应该会收到 -G 并使用:

curl