緊急告知!
お年玉企画前倒し?!
日ごろの感謝の気持ちとして、クリスマスプレゼント企画に引きつづき、
お年玉企画をと考えていましたが、スケジュールの関係で日程前倒し、企画変更です。
今回は、年越し&お年玉プレゼントとして、
前回と同様、VolAveP2008_1.ex4 をプレゼント!
前回ダウンロードできなかった方は、是非ダウンロード・リンクを見つけてくださいね!
(リンク元は前回とは違う場所にしました^^;)
VolAveP2008_1.ex4 の説明
まずはじめに
VolAveP2008_1.ex4は利益を保証するものではありません。
取引は、自己責任でお願いいたします。
MetaTrader4のExpert Advisor としてご利用いただけます。
ダウンロード先は、こちらの記事でご確認ください。
有効期限は2008年1月末までです。
USDJPYの一時間足を使います。
特徴
VolAveは損小利大ではありません。
損少々利多を目指しております。
統計データに基づいた小さな波をキャッチ。
10ピプスをきっちりゲットを目指します。
取引頻度は平均1回/1日。取引無しの日が続く事もあります。
複利・単利を選べます。(複利はレバレッジ10倍)
コツコツ型ですので、爆発的な利益は望めません。
その他、質問や感想などコメントお待ちしております(^0^)/
応援ありがとうございます!
→FXシステムトレード派
→rank応援クリック
→人気ブログランキング
2007年12月29日|コメント (21)|トラックバック (0)
カテゴリー:その他
zyx40さんのルール検証2
前回の記事(zyx40さんのルール検証)で、zyx40さんの使用したEAと紹介しましたが、ご指摘があり訂正しました。正しくは、zyx40さんのEAのベースのようです。申し訳ございません。
このEAにzyx40さんの考えをプラスしたそうです。
さあ!
前回の続きを見ていきましょう!
int start(){}の中身ですね。
if((TimeHour(TimeCurrent())>TradeTime)) cantrade=true;
となってます。
ここで、TimeHour(TimeCurrent())は現在の時間ということです。
例えば、現在 19:25 だとすると、TimeHour(TimeCurrent())は19という数字になります。
もっと、分解してみていきましょうか。
TimeHour() のカッコ内に、1970年1月1日0時0分0秒から何秒経った時の事かを入れてあげるとその時の時間を計算してくれます。
TimeCurrent() は、現在、1970年1月1日0時0分0秒から TimeCurrent() 秒経ってますよっと言った感じで秒数を計算してくれます。
それで、TimeHour(TimeCurrent())は現在の時間ということになります。
TradeTime はパラメータ用の変数、 cantrade は記憶用の変数でしたね。
なので、「もし現在の時間が TradeTime より大きかったら cantrade を true にしてください」といった意味になります。
次に、
// проверяем есть ли открытые ордера ...
total=OrdersTotal();
としています。
//オープンオーダーがあるかどうかをチェック
というメモと、
OrdersTotal()で調べたポジションの数を total という変数に代入してくださいという文ですね。
次、
if(total<Orders)
{
もし、total がパラメータで指定した Orders より小さい場合はという意味ですね。
// ... если нет ни одного открытого ордера, то идем дальше
// проверяем настало ли время для торговли
if((TimeHour(TimeCurrent())==TradeTime)&&(cantrade))
{
// ... если настало время, то
//もし取引権利がない場合、飛ばします
//時間をチェックします
もし、現在の時間がTradeTime でかつcantradeがtrueの場合。
//もしその時間の場合
といった感じです。
次に
if (((Open[t1]-Open[t2])>delta_S*Point)) //Если цена уменьшилась на величину delta
{
もしt1の始値からt2の始値を引いたものがdelta_S*Pointより大きい場合といった意味ですね。
//もし価格がデルタ量より減少してたら
という具合です。ここの部分がこのEAの心臓部分のような感じですね!
次に
//условие выполнено значит входим в короткую позицию:
// проверяем есть ли свободные деньги для открытия короткой позиции
if(AccountFreeMarginCheck(Symbol(),OP_SELL,lot)<=0 || GetLastError()==134)
{
Print("Not enough money");
return(0);
}
となってます。
//条件が満たされたら売り注文を出す
//売り注文を出す余剰証拠金があるかどうかをチェック
ここで、AccountFreeMarginCheck() という関数を使っています。
これは、仮にカッコ内の指定(通貨、売りor買い、ロット数)通りオーダーした場合、余剰証拠金はいくらになるかを教えてくれる関数です。もし、指定したオーダーが出来ないときはエラー番号134というエラーを出します。(エラー134は資金不足というエラーです)
なので、
もしこの通貨をlotロット売った時の余剰証拠金が0以下、または最後に生じたエラーが134ならば
Not enough money と表示させて
実行終了してください
という意味になります。
そして
OpenShort(lot);
cantrade=false; //запрещаем торговать повторно до следующего бара
return(0);
}
ここで出てきましたね!自作の関数OpenShort。
カッコ内のlot(初期設定では0.1)という数字を引き連れて、
OpenShortという関数を宣言したところに一旦移ります。宣言した所のカッコ内はvolumeとなっていますので、この場合は、volumeにlotを代入。そして一通りOpenShort関数の内容を実行したらまた戻ってきます。
OpenShort関数の中で、売り注文を出してますね。
その後、「cantradeをfalseにしてください」としています。
メモは、//次のバー(時間)まで再売り禁止
という感じです。
そして、実行終了ですね。
次に
if (((Open[t2]-Open[t1])>delta_L*Point))
として、今度はdelta_L*Pointより大きく値が上がった場合の時の処理です。買い注文のプログラムですね。
内容は、売りの時と同じ感じです。説明は省略^^;
そして、if((TimeHour(TimeCurrent())==TradeTime)&&(cantrade))とif(total<Orders)のカッコを閉じてます。
次に
// блок проверки времени жизни сделки, если MaxOpenTime=0, то проверку не проводим.
として、
//保持ポジションの残り時間をチェックする部分です。もし、MaxOpenTimeが0なら、この確認プロセスはおこないません。
という感じです。
では、見ていきましょう。
if(MaxOpenTime>0)
{
MaxOpenTime が0より大きい場合、ですね。
なので、MaxOpenTime が0以下ならこの確認プロセスは実行されないことになります。
次に、
for(cnt=0;cnt<total;cnt++)
{
として、繰り返しのfor文が使ってありますね。
cntが0からtotalより小さいうちはcntに1を足しつつ繰り返してくださいといった感じです。
なので、例えばtotalが3の場合は、cntが0、1、2の3回繰り返されるということです。
そして、
if (OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))
{
として、そのcntが使われてます。
「もしインデックスcntのポジションを選択したときtrueになったら」
といった意味ですね。
次にここで
tmp = (TimeCurrent()-OrderOpenTime())/3600.0;
としてtmpに現在と選択されたポジションのオープン時の秒差を3600で割ったものを代入しています。
これは、選択されたポジションを何時間保持してるかを計算しtmpに入れているわけですね。
次に
if (((NormalizeDouble(tmp,8)-MaxOpenTime)>=0))
{
としています。経過時間 - MaxOpenTimeが0以上の場合という意味です。
ここで、NormalizeDouble(小数値,0~8)という関数は、小数値の第何位(0~8)の後ろで四捨五入するといった関数です。
例えば、
NormalizeDouble(3.1415,3)
とすれば、
3.142
というように小数点以下第3位の後ろで四捨五入した値になります。
この場合、私が調べたところNormalizeDoubleを使っても使わなくても値は変わりませんでした。
次に
RefreshRates();
としてます。
これは、EAの計算時間が長くて Ask や Bid といったあらかじめ作ってある変数の値をもう一度取得する必要があるときに使います。
文字通りレートのリフレッシュですね。
そして、
if (OrderType()==OP_BUY)
closeprice=Bid;
else
closeprice=Ask;
として選択されたポジションが買いの場合、closeprice に現在の売値を代入。その他(ポジションが売り)の場合、closeprice に現在の買値を代入。
といった感じです。
次に
if (OrderClose(OrderTicket(),OrderLots(),closeprice,10,Green))
として、そのポジションを手仕舞いしてます。
と同時にOrderCloseはbool型の関数というのを利用して
「この手仕舞いが無事に取引された(OrderClose関数がTrueになった)場合」
というif文にしています。
{
Print("Принудительное закрытие сделки - №",OrderTicket());
OrderPrint();
}
else
Print("OrderClose() в блоке проверки времени жизни сделки вернул ошибку - ",GetLastError());
として、
「強制手仕舞い-No」という文字と選択されたポジションのチケットナンバーをつなげたものを表示してください。
選択されたポジションの情報を表示してください。
そうでない場合(OrderClose関数がfalseの場合)は
「 保持ポジションの残り時間をチェックする部分のOrderClose()でエラーが返されました - 」という文字とエラーナンバーをつなげたものを表示してください。
といった感じです。
ここでOrderPrint()は、
チケットナンバー、エントリーの時間、売りor買い、ロット数、通貨、エントリーの値、損切り値、利食い値、手仕舞いの値、手数料、スワップ、売買差益、コメント、マジックナンバー
といった感じで表示されます。
そして、
if (OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))の終わりカッコのあとの
else
Print("OrderSelect() в блоке проверки времени жизни сделки вернул ошибку - ",GetLastError());
}
として、ポジション選択できなかった場合の処理を書いてます。
保持ポジションの残り時間をチェックする部分のOrderSelect()でエラーが返されました - エラーナンバー
を表示してください。といった意味です。
次の閉じカッコはfor文の閉じカッコです。ここまできたらcntに1を足してまたfor文以下を繰り返します。
最後に
}
return(0);
}
として、保持ポジションの残り時間をチェックする部分の始のif文のカッコを閉じて、実行終了、int start終了。
です。
エントリー時間を決めて、その時の過去数時間の始値の差で売りor買いを決める。ポジションには寿命がある。
といった売買ルールですね。
今回はこのへんで。
次回は、zyx40さんはどのようにしたのか。パラメータをどう変えたらいいのかなどを書きたいと思います。
応援ありがとうございます!
→FXシステムトレード派
→rank応援クリック
タグ
2007年12月28日|コメント (4)|トラックバック (0)
カテゴリー:EAの作成方法
zyx40さんのルール検証
今回は、自動売買チャンピオンシップ2007で第5位に入賞し
3ヶ月弱で$10000を約3.7倍にしたzyx40さんが元にしたEAを見ていきましょうか!
(2007.12.27 記事訂正しました)
なんだか、ロシア語が書いてありますが^^;
早速、上から見ていきましょう!
extern int TakeProfit_L = 40; // Уровень тейкпрофит в пунктах
extern int StopLoss_L = 133; // уровень стоплосс в пунктах
extern int TakeProfit_S = 27; // Уровень тейкпрофит в пунктах
extern int StopLoss_S = 200; // уровень стоплосс в пунктах
extern int TradeTime=18; // Время входа в рынок
extern int t1=7;
extern int t2=2;
extern int delta_L=9;
extern int delta_S=10;
extern double lot = 0.1; // Размер лота
extern int Orders=1; // максимальное количество одновременно открытых позиций
extern int MaxOpenTime=138;
パラメータですね。
ロング(買い)とショート(売り)の利幅と損切り幅を作ってます。(ロシア語部分は各パラメータの説明です)
TradeTime は、時間の設定です。(このEAは、ODLの時間に合わせてあるようです。)
t1,t2はいつのバーなのかを、設定するものです。
delta_L,delta_Sは、変動ピプスのようです。
lotはロット数。
Ordersは、一度に持つポジションの数のようです。
MaxOpenTimeで、ポジション保持時間を制限します。
各パラメータは、コードを見ていくと役割が分かってきますので、次に進みましょう。
int ticket,total,cnt;
bool cantrade=true;
double closeprice;
double tmp;
記憶用の変数を宣言してます。
これらも後にでてくる、大事な変数です。
次から、自作の関数を宣言しています。プログラマーさんが書いたものを見ると、よく見かける形なのですが、こうすることで処理速度を速めてるのだと思います。(推測ですが^^;)
int OpenLong(double volume=0.1)
// функция открывает длинную позицию размером лота=volume
{
整数の性質を持った OpenLong(小数値) という関数を作ります。カッコ内は volume という初期値0.1の小数変数を宣言しています。
その下の説明では、
//ロット数=volume の買いポジションを持つ関数
としてあります。
次に
int slippage=10;
string comment="20/200 expert v2 (Long)";
color arrow_color=Red;
int magic=0;
として、この関数の中だけで使う変数を宣言しています。
SendOrder のカッコ内のもののようですね!commentには v2 の文字がありますが、
バージョン更新の前のままのものかと思います。
そして、
ticket=OrderSend(Symbol(),OP_BUY,volume,Ask,slippage,Ask-StopLoss_L*Point,Ask+TakeProfit_L*Point,comment,magic,0,arrow_color);
としています。
ここで、OrderSend という関数の性質なのですが、「カッコ内で指定したものをオーダーする」ということと、「オーダー先のサーバーから割り当てられた注文番号を返す」というものがあります。
ここでは、注文を出しつつ、ticket という整数変数に注文番号を代入しています。
(もし、エラーなどで注文が成立しなかった場合は、【-1】という整数が代入されることになります。)
OrderSend のカッコ内は、ほとんど変数で指定されています。
ここで、volume が出てくるのですが、これは、自作の関数OpenLong(volume) を使ったときに取得するものです。
例えば、プログラム中に
・・・
OpenLong(0.6);
・・・
といった感じで書かれた場合は、小数変数 volume に0.6を代入して
OpenLong(volume)を宣言した{}内をおこなうという手順になります。
次に
if(ticket>0)
{
として、注文番号が割り当てられた時に実行することを書いてあります。
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
return(0);
}
となっています。
ここで、OrderSelect という関数の性質なのですが、「カッコ内で指定したものを選択する」ということと、「無事選択できたら true 、選択できなかったら false になる」というものがあります。
ここでは、二つ目の true か false になるということを利用しています。(,MODE_TRADESを省略しても同じ意味になります)
また、ここではプログラミングの構文みたいなものが使用されています。
それは、
if(bool型)
{
true(真)の場合、実行するコード
}
else
{
false(偽)の場合、実行するコード
}
といったものです。if文のカッコの中に==や>などがないのが特徴的ですね。
なので、
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
return(0);
}
は、注文番号ticketのものをちゃんと選択できたら、
この関数(OpenLong)内の実行は、これでおしまいといった感じです。
次に
else
{
Print("OpenLong(),OrderSelect() - выдал ошибку : ",GetLastError());
return(-1);
}
}
は、先ほどのfalseになったときの実行コードですね。
ここで、Print()というものが、でてきます。これは、()内のものを操作履歴に書き込むというものです。
複数書き込むには、カンマで区切って書いてあげます。また、文字を書き込みたいときは【"】で挟んであげます。
この場合は、OpenLong(),OrderSelect() - выдал ошибку : という文字と、GetLastError()という関数でどんなエラーが生じたのかを書き込みます。
文字の部分は、OpenLong()関数内のOrderSelect()関数で発せられたエラーは:っと言った感じです。
その後、return(-1);で、OpenLong()関数は-1ですよという処理をしてこの関数の実行は終了しています。エラーが出た関数は-1にするといった習慣なのでしょう。
次に
else
{
Print("Error opening Buy order : ",GetLastError());
return(-1);
}
}
として、Ticket が0より大きくない時に実行するコードが書いてあります。
ここでも、先ほどと同じ感じですね。買いのオーダーの時のエラーは:~ といった感じですね。そして、return(-1);で終了です。
最後の}でOpenLongの関数の実行は終わりです。
プログラム中に
OpenLong(小数値);
と書くだけで、
int OpenLong(double volume=0.1)
{
}
の事を実行するわけですね!
次に、
int OpenShort(double volume=0.1)
として、今度は売りオーダーの関数を作るわけです。
やりかたは、OpenLong の時と同じ感じですね。説明は省略です^^;
そのあとの、int init() と int deinit() は空っぽですね。前処理、後処理は特におこなっていません。
さあ、いよいよint start() の中身です!
ですが、今回の記事はこの辺で。
次回は、int start() の中身からです。
皆様の応援のおかげでランキング上位に!ありがとうございます!
みんなの応援クリックが活力になっております。
これからも、よろしくお願いいたしますm(..)m
→FXシステムトレード派
→rank応援クリック
タグ
2007年12月26日|コメント (13)|トラックバック (0)
カテゴリー:MetaTrader EA
プレゼント!
今回は、前に企画したVolAveプレゼントについてです。
12/25クリスマス、夕方頃より、VolAveP2008_1.ex4プレゼントゲリラリンクを貼りました!
トップページ右上に

記事下に

という具合にしました。
サーバーメンテナンスを挟んでの企画でしたが見つけられたでしょうか?
これで今回のプレゼント企画は終了~!
・・・。
では、ありません^^;
たまたま、見つけられなかった読者の為にもまた企画したいと思います。
いつも応援本当にありがとうございます!
読者の応援クリックに支えられています!
→FXシステムトレード派
→rank応援クリック
2007年12月26日|コメント (12)|トラックバック (0)
カテゴリー:その他
EA作成の為のテンプレート
今日は、まだ一度もExpert Advisorを作ったことがない人のために
テンプレートなるものを作りました!
移動平均と終値を使った単純ルールです。エントリーのフィルタも移動平均を使った単純なものです。利益は望めません^^;
移動平均の代わりに何かをつかったり、フィルタを変えたり、シグナルの条件を変えたりしてみましょう!
プログラミングの練習に役立てていただけたらうれしいです。
→template.zip
本当に応援ありがとうございます!
→FXシステムトレード派
→rank応援クリック
ps
素敵なクリスマスをお過ごしください(^0^)/
2007年12月24日|コメント (7)|トラックバック (0)
カテゴリー:EAの作成方法
VolAveの動き
私事なのですが、昨日の夜VolAveの連勝がストップいたしました。
その様子をアップします。
上昇前に売りポジションを持ち、-14pipsで手仕舞いです。損失を小さく抑えられたのではと思います。
メタトレ読者限定、期間限定でVolAve2008_1.ex4をプレゼントするといった企画も考えています。(リアル取引での責任は負いません)
応援お願いします!
→FXシステムトレード派
→rank応援クリック
2007年12月22日|コメント (9)|トラックバック (0)
カテゴリー:その他
NewNiceにフィルタをつける
前回の記事で、RCIのフィルターを付け加えたいという意見がありましたので、
改良したものを、書いていきたいと思います。
その前に、
応援お願いします!→rank応援クリック
今回は、MetaboNewNiceRCI という名前にしました。インディケータは
SpearmanRankCorr というものを使います。
2つともZipフォルダに入れてあるので、それぞれ所定の場所に保存し、コンパイルしてください。
今回の変更点は、RCIのフィルターを付け加えたのはもちろんですが、
ボラティリティ確認のためのバンド幅の初期値を少し広めにとったことと、
へばりつきの定義を少し和らげたこと。
ドル口座、円口座を選べるようにしたことと、同時に複数の通貨を取引できるようにポジション確認に通貨の区別も加えたこと。
そして、付属として、本日のある時間までに残高が設定した金額を割ったら取引しないといったストップシステムを付け加えました。(これについては、まだ少し使いづらい部分があるので細かいところはそれぞれ改良してください。)
という感じです。
では、さっそくコードをみていきましょう!
パラメータには
extern int RCIPeriod=52;
と
extern string setsumei2="【time】時までに残高【border】を割ったらストップ";
extern bool StopSystem=false;
extern int time=23;
extern double border=0;
というのが加えられました。
フィルタ用のRCIの計算期間を設定できるようにしました。
あとは、付属のストップシステムの設定用ですね。必要がない場合は、
StopSystemをfalseのままにしておきましょう。
続いて、int start()の中身です。
if(StopSystem== true && TimeHour(TimeCurrent())<time && AccountBalance()<border) return(0);
は、もしStopSystemがtureで現在時刻が time 未満で残高が border 未満ならプログラム終了という感じです。timeを24にした場合は時間に関係なく残高が border 未満ならプログラム終了。仮に、timeを12にしたときは現地の午前中だけ有効なシステムになる感じです。
次に、
//RCIの値
double RCI1=iCustom(NULL,0,"SpearmanRankCorr",RCIPeriod,0,RCIPeriod,0,1);
double RCI2=iCustom(NULL,0,"SpearmanRankCorr",RCIPeriod,0,RCIPeriod,0,2);
でiCustom関数を使ってRCIの1コ前と2コ前の値を引き出します。
インディケータのパラメータがRCIPeriod,0,RCIPeriod,と3つあるのは、
一つ目は、そのまま計算期間なんですが、3つ目は計算期間の最大値が入ります。
デフォルトでは30になっているのでそれ以上を計算できるように、3つ目も変更するようにしました。
次に、
//買い条件
if(STC[2]<5 && STC[1]>5 && RCI1>RCI2)
として、RCIが上昇のときという条件も加えました。
そして、
for(i=2;i<=SchaffHebariPeriod;i++)
{
if(STC[i]<5) STCcnt=STCcnt+1;
}
というようにシャフが5未満ならへばりついているとみなしています。
売り条件も同様に変更しました。
そして、
//ロット計算
double mantuka;
if(USD1JPY2==1) mantuka = AccountBalance() / 10000;
if(USD1JPY2==2) mantuka = AccountBalance()/Ask / 10000;
int baituka = mantuka * Leverage;
double lots = baituka * 0.1 ;
if(lots<=0.1) lots=0.1;
if(lots>=1000) lots=1000;
として、ドル口座か円口座を選べるようにしました。ただし、円口座の場合はドル円やユロ円などに限ります。ユロドルなどを取引する場合は、別途MarketInfo関数で計算するコードが必要です。
最後に
OrderSelect(cnt,SELECT_BY_POS);
if(OrderSymbol() == Symbol() && OrderMagicNumber() == 999) CurrentPosition=cnt;
として、このMetabo戦略を複数通貨同時に取引できるようにしました。
個人的な感想として、RCIとの相性は若干薄いのではといったところです。
また、いい方法があったら教えてくださいm(..)m
応援お願いします!
→FXシステムトレード派
ps
最近、優良ルールVolAveが絶好調\(^0^)/
→VolAve
タグ
2007年12月21日|コメント (0)|トラックバック (0)
カテゴリー:MetaTrader EA
メタボリック社長のNewNice戦略
今回はFX システムトレード派ブログランキング現在5位の【MetaTraderでFX自動売買ブログ】さんの12月13日の記事で書かれているメタボリック社長のNewNice戦法の
インジケーター(テクニカル分析)とストラテージ(売買ルール)です。
まずは、インディケーターですが、二つ用意する必要があります。
一つは、Bollinger Bands - Fibonacci Ratios というもので
もう一つは、Schaff Trend Cycleです。
この二つはMT4にはあらかじめの用意が無いため、自力で作るか作られたものをダウンロードするかしないと、使うことができません。
私は、Bollinger Bands - Fibonacci Ratios は作ることができましたが、
Schaff Trend Cycle についてはちょっと難しそうなので、Web検索してダウンロードしました。
中に入っている二つのインディケータを
expertsフォルダの中のindicatorsフォルダの中に入れます。
そして、一度開いてコンパイルしてあげましょう。
(ダウンロードしたものは、mq4ファイルといって人間用のファイルでコンパイルしてあげると、ex4ファイルというコンピュータ用のファイルが作られます。)
あと、Bollinger Bands - Fibonacci Ratios は7本のラインがありますが、一つずつインデックスという番号が割り当てられています。
真ん中のラインが0。その上が1。またその上が2。一番上が3。
真ん中の下のラインが4。その下が5。一番下が6。
となります。
これは、私が勝手に決めたものですが、後でExpert Advisor でルールを作るときに使われる番号なのでとても重要です。
Schaff Trend Cycle のラインは1本なのでインデックスは0でよいようです。
さあ、これらのインディケータを表示させてみましょう!
MT4を開いて、ユロ円1分足を表示させます。
ナビゲーターウィンドウの中の Custom Indicators の中にある
Bollinger Bands - Fibonacci Ratios をチャートにもっていくかダブルクリックで出てきたウィンドウのOKボタンを押せば表示されます。
Schaff Trend Cycle も同様にやってみましょう。
二つが、見当たらない場合はファイルを入れる場所が違っているかもしれません。
indicators という名前のフォルダは2つあるので注意してくださいね。
expertsフォルダの中のindicatorsフォルダの中に入れましょう。
(もしかすると、MT4を再起動する必要があるかもです。)
パラメータは初期化の時点でメタボリック社長のNewNice戦法の値にしてあります。
さて、これで道具がそろったわけです。
今回はCM無しなので、この辺で一旦休憩!
背伸びをしましょ~^^
はい!
次はいよいよ、売買ルール作りです!
私はこれを MetaboNewNice と名づけました。
売買ルールの概要は
・ボラティリティ確認
バンドの一番外側のラインの幅と一度は一本目のラインを割る
・エントリータイミング
下にへばり付いていた線が+5より上がってきたことが確認された後、買い。
(売りの場合は逆で+95)
・利食い損切り幅
利食いは+5、損切りは-10。
これらを MetaboNewNice というExpert Advisor にするために機械的に定義しました。
ちょっと分かり辛いですが、私が作った変数を交えてルールの概要を表すと
・ボラ確認
バンドの一番外側のラインの幅が、「パラメータ変数 BandsHaba」よりも大きくてはならない。
過去「パラメータ変数 BandsHamidePeriod」分の間に一度は一本目のラインを割る。
・エントリータイミング
「パラメータ変数 SchaffHebariPeriod」本前のバーから2本前のバーまでずっとSchaffの値が+1未満で、1本前のバーのSchaffの値が+5より大きい時買い。(売りの時は逆)
といった具合です。
プログラムの中身の説明に移ります。
まずは、
→MetaboNewNice.zip
上から
//パラメータ用の変数
extern int StopLoss =10;
extern int TakeProfit = 5;
extern int Leverage =10;
この辺はいいですよね^^;
extern double BandsHaba=20;
これはボラ確認のためのパラメータ。
後で出てきますが一番外側のラインの幅が BandsHaba より大きくないと取引しません。ってゆう値。
extern string setsumei="以下は2~10の範囲";
これは、パラメータを入力するときの案内なので直接システムには影響しません。
extern int BandsHamidePeriod=10;
extern int SchaffHebariPeriod=5;
これらは、バンドの1本目のラインをはみ出たかどうかを何本前のバーまでを確認するかという値と、
シャフのへばり付きは何本前のバーからかを設定する値です。
次の
int bar;は記憶用の変数です。
さあ、いよいよです!
int start(){
return(0);
}
の{}内を見ていきましょう!
//現在の外側のラインの値
double BBFUper3,BBFLower3;
BBFUper3=iCustom(NULL,0,"Bollinger Bands - Fibonacci Ratios",3,0);
BBFLower3=iCustom(NULL,0,"Bollinger Bands - Fibonacci Ratios",6,0);
まずは、現在のバンドの外側のラインの値を代入する小数の変数として、
上は BBFUper3 、下は BBFLower3 という名前にして宣言しました。
それらに、現在の外側のラインの値を代入しますが、ここで
iCustom(・・・) という関数を使います。
これは、expertsフォルダの中のindicatorsフォルダの中にあるインディケータを呼び出す関数です。
カッコ内は( 通貨, 時間足, インディケータの名前, パラメータ, インディケータのインデックス, 時期)
という具合です。しかし、パラメータは省略できるので、今回は入れていません。
仮に
iCustom(NULL,0,"Bollinger Bands - Fibonacci Ratios",25,3,0)
とすると、
Bollinger Bands - Fibonacci Ratios の中のパラメータ BF_Period が25になるといった感じです。
ここでインデックスにはインディケータで決めたインデックスが入るので、一番上のラインは3、一番したのラインは6ということになります。
次に、
//シグナル
//外側のラインの幅がBandsHabaより大きいとき
if(BBFUper3-BBFLower3>BandsHaba*Point)
{
外側のラインの幅がBandsHabaより大きいときだけシグナルを出す計算をするといった感じ。BandsHabaはピプスで入力されてますので、Pointを掛けてあげてレートの値にしてあげましょう。
//過去10分のインディケータの数値算出
double STC[11],BBFUper1[11],BBFLower1[11];
for (int i=1;i<=10;i++)
{
BBFUper1[i]=iCustom(NULL,0,"Bollinger Bands - Fibonacci Ratios",1,i);
BBFLower1[i]=iCustom(NULL,0,"Bollinger Bands - Fibonacci Ratios",4,i);
STC[i]=iCustom(NULL,0,"Schaff Trend Cycle",0,i);
}
シャフの値をSTCという配列、バンドの1本上のラインの値をBBFUper1という配列、バンドの1本下のラインの値をBBFLower1という配列にしました。
配列のインデックスはそれぞれ0~10の11コとなっております。
for文を使いSTC、BBFUper1、BBFLower1のそれぞれにインディケータの1本前のバーの時の値から10本前のバーの時の値を配列にして代入しています。
次に
int BBFcnt=0,STCcnt=0,sign=0;
でバンドのはみ出し回数、シャフのへばり付き期間、シグナルを整数の変数として宣言します。
//買い条件
if(STC[2]<1 && STC[1]>5)
{
for(i=1;i<=BandsHamidePeriod;i++)
{
if(BBFLower1[i]>Close[i]) BBFcnt=BBFcnt+1;
}
for(i=2;i<=SchaffHebariPeriod;i++)
{
if(STC[i]<1) STCcnt=STCcnt+1;
}
if(BBFcnt>0 && STCcnt==SchaffHebariPeriod-1) sign=1;
}
2つ前のシャフの値が1より小さくて1つ前のシャフの値が5より大きいとき、
BandsHamidePeriod 前までのバンドからのはみ出し回数と
二つ前からSchaffHebariPeriod 前までのシャフのへばりつき回数を
カウントします。
バンドのはみ出し回数が0より大きい(一度ははみ出ている)、かつ
シャフが全部へばりつきの場合、sign に1を代入します。
//売り条件
if(STC[2]>99 && STC[1]<95)
{
for(i=1;i<=BandsHamidePeriod;i++)
{
if(BBFUper1[i]<Close[i]) BBFcnt=BBFcnt+1;
}
for(i=2;i<=SchaffHebariPeriod;i++)
{
if(STC[i]>99) STCcnt=STCcnt+1;
}
if(BBFcnt>0 && STCcnt==SchaffHebariPeriod-1) sign=-1;
}
}
売りの条件も同じようにします。^^;
sign は-1にします。
//オーダー
//ロット計算
double mantuka = AccountBalance() / 10000;
int baituka = mantuka * Leverage;
double lots = baituka * 0.1 ;
if(lots<=0.1) lots=0.1;
if(lots>=1000) lots=1000;
//ポジション確認
int CurrentPosition = -1 ;
for(int cnt=0;cnt<OrdersTotal();cnt++)
{
OrderSelect(cnt,SELECT_BY_POS);
if(OrderMagicNumber() == 999) CurrentPosition=cnt;
}
//ポジション無しの場合
if(CurrentPosition == -1)
{
if(bar!=Bars && sign==1)
{
//買い
OrderSend(Symbol(), OP_BUY, lots, Ask, 3, Ask-(StopLoss*Point), Ask+(TakeProfit*Point), "Buy", 999, 0, Blue);
bar=Bars;
}
if(bar!=Bars && sign==-1)
{
//売り
OrderSend(Symbol(), OP_SELL, lots, Bid, 3, Bid+(StopLoss*Point), Bid-(TakeProfit*Point), "Sell", 999, 0, Red);
bar=Bars;
}
}
オーダーは今までどおりな感じですが、他のシステムと併用して使えるようにマジックナンバーで区別して、ポジション確認してます。
あとは、手仕舞い条件が無しですね。
ふ~。
これで、一通りできあがりです。
次回は、バンド幅が大きいときにははみ出し条件は無くても良いとか、その後の議論で出ていたトレンド方向のみのエントリーにするとか、精度を高めていきたいと思います!
もし、ここ間違ってる!とか、こうした方がいい!とか、
質問など、コメントしてください。
今回はこの辺で。
最後までお付き合いしてくださってありがとうございますm(..)m
タグ
2007年12月19日|コメント (23)|トラックバック (0)
カテゴリー:MetaTrader EA
お詫び
いつも【メタトレ!完全自動売買のススメ】を見に来て頂きまして誠にありがとうございます。
昨日の夕方ごろから、ページが表示されないという不具合が生じておりました。現在は復旧しております。
まだ、Seesaaサービスの方から障害報告はでておりませんが、
他のSeesaaブログも不具合が起きた広い範囲での障害でした。
みなさまには、ご迷惑をおかけし大変申し訳ございませんでした。
今後とも【メタトレ!完全自動売買のススメ】をよろしくお願いいたします。
2007年12月17日|コメント (1)|トラックバック (0)
カテゴリー:その他
Optimization機能の少し変わった活用法
今回は、Optimization 機能の少し変わった使い方を紹介!
週1回、決まった時間に買いポジションを持ち、決まった時間に決済する
といった売買ルールを作り、曜日や時間をパラメータ化することで、
過去の一定期間において、レートが上がり易かった時間がわかるというもの。
今回は、先月の下げの中での上がりやすかった時間を調べてみましょう!
まずは、
パラメータですね!
extern int TakeProfit=100;
extern int StopLoss=50;
extern int OpenWeek,OpenHour,OpenMinute,CloseHour,CloseMinute;
としましょうか。TakeProfit や StopLoss は無くてもいいのですが
指定した結果も調べられるように付け加えてあります。
その下の変数は、ポジションを取る曜日、時間、分、手仕舞いの時間、分です。
ここで、手仕舞いの曜日が無いのは、24時間以内に手仕舞いするため
指定してません。
(1週間以内に手仕舞いするというルールでは CloseWeek が必要になります。)
そして、記憶用の変数として
int bar;
と書きます。
次に
int start()
{
return(0);
}
の中身を書いていきましょう!
指標の計算が無いのでいきなりオーダーです^^;
まず、
int OpenPos = OrdersTotal();
として変数 OpenPos にポジションの数を代入します。
次に、
if (OpenPos < 1)//ポジション無し
{
}
として、{}内にポジション無しの時のオーダー条件とオーダーを書いていきましょう!
if(bar!=Bars
&& TimeDayOfWeek(CurTime()) == OpenWeek
&& TimeHour(CurTime()) == OpenHour
&& TimeMinute(CurTime()) >= OpenMinute)
{
OrderSend(Symbol(), OP_BUY, 1, Ask, 3, Ask-(StopLoss*Point), Ask+(TakeProfit*Point), "Buy", 0, 0, Blue);
bar=Bars;
}
です。
上から、
bar が Bars ではない
今の曜日が OpenWeek のとき
今の時間が OpenHour のとき
今の分が OpenMinute 以上のとき
です。
ここで、TimeDayOfWeek(CurTime()) は今の曜日を数字の0~6で表すものです。
0の日曜日から6の土曜日までです。
そして、OrderSend でオーダーし記憶用の変数 bar に Bars を代入。
ここで、 OpenMinute 以上のときとしたのは、たまたま OpenMinute で指定した
分のデータが無かったとき(変動がなかった等)、次の分でオーダーするためです。
また、1時間足以上を使わないと次のバーでもオーダーしてしまうということが起こるので注意してください!
次に、
if(OpenPos >0)//ポジション有り
{
}
として、{}内にポジション有りの時の手仕舞い条件と手仕舞いを書いていきましょう!
if(TimeHour(CurTime()) == CloseHour && TimeMinute(CurTime()) >= CloseMinute)
{
//ポジションのデータを取得
OrderSelect(0,SELECT_BY_POS);
OrderClose(OrderTicket(),OrderLots(),Bid,3,Green);
}
こちらも、同じような感じですね!手仕舞いの時間と分で手仕舞いの
注文を出します。
コードは以上です。
→CalculationProgram(TimeTrade_Buy).zip(mq4ファイル)
コピペします↓
//+------------------------------------------------------------------+
//| CalculationProgram(TimeTrade_Buy).mq4 |
//| SAMURAI |
//| http://samuraifx.seesaa.net/ |
//+------------------------------------------------------------------+
#property copyright "SAMURAI"
#property link "http://samuraifx.seesaa.net/"
extern int TakeProfit=100;
extern int StopLoss=50;
extern int OpenWeek,OpenHour,OpenMinute,CloseHour,CloseMinute;
int bar;
int start()
{
//Order
int OpenPos = OrdersTotal();
if (OpenPos < 1)//ポジション無し
{
if(bar!=Bars && TimeDayOfWeek(CurTime()) == OpenWeek && TimeHour(CurTime()) == OpenHour && TimeMinute(CurTime()) >= OpenMinute)
{
OrderSend(Symbol(), OP_BUY, 1, Ask, 3, Ask-(StopLoss*Point), Ask+(TakeProfit*Point), "Buy", 0, 0, Blue);
bar=Bars;
}
}
if(OpenPos >0)//ポジション有り
{
if(TimeHour(CurTime()) == CloseHour && TimeMinute(CurTime()) >= CloseMinute)
{
//ポジションのデータを取得
OrderSelect(0,SELECT_BY_POS);
OrderClose(OrderTicket(),OrderLots(),Bid,3,Green);
}
}
return(0);
}
さて、これをコンパイルしたらいよいよです!
メタトレーダーのテスターでCalculationProgram(TimeTrade_Buy),SUMURAI を選び、
通貨は USDJPY にしときますか。
モデルで Every tick を選ぶとすごく時間がかかるので
今回は、Control points にしましょうか。
(時間に余裕があるときは Every tick で調べてみましょう)
日付と時間を使用にチェックをいれて2007年11月の月初めから月末までを選びます。
そして、ここから重要です!
Expert properties をクリック。
Testingタブを選択。Initial deposit を10000のUSDにしときましょう。
パラメーターの入力タブを選択。
TakeProfit と StopLoss は100と50のままにしときましょうか。
OpenWeek 以下5コにチェックを入れます。スタートの列は全て0のままにしておきましょう。
OpenWeek のステップは1。ストップは6。
OpenHour のステップは1。ストップは23。
OpenMinute のステップは10にしましょうか。となるとストップは50。10分おきに調べるということですね。
CloseHour と CloseMinute も同じように1と23、10と50といった具合です。
OpenWeek に0や6も含めるのは、業者によってデータの時間が違っていて、週の最初のデータが日曜日の夜から始まってたりするので、全てで調べてみましょう。(蓄積データはツールのHistory Center でみれます。)
そして、OKボタンを押して、Optimization にチェックを入れましょう!
期間は、H1 以上にしなければなりません。今回はH1でやってみましょう。
いよいよ計算開始です!スタートボタンを押してしばらく待ちましょう!
その間に、一旦CMです。
↑世界中のみんなが読んだ本。日本でも200万人以上が読んでます。
金持ち父さんシリーズの1作目。このシリーズを読んでない人は、まず入門編としておすすめします!
私はこの本で、お金(収入)に対する概念がガラリと変わりました!
はいっ。
計算が終了しましたら、Optimization Results タブをクリックして、
結果を見てみましょう!利益が出た曜日と時間の組み合わせが表示されています。
OpenよりもCloseの方が早い時間の場合は次の日の手仕舞いということになります。
でも、このままではチョットわかりづらいので、私はエクセルにコピーして見たりします。
やり方は、データのどこでもいいので右クリックして、Copy All を選択。エクセルを開いて2段目に貼り付け。一段目に項目を入力して、一段目全てを選択。データ→フィルタ→オートフィルタです。
これで、いろんな条件で絞り込んで見たりできます。
Profit factor が空欄(または0)のデータは勝率100%ということになります。
こんな具合にして、利食い損切り幅を狭めたらどうかとか、過去1年間の傾向や売りの場合はどうなのか、CloseWeek を加えて、一週間以内で手仕舞いするシステムではどうなのか(計算時間がかなり長くなってしまいますが^^;)、などいろいろ試すことができます。
今回は、このへんで。
次回は、FX システムトレード派ブログランキング現在6位の【MetaTraderでFX自動売買ブログ】さんの12月13日の記事が気になっていますので、そちらの研究と検証をして、記事を書きたいと思います!
2007年12月16日|コメント (2)|トラックバック (0)
カテゴリー:EAの作成方法
ポジションサイジングの検証
今日は、私が使用している売買ルール VolAve に、
前回作ったポジションサイジングの方法(こちらの記事)を適用した結果と
それに対するあれこれです。
VolAve の性質
・薄利を重ねて利益をあげていく
・勝率が高め
・頻度は1日に1回程度
バックテストはHistory Centerのデータを使用
というのを前提に読み進めてくださいね!
まずは、普通にレバレッジ10倍で2000年~2006年の結果を調べてみました。
7年間で
損益 +9,277%
最大ドローダウン 23.04%
となります。
ここで、前回のポジションサイジングを取り入れると
7年間で
損益 +33,313%
最大ドローダウン 29.41%
となります。
まあ、勝率が高いので基本レバレッジ10倍より利益が大きくなるのは
当たり前ですよね^^;
最大ドローダウンが約30%だとちょっとツライですね。
次に、一定レバレッジで11倍から14倍の損益、最大ドローダウンなどを
調べてみました。
→こちら
上から順に11倍から14倍になってます。
これによると、一定レバレッジ13倍で取引したほうが利益があがり
最大ドローダウンもわずかに抑えられたといった結果になりました。
次に、短い期間でその性質をみていきましょう!
その前に一旦、CMです!
FX完全自動売買システム構築のための250の技 MetaTrader4逆引き大全集
↑プロのプログラマーが書いた辞書。本屋さんには売ってません!
MT4で独自の戦術を作るには持っておきたい一品!
今、発売から一ヶ月で300人が購入しています。
FXメタトレーダー入門―最先端システムトレードソフト使いこなし術
↑神奈川大学工学部教授が書いた本。今月発売されました!
↑リスク管理、ポジションサイジングの教科書みたいなもの。
システムトレードで自動売買する人は、大体読んでいますよね!
まだの人は、是非読んでください。
はい。
では、一定レバレッジ13倍のものと、新たなポジションサイジングでのものの
去年1年間の結果を見比べましょう!
損益グラフの動きを見てみると、新たなポジションサイジングでのものの
特徴として、
山がとんがっている
谷がまるい
というように、お椀型の連続のような感じになりますね!
連勝中は加速し、連敗中はブレーキをかける感じ。
結果、連勝や連敗が偏るシステムには向いているのかもしれません。
2007年12月13日|コメント (6)|トラックバック (0)
カテゴリー:投資戦術の検証
ポジションサイジング
今回は、ポジションサイジングについてです。
ポジションの大きさを決めるとき、よく使われるのが複利システムにする方法でも紹介した、
口座残高に応じて取引額を決定するといった方法ですが、
今回はそれに『システムの調子』の要素も加えてみましょうか。
『システムの調子』の定義は、
単純に今何連勝中か?または、何連敗中か?といった感じにしました。
ルールの設定
・基本レバレッジは10倍。
・2連勝したら11倍、3連勝したら12倍というようにレバレッジを
一つずつ増やしていき、最大20倍まで。
・2連敗したら10倍の2分の1、すなわち5倍。3連敗なら3分の1、
すなわち約3.33倍。というように減らしていきます。
では実際に構築していきましょう!
今回も前の記事(トレイリングストップ)のランダムエントリーのシステムに
付け加える感じでやってきます。
まずはじめに、
記憶させておきたいものは、今何連勝中かまたは、何連敗中かといった
情報ですね。
これを変数の記憶させる箇所に
int win,loss;
と宣言しましょう。
さらに、勝ち負けを判断するために手仕舞い前の残高を記憶させます。
double LastBalance;
とします。
次に初期設定として int init() の{}内に
LastBalance=AccountBalance();
としておきます。
次にいよいよ連勝連敗の計算ですよ!
//Entry
OpenPos = OrdersTotal();
if (OpenPos < 1)//ポジション無し
{
の下あたりに
//win,lossの算出
if(AccountBalance()>LastBalance)
{
win=win+1;
loss=0;
}
if(AccountBalance()<LastBalance)
{
loss=loss+1;
win=0;
}
LastBalance=AccountBalance();
としましょう。
これは、ポジションが無くて、前の残高より今の残高の方が大きい時は
変数 win に1を足して、変数 loss を0にしましょう。
逆に、前の残高より今の残高の方が小さい時は
変数 loss に1を足して、変数 win を0にしましょう。
そして、変数 LastBalance に今の残高を記憶させましょう。
といった意味ですね!
続いてその下に
//lotsの算出
double leverage=10;
if( win != 0 ) leverage = 9+win;
if( loss != 0 ) leverage = 10/loss;
if( leverage >20) leverage = 20;
int ilots = AccountBalance() * leverage / 10000;
double lots = ilots * 0.1 ;
if(lots<=0.1) lots=0.1;
if(lots>=1000) lots=1000;
としましょう。
これは、ポジションサイズの最終決定です!
leverage という変数の宣言は上の方で StopLoss や TakeProfit を宣言した
のと併せてもいいですよね。今回はlotsの算出のまとまりのところで
宣言させてもらいました。初期値は10ですね。
(最初の取引は win も loss も 0 なので、初期値が適用されます。)
和訳^^;というと、
もし win が 0 じゃなかった(前回の取引は勝ちだった)ら、
leverage に 9+win を代入しましょう。
(ここで、 9+win としたのは、1回勝ちで leverage は 10 に、
2連勝で leverage が 11 にするためです。)
もし loss が 0 じゃなかった(前回の取引は負けだった)ら、
leverage に 10/loss を代入しましょう。
ここでもし leverage が 20 より大きかったら、
leverage を 20 としましょう。
整数 ilots に残高に leverage をかけて、一万で割った数を
代入します。
小数 lots に ilots*0.1 を代入しましょう。
もし lots が最小最大を超えた場合は最小値、最大値にする。
といった感じです。
後半の計算は前の複利システムの記事と同じ感じですね!
後は、 OrderSend の()内のロット数を入力する場所に lots と
書き換えるだけです。
ここで一旦、CMです。
FX完全自動売買システム構築のための250の技 MetaTrader4逆引き大全集
↑プロのプログラマーが全編書き下ろし。
まさにプログラムを勉強したい人にはうってつけの書籍!
FXメタトレーダー入門―最先端システムトレードソフト使いこなし術
↑神奈川大学工学部教授が書いた本。今月発売されました!
はい!
では、
いつものようにできあがったコードをコピペしたいと思います!
//+------------------------------------------------------------------+
//| Matsui.mq4 |
//| SAMURAI |
//| http://samuraifx.seesaa.net/ |
//+------------------------------------------------------------------+
#property copyright "SAMURAI"
#property link "http://samuraifx.seesaa.net/"
//パラメータ用の変数
extern int StopLossPer =3;
extern int TakeProfitPer = 5;
extern int TrailingStopPer =50;
extern int TrailingStopStartPer =1;
extern int Frequency = 10;
extern int BandsPeriod=4;
extern double TrailingStopStartBandsPerBid =1.5;
//記憶用の変数
double StopLoss,TakeProfit,TrailingStopStart;
int Bar,MaxVolume;
int win,loss;
double LastBalance;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
MathSrand(LocalTime());
LastBalance=AccountBalance();
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
//変数の宣言
double StopLoss, TakeProfit, TrailingStop, Width, AWidth;
int Pos, Type, OpenPos;
//Entry抽選
Pos = MathRand() % (Frequency + 1);
Type = MathRand() % (1 + 1);
//Entry
OpenPos = OrdersTotal();
if (OpenPos < 1)//ポジション無し
{
//win,lossの算出
if(AccountBalance()>LastBalance)
{
win=win+1;
loss=0;
}
if(AccountBalance()<LastBalance)
{
loss=loss+1;
win=0;
}
LastBalance=AccountBalance();
//lotsの算出
double leverage=10;
if( win != 0 ) leverage = 9+win;
if( loss != 0 ) leverage = 10/loss;
if( leverage >20) leverage = 20;
int ilots = AccountBalance() * leverage / 10000;
double lots = ilots * 0.1 ;
if(lots<=0.1) lots=0.1;
if(lots>=1000) lots=1000;
//MaxVolumeのリセット
MaxVolume = 0;
//Buy
if (Pos == 0 && Type == 0 && Bars != Bar)
{
//Order時の値決定と記録
StopLoss = Close[0] * StopLossPer / 100;
TakeProfit = Close[0] * TakeProfitPer /100;
TrailingStopStart = Close[0] * TrailingStopStartPer /100;
Bar = Bars;
//Order
OrderSend(Symbol(), OP_BUY, lots, Ask, 3, Ask-StopLoss, Ask+TakeProfit, "Buy", 616, 0, Blue);
return(0);
}
//Sell
if (Pos == 0 && Type == 1 && Bars != Bar)
{
//Order時の値決定と記録
StopLoss = Close[0] * StopLossPer / 100;
TakeProfit = Close[0] * TakeProfitPer /100;
TrailingStopStart = Close[0] * TrailingStopStartPer /100;
Bar = Bars;
//Order
OrderSend(Symbol(), OP_SELL, lots, Bid, 3, Bid+StopLoss, Bid-TakeProfit, "Sell", 616, 0, Red);
return(0);
}
}
if(OpenPos >0)//ポジション有り
{
//bandの幅
double BandsWidth = iBands(NULL,0,BandsPeriod,1,0,PRICE_CLOSE,MODE_UPPER,0)
- iBands(NULL,0,BandsPeriod,1,0,PRICE_CLOSE,MODE_LOWER,0);
double BandsPerBid = BandsWidth / Bid * 100;
//Volumeの確認
if(Volume[1] > MaxVolume) MaxVolume = Volume[1];
//10日間の平均振幅の算出
for(int i=3;i<13;i++)
{
Width = Width + High[i] - Low[i];
}
AWidth = Width / 10;
//ポジションのデータを取得
OrderSelect(0,SELECT_BY_POS);
//買いポジション
if(OrderType()==OP_BUY)
{
//Trailing stop
TrailingStop=OrderOpenPrice()+(Bid-OrderOpenPrice())*TrailingStopPer/100;
if(Bid>OrderOpenPrice()+TrailingStopStart && OrderStopLoss()<TrailingStop && BandsPerBid>TrailingStopStartBandsPerBid)
{
OrderModify(OrderTicket(),OrderOpenPrice(),TrailingStop,OrderTakeProfit(),0,Magenta);
return(0);
}
//急騰による手仕舞い
if(Bid > OrderOpenPrice() + TakeProfit * 0.3 &&
Close[2] - Open[2] > AWidth * 3 &&
Volume[2] > MaxVolume * 0.9 &&
Volume[2] > Volume[1] * 2)
{
OrderClose(OrderTicket(),OrderLots(),Bid,3,Red);
}
}
if(OrderType()==OP_SELL)
{
//Trailing stop
TrailingStop=OrderOpenPrice()-((OrderOpenPrice()-Ask)*TrailingStopPer/100);
if(Ask<OrderOpenPrice()-TrailingStopStart && OrderStopLoss()>TrailingStop && BandsPerBid>TrailingStopStartBandsPerBid)
{
OrderModify(OrderTicket(),OrderOpenPrice(),TrailingStop,OrderTakeProfit(),0,Magenta);
return(0);
}
//急落による手仕舞い
if(Ask < OrderOpenPrice() - TakeProfit * 0.3 &&
Open[2] - Close[2] > AWidth * 3 &&
Volume[2] > MaxVolume * 0.9 &&
Volume[2] > Volume[1] * 2)
{
OrderClose(OrderTicket(),OrderLots(),Ask,3,Blue);
}
}
}
//----
return(0);
}
//+------------------------------------------------------------------+
次回は、
今のところ安定して利益を出している優良ルール VolAve に、
このポジションサイジングの方法を適用した結果と
それに対するあれこれです^^;
2007年12月11日|コメント (6)|トラックバック (0)
カテゴリー:EAの作成方法
トレイリングストップ2
前々回の記事トレイリングストップの続きです。
今回は、トレイリングストップを機能させる条件を付け加えたいと思います。
その条件とは、いままでの条件に
ボリンジャーバンドの幅が一定以上になったら、
トレイリングストップを機能させる
といったものをさらに加えたいと思います。
まずは、パラメータとして
extern int BandsPeriod=4;
extern double TrailingStopStartBandsPerBid =1.5;
とします。
これは、ボリンジャーバンドに使う平均移動線の計算期間と
『ボリンジャーバンドの幅が一定以上になったら』というところの
値です。
後にでてきますが今回は『バンド(標準偏差1倍)の上下幅が売値の1.5%になったら』
ということにしました。
次に、計算として
if(OpenPos >0)//ポジション有り
{
の後に
//bandの幅
double BandsWidth = iBands(NULL,0,BandsPeriod,1,0,PRICE_CLOSE,MODE_UPPER,0)
- iBands(NULL,0,BandsPeriod,1,0,PRICE_CLOSE,MODE_LOWER,0);
double BandsPerBid = BandsWidth / Bid * 100;
としてます。
これは、iBands関数を使って、バンドの上下幅を計算し、
変数 BandsWidth に代入。
つぎに、BandsWidth が売値の何パーセントかを計算し、
変数 BandsPerBid に代入。
といった感じです。
最後に、
if(Bid>OrderOpenPrice()+TrailingStopStart && OrderStopLoss()<TrailingStop && BandsPerBid>TrailingStopStartBandsPerBid)
のようにトレイリングストップを機能させる条件文の部分に
&& BandsPerBid>TrailingStopStartBandsPerBid
と付け加えます。
これで、値動きが大きいときだけトレイリングストップを機能させる
といったものになりました!
2007年12月 8日|コメント (2)|トラックバック (0)
カテゴリー:EAの作成方法
続トレイリングストップ
前回の記事で、トレイリングストップのことについて書きましたが、
そこでは、トレイリングストップの開始のタイミングは、
利益方向に1%動いてからという設定でおこないました。
しかし、トレイリングストップは、
トレンド相場では本領発揮できますが、
持ち合い相場には向いてません。
なので、トレイリングストップを発動させるタイミングを
考えたいと思います!
今のところ、
ボラティリティを使ったもの、
レジスタンスブレイクを使ったもの
を考えてます。
さらに、ロット数は1ロット固定でしたので、
ポジションサイジングもあわせてやっていきたいと思います!
次回、カテゴリ(スキルアップ)をお楽しみに!(^w^)
PS
ランキング参加しました(^0^)/
2007年12月 4日|コメント (2)|トラックバック (0)
カテゴリー:その他
トレイリングストップ
今日は、手仕舞いの仕方について書いていこうと思います。
All Aboutのマネーの記事の松井宗則氏の手法を参考にします!
・ロスカットは2~3%
・利益確定はロスカット幅以上
・最大含み益の50%まで下落したら一旦利益確定
・30%以上含み益が出て、過去最大級の出来高で急騰後、
出来高が半減したら一旦利益確定
以上の条件で、仕掛けのタイミングはランダムエントリーにしました。
(ランダムエントリー参考記事→SKILL UP FX!さんの記事)
この数値では、中期トレード向きかと思います。デイトレや短期トレードに対応できるように、パラメータ化しました。
ロジック内容は、
・パラメータ
ロスカットパーセンテージ
利益確定パーセンテージ
トレーリングストップパーセンテージ
トレーリングストップ開始パーセンテージ
ランダムエントリー確率
・エントリー抽選
・エントリー
ロスカット値の算出
利益確定値の算出
トレーリングストップ開始値の算出
・ポジション保持時
平均振幅の算出
トレイリングストップ
急騰急落時の手仕舞い
といった具合です。
30%以上含み益が出て、過去最大級の出来高で急騰後、
出来高が半減したら一旦利益確定という部分を
どのようにしようか悩みましたが、
今回は、
・30%以上含み益
エントリーから利益確定値までを100%とし、その30%で算出。
・過去最大級の出来高
エントリーからの最大出来高を記憶させ、その90%以上。
・急騰
過去10日間の平均振幅の3倍上昇。
・出来高が半減
急騰時の出来高の50%未満。
(急落時も同様に)
といった感じで定義しました^^;
検証結果はというと、通貨によってまちまちですが、
パラメータやその他の値を変更するなどして、
手仕舞いの方法の一つとして、覚えておいても良いのではと思います。
コードをコピペしますので、ご指摘やご質問などなどありましたら、
ぜひお聞かせくださいm(._.)m
//+------------------------------------------------------------------+
//| Matsui.mq4 |
//| SAMURAI |
//| http://samuraifx.seesaa.net/ |
//+------------------------------------------------------------------+
#property copyright "SAMURAI"
#property link "http://samuraifx.seesaa.net/"
//パラメータ用の変数
extern int StopLossPer =3;
extern int TakeProfitPer = 5;
extern int TrailingStopPer =50;
extern int TrailingStopStartPer =1;
extern int Frequency = 100;
double StopLoss,TakeProfit,TrailingStopStart;
int Bar,MaxVolume;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
MathSrand(LocalTime());
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
//変数の宣言
double StopLoss, TakeProfit, TrailingStop, Width, AWidth;
int Pos, Type, OpenPos;
//Entry抽選
Pos = MathRand() % (Frequency + 1);
Type = MathRand() % (1 + 1);
//Entry
OpenPos = OrdersTotal();
if (OpenPos < 1)//ポジション無し
{
//MaxVolumeのリセット
MaxVolume = 0;
//Buy
if (Pos == 0 && Type == 0 && Bars != Bar)
{
//Order時の値決定と記録
StopLoss = Close[0] * StopLossPer / 100;
TakeProfit = Close[0] * TakeProfitPer /100;
TrailingStopStart = Close[0] * TrailingStopStartPer /100;
Bar = Bars;
//Order
OrderSend(Symbol(), OP_BUY, 1, Ask, 3, Ask-StopLoss, Ask+TakeProfit, "Buy", 616, 0, Blue);
return(0);
}
//Sell
if (Pos == 0 && Type == 1 && Bars != Bar)
{
//Order時の値決定と記録
StopLoss = Close[0] * StopLossPer / 100;
TakeProfit = Close[0] * TakeProfitPer /100;
TrailingStopStart = Close[0] * TrailingStopStartPer /100;
Bar = Bars;
//Order
OrderSend(Symbol(), OP_SELL, 1, Bid, 3, Bid+StopLoss, Bid-TakeProfit, "Sell", 616, 0, Red);
return(0);
}
}
if(OpenPos >0)//ポジション有り
{
//Volumeの確認
if(Volume[1] > MaxVolume) MaxVolume = Volume[1];
//10日間の平均振幅の算出
for(int i=3;i<13;i++)
{
Width = Width + High[i] - Low[i];
}
AWidth = Width / 10;
//ポジションのデータを取得
OrderSelect(0,SELECT_BY_POS);
//買いポジション
if(OrderType()==OP_BUY)
{
//Trailing stop
TrailingStop=OrderOpenPrice()+(Bid-OrderOpenPrice())*TrailingStopPer/100;
if(Bid>OrderOpenPrice()+TrailingStopStart && OrderStopLoss()<TrailingStop)
{
OrderModify(OrderTicket(),OrderOpenPrice(),TrailingStop,OrderTakeProfit(),0,Magenta);
return(0);
}
//急騰による手仕舞い
if(Bid > OrderOpenPrice() + TakeProfit * 0.3 &&
Close[2] - Open[2] > AWidth * 3 &&
Volume[2] > MaxVolume * 0.9 &&
Volume[2] > Volume[1] * 2)
{
OrderClose(OrderTicket(),OrderLots(),Bid,3,Red);
}
}
if(OrderType()==OP_SELL)
{
//Trailing stop
TrailingStop=OrderOpenPrice()-((OrderOpenPrice()-Ask)*TrailingStopPer/100);
if(Ask<OrderOpenPrice()-TrailingStopStart && OrderStopLoss()>TrailingStop)
{
OrderModify(OrderTicket(),OrderOpenPrice(),TrailingStop,OrderTakeProfit(),0,Magenta);
return(0);
}
//急落による手仕舞い
if(Ask < OrderOpenPrice() - TakeProfit * 0.3 &&
Open[2] - Close[2] > AWidth * 3 &&
Volume[2] > MaxVolume * 0.9 &&
Volume[2] > Volume[1] * 2)
{
OrderClose(OrderTicket(),OrderLots(),Ask,3,Blue);
}
}
}
//----
return(0);
}
2007年12月 1日|コメント (0)|トラックバック (0)
カテゴリー:EAの作成方法




