システムの質を高める2

システムの質を高める2

今回は、

①売り取引もする
②売買条件にフィルタを付け加える
③最適化をする

ということをやっていきましょう。


まずは、①の売り取引もする方法。
これは、買い取引の条件文を書いたときと、同じようにすればいいです。
場所は、ポジション無しの条件文の{}内の、買いの条件文の{}のつぎあたりに書きましょうか。

if(nowbar != Bars && Close[1]<ave )
{
//売りポジションを取る。
OrderSend(Symbol(), OP_SELL, lots, Bid, 3, Bid+(StopLoss*Point), Bid-(TakeProfit*Point), "Sell", 10, 0, Red);
nowbar = Bars;
}

とすればよいです。
注意点は、価格は Ask ではなくて Bid になるということ。損切り値、利食い値の +- が反対になることです。あとは、コメントや色も変えてあげましょうか。

更に、決済のときのポジションの振り分けも必要ですね。

// ポジション有りの場合
else
{
//ポジションのデータを取得。
OrderSelect(CurrentPosition,SELECT_BY_POS);
//もしポジションが買いポジションだったら
if(OrderType()==OP_BUY)
{
//もし1本前の終値が移動平均より下ならば
if(Close[1]<ave)
{
//買いポジション決済
OrderClose(OrderTicket(),OrderLots(),Bid,3,Red);
}
}
//もしポジションが売りポジションだったら
if(OrderType()==OP_SELL)
{
//もし1本前の終値が移動平均より上ならば
if(Close[1]>ave)
{
//売りポジション決済
OrderClose(OrderTicket(),OrderLots(),Ask,3,Blue);
}
}
}

このように、選択されたポジションが売りか買いかを調べるときは、
OrderType()
を使います。

これで、上のように条件をつけて、振り分けて、そのうえで決済条件を書きましょう。

売りポジションの決済の場合の価格は、Ask になるので気をつけましょう。


続いて、

このままでは、移動平均より上ならばホイホイと買い、下ならばホイホイト売り。これでは、勝率も上がりませんし、利益も出しづらいと思います。
なので、一般的には条件を絞ってあげて、勝てるときに取引をするといった売買戦略をつくります。
今回は、フィルタとしてオシレータ系のストキャスティクスを使いましょうか。

まずは、ストキャスの値を代入しておく変数の宣言です。変数名は、
sto にしておきましょうか。

double ave,sto;

このように、既存の ave の後ろにカンマと sto を割り込ませましょう。これで、ave と sto は小数ですよといった意味になります。

つぎに、ストキャスの値を計算します。といっても、便利な関数があるので、簡単です。

//ストキャスティクス
sto = iStochastic(NULL, 0, 5, 3, 3, MODE_SMA, 0, MODE_MAIN, 0);

これを、移動平均の計算式の下あたりに入力します。

iStochastic(・・・) はストキャスの関数です。

()内の意味は、
(通貨ペア,時間足,%K期間,%D期間,スロー期間,移動平均の種類,使う価格,ラインの選択,時期)

といった感じです。

これを使って売買の条件を絞りたいのですが、ここはひとつ、条件の値をパラメータにしましょうか。

ストキャスの許容度として stoLevel という変数を作りましょう。
まずは、変数の宣言ですが、パラメータ用の変数のところに

extern int stoLevel=20;

を付け加えましょう。

そして、ポジション無しの場合の買いの条件を

//買いの条件
if(nowbar != Bars && Close[1]>ave && sto<stoLevel)

といった感じに付け加えましょう。

売りの時も同様に

//売りの条件
if(nowbar != Bars && Close[1]<ave && sto>100-stoLevel)

という具合です。

ここで、売りのときは、sto の値は 100 に近いほうがよいので
sto>100-stoLevel としておきましょう。

これでフィルタは装着完了です。コンパイルしましょう。


③の前にもう一度仕上がりのコードをコピペしておきますね。

//+------------------------------------------------------------------+
//| HeikinSample.mq4 |
//| SAMURAI |
//| http://samuraifx.seesaa.net/ |
//+------------------------------------------------------------------+
#property copyright "SAMURAI"
#property link "http://samuraifx.seesaa.net/"
//パラメータ用の変数
extern int StopLoss =40;
extern int TakeProfit = 20;
extern double lots = 0.1;
extern int avePeriod=12;
extern int stoLevel=20;
//記憶用の変数
int nowbar;

//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
//変数の宣言
double ave,sto ;
int cnt, CurrentPosition = -1 ;

//移動平均値の算出
ave=iMA(NULL,0,avePeriod,0,MODE_SMA,PRICE_CLOSE,1);
//ストキャスティクス
sto = iStochastic(NULL, 0, 5, 3, 3, MODE_SMA, 0, MODE_MAIN, 0);
//オーダー
for(cnt=0;cnt<OrdersTotal();cnt++)
{
OrderSelect(cnt,SELECT_BY_POS);
if(OrderMagicNumber() == 10) CurrentPosition=cnt;
}

//ポジション無しの場合
if(CurrentPosition == -1)
{
//買いの条件
if(nowbar != Bars && Close[1]>ave && sto<stoLevel)
{
//買いポジションを取る。
OrderSend(Symbol(), OP_BUY, lots, Ask, 3, Ask-(StopLoss*Point), Ask+(TakeProfit*Point), "Buy", 10, 0, Blue);
nowbar = Bars;
}
//売りの条件
if(nowbar != Bars && Close[1]<ave && sto>100-stoLevel)
{
//売りポジションを取る。
OrderSend(Symbol(), OP_SELL, lots, Bid, 3, Bid+(StopLoss*Point), Bid-(TakeProfit*Point), "Sell", 10, 0, Red);
nowbar = Bars;
}
}
// ポジション有りの場合
else
{
//ポジションのデータを取得。
OrderSelect(CurrentPosition,SELECT_BY_POS);
//もしポジションが買いポジションだったら
if(OrderType()==OP_BUY)
{
//もし1本前の終値が移動平均より下ならば
if(Close[1]<ave)
{
//買いポジション決済
OrderClose(OrderTicket(),OrderLots(),Bid,3,Red);
}
}
//もしポジションが売りポジションだったら
if(OrderType()==OP_SELL)
{
//もし1本前の終値が移動平均より上ならば
if(Close[1]>ave)
{
//売りポジション決済
OrderClose(OrderTicket(),OrderLots(),Ask,3,Blue);
}
}

}
//----
return(0);
}
//+------------------------------------------------------------------+


さあ、いよいよ最適化です。

最適化とは、特定の通貨ペアの特定の時間足で、
このシステムのパラメータを変化させて利益を出しやすくする作業です。

やり方は、バックテストの作業と似ています。

MT4 を開き、テスターを開きます。

Expert Advisor: にHeikinSample を選びます。

その他、それぞれをセッティングします。(バックテストのときと同じ要領)

右上の Expert properties ボタンを押してパラメーターの入力タブを押します。

最適化したいパラメータのチェックボックスにチェックをいれます。

スタート、ステップ、ストップの欄にそれぞれ、スタートからストップまでステップの幅で調べたい数値を入力します。

例えば、損切り・利食い幅は広めに取って、lots は 1 にしておいて、avePeriod と stoLevel にチェックを入れて、
avePeriod は 6 から 3 つとびの 21 まで、
stoLevel は 10 から 5 つとびの 30 まで。
といった感じです。

OK ボタンを押して、ウィンドウを閉じ、Optimization にチェックをいれてスタートボタンで開始します。

終了したら、Optimization Results で並べ替えをしたりして見ていきましょう。特に、取引回数、プロフィットファクター、ドローダウンをみてよさそうなもののパラメーターの入力の欄をみてみましょう。
それを参考に更に、練り込んでやってみましょう。
時間が許すなら、Every ticks の方でやってみましょう。


このように、パラメータを過去のデータにあわせていく作業が最適化です。

ここで気をつけてほしいのは、全ての通貨ペアに通用するパラメータを探すのはやめましょう。なぜなら、1pipsの価値も違うしそれぞれ動き方に性格のようなものがありますので、システムとの相性も当然出てくるからです。

今回、作ってきたシステムは、単純ですが意外によいかもしれません。相性のよい通貨ペア、時間足が見つかったら、デモ取引で試してみましょう。

トラックバック(0)

このエントリーのトラックバックURL:
http://www.dr-ea.com/base/mt-tb.cgi/85

コメント (4)

このシリーズですが、自動売買のむずかしい部分を判りやすく説明していただき、大変勉強になります。ありがとうございます。

投稿者:YUME |2009年5月13日 16:37

YUMEさん

こんにちわ!
コメントありがとうございます^^
自動売買のプログラムは難しいところもありますが、慣れてくると楽しいです^^

がんばりましょうね!

投稿者:慶次 |2009年5月13日 16:59

はじめまして
EAのプログラムに挑戦してみようと、いろいろと勉強させてもらっています。
非常に解りやすくて、助かります。

プログラムの件で質問があります。
例えば、移動平均線のゴールデンクロス、デットクロスのEAを何とか作成したのですが、
手動で止めてやらないとどんどん売買されてしまします。
一度だけエントリーし決済したら止まるようにするには、どのようにすれば可能ですか?

投稿者:ATOM |2010年8月12日 20:15

ATOMさん

こんにちわ^^

エントリしたときに、エントリしたということを記憶用変数に覚えてもらって、
エントリ条件にまだエントリしていないということを加えればOKだとおもいます。

この記事では、
エントリしたときに、

nowbar = Bars;

として、エントリしたローソク足の番号(数)を覚えてもらって、
その足では、もうエントリしないように

if(nowbar != Bars && ・・・

としてますが、

それを、1回エントリしたらもう2度とエントリしない
という条件に変更すればよいです。


1つ注意点があり、記憶用変数(グローバル変数)は、
EAを外したときにリセットされますので、
パラメータ再設定などでは、前の記憶が残ってます。

パラメータ再設定などでも、値をリセットするには、
init()関数の中で初期値を代入するといった処理が必要です。

この記事のEAでいうと

int init()
{
nowbar = 0;

として、

エントリ条件文を

if(nowbar == 0 && ・・・

とすれば、1回のみのエントリということになります。


nowbar を、entry_flag としてbool型にして、
true/falseで判定するのが自然ですかね^^;

投稿者:慶次 |2010年8月13日 09:51

コメントを投稿する






画像の中に見える文字を入力してください。

Captchaの認証で入力ミスがありますと、コメントが消えてしまいますのでご注意ください。
コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。