基礎から学ぶシステムトレード
シストレブログ人気ランキング  

シストレ徹底攻略シストレマスターへの道ワールド・トレーディング・エッジ基礎から学ぶシステムトレードシストレニュースシストレツールシストレナビTOPへ

 

2010年04月27日(火)

MT4によるトレードシステム開発(5) [MetaTrader4]



前回、エキスパートプログラム(EA)でオーダーのエントリー部分を作ってみました。

ただ、エントリーしっ放しではいくつか問題があるので、今回は、週末の処理を追加してみます。

このシステムでは、週明けに逆指値買いと逆指値売りの両方のオーダーをエントリーします。

まずは、週末までにどんなシナリオがあるか考えてみましょう。

1.逆指値買い、逆指値売りのどちらもヒットしない場合
逆指値買いオーダー、逆指値売りオーダーが残ります。

2.逆指値買いがヒットし、買いポジションになった場合
この場合、さらに次の二つの場合が考えられます。

(1)損切り、利食いのどちらかににヒットし、決済される。
(2)損切り、利食いのどちらにもヒットせず、買いポジションのまま残る。

3.逆指値売りがヒットし、売りポジションになった場合
この場合も、さらに次の二つのケースが考えられます。

(1)損切り、利食いのどちらかににヒットし、決済される。
(2)損切り、利食いのどちらにもヒットせず、売りポジションのまま残る。

さらに2の場合、買いポジションが決済された後に逆指値売りオーダーがヒットするケース、3の場合、売りポジションが決済された後に逆指値買いオーダーがヒットするケースもあります。

一方のオーダーがヒットしたら、他方をキャンセルする方法(OCO:One Cancels the Other)もありますが、ここでは簡単のため、そのままにしておきます。

色々なシナリオを考えてみましたが、結局は逆指値オーダーのまま残るケース、ヒットしてオープンポジションとして残るケースとあるわけです。

なので、週末処理としては、逆指値オーダーがあればキャンセル、オープンポジションがあれば決済という処理をすればよいということになります。

ここで、週末を金曜日の22時とすると、オーダーエントリーのときと同じように次のようなif文で条件を書くことができます。

   // 週末のオーダー決済
if(DayOfWeek() == 5 && Hour() == 22 && Volume[0] == 1)
{
// 逆指値オーダーのキャンセル
// オープンポジションの決済
}

ここで、「逆指値オーダーのキャンセル」、「オープンポジションの決済」の部分が簡単に書ければいいのですが、メタトレーダーではちょっと複雑になります。

逆指値オーダーのキャンセルに関しては、オーダーエントリーのときに有効期限を指定できるので、それを使った方が簡単かつ確実でしょう。

金曜日の22時ということは、月曜日の19時にエントリーしたとすれば、99時間後です。

なので、OrderSend()関数のパラメータに TimeCurrent()+99*3600 を追加すれば対応できます。

一方、オープンポジションの決済はちょっと面倒です。下のようなプログラムになります。
   // 週末のオーダー決済
if(DayOfWeek() == 5 && Hour() == 22 && Volume[0] == 1)
{
for(int i=OrdersTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS) == false) break;
if(OrderSymbol() != Symbol() || OrderMagicNumber() != MAGIC) continue;

// オープンポジションの決済
if(OrderType() == OP_BUY || OrderType() == OP_SELL)
OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage);
}
}

このあたりがMQL4の難しいところですね。

ただ、面倒な部分を関数にして、それを呼び出すだけにすればもっと簡単にプログラムを書くことはできます。詳しくは、このページで紹介しているメタトレーダーの本を参考にしてください。

最後に今回追加した部分も含めてEAのプログラムを通して書いておきます。プログラム名は「WeeklyBreakout.mq4」としておきます。

これで一応バックテストのできるEAとなりました。
// マジックナンバー
#define MAGIC 20100419

// 外部パラメータ
extern double Lots = 0.1;
extern int Slippage = 3;
extern double MultBreakout = 1.0;
extern double MultTarget = 0.8;

// スタート関数
int start()
{
// 週明けのオーダーエントリー
if(DayOfWeek() == 1 && Hour() == 19 && Volume[0] == 1)
{
double sell_sl = iCustom(NULL, 0, "WeeklyOpenRange",
MultBreakout, MultTarget, 0, 0);
double buy_sl = iCustom(NULL, 0, "WeeklyOpenRange",
MultBreakout, MultTarget, 1, 0);
double buy_entry = iCustom(NULL, 0, "WeeklyOpenRange",
MultBreakout, MultTarget, 2, 0);
double sell_entry = iCustom(NULL, 0, "WeeklyOpenRange",
MultBreakout, MultTarget, 3, 0);
double buy_tp = iCustom(NULL, 0, "WeeklyOpenRange",
MultBreakout, MultTarget, 4, 0);
double sell_tp = iCustom(NULL, 0, "WeeklyOpenRange",
MultBreakout, MultTarget, 5, 0);

double spread = Ask-Bid;

// 逆指値買い注文
OrderSend(Symbol(), OP_BUYSTOP, Lots, buy_entry+spread, Slippage,
buy_sl, buy_tp, "", MAGIC, TimeCurrent()+99*3600);
// 逆指値売り注文
OrderSend(Symbol(), OP_SELLSTOP, Lots, sell_entry, Slippage,
sell_sl+spread, sell_tp+spread, "", MAGIC, TimeCurrent()+99*3600);
}

// 週末のオーダー決済
if(DayOfWeek() == 5 && Hour() == 22 && Volume[0] == 1)
{
for(int i=OrdersTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS) == false) break;
if(OrderSymbol() != Symbol() || OrderMagicNumber() != MAGIC) continue;

// オープンポジションの決済
if(OrderType() == OP_BUY || OrderType() == OP_SELL)
OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage);
}
}

return(0);
}


>>“基礎から学ぶシステムトレード”全記事バックナンバーはこちらから




Posted at 13時18分


ページのトップへ ページのトップへ

Sponsor AD

2010/4

        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30  

プロフィール

豊嶋久道

2003年よりFX取引を始め、システムトレードの道へ。最近ではFXオプション取引も含めたトレーディングシステムの研究を行っている。システムトレードを基礎から正しく理解するための情報を発信する予定。

PHOTO

実際の相場におけるランダムウォーク

実際の相場におけるランダムウォーク

カテゴリーリスト

最近の記事

検索


当サイトコメントについて

当コメントは情報提供のみを目的として作成されたものであり、投資に関してはご自身でご判断くださいますようお願い致します。また、当資料は著作物であり著作権法により保護されております。無断で全文または一部を転載することはできません。

RSS1.0

[Login]


powered by a-blog
Copyright (C) 2008 PhiConcept,Inc. All rights reserved.