(MQL4)WEBサイトの情報を取得するやり方[EA]WebRequest
公開日:
:
中級者EA開発 ソースコードあり, MQL, WebRequest
目次/もくじ
MT4のチャート上にWEBサイトの情報を参照する方法について紹介します。
背景
オンラインの情報をトレードの判断に使う、というのは至極まっとうな考え方だと思います。
日経が為替に影響を与えるでしょうし、SP500も影響するでしょう。はたまたツイッターの群集心理による相場の形成や天候による先物相場への影響も考えられます。
MT4、MT5ではこれらの需要に答えるためにWEBにアクセスして、情報を取得することができます。
また、便利なのはWEBアクセス周りのプログラミングはMQL4とMQL5でほとんど同じだということです。
もともとMQL4ではオンラインアクセスするための関数がなかったのですが、2014年2月以降はDLLを使用せずにWEB(サイト)に接続できるようになりました。
GETとPOST
さて、ここからは技術的な話です。
WEBサイトにアクセスするには、GETとPOSTというメソッドがあります。ただサイトを閲覧するだけの場合GETで十分です。
POSTはログイン操作やフォームの送信に使います。
また、MT4,MT5で特定のWEBサイトにアクセスするにはあらかじめ接続先のドメインを登録しておく必要があります。
なぜこんな仕様になっているかというと、どんなWEBサイトにも無条件でアクセスできる仕様にしてしまうと、DDos攻撃や不正アクセスの末端になってしまう可能性があるから(だと思います。)
おそらく「これから接続するサーバーをユーザーが把握しとけよ」というメタクオーツの配慮でしょう。
アクセスするサイトの登録方法
メタトレーダーの上部タブの「Tools」-> 「Options」を選択すると下記の画面が出てきます。
「Expert Advisers」タブを選択すると、許可するURLが出てくるので、
アクセスしたいサイトのURLを入力してください。
複数のページにアクセスする場合でも、トップレベルドメイン一つ登録されていれば接続可能です。
ただし、注意しなければならないのはhttpとhttpsの違いです。WEBサイトの方でリダイレクトの設定がされている場合はOKですが、これを間違えるとアクセスできない場合がありますので、気を付けてください。
ヤフーファイナンスのデータを参照するコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
void OnTick() { //--- GetWebData(); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ string URL = "https://info.finance.yahoo.co.jp/ranking/?kd=1&tm=d&mk=1"; void GetWebData() { int WebR; int timeout = 5000; string cookie = NULL,headers; char post[],ReceivedData[]; string str; StringToCharArray( str, post ); WebR = WebRequest( "GET", URL, cookie, NULL, timeout, post, 0, ReceivedData, headers ); if(!WebR) Print("Web request failed"); string ReceivedText = CharArrayToString(ReceivedData); Comment(ReceivedText); } |
こんな関数を作って稼働させるだけでWEBサイトの情報を取得できます。
お察しの通り、メタトレーダーではHTML、Javascript、CSSの表示はできないため、この取得したデータをスクレイピングする必要があります。
本来は一度、自前のWEBサーバーでスクレイピングしたものに対して、メタトレーダーからアクセスした方が効率がいいのですが、(PHPの方がスクレイピングのライブラリが充実しているため)
EAからWEBサイトの情報を収集するときにどのタイミングで整形するのか問題
繰り返しになりますが、MT4ではEAを経由して各種WEBサイトの情報を参照することが可能です。
これにはWebRequest関数を使う訳ですが、この関数自体にはURLを指定して、そのページのコンテンツを引っ張ってくる能力しかありません。
しかもこれはすべてのタグを含むHTML情報なので、欲しいコンテンツを得るにはその取得データを整形する必要があります。(ちなみに、参照できるWEBサイトに制限はありません。ログインが必要なWEBサイトでもログインを自動化して収集できちゃいます。)
EA上でパース・スクレイピングする
とりあえず、データを全部取得してからEA上でパースする(文字情報を整形すること)ことも可能です。
以前の投稿では「専用の関数もないから絶対にやめた方が良い」と書いたのですが、MQL5フォーラム上のもの好きな方がパース用のライブラリを書いてくれたので、それを使えば比較的簡単にパースできるんじゃないかと思います。
詳しくはそちらのページで
https://www.mql5.com/en/articles/5706
https://www.mql5.com/en/market/product/12635
(ただし、35ドルかかります)
たぶん、現実的にはこれを使うのが一番いいんじゃないかと思います。
MQLしか触ったことがない人にとっては”パーサー”の使い方にちょっと戸惑うかもしれませんが、PHPとかWEB系の言語を触ったことがある人にとっては、Simple DOM Parserに近い環境にしてくれているのでとっつきやすいと思います。
デメリットとしてはMT4のバージョンアップでこのライブラリが使えなくなる可能性です。(とは言いつつ、しばらくは大丈夫なんじゃないっすか~)
自前サーバー上でパースする
これまで提案してきた方法です。一度自前のサーバーにパース用のPHPファイルを置いておいて、EAからはその自前サーバーに対してアクセスをするという方法です。
この場合、多くの人が使っているPHPのライブラリであるSimple DOM parserが使えるので、コードをパクってくるのもちょっと検索すれば簡単です。
デメリットとしては、サーバーを持っていない人の場合、これだけのためにサーバーを契約するのはちょっとめんどくさいかもしれません。
少し無理やりMQLでスクレイピングします。
EA内でスクレイピングしてみる
WEBサイトから取得したデータのスクレイピングです。
スクレイピングとは、すごい長い文字列から欲しい文字列だけを抽出することです。
WEBサイトの構成
基本的にWEBサイトは、
1 2 3 4 5 6 |
<head> ウェブサイトのタイトルとか文字コードとか言語とかCSSとかJavascriptの呼び出しとか </head> <body> サイトの中身 </body> |
の構成になっています。
まず第一段階として、ヘッダの情報はいらないので削除します。
1 2 3 |
ReceivedText = "ウェブサイトの長ったらしい文字列"; string Header = StringSubstr(ReceivedText,0,StringFind(ReceivedText,"<body",0)); StringReplace(ReceivedText,Header,""); |
StringFindで<bodyまでの文字数をカウントし、最初からそのカウントまでの文字を””に変換します。
<body>としてタグを閉じてしまうと、<body class=””…となっているWEBサイトの場合に対応できないので、<bodyで検索をかけます。
(<スペースbody となっていないことを祈るばかりです。)
これでHTMLのbodyだけを抽出できました。
あとはこれの繰り返しです。
多くのサイトはテンプレートを使っているかワードプレスのようなCMSなので、同じような構成です。
テンプレートを使っていない場合でも、基本となる”暗黙の了解”のようなものがWEBの世界にはあるので、
メインとなる箱はたいてい
<div class=”main”>とか<div id=”wrapper”>とか<div class=”container”>
とかだったりします。
ある程度欲しい情報のまとまりが取れてきたら、今度はHTMLタグを外します。
1 2 3 4 5 6 |
ReceivedText = "ある程度欲しい情報がまとまった文字列"; StringReplace(ReceivedText,"<div class=”main”>",""); StringReplace(ReceivedText,"<div id=”wrapper”>",""); StringReplace(ReceivedText,"<a>",""); StringReplace(ReceivedText,"</a>",""); StringReplace(ReceivedText,"<div class=”container”>",""); |
また、日本語のサイトを表示させようとすると文字化けすることがありますが、
これはもう仕方ないです。
“自サーバーで一度文字コードを変換する”とかしかありません。
基本的にMQLは文字化けに滅茶苦茶弱いので、というか文字化けに対応させようとする気がメタクオーツ社にあまりないので、
MQL内で文字コードの変換はできないものと思っておいてください。
(今後のアップデートで改良される可能性はわずかながらにあるかもしれません。)
また、WebRequestはティック更新ごとに行うと十中八九Dos攻撃とみなされ、WEBサーバーがアクセスを一定時間拒否します。
1分に一回くらいのアクセスにしておきましょう。
(逆に言えば、EAでDos攻撃ができるわけです。)
WebRequestのヘルプのPOSTのサンプルコードが間違っている件と代替コード
最近になってMQL4でもオンラインに接続できるようになりましたが、WebRequestのPOSTには意外と厄介な点があります。
というのも、
WebRequestのヘルプのリファレンスが間違っていて、いつまでも修正されないという問題があるからです。(英語で検索すればこの件に関する騒ぎがヒットすると思います)
GETを使えば問題ないのですが、セキュリティの問題などでPOSTを使った方が良いことも多々あります。
また、WEBサイト上でログイン操作が必要な場合、POSTは必須になります。
下記はWebRequestでPOSTするための関数です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
int SendPOST() { int WebR; string URL = "https://fxantenna.com/post-test.php"; int timeout = 5000; string cookie = NULL,headers; char post[],FTPdata[]; string str= "&pair="+StringSubstr(Symbol(),0,6) +"&servertime1="+TimeCurrent() +"&servertime2="+TimeToStr(TimeCurrent(),TIME_DATE|TIME_MINUTES|TIME_SECONDS) +"&bid="+MarketInfo(Symbol(),MODE_BID) +"&ask="+MarketInfo(Symbol(),MODE_ASK) +"&point="+MarketInfo(Symbol(),MODE_POINT) +"&digits="+MarketInfo(Symbol(),MODE_DIGITS) +"&spread="+MarketInfo(Symbol(),MODE_SPREAD); StringToCharArray( str, post ); WebR = WebRequest( "POST", URL, cookie, NULL, timeout, post, 0, FTPdata, headers ); return(WebR); } |
このSendPost()をOnInitやOnCalculate内に貼り付けることで、POSTを実行できます。
PHPでデータを取得する場合は$_POST[‘bid’]などで取得できます。
第3者のウェブサイトにログインする場合は、そのログインフォームのinputのnameを取得して、nameと一致するようにPOSTデータを送信します。
(ここら辺が何言ってるか分からない場合は、HTMLのフォームについて調べてみてください。)
また、
これを応用すれば、オンラインで口座認証したり、サーバー側からEAを管理することが可能になります。
使い方を変えれば、ティック毎にサイトにアクセスするDos攻撃にもなりますので、あまり頻繁にアクセスしないようにしましょう。
関連記事
-
[MT4]EAに口座縛り/期間限定縛りをかける種類と方法(MT5)
良いEAができた場合、身内で配布したい場合があります。しかし、知らない間に自分のEAが出回っていた場
-
利用可能なトレード系金融APIまとめ FIX API,REST API,OPEN API
今まで当たり前のようにMT4/MT5/TradeStationで開発をしてきましたが、そういえばAP
-
[MT4]チャートを分析して、一番多いパターンが来たらトレードするEA
パターン分析トレードとは 今回はMT4のファイル関数を使って、パターン分析トレードシステムを作成し
-
2chのスレをテキストマイニングするやり方
よく「大衆の逆をいけば勝てる」みたいなことが相場の世界では言われますよね。今回は2chの市況版の住民
-
[MQL4]MT4でマルチタスク/マルチスレッド処理
MT4/MT5は基本的にC言語ベースなのでマルチスレッドはできません。 しかし、複数のチャート上で
コメント
とても濃い内容をありがとうございます。
自分は、Telegram の無料で配信しているFXのbuy-sell signal1を
EAのwebrequestで習得してオーダーを出したいのですが、
やり方がわかりません。
是非、今度記事にして頂けないでしょうか?
是非よろしくおねがいします。