時系列データ分析の本を読んでの整理1

読んだ本は、これ。

現場ですぐ使える時系列データ分析 ~データサイエンティストのための基礎知識~

現場ですぐ使える時系列データ分析 ~データサイエンティストのための基礎知識~

slideshareにメモを置いた。
読みながら纏めているもので、はじめて学ぶ分野な上、独学なので間違いが多いと思うので、注意してください。

libmysql.dllだけでは、selectの結果をMetatrader4で扱えない?

libmysql.dllをインポートしてMySQLに作成したテーブルからデータを取得し、MQLプログラム中で扱おうとしたが上手くいかない。
create tableは実行できたので、おそらく実行結果を適切な型で扱わないといけないと思われるが、libmysql.dllだけでは出来ないのではないかと思っている。

 //SQLの定義
 string query="select * from metatrade";
 int query_res = mysql_real_query(mysql,query,StringLen(query));
 
 //SQLの実行
 int result = mysql_store_result(mysql);
 int numOfRows = mysql_num_rows(result);
 
 //取得行数の確認
 Print("numOfRows="+numOfRows);
 
 //クエリの実行結果
 string row;
 row = mysql_fetch_row(result);
 
 //1行ずつ表示したいが、これでは駄目。  
 for (int i=0;i<numOfRows;i++) {
      Comment(i);
      Print("row:"+row);
 }

実行してエキスパートタブでメッセージを確認すると表示がおかしい。
バイナリを表示しようとしているようだ。

mysqlのリファレンスを確認すると、
mysql_fetch_row()の戻り値の型は、MYSQL_ROW構造体
MySQL_ROWの説明を読むと次のようにある。

MYSQL_ROW
1 行のデータのタイプセーフな表現。現在は、バイト文字列の配列として実装されている(フィールドにはバイナリデータが格納される場合があり、そのようなデータでは内部的にヌルバイトが使用される可能性があるので、バイト文字列をヌル終端文字列として扱うことはできない)。レコードを取得するには、mysql_fetch_row() を呼び出す。

C言語では、この構造体を扱えるだろうが、Metatraderでは直接扱えないため、C言語で作成したインターフェースを用意してあげないといけないのかなぁと・・・。

libmysql.dllだけで対処することは諦めてMySQL wrapperを使用してみる

libmysql.dllだけでは、selectの結果をMetatrader4で扱えない?」で、libmysql.dllだけを使用してMySQLからselectするMT4プログラムを動かそうとしたが自力ではできずに諦め、MySQL wrapperを使用することにした。
以下、その時のメモ。

0.資源を「MQL4 - automated forex trading Code Base」からダウンロードする。-ダウンロードしたら、全て解凍する。
1.\experts\includeにmysql_v2.0.5.mqhを配置する-mysqlMT4Solution.zipを解凍すると、expertsフォルダができるので、其の中の\experts\include\mysql_v2.0.5.mqhを\experts\includeにコピーする。

2.\\experts\librariesにmysql_wrapper.dllを配置する-mysqlMT4Solution.zipを解凍すると、expertsフォルダができるので、其の中の\Debug\mysql_wrapper.dllを\experts\librariesにコピーする。

3.\\experts\librariesにlibmysql.dllを配置する-2で展開したフォルダと同じ場所のlibmySQL.dllを\experts\librariesにコピーする。

これで、準備は終了。
あとはサンプルプログラムを書いて試すだけ。

①予めMySQLにデータを用意しておく。
ここでは次のように用意した。

DB名:test
テーブル名:metatrade

データは下図のように3行用意した。

②テーブルからselectするプログラムを書く
サンプルを元にテストプログラムを書く。

#property indicator_chart_window
#include <mysql_v2.0.5.mqh>
#import "libmySQL.dll"
#import "mysql_wrapper.dll"

string  host     = "ホスト名";
string  user     = "ユーザ名";
string  pass     = "パスワード";
string  dbName   = "test";
int     port     = 3306;
int     socket   = 0;
int     client   = 0;

int     dbConnectId = 0;
bool    goodConnect = false;

int init(){
   goodConnect = mysqlInit(dbConnectId, host, user, pass, dbName, port, socket, client);
   if ( !goodConnect ) {
       return (1); // bad connect
   }
   executeQuery();
   return(0);
}

int deinit(){
   mysqlDeinit(dbConnectId);
   return(0);
}

int start(){
   return(0);
}

void executeQuery(){ 
   string data[][2];
   string lsQuery = "select * from metatrade";
   int result = mysqlFetchArray(dbConnectId, lsQuery, data);
   if ( result == 0 ) {
        Print("0 rows selected");
   } else if ( result == -1 ) {
        Print("some error occured");
   }
   
   int rows = ArrayRange(data, 0);
   int cols = ArrayRange(data, 1);
   for (int i = 0; i < rows; i++){
      for (int j = 0; j < cols; j++){
         Print(data[i][j]);
      }
   }
}

実行すると結果が取得できている。

これで終わり。

最後に、混乱したことを纏めておく。
・ライブラリ、インクルードファイルは同一ダウンロード元から取得すること。
mysql_v2.0.4.mqhmysql_v2.0.5.mqhは関数名が変更されたりと、仕様が変わっている。
そのため、mysql_v2.0.4.mqhで紹介されているExampleは、v2.0.5では動かない。その他、見えない部分で整合性が取れていないと不具合の可能性もあるので、同一箇所からダウンロードする。

dll化されている部分は実装が分からないので、それが気持ち悪い場合は、自分でDLLを作成した方が良さそう。個人的にはC言語でデータベース接続プログラムを書いたことはないので、勉強にもなる。

MySQLでテーブルのバックアップ

特に難しいことはない。
コマンドプロンプトからmysqldumpを実行するだけ。

下記では、「test」という名前のデータベースの、「historicaldate」という名前のテーブルをbak.sqlにダンプする時のコマンド。

C:\dev>mysqldump -uroot -p --opt test historicaldate > bak.sql
Enter password: *******

MySQLコマンドラインクライントから実行して、上手くいかなくて悩んだのは秘密だw。
下記のように文法見なおせって怒られるから注意しようw。
mysqldumpはwindowsの実行ファイルでコマンドプロンプトから使用するもので、mysqlのコマンドではないので。

mysql> mysqldump --opt database > bak.sql;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'mysql
dump --opt database > bak.sql' at line 1