豊島久道著「FXメタトレーダー入門」で最初のEAとして登場したのは「MACross_Exp.mq4」というプログラム例であった(同著222頁)。長短2本の移動平均線を使った途転売買システムで、およそ実用には堪えないEAであったが、初めてプログラムに取り組む初級者にとっては、格好な教材であった。
今回はこの旧MT4で書かれた「MACross_Exp.mq4」を新MT4 Strictで書き直してみるとどうなるのか、オリジナルの中身を変えないでエラーやウオーニングが出ない範囲の修正で改造してみたのを末尾に掲げておいた。出来上がったソースコードをコンパイルするとエラーも警告も出てこない。それでは、これでEAとして完全な姿かというと実はそうではない。著者もその後の著作やブログで修正を重ねておられるが、補強すべきところは次の諸点である。次回には、改良後のEAを紹介したい。
① Slippage
著書刊行当時の通貨ペアの表示は、小数点以下2桁(ドル円)と4桁(ユーロドル)が主流であり、Slippageの単位も当時の1point単位であった。ドル円では0.01円、ユ→ロドルでは0.0001ドルであった。最近では、3桁と5桁表示とするのがほとんどであり、最小表示単位である1pointの価値も1/10となっている。プログラム中のSlippage 3も10倍しなければならない。
② if(volume[0] > 1) return;
エントリーは仕掛け条件を満足した次のローソク足の始値でなされることになっており、そのため volume[0] > 1 というフィルターが加えられている。ところがこの関数が実際の運用ではしばしば正しく作動しないことが分かっており、著者もその後のEAでは一切採用されていない。代替処理を必要としている。
③ クラスライブラリーの活用
新MT4では構造体をさらに拡張した「クラス」機能を利用した「標準ライブラリー」が用意されている。本EAにも使われているテクニカル指標もCiMAとして定義されている。これのオブジェクトを作成してEAのiMA()に替えた場合のプログラムも試してみたい。
// MACross_Exp_Strict.mq4
#property strict
//マジックナンバー
#define MAGIC 20070828
//パラメーター
input int FastMA_Period = 10;
input int SlowMA_Period = 40;
input double Lots = 0.1;
input int Slippage = 3;
// ポジションを決済する |
void ClosePositions()
{
for(int i=0; i<OrdersTotal(); i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == false) break;
if(OrderMagicNumber() != MAGIC || OrderSymbol() != Symbol()) continue;
//オーダータイプのチェック
if(OrderType()==OP_BUY)
{
int ticket = OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,White);
break;
}
if(OrderType()==OP_SELL)
{
int ticket = OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,White);
break;
}
}
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//バーの始値でトレード可能かチェック
if(Volume[0]>1 || IsTradeAllowed()==false) return;
//移動平均の計算
double FastMA1 = iMA(_Symbol,0,FastMA_Period,0,MODE_SMA,PRICE_CLOSE,1);
double SlowMA1 = iMA(_Symbol,0,SlowMA_Period,0,MODE_SMA,PRICE_CLOSE,1);
double FastMA2 = iMA(_Symbol,0,FastMA_Period,0,MODE_SMA,PRICE_CLOSE,2);
double SlowMA2 = iMA(_Symbol,0,SlowMA_Period,0,MODE_SMA,PRICE_CLOSE,2);
//買いシグナル
if(FastMA2 <= SlowMA2 && FastMA1 > SlowMA1)
{
ClosePositions();
int ticket = OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,0,0,"",MAGIC,0,Blue);
return;
}
//売りシグナル
if(FastMA2 >= SlowMA2 && FastMA1 < SlowMA1)
{
ClosePositions();
int ticket = OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,0,0,"",MAGIC,0,Red);
return;
}
}
//+------------------------------------------------------------------+
※コメント投稿者のブログIDはブログ作成者のみに通知されます