2011/03/31

MQL4で使用していたDLLをMQL5で使用する方法 ■■■

※追記2011/4/3しました。
MQL4で使用していたDLL(ANSI版DLL)は、そのままでは、MQL5で使用できません。原因は、MQL4とMQL5の、文字コードが異なるからです。MQL5は、より高速処理を実現させるために、WINDOWSの内部処理文字コードであるUNICODEを採用しています。そのため、引数をDLLに渡す時や、DLLから戻り値を受け取る際に文字コードエラーが発生します。

MQL5用のUNICODE版DLLの作り方

以下のサイトに簡単な作り方が紹介されている。
How to Exchange Data: A DLL for MQL5 in 10 Minutes

ANSI版DLLをMQL5で使用する方法

先に記述の通り文字コードの互換問題をクリアすればANSI型DLLを使用することが可能です。
方法は、以下のサイトにまとめられていますので参照してくだい。
MQLmagazine.com DLL Hell, MQL5 edition : UNICODE vs ANSI
変換方法は、上記サイトにある【stringlib.mqh】をインクルードし 、
UNICODE2ANSI関数でUNICODEからANSICODEに変換
ANSI2UNICODE関数でANSICODEからUNICODEに変換
します。
実際にテストしてみると、
kodee
前々回紹介したSQLite3のデーターベースを接続することができました。

まとめ

ANSI型DLLの場合でも内部的にはUNICODEに変換して処理しているので、ANSI型DLLを使用した場合、文字変換を4回行う結果となり、処理能力を下げる結果となります。

※追記事項
MQL5からSQLite3への接続には、ラッパーが必要ありません。
新しいプロジェクトが誕生したようです。
sqlite-class-for-metatrader5

2011/03/29

為替の変化量を考える。■■■

EAを作り込んで行く過程で理想的なパラメーターの決定方法は、全通貨に対応可能な(変更せずに使用できる)設定であろうと考えます。今回は、価格の変化量について、そうしたことが可能か考えてみました。

変化量を算定する方法(種類)

【 差 】 = 比較時点の値 - 基準時点の値
【 比 】 = 比較時点の値 / 基準時点の値
【 変化率 】 = (比較時点の値 - 基準時点の値)/基準時点の値
【対数変化率】 =Log(比較時点の値 / 基準時点の値)
計算方法としてまだあるだろうが、今回は上記のものを確認してみました。
※変化率と対数変化率は、変化量が小さい場合、近似することが知られているが確認のために入れてみました。

確認方法

【検証用データ取得先】 Forexite 
【データ取得方法】 AutoForexite.exe フルレバ50倍でFXシステムトレード(ありがとうございます。)
【使用通貨】(AUDJPY/AUDUSD/CHFJPY/EURCAD/EURBBP/EURJPY/EURUSD/GBPJPY/GBPUSD/NZDJPY/NZDUSD/USDCHF/USDCAD/USDJPY)
【期間・値】 30分足を使用し、基準点の値を(Open)比較時点の値を(Close)と設定
【グラフ作成】 Rを使用してみました。参考(R でプログラミング:データの一括処理とグラフ描き )

視覚化

全通貨を対象にグラフを作成しようとしましたが、見ずらいのでJPYがらみとその他に分けてグラフ化してみました。
以下は、JPYがらみ(AUDJPY/CHFJPY/EURJPY/GBPJPY/NZDJPY/USDJPY)をまとめて各方法でグラフ化したものです。わかりやすくするために倍率を掛け単位を一様にし、絶対値を取っています。
_JPY
以下は、JPYがらみ以外の通貨ペアをまとめたグラフです。
outJPY
上記の結果から、【比】【変化率】【対数変化率】は、基準値(Open)が小さいと過大評価され、基準値(Open)が大きいと過小評価される傾向があることがわかります。
【差】を抜き出して直線回帰モデルに当てはめてみると以下の様になります。
usdy
上記は、JPYがらみのグラフで,下記は、JPYがらみ以外のグラフです。
outJPYt
直線回帰モデルのパラメータが、十分に小さく近似した数値を示していることから、上記の式で変化量を求める場合は、【差】を用いることが望ましいことがわかります。
また、個別の通貨ペアで見た場合。
USDJPY30
上記は、USDJPYで下記が、EURUSDです。ただし、EURUSDの差は100倍したものです。
EURUSD30
【一言】
今回の結果から、変化量を見るパラメータは、全通貨に対応した値を取ることが可能であると思われます。また、毎度エクセルを使用してグラフを作成してきましたが、今回のようにプロット数が増えるとエクセルが使用できません。『R』を活用できるように勉強していきたいものです。

2011/03/14

MT4からDATABASEを利用する。 ■■■

MT4に外部データを渡す場合は、一般的にテキストファイル(CSVファイル)が使用されますが、今回はデータベースを使用する方法を調べてみました。

【データーベースの選択】

サーバーを使用しないこと、コンパクトで高速処理が可能であるこ、MT4用のラッパを公開されている方がいらっしゃったことから、【SQLite3】を使用することにしました。

【環境整備】

①SQLite3の取得 サイト:http://www.sqlite.org/
main
down
【Download】→(Precompiled Binaries For Windows)-(This ZIP archive contains a DLL for the SQLite library)をダウンロードし、解凍後≪sqlite3.dll≫をMT4のlibrariesファイル内に保存。
②MT4用ラッパの取得 サイト:http://www.shmuma.ru/
mainwrapper
wrapper
【SQLite library for MetaTrader4】→(Download)-≪sqlite3_wrapper.dll≫をダウンロードしMT4のlibrariesファイル内に保存。sqlite.mqhをコピペしてヘッダーファイルを作成。
③SQLiteの管理ソフトの取得
今回は、PupSQLを使用させてもらいました。

【sqlite3_wrapper.dllの公開関数の説明】

int sqlite_exec (string db_fname, string sql);
db_fname: pathを含むデータベース名(pathは、絶対パス若しくは相対パス)
sql    : クエリ
  ※作成、更新、削除などの戻りデータのないクリエを発行する。

int sqlite_table_exists (string db_fname, string table);
  db_fname: pathを含むデータベース名(pathは、絶対パス若しくは相対パス)
  table      : テーブル名
  ※データベースを開き、テーブルを指定する。(1:あり 0:なし)

int sqlite_query (string db_fname, string sql, int& cols[]);
  db_fname: pathを含むデータベース名(pathは、絶対パス若しくは相対パス)
  sql         : クエリ
  cols[ ]      : int cols[1];と設定。列数の合計を受け取る。
  ※戻りデータのあるクリエを発行し、ハンドルを返す。
  ※反復処理は、(sqlite_next,sqlite_get_col)を使用。
  ※(sqlite_free_query)を使用しクリエの解放をおこなう。

int sqlite_next_row (int handle);
  ※次の行を取得する 。(1:あり 0:なし)

string sqlite_get_col (int handle, int col);
  col       : テーブルの列番号(0,1,2,3,……)
  ※列の値を取得する。

int sqlite_free_query (int handle);
  ※クリエの解放。

【テスト】

さて環境が整いましたのでテストしてみたいと思います。
どうせならということで前々回スクレイピングした内容をデータベース化し、国名とランクを条件に抽出するスクリプトを作成してみました。
PupSQLにてデータベース化したものを添付しておきます。
ダウンロード: EventDate.db
base
ダウンロード後解凍しMT4のfilesフォルダに保存。
作成したスクリプトをダウンロードしスクリプトフォルダに保存。
ダウンロード: EventHist.mq4

稼働させた結果は以下の通りです。
kekka
【SQLite3】は、文字コードが、UTF-8となっているため読み込んだ日本語が文字化けしました。
文字化け対策は後日としたいと思います。

【sqlite3_wrapper.dllのコンパイルに挑戦記録】

いろいろ苦戦したので、自分の記録に・・・
使用したIDEは、Dev-C++(v4.9.9.2)です。
sqlite_wrapper.cをGet
② 【SQLite Download Page】-(SorceCode)-(sqlite-amalgamation)をGet
解凍後≪sqlite3.h≫を抜き取り上記と結合
③ ≪sqlite-dll-win32-x86-××××.zip≫より≪sqlite3.def≫を取得しDev-C++のパス内に置き
コマンドプロンプトにて[\Dev-Cpp\bin]以下コードでライブラリファイルを作成-詳しくはココ
【dlltool –dllname “sqlite3.dll” –input-df “sqlite3.def” –output-lib libsqlite3.a】
④sqlite_wrapper.cの変更
1: 《extern”C”{ }》にて関数群を囲む。詳しくはココ
  2: コンパイルエラーとなるため、build_db_fname関数内【res = (char*)malloc (s);】と変更。
3: コンパイルエラーとなるため、sqlite_get_col関数の型を【unsigned char】に変更。
4: 公開する関数の型に【__declspec(dllexport)】を追加
⑤【コンパイラオプション】→リンカーのコマンドに【libsqlite3.a -k】と記入しコンパイル。
※正しいがどうかは不明だがこの方法でコンパイルが完了し作動も確認できた。

【最後に・・】

おもしろき こともなき世を おもしろく すみなしものは 心なりけり  by 高杉晋作