ブログトップ 記事一覧 ログイン 無料ブログ開設

とあるMetaTraderの備忘秘録 RSSフィード Twitter

忙しいです。ネタもないし・・・

2009-10-23

MQL4のMovingAverageEA を MQL5 に移植する。

最新のMetaTrader5 のインストーラからインストールすると、MQL5 Reference の英語版が手に入ります。関数名が変わった部分もあるので、それを参照するのがよさそうです。

(ちなみに、この英語版、google翻訳版を校正して作られているっぽいです..。「C++」という表記が「C + +」と間延びしているのが特徴です。笑)



さて、Nero Tulipさんから、単純なEAの移植をしてみて欲しいとのリクエストがありましたので、MQL4付属のサンプルEA Moving Average.mq4でロット管理、ポジション管理を割愛したサンプルを移植してみました。MovingAverageEA_MQL4to5.mq5


このEA自体、いくつか問題があって、例えば

if(Volume[0]>1) return;

は、新規 Bar の初回更新時に、既に Volume[0]=2 で来てしまったらダメじゃん..とか、

if(Open[1]>ma && Close[1] < ma)  

は、偶然 ma=Open[1] やma=Close[1] だったら成立しないし、窓明け気味に ma を超えてしまったら検出できない..という致命的な欠陥があるのですが、シンプルな構造なのでサンプルとして分かりやすいかなと思って選んでいます。


それから、既にご存知の通り、MetaTrader5 ではポジションが合算されているのと、売買履歴は、注文履歴と約定履歴の2つに分かれてしまったので、今回の移植からは、履歴を参照するロット管理、ポジション管理を省略しています。



まず、移植の方針ですが、

(A) MQL5時代にふさわしいコードとして新規に書き直す

(B) MQL4のコードを出来る限り再利用する

があると思います。(A) をやりたい人は、MACD_Sample_1.zipを参考に自力でどうにかできるでしょうから、当分は、(B)を想定して移植を進めます。現状では、MQL5 のプログラミングに構造体の知識は必須ですが、クラスは一切使わなくても、EAは作れます。ただ、便利なクラスを敢えて使わないでおくのも、もったいないので、一部使用することにします。



Close[ ],Open[ ],High[ ],Low[ ],Bid,Ask,BarsをMQL4 互換にする。


これまでグローバルな配列、変数として、プログラム内の任意の場所で利用できていましたので、MQL5 でもそのようにしてしまいます。

(..そんなことしたらバグの温床に…と拒否反応を示す人は、真似しないでください...T_T)

(1)グローバルな領域に変数宣言し、

//MQL4 Compatible start
double Ask,Bid;
double Open,Close,High,Low;
long   Volume[];
int Bars;
//MQL4 Compatible end

(2)OnInit()内で、配列を数える方向を MQL4方式に変更し

int OnInit()
  {
//---
//MQL4 Compatible start
   ArraySetAsSeries(Open,true);
   ArraySetAsSeries(Close,true);
   ArraySetAsSeries(High,true);
   ArraySetAsSeries(Low,true);
   ArraySetAsSeries(Volume,true);
//MQL4 Compatible end

(3)Tick更新のたびに、全データをコピーする。

void OnTick() // void start()
  {
//MQL4 Compatible start
   Ask  = SymbolInfoDouble(Symbol(),SYMBOL_ASK);
   Bid  = SymbolInfoDouble(Symbol(),SYMBOL_BID);
   Bars = Bars(Symbol(),PERIOD_CURRENT);
   CopyClose(_Symbol,PERIOD_CURRENT,0,Bars,Close);
   CopyOpen(_Symbol,PERIOD_CURRENT,0,Bars,Open);
   CopyHigh(_Symbol,PERIOD_CURRENT,0,Bars,High);
   CopyLow(_Symbol,PERIOD_CURRENT,0,Bars,Low);
   CopyTickVolume(_Symbol,PERIOD_CURRENT,0,Bars,Volume);
//MQL4 Compatible end

とすればOKです。

自分は Close[ ] しか使わないよって人は、余分な宣言やコピーを削除してしまってもよいですし、

配列の順序が、Close[0] が最新ではなくて Close[Bars-1] が最新でかまわないのなら (2) は省略可能です。



テクニカル指標関数 iMA を使う

(1)グローバルな領域にiMA のハンドルと配列を宣言し、

// use iMA
int iMA_handle;
double MABuffer[];

(2)OnInit()内で、iMA のハンドルを設定し、配列を数える方向を MQL4方式に変更し

// use iMA
   iMA_handle=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE);
   ArraySetAsSeries(MABuffer,true);

(3)Tick更新のたびに、データをコピーする。

// use iMA
   int copied=CopyBuffer(iMA_handle,0,0,Bars,MABuffer);
   if(copied<3) return;

これで、移動平均の値が MABuffer[0] のような形で取得できます。

iMACD やiBands のような複数の値を持つテクニカルでは、

CopyBuffer(iMACD_handle,0,0,Bars,MACDBuffer);
CopyBuffer(iMACD_handle,1,0,Bars,MACDSignalBuffer);

のように CopyBuffer の2番目の引数を指定して取得します。


iMA の呼び出し回数が少ないプログラムでは、http://www.dr-ea.com/meta-blog/mql5/mql4tomql5no1.html で紹介されている簡潔な手法でもかまわないと思います。

iMAと互換性のある関数を用意する実装なので、移植は楽なのですが、forループの中でiMA を呼び出している場合に、無駄な処理が多くなるので、動作速度が気になります..^^;;


とりあえず、今日はここまで。

alohafxalohafx 2009/10/23 08:18 もうこれだけで泣きそうです。
MT5が嫌いになってきました。
MQL5を全く始めから勉強し直すようですね。

ロロマルロロマル 2009/10/23 12:49 faiさん、こんにちは。
解説いつもありがとうございます!
プログラムの基本がわかっていないので難儀しています^^;
とりあえず、プリントアウトして赤ペン片手に勉強中です。

google翻訳版がこんなところ活躍していているとはw

alohaFXさん、お久しぶりです^^
私はすでに号泣していますw

fai_fxfai_fx 2009/10/23 12:50 この程度の事は、なんでもないレベルです。
調べれば調べるほど、MT5がもっと嫌いになります...orz

Nero TulipNero Tulip 2009/10/24 00:37 サンプルEAを参考にいろいろ研究して、少しずつ慣れてきました(まだ少しですw)。
インジケータがらみは、慣れの問題だという気がします。

MT5自体はまだ、変数の値が消失したり(謎)、
SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)の戻り値が0.00000...で、割り算がZeroDevideになったり、結構バグだらけな気がします・・・。(使い方が間違ってるのかもしれませんw)

目下の興味の中心は、オーダーの合算&両建て不可という使えない仕様を解決することなので、
OrderCloseや初期SL/TPでポジションを閉じるのではなく、

1) エントリーと同時に、MAGIC・Deal・SymbolなどをIDにして、MT4ライクなバーチャルなチケットとして、
OrderOpenPrice、SL/TP、ロット数、OrderOpenTime(時限退出用)などをGlobalVariable(またはFile)に保存

2) Tick毎にGVをスキャンして、ヒットしたら個別に反対売買で決済する(決済後、同一IDを持つGVを全て削除)

3) トレーリングはこのバーチャルなSL価格を個別にModifyする

という方法を模索中ですが、バグ出まくりでうまく動作しませんw。

うまくいけば、バーチャルにほぼMT4同様のトレードができるのではないかと思うのですが・・・
(先走りすぎかもしれませんw)

回線不通や、GV値の読み書き・削除時のエラーなどが怖い方法ではありますが、
とりあえずこのような方法以外思いつきません。
faiさんなら、何か他に名案はありますでしょうか。

fai_fxfai_fx 2009/10/24 23:17 バグだらけなのは間違い無いです。笑
動いていない関数をみつけたらバグレポートを出しましょう。^^;

えっと、MT4互換な建玉管理をするには、基本的に、Nero Tulipさんの考えている方法しかないと思います。バーチャルなSL(orTP) は、その価格に反対注文となる指値注文を入れてしまっても良いかもしれません。

MQ社からは、注文履歴を解析すればいい..旨のコメントが出ているので、注文履歴と約定履歴から、どこまで実用的にMT4互換にできるか考えたいとは思っています...。

投稿したコメントは管理者が承認するまで公開されません。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/fai_fx/20091023/1256244564