概要
MT4のEAでWebサーバーと連携すると、指標の取得や、シグナルの外部発信など、いろいろな世界が見えてきます。とりあえず、Xサーバーのデータベース(MySQL)にEAからのデータを登録していろいろ操作できるようなものを、ということで、初学者の備忘録をつづりたいと思います。
参考にさせていただいたサイト
・外部サーバーにシグナルを送出し、シグナルコピーをする方法を勉強させてもらいました。特に、どのような処理が必要か、などが詳細に書かれています。基本的な知識がない場合は、別途サイト等で情報収集は必要です。
・phpを使ってSQLを操作する部分を勉強させてもらいました。phpは使ったことがあっても、SQLは情報処理の試験で勉強したくらいで、普段実務等では使用しておらず、結構未開の地でしたので、かなり勉強になりました。
https://blog.codecamp.jp/php-mysql
Xサーバーにデータベースを作る
①データベースを追加->③ユーザーの作成->③ユーザーの登録
の順に作業を行います。
①データベースの追加
データベース名は任意のものです。この後使用するので、忘れないようにメモします。
②ユーザーの作成
ここのユーザー名、パスワードも忘れないようにメモします。
③データベースにユーザーを追加
これで、作成したデータベースに、追加したユーザーでアクセスできるようになりました。
作成するシンプルなシステム
①EA側
・EAから一定時間毎にカウントアップする変数をサーバーに送信。
②サーバー側
・受け取ったデータをUPDATEしてデータベーステーブルを更新。
・処理の成功可否をEAにレスポンスする。
③EA側
レスポンスをチャートにコメントで表示する。
たぶん、こんなイメージです。
MQL側のコーディング
MT4のURLへのアクセスを可能にする設定
以下のように、POSTを送信するドメインを設定します。
今回は、適当にサブドメインを作成して行いました。
この作成したサブドメインに、index.phpとしてphpプログラムを作成していきます。
※SSL接続の場合、httpsとしたURLを記載します。
EAの作成
一定時間毎にカウントアップした変数をサーバーにPOSTするEAです。
#property copyright "panda" #property link "https://panda-clip.com" #property version "1.00" #property strict int count = 0; int OnInit() { EventSetMillisecondTimer(2000);//タイマーを2秒間隔に設定 return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { EventKillTimer(); } void OnTick() { } string SendPost(string URL, string str){ str = "value1=1" + "&value2=" + str; int WebR; int timeout = 5000; string cookie = NULL,headers; char post[],ReceivedData[]; StringToCharArray( str, post ); WebR = WebRequest( "POST", URL, cookie, NULL, timeout, post, 0, ReceivedData, headers ); if(!WebR) Print("Web request failed"); //CharArrayToStringにて、charの値0(ASCIIコードでNULL)の場合、そこで文字列変換が止まるため、スペース(32)に変更。 for (int i = 0; i < ArraySize(ReceivedData); i++) { if(ReceivedData[i] == 0){ ReceivedData[i] = 32; } } return CharArrayToString(ReceivedData); } void OnTimer() { count++; Comment(SendPost("https://svtest.panda-clip.com",IntegerToString(count))); Print("動作"); }
・一定時間毎の処理に、OnTimer()での処理を行っています。(2秒毎の処理)
・SendPost関数は、ページ最初のコピートレード作成の参考サイトを参考にさせてもらいました。
SendPostに、URLと送信したい文字列を入れると、サーバーからのリクエストをstring型で返すような関数となっています。WebRequest関数の、「RecievedData」に、サーバーからのレスポンスがchar型配列で返されます。そのため、CahrArrayToString関数にて、文字列に変換しています。
・プログラム内の「//CharArrayToStringにて、charの値0(ASCIIコードでNULL)の場合、そこで文字列変換が止まるため、スペース(32)に変更。」の部分は、このようにしないと、すべてのレスポンスがCommentで表示できなかったので、このようにしました。この部分の検証については、涙ぐましい2日間の格闘があったので、別の投稿で書きたいなと思います^^;
サーバーサイドのコーディング
適当なデータベーステーブルを作成
今回作成するシンプルな「test」テーブルです。
UPDATEで「id 」カラム「1」の「value」(初期値に0を入れておく。)を一定間隔で更新します。
XサーバーでMySQLを操作するには、「myphpadmin」で操作できます。
作成したデータベースに追加したユーザー、パスワードを入力するとログインできます。
ログインすると、左のツリーに作成したデータベース名があるので、それをクリックします。
以下の図のようにして、追加したデータベースに「testテーブル」を作成します。
これで空のテーブルができましたので、1行、UPDATEの対象の行を作成しておきます。
「SQL」タブから、
INSERT INTO `データベース名`.`test` (`id`, `value`) VALUES ('1', '0')
としておきます。
以上で、testテーブルの作成が完了です。
PHPコーディング
今回は、シンプルに、index.phpとしてドメイン直下に配置し、動作させます。
※行頭に<?phpをつけるとブログの環境上投稿できなかったので、(めんどくさいので^^;)動作させるときは、1行目に<?phpを追加します。
$link = mysqli_connect('サーバー名', 'DBユーザー名', 'DBユーザーパスワード', 'データベース名'); $echo_str = "";//レスポンス用の文字列格納用 // 接続状況をチェックします if (mysqli_connect_errno()) { die("cannot access db:" . mysqli_connect_error() . "\n"); } else { $echo_str = "DB OK.\n"; } $value1 = ''; $value1 = $_POST['value1']; $value1 = htmlspecialchars($value1); if(get_magic_quotes_gpc()) $value1 = stripslashes($value1); $echo_str = $echo_str . "$value1" . "\n"; $value2 = ''; $value2 = $_POST['value2']; $value2 = htmlspecialchars($value2); if(get_magic_quotes_gpc()) $value2 = stripslashes($value2); $echo_str = $echo_str ."$value2" . "\n"; $query1 = 'UPDATE test SET id = 1, value = "' .$value2. '" Where id = 1'; if (mysqli_query($link, $query1)) { $echo_str = $echo_str . "UPDATE success"; } echo "$echo_str"; mysqli_close($link);
・このphpプログラムは、データベースへの接続等、ページ最初の参考サイトの2つ目を参照させていただきました。サーバー名は、Xサーバーの場合、MySQL設定メニューのデータベースサーバーを指定します。
・’DBユーザー名’, ‘DBユーザーパスワード’, ‘データベース名’は、先に作成してメモしたものになります。
・EAからは、value1という値と、value2という値がPOSTで送信されてきます。value1は固定値1、value2はカウントアップした数値です。value1は使ってないんですけれども^^;とりあえず2個以上送信するサンプルのメモとして入れておきました。
・echoでレスポンスするために、echo_strという変数にEAに返したい文字列を追加していき、最後にechoしています。
・SQLのクエリはまだ慣れていないのでもっと勉強します 笑
動作確認
EAを動作させて、チャート上のcommentと、myphpadminのテーブルの確認です。
こんな感じで動作確認ができました。
まとめ
要素技術としての検証で勉強になりました。セキュリティ的な面ではまだな何もしていないので、実用的なものを目指すため、これをベースにいろいろやってみたいと思います。
例えば、サーバーがpostで受けるとき、value1とvalue2をhtmlのフォームから投げてもDBが更新されてしまうため、そのあたりも回避したり、やることがありそうです。