WebRequest関数でデータを取得する方法と簡易表示の仕方
OnTimer関数を利用
この記事では、Webデータを取得するためのWebRequest関数を利用して、インターネット上の文字列データを取得し、その取得した文字列データから情報を抽出のうえ簡易表示する方法を解説します。
まず、ファイルを新規作成する注意点として、WebRequest関数はEA(エキスパートアドバイザ)専用であり、カスタムインディケータでは使えません。そのため、メタエディターを開いて「新規作成ボタン」をクリックしたら、「エキスパートアドバイザ(テンプレート)」にチェックを入れて「次へ」を押します。
ここではファイルの名前を「WebRequest_demo」とし、土日等でも動くようにするため「エキスパートアドバイザのイベントハンドラ」で「OnTimer」にチェックを入れて「次へ」をクリックします。「エキスパートアドバイザのテスターイベントハンドラ」では何も操作せず、「完了」をクリックすればファイルの完成です。
まずタイマーの設定をしましょう。今回、最初は1秒ごとに処理を実施し、それ以降は1時間ごとに動くように設定するので、OnTimer配下に次のコードを記述します。
void OnTimer()
{
//---
static int timeHour = -1;
if (Hour() == timeHour) return;
timeHour = Hour();
このif文は、「もし時間が変わらないようだったら、そこで計算は終わり」という指示です。現在時間を格納し、それが切り替わらなかった場合には計算が行われません。0時の場合を考慮して初期値は「-1」としています。
これで、最初はすぐに処理を実施して、その後は1時間ごとに処理するコードが作成できました。
データを取得する先のURLを指定
WebRequest関数のサンプルコードは、MQL4リファレンスから拝借します。MQL4リファレンスの目次にある「Common Functions」→「WebRequest」をクリックし、そのページ内にある下記コードをOnTimer配下に貼り付けます。
string cookie=NULL,headers;
char post[],result[];
int res;
//--- to enable access to the server, you should add URL "https://www.google.com/finance"
//--- in the list of allowed URLs (Main Menu->Tools->Options, tab "Expert Advisors"):
string google_url="https://www.google.com/finance";
//--- Reset the last error code
ResetLastError();
//--- Loading a html page from Google Finance
int timeout=5000; //--- Timeout below 1000 (1 sec.) is not enough for slow Internet connection
res=WebRequest("GET",google_url,cookie,NULL,timeout,post,0,result,headers);
//--- Checking errors
if(res==-1)
{
Print("Error in WebRequest. Error code =",GetLastError());
//--- Perhaps the URL is not listed, display a message about the necessity to add the address
MessageBox("Add the address '"+google_url+"' in the list of allowed URLs on tab 'Expert Advisors'","Error",MB_ICONINFORMATION);
}
else
{
//--- Load successfully
PrintFormat("The file has been successfully loaded, File size =%d bytes.",ArraySize(result));
//--- Save the data to a file
int filehandle=FileOpen("GoogleFinance.htm",FILE_WRITE|FILE_BIN);
//--- Checking errors
if(filehandle!=INVALID_HANDLE)
{
//--- Save the contents of the result[] array to a file
FileWriteArray(filehandle,result,0,ArraySize(result));
//--- Close the file
FileClose(filehandle);
}
else Print("Error in FileOpen. Error code=",GetLastError());
}
こちらのサンプルは、Googleのサイトにアクセスして、そこから取得したデータをファイルに保存するコードです。
今回は「ファイルに保存」を実行しないので、「//— Save the data to a file」以下を削除します。また、Googleではなく経済指標の発表時間やイベント内容などを公開している「Yahoo!ファイナンス」のページにアクセスするようにしたいので、「google」に関連する箇所を削除しURLを「https://m.finance.yahoo.co.jp/fx/marketcalendar」に修正します。
下記の赤字箇所が修正した部分です。
string cookie = NULL, headers;
char post[], result[];
int res;
//--- to enable access to the server, you should add URL
//--- in the list of allowed URLs (Main Menu->Tools->Options, tab "Expert Advisors"):
string url = "https://m.finance.yahoo.co.jp/fx/marketcalendar";
//--- Reset the last error code
ResetLastError();
//--- Loading a html page
int timeout = 5000; //--- Timeout below 1000 (1 sec.) is not enough for slow Internet connection
res = WebRequest("GET", url, cookie, NULL, timeout, post, 0, result, headers);
//--- Checking errors
if(res == -1) {
Print("Error in WebRequest. Error code =", GetLastError());
//--- Perhaps the URL is not listed, display a message about the necessity to add the address
MessageBox("Add the address '" + url + "' in the list of allowed URLs on tab 'Expert Advisors'", "Error", MB_ICONINFORMATION);
} else {
//--- Load successfully
PrintFormat("The file has been successfully loaded, File size =%d bytes.", ArraySize(result));
これで、指定したURLのページからデータを受け取り、定義したresult配列にそのデータが格納されます。今回はその配列をstring型に変換し、Comment関数を利用して変換したデータをチャートに表示したいので、最後に次の式を加えましょう。
string text = CharArrayToString(result);
Comment(text);
これで変換したデータを表示できる状態です。
アクセス先のサイトを登録
Comment関数を利用して変換したデータを表示できます。しかし、WebRequest関数を使う場合は、MT4側でそれを許可する設定が必要です。
MT4のメニューにある「ツール」→「オプション」をクリックして「エキスパートアドバイザ」タブを選択し、「WebRequestを許可するURLリスト」にチェックを入れて、アクセス先のURLを登録します。今回は「Yahoo!ファイナンス」のページにアクセスするので、「https://m.finance.yahoo.co.jp」を追加して「OK」をクリックしましょう。
URL登録後にコンパイルした「WebRequest_demo」をチャートにセットすると、「https://m.finance.yahoo.co.jp/fx/marketcalendar」のページのソース(Yahoo!ファイナンスの経済指標ページ上で右クリック→「ページのソースを表示」を選択すると出てくるソース)がそのまま表示されることが分かります。
表示されたソースを見ると、文字コードを指定していないので文字化けした状態です。これを解消するには、配列をストリング型に変換する「CharArrayToString」という関数で次のようにパラメーターを指定します。
string text = CharArrayToString(result, 0, WHOLE_ARRAY, CP_UTF8);
このコードは、配列の0番目から全体を変換し、「UTF8」の文字コードを指定するという意味です。これでコンパイルすると、文字化けが解消されます。
経済指標のデータを抽出
続いて、表示されたソースの中から経済指標のデータを抽出していきましょう。Yahoo!ファイナンスの経済指標ページのソースを確認すると、経済指標の時間情報の前には必ず「”time”>」という7文字の文字列があるので、これをまず見つけて、そこから検索していくロジックを組みます。
ここではfor文を利用して、文字列の中を検索していきます。テキスト文字列の0番目から文字数全てを検索するように指定したいので、「StringLen」という文字列の文字数を返す関数を使います。
for (int i = 0; i < StringLen(text); i++) {
次に「StringSubstr」関数で、指定した位置から文字列を抽出します。テキストのi番目の文字から7文字を抽出し、「"time">」と一致したときに処理を実施するように、次の式を加えます。ダブルクォーテーションを文字列として認識させるには、その前に「¥」マークを入れる必要があります。
if (StringSubstr(text, i, 7) == "\"time\">") {
これで「"time">」の位置を見つけることができるので、先頭の「"」の位置の7文字後ろから5文字を抽出するよう、次のように指定します。先頭の「"」の7文字後ろから5文字というのは、経済指標が発表される時間の部分に該当します。
string strTime = StringSubstr(text, i + 7, 5);
最後に、「str += strTime + "\n";」という式を加えれば、抽出した経済指標の発表時間が改行して表示されます。
for (int i = 0; i < StringLen(text); i++) {
if (StringSubstr(text, i, 7) == "\"time\">") {
string strTime = StringSubstr(text, i + 7, 5);
str += strTime + "¥n";
}
}
Comment(str);
経済指標の★マークを抽出
続いて、時間のあとに続く重要度を示す★マークを抽出したいと思います。
経済指標ページの★マークは必ず1~3個あるので、まず★マークの場所を探します。そして、★マークのあとに出る「</span>」という文字列を利用します。★マークがあるかどうかを探す処理として、「StringFind」という関数を用いた次の式を入れましょう。
int posStar0 = StringFind(text, "★", i);
StringFind関数の設定項目 | |
---|---|
string_value | 検索が行われる文字列を指定 |
match_substring | 検索する文字列を指定 |
start_pos | 検索を開始する文字列位置を指定 |
次に終わりの位置ですが、探す文字列は「</span>」、検索を開始する場所は★を見つけた後とします。
int posStar1 = StringFind(text, "", posStar0);
そして、この位置情報を利用して、stringでstrStarを定義します。始まりの場所は「posStar0」、文字の長さは「文字が終わる位置(posStar1)」-「文字の始まる位置(posStar0)」です。
string strStar = StringSubstr(text, posStar0, posStar1 - posStar0);
文字列を表示させるための式「str += strTime + "\n";」に★マークの表示「strStar」を加えてコンパイルすると、時間の後ろに★マークが表示されるのが確認できます。
str += strTime + " " + strStar + "¥n";
経済指標のイベント内容を抽出
同様に、今度は経済指標のイベント内容を抽出します。イベントの始まりの部分を検出するのに「]</span>」という文字列を、終わりについては毎回「</dt>」というタグが出てくるのでこれを利用し、次の式を加えましょう。
int posEvent0 = StringFind(text, "]", i) + 8;
int posEvent1 = StringFind(text, "", posEvent0);
string strEvent = StringSubstr(text, posEvent0, posEvent1 - posEvent0);
最初に見つける「]</span>」は8文字なので、この文字を見つけた8文字あとがイベントの文字列の開始となり、終わりは「</dt>」です。長さは「イベントの文字列が終わる位置(posEvent1)」-「イベントの文字列が始まる位置(posEvent0)」です。
先程の文字列を表示させるための式「str += strTime + " " + strStar + "\n";」に、イベントの表示「strEvent」を加えれば完成です。
str += strTime + " " + strStar + " " + strEvent + "¥n";
これでコンパイルすると、時間、★マーク、イベント内容の三つが表示されます。Web上からきちんとデータを抽出できていることが分かります。
ソースコード
今回、作成したソースコードは下記の通りです。
//+------------------------------------------------------------------+
//| WebRequest_demo.mq4 |
//| Copyright 2021, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- create timer
EventSetTimer(1);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- destroy timer
EventKillTimer();
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
}
//+------------------------------------------------------------------+
//| Timer function |
//+------------------------------------------------------------------+
void OnTimer()
{
//---
static int timeHour = -1;
if (Hour() == timeHour) return;
timeHour = Hour();
string cookie = NULL, headers;
char post[], result[];
int res;
//--- to enable access to the server, you should add URL
//--- in the list of allowed URLs (Main Menu->Tools->Options, tab "Expert Advisors"):
string url = "https://m.finance.yahoo.co.jp/fx/marketcalendar";
//--- Reset the last error code
ResetLastError();
//--- Loading a html page
int timeout = 5000; //--- Timeout below 1000 (1 sec.) is not enough for slow Internet connection
res = WebRequest("GET", url, cookie, NULL, timeout, post, 0, result, headers);
//--- Checking errors
if(res == -1) {
Print("Error in WebRequest. Error code =", GetLastError());
//--- Perhaps the URL is not listed, display a message about the necessity to add the address
MessageBox("Add the address '" + url + "' in the list of allowed URLs on tab 'Expert Advisors'", "Error", MB_ICONINFORMATION);
} else {
//--- Load successfully
PrintFormat("The file has been successfully loaded, File size =%d bytes.", ArraySize(result));
string text = CharArrayToString(result, 0, WHOLE_ARRAY, CP_UTF8);
string str = NULL;
for (int i = 0; i < StringLen(text); i++) {
if (StringSubstr(text, i, 7) == "\"time\">") {
string strTime = StringSubstr(text, i + 7, 5);
int posStar0 = StringFind(text, "★", i);
int posStar1 = StringFind(text, "", posStar0);
string strStar = StringSubstr(text, posStar0, posStar1 - posStar0);
int posEvent0 = StringFind(text, "]", i) + 8;
int posEvent1 = StringFind(text, "", posEvent0);
string strEvent = StringSubstr(text, posEvent0, posEvent1 - posEvent0);
str += strTime + " " + strStar + " " + strEvent + "¥n";
}
}
Comment(str);
}
}
//+------------------------------------------------------------------+
本記事の監修者・HT FX
2013年にFXを開始し、その後専業トレーダーへ。2014年からMT4/MT5のカスタムインジケーターの開発に取り組む。ブログでは100本を超えるインジケーターを無料公開。投資スタイルは自作の秒足インジケーターを利用したスキャルピング。
EA(自動売買)を学びたい方へオススメコンテンツ

OANDAではEA(自動売買)を稼働するプラットフォームMT4/MT5の基本的な使い方について、画像や動画付きで詳しく解説しています。MT4/MT5のインストールからEAの設定方法までを詳しく解説しているので、初心者の方でもスムーズにEA運用を始めることが可能です。またOANDAの口座をお持ちであれば、独自開発したオリジナルインジケーターを無料で利用することもできます。EA運用をお考えであれば、ぜひ口座開設をご検討ください。
本ホームページに掲載されている事項は、投資判断の参考となる情報の提供を目的としたものであり、投資の勧誘を目的としたものではありません。投資方針、投資タイミング等は、ご自身の責任において判断してください。本サービスの情報に基づいて行った取引のいかなる損失についても、当社は一切の責を負いかねますのでご了承ください。また、当社は、当該情報の正確性および完全性を保証または約束するものでなく、今後、予告なしに内容を変更または廃止する場合があります。なお、当該情報の欠落・誤謬等につきましてもその責を負いかねますのでご了承ください。