FXボーグ | テクニカル実験室

テクニカル分析を使った自動売買プログラムの開発に挑戦!

スポンサーリンク

mqlからDLL内のインスタンス・データにアクセスする方法

こちらのフォーラムにDLL内クラスをmqlにインポートする方法が書いてあったので試してみました。

f:id:fxborg:20170326172122p:plain

C++に回帰

いろいろと半端な言語でインジケーターを書き直すより、DLL化しておいた方が開発効率がいいんじゃないかと思い至りました。ただし、mqlではクラスのインポートに対応してないそうです。

何とかならないかと調べているとこちらのフォーラムにたどり着きました。

こちらの回答によれば、

C++のクラスのインスタンスはポインタと同じで、ポインタも結局のところint32かint64にすぎません。

ということなので、とりあえず簡単な例で試してみました。

mt4で呼び出せるDLL

mt4でdllを呼び出すには、いくつか決まりごとがあります。

  1. ・x86でビルドする
  2. ・defファイルを作成し、エクスポートする関数名等を公開する
  3. ・エクスポートする関数等には「__extern "C"」修飾子を付ける
  4. ・「mql\libraries」以下に配置する

こちらのサイトなどが参考になりました。

  1. 初めてのDLL(1)/環境準備篇 - とあるMetaTraderの備忘秘録
  2. http://www.green.dti.ne.jp/sdimension/mql/mql_2011_03.pdf(PDF)
  3. ロスカットに負けない男: 【MT4】いちばん簡単なDLLの作り方
  4. neka-nat×株ロボ : MT4で行列計算

C++側のクラス

単純移動平均を求めるクラスを作りました。「CExpClass」というクラスを定義しています。

▼expclass.h

f:id:fxborg:20170326181027p:plain

std::mapは連想配列です。2分木で実装されているのでデータが追加される際に勝手にソートされます。またイテレーターでのアクセスも可能です。

▼expclass.cpp

f:id:fxborg:20170326184126p:plain

エクスポートする関数を定義しています。引数に「CExpClass*  instance」とありますが、外部からはただの数値が渡されます。受ける側ではポインタと解釈するのでインスタンスとして扱うことができます。 

f:id:fxborg:20170326184501p:plain

pushメソッドでは対象期間のデーターをstd::mapにキャッシュしておいて、smaメソッドで計算します。

 mt4から呼び出すには

ビルドで作成された「expclass.dll」を「mql\libraries」以下にコピーします。

▼expclass.mq4

インジケーター側のソースです。

f:id:fxborg:20170326190620p:plain

「expclass.dll」を呼び出す定義を記述して、OnInit() と OnDeinit() イベントにインスタンスの生成と破棄を行う関数をそれぞれ記述します。

f:id:fxborg:20170326191456p:plain

OnCalcurate() イベントのループ内ではバー・インデックスと終値を渡しています。

実行結果

インジケータの期間を変えて4本表示したところ問題なく表示されました。

f:id:fxborg:20170326192502p:plain

最後に

今回は、DLL内のクラスにアクセスする方法を試してみました。この方法の利点はデータを一つずつ渡してDLL内のインスタンスに保持できる点です。またNinjaTraderやcAlgoでも再利用することができます。

Cをずいぶん前に触ったきりだったので「ちょっと面倒だぞ」と思っていたのですが、型推論や STL などあって意外と快適でした。今後は行列演算ライブラリなどを試したいと思います。

こちらからどうぞ
ExpClass.zip