English Русский 中文 Español Deutsch Português
MеtaTrader 4 と MATLAB エンジン(仮想 MATLAB マシン)間のインタラクション

MеtaTrader 4 と MATLAB エンジン(仮想 MATLAB マシン)間のインタラクション

MetaTrader 4 | 22 4月 2016, 13:02
1 248 0
Andrey Emelyanov
Andrey Emelyanov

はじめに

MetaTrader 4 および MATLAB 数学的パッケージは、複雑な計算システムを作成する上での『柔軟性』を含み、ポジティブな特性のおかけでユーザーの間で高い人気を博してきました。MATLAB を外部アプリケーションと連携する主な方法が3つありますが、お薦めできるのはそのうちの1つだけです。仮想デスクトップ MATLAB エンジンを使用する方法です。この方法は MATLAB パッケージとの完全な互換性を保証します。数多くのプログラマーが以下の理由でこの方法を避けています。

  • ユーザーの多くがそれの速度が遅いと感じる。MATLAB の DLL ライブラリから直接関数を呼び出すのと比べれば、これは事実です。主なディレイは処理の最初におこります。呼出し仮定で仮想空間(われわれの場合 MetaTrader 4)にアップロードされる多数のライブラリ呼び出しのために仮想マシンが呼ばれるときです。
  • プロジェクトの転写性プロジェクトを別のコンピュータに転送する際、直接呼出しのときと同様ですが、後者の『関係』、すなわち開始キュー、を知るために MATLAB DLL ライブラリもすべて転送される必要があります
  • C++ または Fortran の知識が必須である。MQL4 を知っていれば、C++ を簡単に学ぶことができますし、その逆も同様です。

私がこの方法をお薦めする理由は以下です。

  1. これは外部プログラムと連携するもっとも信頼性のある独立した MATLAB バージョンの方法です。バージョンを変更することができ、ご自身のインディケータや Expert Advisor はそれに影響を受けることはありません。これはもっとも重要なメリットです。
  2. それは比較的迅速な作成方法を持ちます。デバッガは不要で、DLL ラッパを書くことは全くむつかしくありません。
  3. 複数インディケータおよび/または Expert Advisor 用の『共通デスクトップ』私は、複数インディケータを基に意思決定をする必要がある場合や、ピラミッドトレードを実装する際、この方法が有用であると考えます。

本稿では、Borland C++ ビルダ 6 で書かれた『DLL ラッパー』によって MetaTrader 4 とMATLAB バージョン7.4.0 (R2007a) を連携する方法について説明します。マイクロソフト社製品を好むプログラマーの方々はお手持ちのコンピュータに例を適応する必要があります(この複雑な問題が解決しますように!)。



I. タスク設定

まず、プロジェクトを何から開始するか決める必要があります。作成過程を3つに分割します。

  1. インディケータ/EA の計算を実装する MATLAB の M 関数作成
  2. MATLAB と MetaTrader 4 を接続するための『DLL ラッパー』作成
  3. MQL プログラムの作成


II. M 関数の作成

これはおそらくもっとも興味を引かれる長距離過程でしょう。これには以下のアクションが含まれます。

1. MetaTrader 4 から MATLAB へのデータのプリエクスポート

図は MATLAB へのマニュアルでのデータエクスポート手順を示しています。エクスポートが終了したら、MATLAB デスクトップに変数が作成されます。

2. 正しい式、式パラメータ範囲などの検索

この仮定はクリエイティブでひじょうに重要ですが、インディケータおよび/または Expert Advisor の数学的アルゴリズム作成は本稿では扱いません。その情報は MATLAB に関する文献で見つけることができます。

3. MATLAB でのM 関数作成

C++ および/または MQL4 の知識があるプログラマーにとってはこの関数作成はなんらむつかしいことではありません。また、変数はすべて同一データタイプ-"matrix"、です。すなわち、変数を配列または多次元配列として明確に定義することは重要ではありません。言語が自分でこれをやってくれます。そして、私はデータタイプの選択過程も重要だとは思いません。私はつねにmxREAL を使用します。おそらく、使うメモリは多いでしょうが、そのような場合に混乱がないのです。詳しくは参考資料 1、2 にあります。提供される例では高周波のフィルターが取り入れられています。



III. 『DLL ラッパー』の作成

この点についてさらに詳しく説明します。というのも、空気同様に「不可欠」だからです。遅延バインディングの DLL ライブラリはすべて次の条件を満たす必要があります。

  • それは『廃棄物』収集と、処理後のメモリクリアのため内部関数を持ちます。
  • おそらくマルチスレッド化されるべき、すなわち同時に2つ以上の処理をサポートする必要があります。
  • と規定のディレクトリに入れられる必要があります。さらにプロジェクトファイルの位置を参照してください。

『DLL ラッパー』の主要な外部関数は、MATLAB エンジンの API インターフェースと標準 C++ インプット/アウトプットライブラリの1つの関数です。MATLAB エンジンの API インターフェースはシンプルでコンパクトです。関数は8個しか持ちません。

Engine *pEng = engOpen(NULL) -MATLAB デスクトップを呼ぶ関数。パラメータはつねに NULL で、デスクトップディスクリプタのポインターを返します。別の関数の動作に必要とされます。変数はグローバルで作成されます。

int exitCode = engClose(Engine *pEng) -デスクトップを閉じる関数。デスクトップディスクリプタに対するpEng ポインター。値を返しますがそれは重要ではありません。というのも、この関数は DLL を閉じるときに呼び出され、重要ではないためです。MATLAB デスクトップの『ユーザー』番号を返します。

mxArray *mxVector = mxCreateDoubleMatrix(int m, int n, int ComplexFlag) -MATLAB デスクトップに対する行列を作成する関数。変数 matrix に対するポインターを返します。 MATLAB と互換性のある変数を作成するのに必要なものです。通常のデータ配列および/またはデータタイプは MATLAB には送信されません。

mxArray *mxVector -変数 matrix に対するポインター

int m -行数

int n -列数

ComplexFlag - 複素数型。つねに MetaTrader 4 との正確な動作のための

void = mxDestroyArray(mxArray *mxVector) -MATLAB 行列を削除する関数。メモリクリアに必要とされます。 もはや必要ではなくなったとき、データをつねに削除します。そうしなければ、メモリや結果の『オーバーラップ』の問題が生じます。

mxArray *mxVector -変数 matrix に対するポインター

int = engPutVariable( Engine *pEng, char *Name, mxArray *mxVector) -デスクトップに変数を送信する関数。mxArray タイプの変数が作成されるだけでなく、MATLAB に送信もされます。

Engine *pEng -デスクトップの『ディスクリプタ』に対するポインター

char *Name -MATLAB デスクトップ内の変数名。タイプは char

mxArray *mxVector -変数 matrix に対するポインター

mxArray *mxVector = engGetVariable(Engine *pEng, char *Name) -デスクトップから変数を受け取る関数。前出のものとは逆。mxArray タイプの変数が受け取られます。

mxArray *mxVector -変数 matrix に対するポインター

Engine *pEng -デスクトップの『ディスクリプタ』に対するポインター

char *Name -MATLAB デスクトップ内の変数名。タイプは char

double *p = mxGetPr(mxArray *mxVector) -データ配列に対するポインターを受け取る関数。 memcpy(…)と共にデータをコピーするのに使用されます。mxArray tyタイプの変数を受け取る/書き込む際、この関数を使用し、シンプルタイプ(int、doubleなど)の変数を抽出/ペーストします。

double *p -double タイプの配列に対するポインター

mxArray *mxVector -変数 matrix に対するポインター

int = engEvalString(Engine *pEng, char *Command) -デスクトップにコマンドを送信する関数Command 行のコマンドは MATLAB デスクトップによって実行されます。

Engine *pEng -デスクトップの『ディスクリプタ』に対するポインター

char *Command -MATLAB 向けのコマンド。char タイプの行です。

メモリを処理する関数は1つだけです。

void *pIn = memcpy (void *pIn, void *pOut, int nSizeByte) -変数(配列) pOut を pIn のバイトサイズ変数nSizeByte にコピー(クローン作成)する関数

注意!:配列の次元をよく見てください。それらは等しいか、pIn 配列は pOut よりも大きくなります。

『DLL ラッパー』のエクスポート関数に対する要件

MetaTrader 4 が MATLAB を使えるようにするためには、関数-トランスミッター、を書く必要があります。そのような関数を投影する要件を考察します。MetaTrader 4 から呼ばれる関数はすべて __stdcall、すなわちパラメータはスタックによって送信され、関数がそのスタックを消去します。以下が関数の宣言方法です。

extern "C" __declspec(dllexport) <variable_type> __stdcall Funcion(<type> <name>);

extern "C" __declspec(dllexport) -C++ コンパイラに、関数が外部関数で、エキスパートのテーブルで書かれることを知らせます。-

<variable_type> -返される変数タイプ。void、bool、int、double、合成タイプが可能です。ポインターは送信されません。さらに見ます。

__stdcall -関数とバックへのパラメータ送信の同意

Function -関数名

<type> <name> -インプット変数タイプと名前。変数の最大数は64です。

以下は関数定義のプロトタイプです。 __stdcallにも注意をはらってください。

bool __stdcall Funcion (<type> <name>)

{

//……

}

これ以外に、拡張子 def を持つファイルを作成します。通常、これはライブラリ名とエクスポート関数名を記述するテキストファイルです。このファイルが存在しなければ、みなさんのファイルは独自にこじつけの関数名を『考え出す』こととなり、これは DLL の使用を複雑にします。以下がファイル例です。


LIBRARY NameDll

EXPORTS

NameFunctionA

NameFunctionB

LIBRARY -付属語。DLL名を指し示します。

EXPORTS -付属語は以下の関数名が列挙されていると言います。

NameFunctionA, NameFunctionB -DLL 関数名

ただし、MQL による制約があります。この言語にはポインター、動的メモリがないため、配列、ストラクチャ等は DLL ライブラリから渡されることができないのです。しかし、MetaTrader ではデータは参照によって関数から渡される配列を書き込むことが可能です。結果は、MetaTrader によって作成される配列に書き込まれ、そのポインターを DLL が受け取ります。ただし、配列は一定の次元を持つ必要があり、インディケータ行ではありえません(この制限はおそらくMetaTrader 4 の特定のメモリ配置に関連しています)。

これで、関数の書き方とどの関数を呼び出すかわかったので、『DLL ラッパー』の一般的なアルゴリズムを考察します。

1. DLL の最初の呼出し時に engOpen() 関数によって MATLAB エンジンを起動します。

2. MetaTrader からデータを取得し DLL 関数を送り返します。

2.1. mxCreateDoubleMatrix() 関数によって変数を作成します。

2.2. データを mxVector 変数、関数 memcpy() および mxGetPr() にコピーします。

2.3. 変数を MATLAB デスクトップ、engPutVariable() 関数に渡します。

2.4. 式/コードを MATLAB デスクトップ、engEvalString() 関数に渡します。

2.5. MATLAB デスクトップ、engGetVariable() 関数から返事を受け取ります。

2.6. 値を MetaTrader、関数 memcpy() および mxGetPr() に返します。

3. engClose() 関数によってMATLAB を閉じ、MetaTrader プロセスのアドレス領域から DLL をロードする際変数 mxDestroyArray() をすべて削除します。

次に『DLL ラッパー』ののスケルトンを作成します。

/*---------------------------------------------------------------------------
** Libraries + *.lib + *.def:
** libeng.lib** libmx.lib
** libmex.lib** project_name.def
*/
#include <windows.h>#include <memory.h>#include "engine.h"
//---------------------------------------------------------------------------
extern "C" __declspec(dllexport)<variable_type>__stdcall Funcion(<type><name>);
//---------------------------------------------------------------------------
int WINAPI DllEntryPoint(HINSTANCE hinst,unsigned long reason,void *lpReserved)
  {
   /*    
** reason for DLL call    
*/
   switch(reason)
     {
      case DLL_PROCESS_ATTACH:
         /*            
** DLL uploaded into the address space of the process            
*/
         break;
      case DLL_PROCESS_DETACH:
         /*            
**DLL loaded from the address space of the process            
*/
         break;
     }
   return TRUE;
  }
//---------------------------------------------------------------------------
bool __stdcall Funcion(<type><name>)
  {
   ……
  }
//---------------------------------------------------------------------------

プロジェクト組み立て

以下の図はライブラリと *.def ファイルがプロジェクトに追加される方法を示しています。

以下は『DLL ラッパー』プロジェクトに必要なファイルのリストです。

  1. libeng.lib -所在:\Program Files\MATLAB\R2007a\extern\lib\win32\borland\
  2. libmx.lib -所在:\Program Files\MATLAB\R2007a\extern\lib\win32\borland\
  3. libmex.lib -所在:\Program Files\MATLAB\R2007a\extern\lib\win32\borland\
  4. имя_проекта.def -このファイルは前述のとおり、ノートバッドに作成します。

engine.h ファイルは \Program Files\MATLAB\R2007a\extern\\include からフォルダ \Program Files\Borland\CBuilder6\Include にコピーします。これで、毎回コンパイラへのパスをインクルードする必要がなくなります。

注意:これら説明は Borland C++ ビルダ 6 でのみプロジェクトを組み立てるために提供されています。

IV. MQL4 プログラムの作成

『DLL ラッパー』関数の宣言とパラメータを渡すことにのみ関連した疑問を考察します。関数を宣言するためには以下の言語構造が必要です。

#import "HighPass.dll"

void ViewAnsFilter();

bool TestDllFilter();

bool AdaptiveHighFilter(double& nInVector[], int nSizeVector, double nSizeWind, double dAmplit);

void MakeBuffFilter(int nSize);

void DestrBuffFilter();

#import

ここで、

#import "HighPass.dll" -キーワード、DLL ライブラリ名

void MakeBuffFilter(int nSize); -関数名、返される値タイプ、渡される値の名前とタイプ

備考: "[]" は配列を渡すときに使用されます。dll がこのデータ配列に返事を書き取る場合、アンパサンド文字 "&" が必要です。MQL4 の外部プログラムから配列を渡す方法はほかにはありません 。渡される配列は一定の次元であり、インディケータ配列ではありえません。



V. ファイルの位置

プロジェクトが構築されたら、プロジェクトファイルが正しく配置される必要があります。

*.dll および *.m -カタログ \Program Files\MetaTrader\experts\libraries 内のライブラリファイルとM 関数

*.mql はその通常の場所に配置されます。すなわち、これがインディケータであれば、'indicators' フォルダに、EA であれば 'experts' に、スクリプトであれば 'scripts' フォルダです。

注意:インディケータまたは Expert Advisor を起動する際は、サーバー応答なしの警告が表示されます。

その場合は、タスクバーにコンソールのが表示されるまで 5~10 秒待ち、『Repeat』をクリックします。

追記:私は 512 RAM、Celeron M 2100 のノートブックを持っています。フィルター処理、バッファ合計 500 х 8 х 5 = 20 000 バイトのチャート数5 でディレイを経験したことはありません。選択はみなさん次第です。私はすでに選択を行いました。ディレイが生じた場合、配布された計算システムはに簡単に MATLAB で実行されます。すなわち、複数のデスクトップがローカルネットワークに接続した異なるPC で起動し始めることが可能なのです。

参考資料リスト

  1. 内蔵 MATLAB ヘルプ
  2. 『Matlab 5.х 計算、可視化、プログラミング』 N.N. Martynov 著
  3. 『C++ ビルダ 6. リファレンスマニュアル』A.Y. Arkhangelski 著
  4. 内蔵 MQL4 ヘルプ


おわりに

本稿では、MetaTrader 4 を MATLAB の数学的パッケージとバインディングするために『DLL ラッパー』を作成する基本についてお話しました。複数インディケータおよび/またはr Expert Advisor の操作を行うことについての疑問にはまだ触れていません。それは次稿で述べることとなるでしょう。MACD を持つ添付ファイルは高周波フィルター使用用に改善されています。

MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/1567

添付されたファイル |
highpas.rar (10.19 KB)
highpasFull.zip (355.1 KB)

この著者による他の記事

トレーダーのキット:デコインディケータ トレーダーのキット:デコインディケータ
本稿では、インディケータを装飾する際の主要なタスク、そのソリューションと自動化を見つけ出します。
メタトレーダーでニューラルネットワークを利用する メタトレーダーでニューラルネットワークを利用する
本稿は、みなさんのコードに複数のニューラルネットワークを取り入れて無料の人工ニューラルネットワークライブラリ(FANN)を活用し、MQL4 コードでニューラルネットワークを簡単に利用する方法をお見せします。
金融証券の重ね合わせとインターフェース 金融証券の重ね合わせとインターフェース
通貨ペアの変動に影響を与える要因が多いほど、その変動を評価し将来を予測するのが困難になります。そのため、通貨ペアの構成要素と時間と共に変化する各国通貨の値をなんとか抽出することができれば、その動向に影響を与える要因数と共に、この通貨を通貨ペアと比較して各国通貨の動きの自由度の範囲を定めることができるかもしれません。結果、その変動推定と将来予測の精度を挙げることになるでしょう。どうすればそれができるのでしょうか?
チャネルアドバンスドモデルWolfe Waves チャネルアドバンスドモデルWolfe Waves
この記事は、Wolfe Wavesのマーキングパターンの法則を紹介します。波の正しい形成を理解する上で役に立つ正確なマーキングのルールや構築の詳細をご覧になれます。