複数のシグナル・複数のフィルタを搭載し選択できるEA
今回のテーマは、EAの中で複数のシグナル・複数のフィルタを搭載し、
それを使うかどうかパラメータで選択できるようにする方法です。
サンプルファイルはこちら→Sample_SwitchSignal.zip
(↑'10.01.22 午前 一部修正)
Start()関数の中身は上から、
- シグナル計算2つ
- フィルタ計算3つ
- エントリシグナル計算
- エグジットシグナル計算
- ポジション確認
- エグジット処理
- エントリ処理
という感じです。
シグナルが2種類、フィルタが3種類あり、
それぞれどれを使うか[Use~]というパラメータで選択できるようにしています。
シグナル計算やフィルタ計算はそれぞれ[~sign]や[~filter]といった
個別の変数に計算結果を代入します。
そして、サンプルファイル132行目~140行目を見てください。
int sign;
if((!UseMaCrossSignal || MaCrossSign==1) &&
(!UseMacdCrossSignal || MacdSign==1) &&
(!UseMaTrendFilter || MaFilter==1) &&
(!UseAdxFilter || AdxFilter) &&
(!UseAtrFilter || AtrFilter)) sign=1;
if((!UseMaCrossSignal || MaCrossSign==-1) &&
(!UseMacdCrossSignal || MacdSign==-1) &&
(!UseMaTrendFilter || MaFilter==-1) &&
(!UseAdxFilter || AdxFilter) &&
(!UseAtrFilter || AtrFilter)) sign=-1;
エントリ用のシグナルを代入する整数変数 sign を宣言。
もし、
UseMaCrossSignal が false または、MaCrossSign が1で
UseMacdCrossSignal が false または、MacdSign が1で
UseMaTrendFilter が false または、MaFilter が1で
UseAdxFilter が false または、AdxFilter が true で
UseAtrFilter が false または、AtrFilter が true の場合、
signに1を代入
もし、
UseMaCrossSignal が false ・・・(省略)
・・・の場合、
signに-1を代入
といった感じにします。
これで、選択されたシグナルやフィルタのみを使ったシグナルが
sign に入ります^^
フィルタのシグナル用の変数でtrue/falseのbool型の場合は、
外でif文で書いてもいいですね^^
その下のエグジット用のシグナルの条件では
サンプルではフィルタ用の条件は含めてませんが、
書き方としては、同じ感じですね^^
そのほかで、ちょっと分かりづらいところがありますが^^;
コメントで質問してくださいね^^;
でわ、このへんで^^
タグ
コメント (19)
慶次さん、こんにちは。
どうもありがとうございます。
勉強になりました。
この書き方は時間フィルター等いろいろな場面で使える表現方法ですね。
早速、自作EAの修正を行いました。
プログラムがぐんと短くできました。
それでは、今後ともよろしくお願いします。
投稿者:よっし~ |2010年1月22日 21:06
よっし~さん
こんにちわ^^
私もいろいろな分岐の書き方をやってみましたが、
この書き方が一番修正等が楽です^^;
また、シグナルとフィルタを分けて考えることでエントリシグナルやエグジットシグナルの作成がやりやすくなりますね!
投稿者:慶次 |2010年1月23日 08:13
慶次さん。
こんばんは!
いつも、お世話になっております。
私も、シグナル、フィルター、トレイル、クローズ毎に
個々に選択できるように書いてます。
最近のODLでは、成り行き注文時に、初期SL値が設定不可に
なってしまった為、逆指値注文を行うようにしていたので、
オーダー時の仕掛値の設定方法も、複数設定できるように、選択式にしています。
ところで。
MT4でバックテストを行っている際に、
テスト期間が長いと、後半になるにつれて、非常に遅くなることは
ありませんか。
単に、テスト期間を分割して行えばいいのかと思ったのですが、
もし、なにか御存じでしたらと思いまして。
投稿者:マーサー |2010年1月26日 21:26
マーサーさん
こんにちわ!
MT4のバックテストでは、
データのVolume(ティック数)によってバックテストのティック数が決められているようです。
Volumeが多いところでは、その分次の足に進むのが遅くなるようです。
また、EA内に繰り返し文で過去すべてのデータから計算されるような部分がありますと、
期間が長ければ長いほど、後の方は処理に時間がかかってしまいます^^;
投稿者:慶次 |2010年1月27日 12:35
いつもコメント、ありがとうございます。
確かに、volume(ティック数)も関連しているようですが、
やっぱり後半の方が、遅いような感じです。。
変なこと言って、失礼いたしました。。 ^^;
最近は、以前に作成したR倍数の自動計算するシステムを
改善しまして、複数のシステム・通貨ペア毎の結果より
R倍数の計算結果を、ポートフォリオで、検証を行えるようにして、
ポジションサイズの調整をできるように致しました。
今度のは、かなり、スピードも改善されていますので、
お手隙の時に、チェックしていただけると幸いです!
そういえば、タープ博士の本が、また発売されましたね!
「ポジションサイジング入門」
途中までしか読んでいないのですが、
NLPをもとにしたトレード心理面の強化と、
R倍数をもとにしたポジションサイズの検証方法
をメインにしているようです。
「魔術師たちの心理学」に比べると、
かなり読みやすそうです。
投稿者:マーサー |2010年1月28日 02:35
マーサーさん
こんにちわ!
バックテストを繰り返していると、確かに遅くなりますね^^;
メモリを圧迫しているような感じです。
また、何か分かりましたら連絡しますね^^
>複数のシステム・通貨ペア毎の結果より
>R倍数の計算結果を、ポートフォリオで、検証を行えるようにして、
>ポジションサイズの調整をできるように致しました。
すばらしいです!
ぜひ使ってみたいですm(_ _)m
タープ博士「ポジションサイジング入門」が出たんですね^^
ポジションサイジングは最重要項目ですからね^^
早速読んでみます。ありがとうございました!
投稿者:慶次 |2010年1月28日 16:20
はじめまして、さつきと申します。
こちらで質問させて頂いてもいいでしょうか?
こちらで勉強させていただいた内容を元にして、
あるインジケーター用のEAに、
別のインジケーターでフィルターをかけようと、
int start()
{
bool SHIFilter = false;
if(UseSHIFilter)
{
double GoSigh = iCustom(Symbol(),0,"SHI_Channel_true",AllBars,BarsForFract,0,shift+1);
if(GoSigh > 0 ) SHIFilter= true;
}
・
・
・
bool getSignal(int mode)
{
double _1 = 0,_2 = 0;
if(mode == OP_BUY && momentum(OP_BUY) && SHIFilter)
・
・
・
などとしてみましたが、フィルターがかかりません。
どこが間違っているのかお教えいただけないでしょうか?
投稿者:匿名 |2010年10月22日 18:56
さつきさん
こんにちわ!
書いていただいた箇所だけでは、なんともいえませんが、
その限られたコードで、
SHIFilterがtrueの場合エントリなし、
getSignal関数のif文でシグナル発生する場合は、
if文の最後は、!SHIFilterになりますね。
投稿者:慶次 |2010年10月23日 08:01
慶次さん、こんにちは。
ご回答ありがとうございます。
ひょtっとして、
GoSigh > 0
は、 サインが出ていない状態ということになるのでしょうか?
基本的なことがわかっていなかったようです。
ありがとうございました。
月曜日に試してみます。
また、わからないことがあったら、よろしくお願いいたします。
さつき
投稿者:さつき |2010年10月23日 12:26
こんにちは、さつきと申します。
いつもいろいろお教えいただきありがとうございます。
このページのサンプルプログラムを参考にして、下記のようにしましたが、
Function "MacdSign" is not referenced and will be removed from exp-file
というエラーがでます。
どこを直したらよろしいでしょうか?
長くなるので省略した部分は、サンプルプログラムのコードと同じです。
bool MacdSign(int mode)
{
if(!UseMacdCrossSignal) return(true);
double macd1=iMACD(省略);
double macd2=iMACD(省略);
double macdsignal1=iMACD(省略);
double macdsignal2=iMACD(省略);
if(mode == OP_BUY && macdsignal2>=macd2 && macdsignal1macd1)return(true);
else return(false);
}
続くコードとして
bool getSignal(int mode)
{
double sign = 0;
if(mode == OP_BUY && MacdSign(OP_BUY))
{
sign = iCustom・・・・
というふうにしていきたいのですが。よろしくお願いいたします。
注)if(mode == OP_BUY ・・・
の後には、下記のコードが入っていますが、何度やっても確認画面では消えています。
else if(mode == OP_SELL && macdsignal2macd1)return(true);
投稿者:さつき |2010年11月 7日 00:04
自己レスです。
上記の件、理解できました。
どこにも使われてないから、削除するというようなエラーなのですね。
続くコードを入れる前にコンパイルして確かめてからと思っていたので、
エラーが出ていました。
下記の部分を入れたら、出なくなりました。
if(mode == OP_BUY && MacdSign(OP_BUY))
投稿者:さつき |2010年11月 7日 17:51
さつきさん
こんにちわ^^
解決されてよかったです^^;
関数が使われていないという警告でしたね^^;
続くコードはすでに書き込んであると思って、不思議に思っておりました・・・。
投稿者:慶次 |2010年11月 8日 18:24
慶次さん、レスありがとうございます。
少々、あわて者ですので、お許しください。
自信がないと、落ち着いて考える余裕がなくなってしまいます。
また、わからないことがありましたら、質問させていただきます。
よろしくお願いいたします。
さつき
投稿者:さつき |2010年11月10日 12:51
大変参考になる情報を提供していただきじっくりと勉強させてもらっております。が最近更新がないようで少し残念です。
複数のシグナルを使ったEAを作っているのですがEXITのところで詰まってしまい、ご教授頂ければとコメントしました。
例えば、トレンドの時はAのシグナルで、レンジの時はBのシグナルでENTRYし、AのEXITはCの条件で、BのEXITはDの条件で、とするときSAMPLE SWITCHSIGNALを参考にして作るとしたらどの様につくったらよいか色々試しているのですがうまくいかず...です。
大変勝手なお願いですが教えて頂けないでしょうか。宜しくお願いします
投稿者:Matsu |2011年2月 1日 11:30
Matsuさん
こんにちわ!
>最近更新がないようで少し残念です。
すみません^^;時間を見つけて更新したいとは思っていますが^^;
2つのEAを1つのEAにする感じですね?
シグナルに応じて、マジックナンバーかポジションコメントを変えて、
保有ポジションを分けて認識して、
保有ポジションに応じた決済条件で決済するようにすると
できると思います^^
投稿者:慶次 |2011年2月 1日 12:55
さっそく返事をいただき大変感激です。
仕事中なので中身を見られないのが残念ですが、今夜帰ったら拝見させて頂きます。
不明な点が有りましたら質問させて頂いてよろしいでしょうか?
お忙しい中大変恐縮です!よろしくお願いします。
投稿者:Matsu |2011年2月 1日 20:07
慶次さんへ
先日は大変お世話になりありがとうございました。コメントを頂き、あれこれとやってみましたがまだまだ初心者にはハードルが高く一時棚上げとし、別のものを作っておりましたがなかなか上手くいかずこんなコメントがでて解決できないでいます。 (end_of_program' - unbalanced left parenthesis )
大変恐縮ですがプログラム抜粋したものを張り付けさせていただきましたのでどこをどの様に直したらよいのかご教授いただけないでしょうか。宜しくお願いします。
大変読みにくくて申し訳ありません。
int cnt, CurrentPosition = -1 ;
int Ticket;
for(cnt = 0; cnt Hima1 && HeikinAshi_Close2Close[2]
&& maangle1>Range_hi
&& HeikinAshi_Close11>HeikinAshi_Open11
)
{
Ticket= OrderSend(Symbol(), OP_BUY, lots, Ask, Slippage, Ask-(var2*Point), 0 , "Buy", 999, 0, Blue);
nowbar = Bars;
}
if(nowbar != Bars
&& HeikinAshi_Close1Loma2 && nehaba1>50
&& ema1>Close[1] && Close[1]ema51 && orderpriceema51 && orderprice>ema30 && orderprice>ema50
)
{
OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Blue);
Ticket = OrderSend(Symbol(), OP_SELL, lots, Bid, Slippage, Bid+(var2*Point, 0, "Sell", 999, 0, Red);
}
}
if(OrderType() == OP_SELL)
{
if(
ema30>ema50 && ema31ema30 && orderprice>ema50
)
{
OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, Red);
}
else
if(
ema30>ema50 && ema31<ema51 && orderprice<ema30 && orderprice<ema50
)
{
OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Red);
Ticket = OrderSend(Symbol(),OP_SELL,lots,Bid,Slippage,Bid+Slippage,Bid(var2*Point,0,"Sell",999,0,Red);
}
}
}
}
//----
return(0);
}
//+------------------------------------------------------------------+
//----------------------- PRINT COMMENT FUNCTION
//----------------------- SOURCE : CODERSGURU
int CurrentPosition;
int highestBar;
double highestPrice,lowestPrice,orderprice;
void subPrintDetails()
{
string sComment = "";
string sp = "----------------------------------------\n";
string NL = "\n";
sComment = sp;
sComment = sComment + "HighestPrice=" + DoubleToStr( High [iHighest(NULL,0,MODE_HIGH,100)],5) + " | ";
sComment = sComment + sp;
sComment = sComment + "LowestPrice=" + DoubleToStr( Low [iLowest(NULL, 0, MODE_LOW, 100)],5) + " | ";
sComment = sComment + sp;
sComment = sComment + "OrderOpenPrice=" +DoubleToStr( OrderOpenPrice(),5) + NL;
sComment = sComment + sp;
Comment(sComment);
}
投稿者:Matsu |2011年2月 8日 23:52
慶次さんへ
お騒がせしました。なんとか解決しました!単なるバカなミスでした。
ただプログラム最後の辺りでreturn(0);の後 画面に過去100期間中の最安値と最高値
及びエントリーしたらそのエントリー値を表示させようとしますがなにか変な値がでてしまいます。ここはどの様にしたらよいでしょうか。ご教授宜しくお願いします。
投稿者:Matsu |2011年2月 9日 01:55
Matsuさん
こんにちわ^^
変な値とは、
OrderOpenPrice()ですか?
ポジションの情報を取得するには、まずOrderSelect(・・・)でポジションの選択をする必要があります。
OrderSendで返った注文番号でポジション選択できますね^^
投稿者:慶次 |2011年2月10日 10:40


