システムの質を高める
前回までに作ったシステムに手を加えて、実際の取引の時に使いやすいものにしていきましょう。
①パラメータを作る
②売買制限を設ける
③他の取引(手動での取引や他のシステムでの取引)の邪魔をしないようにする
では、早速
①のパラメータを作る方法。
パラメータとは、外部から設定できる値のことで、これを設けることでシステムに融通性が出てきます。
今回は、
損切り幅
利食い幅
ロット数
移動平均の計算期間
を、設定可能にしていきましょうか。
書く場所は、#property ・・・ の下あたりに書きましょう。
書き方は、
extern int StopLoss = 50;
extern int TakeProfit = 20;
extern double lots = 0.1;
extern int avePeriod = 12;
という感じです。
変数の宣言の前に extern を付け加えるだけです。
宣言の後に = ** と付け加えると、最初は**を入れておいてくださいといった意味になります。
さて、この変数たちをシステム内に忍ばせるわけですが、まずは
OrderSend の()内の損切り値に入れたいと思います。
その前に、パラメータで扱う変数は、損切り幅ですから、これを損切り値に変えてあげなければなりません。
Ask-(StopLoss*Point)
と書けば損切り値に変わります。
Point とは、このチャートの1ピプスの桁のことで、例えば、USDJPYの通貨ペアだったら、0.01になります。
これは、
買値 - ( 損切り幅 * ピプスの桁 )
といった感じです。
利食い値も同様に
Ask+(TakeProfit*Point)
となります。
ロット数はそのままで大丈夫そうですね。
これを、OrderSend の()内にそれぞれ入れてあげましょう。
OrderSend(Symbol(), OP_BUY, lots, Ask, 3,
Ask-(StopLoss*Point), Ask+(TakeProfit*Point),
"Buy", 10, 0, Blue);
といった具合です。
同じように移動平均の関数 iMA の()内にも avePeriod を入れてあげましょうか。
ave=iMA(NULL,0,avePeriod,0,MODE_SMA,PRICE_CLOSE,1);
というように、10のかわりに avePeriod を入れましょう。
さて、これでパラメータを設定できる環境になりました。
コンパイルして、一度、MT4で作動させてみましょう。
やり方は、使い方を覚えるという記事の中で紹介しましたね。
最初にプロパティウィンドウが開きました。その中のパラメータータブをクリックすると、設定した4つのパラメータが並んでいます。
Value の欄の数字をダブルクリックするとパラメータを入力し直すことができます。これで、システムの幅が広がったわけです。
続いて②の売買制限を設ける方法ですが、
今回は、一つのバーの中では、1回しか注文を出さないという制限を付け加えましょう。
ここで、バーとは、ロウソク足の一本一本のことで、実は内部的に一本一本に番号がついています。それを引き出すのが Bars という変数です。
この条件を付け加えると、注文したバーの中で、損切りや利食いが発生したとき、次のバーが現れるまで注文をしないといった意味になります。
まずは、バーの番号を記憶させる変数を nowbar としておきましょうか。
これを、パラメータを設置した下あたりに宣言します。
int nowbar;
としましょう。
これを、int start() の{}内に書いてしまうとint start() の動作が終わるたびにリセットされてしまうので、記憶しておいてもらえません。気をつけましょう。
この変数に、取引したときのバーの番号を記憶させましょう。
やり方は、OrderSend 文の下の段に
nowbar = Bars;
と、書きます。
nowbar に現在のバーの番号を代入するといった意味です。
次に、nowbar と Bars が違うときだけ取引するという条件を加えましょう。
やり方は、OrderSend 文の上のif文の()内を
nowbar != Bars && Close[1]>ave
とするのです。 != はノットイコールの意味です。
これは、
nowbar が Bars と同じでない時、かつ、1本前の終値が ave より大きい時、
という意味です。
これで一つのバーの中では、1回しか注文を出さないようになりました。
③の他の邪魔をしないようにするには、このシステム特有の暗号を作ってあげましょう。
これは、OrderSend のマジックナンバーを使います。
まずは、ポジション無しの場合に使った
if(OrdersTotal()<1) の代わりに
OrdersTotal()のなかで、マジックナンバーが 10 のものがあればそのインデックスを、変数 CurrentPosition に代入する
というプログラムを書き、代入されなかった場合は、ポジション無しとみなす、といった文にしていきましょう。
ここでは、新たに cnt と CurrentPosition という変数をつくりますので、int start() の{}内の ave を宣言した下あたりに
int cnt, CurrentPosition = -1;
と変数の宣言をしてあげましょう。
ここで、CurrentPosition = -1 としたのは、ポジションのインデックスが 0 から始まることで、変数をそのまま宣言したときのデフォルトの 0 とかぶらないようにするためです。
そして、オーダーの条件文の前に
for(cnt=0;cnt<OrdersTotal();cnt++)
{
OrderSelect(cnt,SELECT_BY_POS);
if(OrderMagicNumber() == 10) CurrentPosition=cnt;
}
という文を書いてあげます。
ここで、
for(*1;*2;*3){***}
は、繰り返すときに使う構文で
*1から開始して***する。*2のうちは*3を行い、***する。また、*2のうちは*3を行い、***する。また、・・・。
という感じです。
また、cnt++ とは、cnt=cnt+1 という意味で、cnt に 1 をたして、cnt に代入するといった意味です。
全体では、
cnt が 0 のとき、
0 よりポジションの合計が多いなら続けてください。
持っているポジションのうちインデックス 0 のものを選択してください。
もし、そのマジックナンバーが 10 であるならば、CurrentPosition に 0 を代入してください。
cnt に 1 を足してください。
cnt が 1 のとき、・・・
と続きます。
もし、ポジションの合計が 0 より多くない(0の)とき、{}内の処理はされないので、CurrentPosition には、何も代入されることが無く、デフォルトの -1 になるということになります。
ですので、
if(OrdersTotal()<1) の代わりに
if(CurrentPosition == -1)
と書いてあげましょう。
さらに、ポジション有りの場合のOrderSelect のインデックスの部分には、
0 の代わりに
CurrentPosition
と入力しましょう。
これで、このシステム特有のマジックナンバー 10 だけを選んで取引できるようになりました。コンパイルを忘れずにしましょう。
int init() や int deinit() は今のところ使わないので消しても大丈夫です。
全体をコピペしてみます。
//+------------------------------------------------------------------+
//| 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;
//記憶用の変数
int nowbar;
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
//変数の宣言
double ave ;
int cnt, CurrentPosition = -1 ;
//移動平均値の算出
ave=iMA(NULL,0,avePeriod,0,MODE_SMA,PRICE_CLOSE,1);
//オーダー
for(cnt=0;cnt<OrdersTotal();cnt++)
{
OrderSelect(cnt,SELECT_BY_POS);
if(OrderMagicNumber() == 10) CurrentPosition=cnt;
}
// ポジション無しの場合
if(CurrentPosition == -1)
{
//もし1本前の終値が移動平均より上ならば
if(nowbar != Bars && Close[1]>ave )
{
//ポジションを取る。
OrderSend(Symbol(), OP_BUY, lots, Ask, 3, Ask-(StopLoss*Point), Ask+(TakeProfit*Point), "Buy", 10, 0, Blue);
nowbar = Bars;
}
}
// ポジション有りの場合
else
{
//ポジションのデータを取得。
OrderSelect(CurrentPosition,SELECT_BY_POS);
//もし1本前の終値が移動平均より下ならば
if(Close[1]<ave)
{
//ポジション決済
OrderClose(OrderTicket(),OrderLots(),Bid,3,Green);
}
}
//----
return(0);
}
//+------------------------------------------------------------------+
こんな感じになりましたか。
今回はこのへんで。
2007年10月14日|コメント (0)|トラックバック (0)
カテゴリー:完全自動売買
トラックバック(0)
http://www.dr-ea.com/base/mt-tb.cgi/10
コメントを投稿する
Captchaの認証で入力ミスがありますと、コメントが消えてしまいますのでご注意ください。
コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「<」、「>」は「>」と入力してください。



