MQLでサーバー(PHP,SQL)と連携したEAを作りたい

概要

MT4のEAでWebサーバーと連携すると、指標の取得や、シグナルの外部発信など、いろいろな世界が見えてきます。とりあえず、Xサーバーのデータベース(MySQL)にEAからのデータを登録していろいろ操作できるようなものを、ということで、初学者の備忘録をつづりたいと思います。

参考にさせていただいたサイト

・外部サーバーにシグナルを送出し、シグナルコピーをする方法を勉強させてもらいました。特に、どのような処理が必要か、などが詳細に書かれています。基本的な知識がない場合は、別途サイト等で情報収集は必要です。

MQL&PHP サーバーを経由するコピートレードシステムを作るやり方

・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が更新されてしまうため、そのあたりも回避したり、やることがありそうです。