システムの質を高める2

システムの質を高める2


今回は、

  1. 売り取引もする
  2. 売買条件にフィルタを付け加える
  3. 最適化をする

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

1.売り取引もする方法

これは、買い取引の条件文を書いたときと、同じようにすればいいです。

書く場所は、ポジション無しの条件文の{}内の、買いの条件文の{}の次あたりに書きましょうか。

      if(nowbar != Bars && Close[1] < ma)
      {                          
         //売りポジションを取る。
         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] < ma)
	      {
	         //買いポジション決済
	         OrderClose(OrderTicket(), OrderLots(), Bid, 3, Red);
	      }
      }
      //もしポジションが売りポジションだったら
      if(OrderType() == OP_SELL)
      {
	      //もし1本前の終値が移動平均より上ならば
	      if(Close[1] > ma)
	      {
	         //売りポジション決済
	         OrderClose(OrderTicket(), OrderLots(), Ask, 3, Blue);
	      }
      }      
   }

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

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

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

2.売買条件にフィルタを付け加える

このままでは、移動平均より上ならばホイホイと買い、下ならばホイホイト売り。
これでは、勝率も上がりませんし、利益も出しづらいと思います。

なので、一般的には条件を絞ってあげて、勝てるときに取引をするといった売買戦略をつくります。

今回は、フィルタとしてオシレータ系のストキャスティクスを使いましょうか。

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

   double ma, sto;

このように、既存の ma の後ろにカンマと sto を割り込ませましょう。
これで、ma と 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] > ma && sto < StoLevel)

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

売りの時も同様に

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

という具合です。

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

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

次の「最適化をする」の前にもう一度仕上がりのコードをコピペしておきますね。

//+------------------------------------------------------------------+
//|                                                      HeikinSample.mq4 |
//|                                                                            keiji |
//|                                 http://www.dr-ea.com/meta-blog/ |
//+------------------------------------------------------------------+
#property copyright "keiji"
#property link      "http://www.dr-ea.com/meta-blog/"

//パラメータ用の変数
extern int     StopLoss    = 40;
extern int     TakeProfit  = 20;
extern double  lots        = 0.1;
extern int     MaPeriod    = 12;
extern int     StoLevel    = 20;

//記憶用の変数
int nowbar;

//+------------------------------------------------------------------+
//| expert start function                                                    |
//+------------------------------------------------------------------+
int start()
{
//----
   //変数の宣言
   double ma, sto;
   int cnt, CurrentPosition = -1 ;
   
   //移動平均値の算出  
   ma = iMA(NULL, 0, maPeriod, 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] > ma && 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] < ma && 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] < ma)
         {
            //買いポジション決済
            OrderClose(OrderTicket(), OrderLots(), Bid, 3, Red);
         }
      }
      //もしポジションが売りポジションだったら
      if(OrderType() == OP_SELL)
      {
         //もし1本前の終値が移動平均より上ならば
         if(Close[1] > ma)
         {
            //売りポジション決済
            OrderClose(OrderTicket(), OrderLots(), Ask, 3, Blue);
         }
      }
   }
//----
   return(0);
}
//+------------------------------------------------------------------+

こんな感じですね^^

3.最適化をする

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

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

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

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

Expert Advisor: にHeikinSample を選びます。

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

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

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

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

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

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

終了したら、Optimization Results で並べ替えをしたりして見ていきましょう。
特に、取引回数、プロフィットファクター、ドローダウンをみてよさそうなもののパラメーターの入力の欄をみてみましょう。

それを参考に更に、練り込んでやってみましょう。
時間が許すなら、Every ticks の方でやってみましょう。

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

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

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

今回はこのへんで。

完全自動売買への道のり

タグ

2007年10月15日|コメント (17)

カテゴリー:完全自動売買

コメント (17)

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

投稿者: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

はじめまして
最近EAのプログラム作りをはじめました。

さっそく質問なんですがつくってみた
ExpertAdvisorをバックテストしてみたのですが
結果やグラフが表示されないのですが
どうしてなのでしょうか?

投稿者:maron |2011年3月 3日 15:02

maronさん

こんにちわ。

>バックテストしてみたのですが結果やグラフが表示されない

取引回数が0だと、結果やグラフが表示されません^^;

投稿者:慶次 |2011年3月 3日 17:42

質問させてください
今二つの移動平均線のクロスをした際に売買を行い、
合図として矢印を表示させたく、あるひな形をもとに
作成してみたのですが矢印が表示されません。

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Orange
#property indicator_color2 Green
#property indicator_color3 Blue
#property indicator_color4 Red

//指標バッファ
double BufFastMA[];
double BufSlowMA[];
double BufBuy[];
double BufSell[];

//外部パラメーター
extern int FastMA_Period = 10;
extern int SlowMA_Period = 40;

int init()
{
//---- indicators
SetIndexBuffer(0,BufFastMA);
SetIndexBuffer(1,BufSlowMA);
SetIndexBuffer(2,BufBuy);
SetIndexBuffer(3,BufSell);
SetIndexStyle(2,DRAW_ARROW);
SetIndexStyle(3,DRAW_ARROW);
SetIndexArrow(2,233);
SetIndexArrow(3,234);

//----
return(0);

int start()
{

//----
int counted_bar = IndicatorCounted();
int limit = Bars-counted_bar;

if(counted_bar==0) limit -= SlowMA_Period-1;
for(int i = limit-1 ; i>=0 ; i--)
{
BufFastMA[i]=iMA(NULL,0,FastMA_Period,0,MODE_SMA,PRICE_CLOSE,i);
BufSlowMA[i]=iMA(NULL,0,SlowMA_Period,0,MODE_SMA,PRICE_CLOSE,i);
}
//売買シグナルの生成
if(counted_bar == 0) limit -= 2;
for(i=limit-1; i>=0; i--)

//買いシグナル
BufBuy[i]=EMPTY_VALUE;
if(BufFastMA[i+2] BufSlowMA[i+1])
BufBuy[i] = Open[i];

//売りシグナル
BufSell[i]=EMPTY_VALUE;
if(BufFastMA[i+2]>=BufSlowMA[i+2]
&& BufFastMA[i+1] < BufSlowMA[i+1])
BufSell[i] = Open[i];
//----
return(0);


どこが悪いのかがわかりません。
どうかご指摘いただけないでしょうか
ながながと申し訳ないですがどうぞよろしくお願いします。

投稿者:maron |2011年3月27日 14:42

maronさん

こんにちわ^^

途中抜けて表示されているところがありチョット分りづらいですが、
売買シグナルの生成のfor文の{}はありますか??

投稿者:慶次 |2011年3月28日 19:32

お返事ありがとうございます。
自己解決できました、すみません。

余談なんですが、現在参考書やサイト等をつかって毎日取り組んでいるのですが
なかなか思うように進めていくことができず、このままやり続けてマスターする
ことができるのかと不安になったりします。
慶次さんをはじめ、みなさん独学でやってきたのでしょうか?
慶次さんがどのように取り組まれたのか、また○○をしたらいいよというのが
あれば是非聞かせてください。
私事で申し訳ないですがよろしくお願いします。

投稿者:maron |2011年3月29日 12:48

maronさん

こんにちわ!

解決されてよかったです^^

MQLのスキルアップ法ですが、興味のあるフリーのEAやインジケータのコードを
読み解いてみると新しい発見などがあり、面白いかもですね^^

特に、マスターするということを考えず、作りたいEAやインジケータに必要な知識を
身につけていくという感じの方が、楽しく覚えられるのではと思います^^

和訳リファレンス
http://www.dr-ea.com/meta-blog/mql/mqlreference-metaeditor2.html

が便利ですのでオススメです^^

投稿者:慶次 |2011年3月30日 11:17

アドバイスありがとうございます^^
さっそく気持ちを切り替えてやっていこうと思います。

投稿者:maron |2011年3月31日 15:53

いつもいつもお世話になっております。

前のご連絡よりフリーのインジケータに売買シグナルを出したく試みているのですが、まったく上手くいきません。
ちなみに今やっているのは
http://fxforex.sakura.ne.jp/mt4indicators/Big%20trend.mq4
のインジケータで、UptrendとDntrendのかわりめに矢印をひょうじさせたいので、
よろしければ教えていただけないでしょうか。

いつも初歩的なことで恐縮ですがよろしくお願い致します。

投稿者:maron |2011年4月 6日 11:25

maronさん

こんにちわ!

ご連絡いただいたインジケータについてですが、
2つのローソク足にまたがってEMPTY_VALUEでないときに、はじめてそのラインが表示されます。
例えば、
Uptrend[1]とUptrend[0]に値が入っている時は、現在のところに水色を表示するようにしています。

それを踏まえて、条件式をつくるといいのですが、
変わり目の部分は、UptrendとDntrendの両方に値が入っていてその前の状態で判断するとよいかもです。

しかし、1またぎだけ反転してすぐに戻ったときの表示が特殊です。
水色の線を太くして表示させるとその部分の状態がわかります。
(同じ太さに戻すと、水色が弱くて、トマト色が強い感じです)

その特殊な状態も条件式に入れると、よいのではないでしょうか^^

投稿者:慶次 |2011年4月 8日 15:19

お返事ありがとうございます。
まだまだ勉強不足で中身を解析できていないため、
上手くいかせてないですが、なんとなくは理解できるので、
やってみようとおまいます。
あつかましいのは承知のうえ、これからもアドバイスのほう
おねがいできたらと思います。
よろしくお願致します。

投稿者:maron |2011年4月 9日 14:20

お世話になっております。
今回も質問なのですが、現在、前にとりくんでいた、
http://fxforex.sakura.ne.jp/mt4indicators/Big%20trend.mq4
のインジケータをEA化したく勉強しているのですが、
今の私のレベルでは中身を理解するのは困難で、関数を調べたり
いろいろなサイトやブログで見聞きしているのですが、
理解することができず前に進まないため悩んでいます。
よろしければ、何をすれば(どのように勉強していけば)理解が深まるのか、
ご教授いただけないでしょうか。
よろしくお願いします。

投稿者:maron |2011年4月16日 18:36

お世話になっております。
今回も質問なのですが、現在、前にとりくんでいた、
http://fxforex.sakura.ne.jp/mt4indicators/Big%20trend.mq4
のインジケータをEA化したく勉強しているのですが、
今の私のレベルでは中身を理解するのは困難で、関数を調べたり
いろいろなサイトやブログで見聞きしているのですが、
理解することができず前に進まないため悩んでいます。
よろしければ、何をすれば(どのように勉強していけば)理解が深まるのか、
ご教授いただけないでしょうか。
よろしくお願いします。

投稿者:maron |2011年4月16日 18:44

maronさん

こんにちわ!

iCustom関数で値を取得する場合、思い通りの値が取得できているかどうかを、
Comment関数やPrint関数などで、確認しながら進めるといいかもしれませんね^^

投稿者:慶次 |2011年4月19日 13:30

コメントを投稿する

(初めてのコメントの時は、コメントが表示されるためにこのブログのオーナーの承認が必要になることがあります。承認されるまでコメントは表示されませんのでしばらくお待ちください)






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

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