WebRequest関数を使うかWindows APIを使うか
どこかのWebサイトの情報を取得し、MT4に表示したりトレードの判断に使ったりしたいことってありますよね?
恐らく一番多いケースは経済指標や経済ニュースの情報ではないでしょうか?
Webサイトの情報を取得する技術のことをスクレイピングって言いますが、これを使えば実現できます。
ただ、スクレイピングはMQL4の知識だけでは難しく、HTMLを解析する知識(PHP言語を使うのが個人的にはお勧め)も必要になります。
処理の流れとしては、以下のようになります。
- MQL4側:スクレイピング用のPHP等を呼び出す
- PHP側:WebサイトのHTMLを解析し、取得したいデータを抜き出してレスポンス
- MQL4側:レスポンスデータを受け取って後続の処理を実行
PHP言語等に頼らない方法もあります。
- MQL4側:WebサイトのHTMLを直接根こそぎ取得
- MQL4側:欲しいデータ部分を頑張って抜き出して後続の処理を実行
一見、後者の方がPHP等の外部技術を使わないし、ステップも少ないしで簡単そうに見えるかもしれませんが、「頑張って」の部分がとても大変です。
しかも、取得データが日本語だと文字コードの関係で文字化けすることがあります。
MT4というかMetaQuotes社はマルチバイト文字のことなんかアウトオブ眼中です。
というわけで、通常は前者の方法を採用することになるかと思います。
PHP等にはHTMLを解析するライブラリがありますし、文字コードもごにょごにょできますからね。
さて、「MQL4側:スクレイピング用のPHP等を呼び出す」には2種類の方法があります。
1つはMT4の組込み関数であるWebRequest関数を使う方法。もう1つはWindows APIを使う方法です。
どちらも事前設定作業がありまして、前者の場合は、MT4の[ツール]-[オプション]-[エキスパートアドバイザ]タブにある、[WebRequestを許可するURLリスト]にチェックを入れて、PHP等のアクセス先のURL(ドメインまででOK)を入力欄に記述する必要があります。
後者の場合は、上記画面で[DLLの使用を許可する]にチェックを入れる必要があります。
上記設定が終わったら、MQL4でコードを記述します。例として、YahooファイナンスのFX情報を取得してみましょう。
まずはWebRequest関数の場合です。
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { string headers; char post[]; char result[]; // アクセス先(PHPではなくYahooファイナンスのURLを直接指定することも可能。文字化けしますけどね。) string url = "https://autofx100.com/GetYahooFinanceFX.php"; int res = WebRequest("GET", // HTTPメソッド url, // URL NULL, // cookie NULL, // リファラ 5000, // タイムアウト post, // HTTPメッセージ本体 0, // HTTPメッセージサイズ result, // 応答データ配列 headers); // 応答ヘッダ if(res == -1){ // エラー時の処理 }else{ string text = CharArrayToString(result); Comment(text); // 実現したい処理 } return(INIT_SUCCEEDED); }
続いてWindows APIの場合です。
// Windows APIをインポート #import "wininet.dll" int InternetOpenW(string agent, int accessType, string proxyName, string proxyByPass, int flags); int InternetOpenUrlW(int internetSession, string url, string header, int headerLength, int flags, int context); int InternetReadFile(int, uchar &arr[], int, int &byte); int InternetCloseHandle(int winINet); #import //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // アクセス先(PHPではなくYahooファイナンスのURLを直接指定することも可能。文字化けしますけどね。) string url = "https://autofx100.com/GetYahooFinanceFX.php"; int inet = InternetOpenW("MetaTrader 4 Terminal", 0, "0", "0", 0); if(inet == 0){ // エラー時の処理 }else{ int handle = InternetOpenUrlW(inet, url, NULL, 0, 0, 0); string text = ""; int byteSize = 0; uchar receive[1024]; // 1024バイトずつHTMLデータを取得して、textに追記 while(InternetReadFile(handle, receive, 1024, byteSize)){ if(byteSize <= 0) break; text += CharArrayToString(receive, 0, byteSize, CP_ACP); } // メモリのお掃除 InternetCloseHandle(handle); InternetCloseHandle(inet); } return(INIT_SUCCEEDED); }
上記コードをティックごとに実行してしまう(OnTickで呼び出す)と、ティックごとにWebサーバーにアクセスすることになるので、Webサーバー側は「攻撃を受けた!」と判断する可能性が高いです。
OnTickやOnTimerで実行する場合は、1分おきに実行する等の考慮が必要です。
上記どちらの場合もスクレイピング結果はtextに格納されます。
ちなみに、上記をコンパイルして実行してもGetYahooFinanceFX.phpは未作成なので動きません。
次回の後編ではGetYahooFinanceFX.phpの中身についてご説明いたします。