バックテストをしてみる2
50種類以上の通貨ペア、各種CFD(金、株など)対応
前回、EAを作ってみるでつくったEA(自動売買)、MA_EAをバックテストしてみました。
結果は、あまりよくありませんでしたね。
でも、EAを作ったときにパラメータをいくつか外出しにしたと思います。
覚えていますか?
もしかしたら、このパラメータをいじるといい感じの結果が出そうな予感がしませんか?
思わなくてもしたことにしてください。
話が進まないので。。。
で、パラメータのパターンをテストしていけばいいだけです。
たとえば、1つのパラメータで5パターンするとします。
1つで5パターン。
楽勝!!
2つで25パターン。
ちょっといやになってきますね。
3つで、125パターン。
やる気でないですね。
4つで、625パターン。
もう無理です。
やっぱり無理でした。。。
っていうことになりそうですが、メタトレーダーには、便利な機能があります。
スタート、ステップ、ストップの値をパターン分析したいパラメータにセットすると、すべての組み合わせを行ってくれる機能があるんです。
テスターに「Optimization」というチェックがあったのに気がつきませんでしたか?
このチェックが、パターン分析を行うチェックなんです。
では、チェックを入れてスタート!
と行く前に、
先ほどの説明のスタート、ステップ、ストップを設定して、どのパラメータを変更して解析させるかを指定する必要があります。
では、「Expert properties」ボタンを押して、プロパティウィンドウを開いてください。
次に、「パラメータの入力」タブを押してください。
では、設定していきます。
BuyLots:変更しません。
LossEntry:変更しません。
残りは、すべてチェックします。
MaPerirod:スタート(7)、ステップ(7)、ストップ(35)
TakeMa:スタート(5)、ステップ(5)、ストップ(25)
LossMa:スタート(5)、ステップ(5)、ストップ(20)
TakeEntry:スタート(25)、ステップ(5)、ストップ(50)
では、早速スタートを押してみましょう!
以下のタグに利益が出ているものだけ表示されます。
Optimization Results:損益やトレード回数、ドローダウンと利用したパラメータ
Optimization Graph:損益のグラフ
すべての解析が終了するまで、待ってください。
Optimization Resultsの損益をクリックしたください。
利益の多い順や少ない順にソートされます。
他の項目も同様です。
利益の多い順に並べます。
では、一番利益の多い行をダブルクリックしてください。
セッティングタブに戻ると思います。
「Optimization」のチェックが外れていることを確認してください。
先ほどのダブルクリックで、「Expert properties」のパラメータに選択行のパラメータが自動的にセットされました。
では、このパラメータでバックテストをとしてみましょう。
スタートボタンを押してください。
今度は、利益が出ましたね。
100pipsぐらいは増えたと思います。
サンプル用に適当に作ったEAとしては、まずますですかね。
バックテストは、こんな感じで行います。
ちなみに、一番利益が上がっているからいいパラメータではありません。
ドローダウンが大きく損失も大きいかもしれません。
たまたまその月はよかったと思いますが、未来もよいとは限りません。
また、テストの期間などもどのぐらいがいいのか?というのもEAの特性で変わってくるでしょう。
この辺はやってみないと分かりませんね。
とりあえず、これというパラメータが決まったあとは、フォワードテストというのを行います。
次回は、フォワードテストについて書きたいと思います。
タグ
2009年05月15日
コメント&トラックバック(0)
| トラックバックURL
|
EAを作ってみる2
50種類以上の通貨ペア、各種CFD(金、株など)対応
前回のEAを作ってみるで説明不足のところを説明します。
まず、スリップについてです。
成行でオーダーするときに、メタトレーダーではAskかBidの金額を指定してオーダーします。
しかし、為替は動いていますので、この金額からずれていることがあります。
ですが、注文をなるべく成功させたいと考えたときに、ズレの許容値を指定することができます。
これが、スリップです。
スリップは、オーダーするときもクローズするときも指定可能です。
OrderSend(Symbol(),OP_SELL,BuyLots,Bid,3,Bid+LossEntry*Point,Bid-TakeEntry*Point,”MA_EA Sell”,MagicNo,0,Blue);
OrderClose(OrderTicket(),OrderLots(),Bid,3,Green);
の3がスリップの値になります。
ですから、Bidから+-3pipsのズレまで、許可するということになります。
このズレ以上の場合は、オーダーされないことになります。
クローズの方が失敗するのがいやな人は、多めを指定した方がいいでしょう。
次は、自分でオーダーした注文かどうかを判断する方法です。
前回は、マジックナンバーというのを利用しました。
他にもオーダーしたときにもらえるチケットナンバー、コメントなどをキーに探すことが可能です。
ただし、チケット番号は再起動したときに分からなくなってしまうので、マジックナンバーを利用するのがいいでしょう。
※グローバル変数を使うことで、2週間覚えておく方法もあります。
なぜ、このようなことを行うかというと、利用中の口座のオーダーはすべて見ることができてしまうからです。
別の通貨ペアでも、別のEAでも、手動オーダーでもなんでも見ることができます。
ですから、自分のEAが注文したものかどうかを判断する必要があるんです。
初めてのEAなので、こうしたことをやならくてもよかったのですが、今後EAを作る場合、こうした仕組みで作ることになると思い、初めからちゃんとした機能を持たせました。
そのため、少し難しくなっています。
ちなみに、すべて見えることの応用ですが、たとえば週末にすべてのオーダーをクローズするEAなんていうのも作ることができます。
週末の持ち越しはしたくない!って方で、販売されているEAを利用している方は、こうしたEAを作れると便利かもしれませんね。
タグ
2009年05月12日
コメント&トラックバック(1)
| トラックバックURL
|
トレンドラインを書いてみる3
50種類以上の通貨ペア、各種CFD(金、株など)対応
さて、前回と前々回で、トレンドラインを書くプログラムの基本とプログラムを書くときに気をつけたほうがいいことを書きました。
今回は、トレンドラインの総仕上げとして、ループ回数を最小にして、好きな本数のトレンドラインを書くインジケータを作成します。
少々、難易度が上がりますが、がんばってついてきてください。
トレンドラインを書いてみるを参考にインジケータのスケルトンを作成してください。
前回のソースにそのまま上書きでもかまいません。
まず、前半の定義部分です。
#property indicator_chart_window
extern int nPeriod=9;
extern int Limit=350;
extern int nLine=3;
nLineを追加しました。
これは、トレンドラインの数です。
デフォルトでは、3本ずつ書きます。
初期化部分です。
int init()
{
int i;
for(i=0;i<nLine;i++)
{
ObjectCreate(”Trend DN-”+i,OBJ_TREND,0,0,0,0,0);
ObjectSet(”Trend DN-”+i,OBJPROP_COLOR,Maroon);
ObjectSet(”Trend DN-”+i,OBJPROP_WIDTH,3);
ObjectCreate(”Trend UP-”+i,OBJ_TREND,0,0,0,0,0);
ObjectSet(”Trend UP-”+i,OBJPROP_COLOR,Green);
ObjectSet(”Trend UP-”+i,OBJPROP_WIDTH,3);
}
return(0);
}
オブジェクトの作成ですが、前回と違って指定した数だけ作る必要があるため、ループをまわして指定した数のトレンドラインを書くためのオブジェクトを作成します。
名前が、「Trend UP-0″」など固定でしたが、数にあわせて名前を変更したいので、「Trend UP-”+i」としてループの値を名前に追加するように変更しました。
また、線が細くて見にくかったので、今回は少し太く描画させて見ます。
ObjectSet(”Trend DN-”+i,OBJPROP_WIDTH,3);
の部分で、線の幅をデフォルトの1ポイントから3ポイントに広げます。
次は、終了処理です。
int deinit()
{
int i;
for(i=0;i<nLine;i++)
{
ObjectDelete(”Trend UP-”+i);
ObjectDelete(”Trend DN-”+i);
}
return(0);
}
初期処理と同じく、指定された数分だけ削除するようにループしています。
次は、本題のメイン処理です。
int start()
{
//今回は、線の数が分からないので、配列を使います。
//まず、空の配列を用意します。
//固定で指定する場合は、double r[10];の様に数字を指定します。
double r[];
int rt[];
double s[];
int st[];
//配列に必要な入れ物を指定した数だけ用意します。
//はじめと終わりの入れ物が必要なので、実際の線の数より1つ多い数を指定します。
ArrayResize(r,nLine+1);
ArrayResize(rt,nLine+1);
ArrayResize(s,nLine+1);
ArrayResize(st,nLine+1);
int nCurBar;
int ChkRLine=0;
int ChkSLine=0;
if(Bars<Limit) Limit=Bars-nPeriod;
//前回とは逆に最新のものから指定本数までループをまわします。
for(nCurBar=0; nCurBar<Limit; nCurBar++)
{
//一番低い谷を見つけます。
if(Low[nCurBar+(nPeriod-1)/2] == Low[iLowest(NULL,0,MODE_LOW,nPeriod,nCurBar)])
{
//値が1つだけでは線を引けないので、配列に代入だけします。
if(ChkSLine==0)
{
s[ChkSLine]=Low[nCurBar+(nPeriod-1)/2];
st[ChkSLine]=nCurBar+(nPeriod-1)/2;
ChkSLine++;
}
//2本目の値で、1つ目の値より小さい場合描画します。
else if(s[ChkSLine-1] < Low[nCurBar+(nPeriod-1)/2] && ChkSLine <= nLine)
{
//値の代入を行い
s[ChkSLine]=Low[nCurBar+(nPeriod-1)/2];
st[ChkSLine]=nCurBar+(nPeriod-1)/2;
//描画させます。
ObjectMove(”Trend DN-”+(ChkSLine-1),1,Time[st[ChkSLine-1]],s[ChkSLine-1]);
ObjectMove(”Trend DN-”+(ChkSLine-1),0,Time[st[ChkSLine]],s[ChkSLine]);
//ラインを1つ進めます。
ChkSLine++;
}
//もし、1つ前より小さい値が見つかったときに値を入れ替えます。
else if(s[ChkSLine-1] > Low[nCurBar+(nPeriod-1)/2] && ChkSLine <= nLine)
{
s[ChkSLine-1]=Low[nCurBar+(nPeriod-1)/2];
st[ChkSLine-1]=nCurBar+(nPeriod-1)/2;
}
}
//谷と同様に山を見つけます。
if(High[nCurBar+(nPeriod-1)/2] == High[iHighest(NULL,0,MODE_HIGH,nPeriod,nCurBar)])
{
if(ChkRLine==0)
{
r[ChkRLine]=High[nCurBar+(nPeriod-1)/2];
rt[ChkRLine]=nCurBar+(nPeriod-1)/2;
ChkRLine++;
}
else if(r[ChkRLine-1] > High[nCurBar+(nPeriod-1)/2] && ChkRLine <= nLine)
{
r[ChkRLine]=High[nCurBar+(nPeriod-1)/2];
rt[ChkRLine]=nCurBar+(nPeriod-1)/2;
ObjectMove(”Trend UP-”+(ChkRLine-1),1,Time[rt[ChkRLine-1]],r[ChkRLine-1]);
ObjectMove(”Trend UP-”+(ChkRLine-1),0,Time[rt[ChkRLine]],r[ChkRLine]);
ChkRLine++;
}
else if(r[ChkRLine-1] < High[nCurBar+(nPeriod-1)/2] && ChkRLine <= nLine)
{
r[ChkRLine-1]=High[nCurBar+(nPeriod-1)/2];
rt[ChkRLine-1]=nCurBar+(nPeriod-1)/2;
}
}
//上昇・下降ともに指定本数見つかった場合、ループを抜けます。
if(ChkSLine > nLine && ChkRLine > nLine)break;
}
return(0);
}
メイン処理は、ループの中に納まっていて、必要な本数が見つかった後、breakで抜けいていることが分かると思います。
必要な数だけ、ループをまわすようにして負荷を抑えています。
値は、配列に格納しています。
本当は、配列に代入しなくても描画だけなら可能です。
ですが、今後の拡張のために値を残しておくようにしました。
値を残しておくことで、いろいろ拡張できると思います。
値の格納も1つ目の変数への格納と、条件を満たした場合に次の配列へ格納すること、一度格納した配列より大きい・小さい値の場合入れ替える処理を追加してあります。
少々複雑になりましたが、コンパクトにまとまっていると思います。
インジケータは、
インストールパス\MetaTrader\experts\indicators
に入れてください。
タグ
2009年05月11日
コメント&トラックバック(1)
| トラックバックURL
|
かるく文法(省略記号編)
50種類以上の通貨ペア、各種CFD(金、株など)対応
質問があったので、MQL4で有効な四則演算での省略記号の説明を追加します。
省略記号編
符号(+-)を2回繰り返すことで、1足したり、引いたりすることと同じになります。
i++;
→ i=i+1;
i–;
→ i=i-1;
複数の足し引きをしたい場合
i+=2;
→ i=1+2;
i-=3;
→ i=i-3;
このように同じ数の足し引きには、便利ですので覚えておくといいでしょう。
また、サンプルでもよく使われますので、意味を覚えておいてください。
ちなみに
i-;
では、通常の引き算としてあつかわれるので、iから右辺のものを引こうとしますが右辺が無いためエラーになります。
また、
i-1;
では、計算結果が左辺に出力されますが、結果を受け取ることができません。
省略記号以外は、
代入先の変数=計算式;
と記述してください。
if文などは、()内の変数を利用するため、代入先の変数を用意する必要はありません。
if(a==1)
は、
a==1の計算結果が、trueかfalseになり、その値が引数としてif文にわたされるので、代入先の変数は必要ありません。
関数の説明は、後ほど行います。
タグ
2009年05月11日
コメント&トラックバック(0)
| トラックバックURL
|
トレンドラインを書いてみる
50種類以上の通貨ペア、各種CFD(金、株など)対応
前回は、インジケーターを作ってみるで足に対応したバッファに代入することで、メタトレーダーの機能を使いグラフを自動的に描画方法を試してみました。
今回は、オブジェクトという機能を使い好きな場所に線や文字などを描画する方法を試してみます。
で、単純に線を書いてもおもしろくないのでトレンドラインを書いてみたいと思います。
トレンドとは、上下に動きながら移動している為替も平均してみると上昇していたり、下降しているときがあります。
こうした状態をトレンド相場と呼びます。
平均した線が横ばいの場合は、レンジ相場と呼びます。
為替は、上昇トレンド、下降トレンド、レンジ相場の3種類のどれかの状態になっています。
このトレンドを表す線をトレンドラインと呼びます。
上昇トレンドラインは、上下に動いている山の高値と高値を結んだ線。
下降トレンドラインは、谷の安値と安値を結んだ線のことをいいます。
このトレンドラインをインジケーターの機能を使って、描画したいと思います。
インジケーターを作ってみるを参考にスケルトンを作ります。
Nameを「TrendLine」。
その他は、何も入力しません。
まずは、TrendLineのスケルトンを作成してください。
まず、前半の宣言部分を作成します。
//メインウィンドウに描画します。
#property indicator_chart_window
//山と谷を見つける幅をパラメータとして指定します。
extern int nPeriod=9;
//先頭から何本まで山、谷を見つけるかパラメータとして指定します。
extern int Limit=350;
次は、初期化処理です。
int init()
{
//下降トレンドライン0番目のオブジェクトを作ります。
ObjectCreate(”Trend DN-0″,OBJ_TREND,0,0,0,0,0);
//下降トレンドライン0番目のオブジェクトの色を指定します。
ObjectSet(”Trend DN-0″,OBJPROP_COLOR,Maroon);
//上昇トレンド0番目のラインオブジェクトを作成します。
ObjectCreate(”Trend UP-0″,OBJ_TREND,0,0,0,0,0);
ObjectSet(”Trend UP-0″,OBJPROP_COLOR,Green);
return(0);
}
上昇、下降用のトレンドラインを引くためのオブジェクトを用意しました。
次は、終了処理です。
インジケータを削除したときに、オブジェクトが残ってしまいます。
そのために、インジケータ終了時に自分が作ったオブジェクトを削除する処理を追加します。
次は、トレンドラインを描画するための山、谷を見つけラインを引く処理です。
//山、谷の値と足番号を格納する変数と描画する値を格納する変数を宣言します。
これで、終了です。
コンパイルして、インジケータを表示させてみてください。
以下のようにトレンドラインが表示されれば成功です。
ちょっとは、らしいものができたのではないでしょうか?
少しずつレベルをアップしていきますね。
今回のプログラムは、以下からダウンロードできます。
インジケータは、
インストールパス\MetaTrader\experts\indicators
に入れてください。
タグ
2009年05月09日
コメント&トラックバック(3)
| トラックバックURL
|
かるく文法(まとめ)
50種類以上の通貨ペア、各種CFD(金、株など)対応
メタトレーダーのMQL4は、CやC#と同じような書式で、
関数は、{}の中が有効で、計算や条件は()でくくります。
if(a==0)
{
//処理
}
上記のように条件は()でくくります。
a==0は最終的に、true、falseのどちらかとしてあつかわれ、条件があっている場合は、true、
間違っている場合は、falseになります。
{}の間は、関数(上記の例ではif)の処理が有効な範囲として表します。
また、計算も()でくくることができて
a=(10/(2+3));
の様に表すことができて、
a=10/5;
となり
a=2;
と同じ意味になります。
四則演算は、かるく文法(四則演算編)を参照してください。
条件判断は、かるく文法(if文編)を参照してください。
ループ(繰り返す処理)は、かるく文法(for文編)、かるく文法(while文編)を参照してください。
タグ
2009年05月05日
コメント&トラックバック(0)
| トラックバックURL
|
かるく文法(while文編)
50種類以上の通貨ペア、各種CFD(金、株など)対応
かるく文法(for文編)と同じようにぐるぐる回す系です。
メタトレーダーのMQL4でもそうですが、文法的にはCやC#と同じなので、この辺のプログラムを使っている方は、おなじみの文法です。
while編
while(条件)
{
}
の様に使います。
条件を満たしている間は、ぐるぐる{}の間を回り続けます。
int i=10;
whie(i>=0)
{
//処理
i–;
}
このように記述するとiが10から0の間、処理を続け-1になったときに抜けます。
このような記述の場合は、for文を利用してもかまいません。
int flg=1;
int a=0;
while(flg==1)
{
//処理
a++;
if(a==10) flg=0;
}
上記のようにaが10になったときにflgへ0を代入して、ループを抜けるような使い方も行います。
while文の場合は、下の例のような使い方が一般的かもしれません。
タグ
2009年05月05日
コメント&トラックバック(0)
| トラックバックURL
|
かるく文法(for文編)
50種類以上の通貨ペア、各種CFD(金、株など)対応
ぐるぐる決まった数だけ、回したいときの方法を説明します。
for文編
for(初期値;条件;ステップ)
{
//やりたいこと
}
たとえば、
int i;
int Num[10];
for(i=0;i<10;i++)
{
Num[i]=i;
}
こんな感じだと。
iが0から9まで、1づつ足していきます。
配列は、0から始まるので、iを0から始めています。
Num[配列番号]に配列番号と同じ数字を代入しているわけです。
だから、Num[2]は2になります。
i<10はiが10より小さい間、ループすることを意味しています。
ですから、0から9の間で、10になったときにループを抜けます。
i++は、i=i+1の略で、ループするたびに1足していくことを意味します。
決まった数だけ、ループしたいときにfor文を使うことを覚えておいてください。
ちなみに
for(i=9;i>=0;i–){}
この場合は、9から0までカウントダウンして、-1になったときにループを抜けます。
逆にカウントダウンしたいときはこんな感じ。
条件がi>=0で=が入っていることに注意してください。
0までを含みますからね。
i>-1としても同じことです。
i–はi=i-1の略です。
タグ
2009年05月04日
コメント&トラックバック(0)
| トラックバックURL
|
かるく文法(四則演算編)
50種類以上の通貨ペア、各種CFD(金、株など)対応
基本の演算方法を説明します。
四則演算編
四則演算は、
+:足し算
-:引き算
*:かけ算
/:割り算
%:割り算のあまり
int a=1;
int b=2;
int c=0;
c=a+b;
//1+2でcは3になります。
c=b-a;
//2-1でcは1になります。
c=a*b;
//1*2でcは2になります。
c=b/a;
//2/1でcは2になります。
double d=0.0;
c=a/b;
d=a/b;
この場合は、ちょっと変わってきます。
cはint型で整数、dはdouble型で小数点を格納できます。
だから、cは0.5を四捨五入した値の1。
dは0.5になります。
ちなみに、
d=a%b;
は、0.5になり、あまりを計算することができます。
d=3%2;
これも0.5です。
doubleは、もう一つ気をつけなければいけないことがあります。
精度といわれるもので、計算する通貨ペアの最低単位にあわされます。
USDJPYの場合は、0.01が最低単位なので、
d=1/7;
は、0.14285714285714285714285714285714
ですが、0.14になります。
EURUSDは、0.001が最低単位なので、
0.1429になります。
この最低単位は、Pointという変数に格納されています。
桁数は、Digitsに格納されています。
USDJPYの場合は、Pointは0.01。
Digitsは、2が格納されています。
また、計算上もっと細かい単位にしたい場合は、
を使います。
今の精度より、2桁下まで利用したいときは
こうすることで、USDJPYで0.0001の単位まで、計算されます。
タグ
2009年05月04日
コメント&トラックバック(0)
| トラックバックURL
|
かるく文法(if文編)
50種類以上の通貨ペア、各種CFD(金、株など)対応
あまり難しい、文法を使うつもりはないけど基本的なやつだけ説明しておきます。
if文
もし、こんなんだったら、こうする。
っていうことを行います。
int ChkNo=1;
if(ChkNo==0)
{
//ChkNoが0のとき
}
else if(ChkNo==1)
{
//ChkNoが1のとき
}
else
{
//ChkNoが0と1以外のとき
}
こんな感じで書きます。
上記の例だと、2番目に入ってきます。
条件文は
==:右と左の値が同じ場合
!=:右と左が違う場合
<:左より右が大きい場合
<=:左と同じか、右の方が大きい場合
>:右より左が大きい場合
>=:右と同じか、左の方が大きい場合
こんな感じの条件文が使えます。
条件は、連結することができて
&&:AND
||:OR
で結ぶことも可能です。
int a=1;
string strBuf=”ABC”;
if(a==1 && strBuf==”ABC”){}
こんな感じで、2つの条件が整ったときだけ処理するように指定できます。
タグ
2009年05月03日
コメント&トラックバック(0)
| トラックバックURL
|



![[image]投資で失敗しない7つの法則:無料CDプレゼント](http://www.affiliatecenter.jp/invest/img/FX_freeCD/banner165x100seven_rule5e.gif)
![[image]無料レポートプレゼント:ドルが紙くずになった時に資産を守る方法](http://www.affiliatecenter.jp/invest/img/dollar/MNL4_165x100.jpg)



MyBlog
