文系人間のためのシステムトレーダー養成所 MQL4講義 第14回 初めてのエキスパートアドバイザー第2部
--------

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
2009-03-31

MQL4講義 第14回 初めてのエキスパートアドバイザー第2部

皆さんおはようございます。FXboyです。
今回のコード文ですが、赤で表示した文が今までちゃんと表示されていなく、
わけわからないコードになっておりました。

時々「>」を書いた間近のコード文が管理画面の文章を書くところでは書いていても
ブログには表示されないというケースが存在します。
そういう時は仕方なくコードで>の代わりに>で書いたりしていますのでご了承ください。

今回ご指摘頂くことで修正箇所が見つかり大変ありがたく思っております。
もし何かおかしいな。っていうところがございましたら僕のミスであることがほとんどだと
思いますのでこれからもご指摘、ご教授頂けると嬉しいです。

コード文にミスがあったことで、プログラムがしっかり動かずお手間を取らせてしまった方が結構いらっしゃると思います。大変申し訳なく思っています。本当に失礼いたしました。ミスをなくすように努力しますので今後ともよろしくお願い致します。




この文章はCodersGuruさんのMQL4Lesson4の訳文です。(翻訳しての転載に本人の許可はとってあります)     
                         MQL4講座  
                         Coders'guru   
                           www.forex-tsd.com
                               -13-
                       初めてのエキスパートアドバイザー
                           第2部


初めてのエキスパートアドバイザー作成の第二回目の講義によくいらっしゃいました。
今回は、前回作られた操作ガイドによって作りだされたコードと、私たちが付け加えたコードを一行ずつ見ていくことにします。

コードを分析する用意はいいですか?さぁ始めましょう。

メモ:繰り返しますが、前回のエキスパートアドバイザーは教育のサンプルとして取り上げたもので、利益を追求するものではありません。

私たちのコード


//+------------------------------------------------------------------+
//| My_First_EA.mq4 |
//| Coders Guru |
//| http://www.forex-tsd.com |
//+------------------------------------------------------------------+

#property copyright "Coders Guru"
#property link "http://www.forex-tsd.com"

//---- 埋め込まれた設定値
extern double TakeProfit=250.0;
extern double Lots=0.1;
extern double TrailingStop=35.0;
//+------------------------------------------------------------------+
//| expert initialization function                    |
//+------------------------------------------------------------------+

int init()
{
//----

//----

return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                   |
//+------------------------------------------------------------------+

int deinit()
{
//----

//----
return(0);
}
int Crossed (double line1 , double line2)
  {
   static int last_direction = 0;
   static int current_direction = 0;

   if(line1>line2)current_direction=1; //アップ
   if(line1<line2)current_direction=2; //ダウン

   if(current_direction !=last_direction) //変化
   {
      last_direction = current_direction;
      return(last_direction);
   }
   else
   {
     return (0);
   }
 }
//+------------------------------------------------------------------+
//| expert start function                     |
//+------------------------------------------------------------------+

int start()
 {
 int cnt, ticket, total;
 double shortEma,longEma;

 if(Bars<100)
 {
  Print("bars less than 100");
  return(0);
 }
 if(TakeProfit<10)
 {
  Print("TakeProfit less than 10");
  return(0); //check TakeProfit
  }

 shortEma=iMA(NULL,0,8,0,MODE_EMA,PRICE_CLOSE,0);
 longEma=iMA(NULL,0,13,0,MODE_EMA,PRICE_CLOSE,0);

 int isCrossed = Crossed(shortEma,longEma);

 total = OrdersTotal();
 if(total < 1)
  {
  if (isCrossed == 1)
   {
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,
"My EA",12345,0,Green);
     if(ticket>0)
     {
     if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
Print("BUY order operand : ",OrderOpenPrice());
     }
    else Print("Error opening BUY order : ",GetLastError());
     return(0);
     }
    if(isCrossed == 2)
    {

     ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,
     Bid-TakeProfit*Point,"My EA",12345,0,Red);
      if(ticket>0)
        {
        if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
      Print("SELL order opened ; ",OrderOpenPrice());
        }
      else Print("Error opening Sell order : ",GetLastError());
       return(0);
       }
       return(0);
    }
     for(cnt=0;cnt<total;cnt++)
     {
     OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
     if(OrderType()<=OP_SELL && OrderSymbol()==Symbol())
    {
    if(OrderType()==OP_BUY) //ロングポジションでエントリー
    {
    //手仕舞うか?
     if(isCrossed ==2)
      {
         OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet);
  //手仕舞い
     return(0); //次へ
      }
    if(TrailingStop>0)
     {
     if(Bid-OrderOpenPrice()>Point*TrailingStop)
       {
       if(OrderStopLoss()<Bid-Point*TrailingStop)
        {
         OrderModify(OrderTicket(),OrderOpenPrice(),Bid-
          Point*TrailingStop,OrderTakeProfit(),0,Green);
         return(0);
         }
        }
       }
      }
     else//ショートポジションへ
      {
     //手仕舞うべきか
      if(isCrossed ==1)
      {
      OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet);
  //手仕舞い
     return(0); //決済
      }
     //トレイリングストップのチェック
      if(TrailingStop>0)
       {
        if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
        {
         if((OrderStopLoss()>(Ask+Point*TrailingStop)) ||
      (OrderStopLoss()==0))
             {

    OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,
     OrderTakeProfit(),0,Red);
            return(0);
             }
            }
           }
          }
         }
       }
 return(0);
 }
//+------------------------------------------------------------------+

____________________________________________________________________
私たちのエキスパートアドバイザーの背後にあるアイディア

コードの解説に掘り下げていく前に、まず、私たちのエキスパートアドバイザーはどのようなアイディアで作られたものなのかを説明して行きたいと思います。どのエキスパートアドバイザーも、いつマーケットにエントリー注文をだして、いつイグジットするかを決めなくてはなりません。
エキスパートアドバイザーの背後にあるアイディアは、どのような状況の時にエントリーして、イグジットするかになります。私たちのエキスパートアドバイザーの後ろにあるアイディアはとても単純なものです。さぁ見ていきましょう。

私たちは二つの指数加重移動平均線を使っています。最初のEMA(指数加重移動平均線)は8日(短期EMA)のもので、二つ目のEMA(指数加重移動平均線)は13日(長期EMA)です。

メモ:これらの指数加重移動平均線を使うことや、その他の考えは、ただ講義を目的として使用しているもので、私がお勧めするものではありません。

エントリー(参入);

私たちのエキスパートアドバイザーがマーケットにエントリーする時は、短期EMA長期EMAとクロスした時になります。二つの線の方向が注文の種類を決定することになります。
もし短期EMA長期EMAにあれば買い注文(ロング)で入ります。
もし短期EMA長期EMAにあれば売り注文(ショート)で入ります。
常に買いか売りかの一つの注文が入ります。

エクジット(手仕舞い);

初めてのエキスパートアドバイザーは、買い注文でエントリーした時は短期EMA長期EMAを交差し、かつ短期EMA長期EMAにある時に手仕舞います。
また売り注文でエントリーした時は短期EMA長期EMAを交差し、かつ短期EMA長期EMAの上にある時に手仕舞います。

私たちの注文(買いでも売りでも)はTakeProfit,TrailingStopのポイントに達した時も自動で手仕舞われることになります。

修正

マーケットへのエントリーにエクジットに加えて、エキスパートアドバイザーにはトレイリングストップの概念でエクジットの値を変更し続けることができるという特質があります。

さぁ、私たちのコードを解読していきましょう。
____________________________________________________________________________________________
//---- input parameters
extern double TakeProfit=250.0;
extern double Lots=0.1;
extern double TrailingStop=35.0;

上記のコードは操作ガイドに三つの(extern)外部変数として宣言してくれと頼んだものです。(外部変数の値はユーザーがエキスパートアドバイザーのpropertyウィンドウで変更することができます)
三つの変数のデータタイプはdoubelです。私たちは初期設定値を決め初期化しました(ユーザーは三つの変数の値をpropertyウィンドウで変更することができますが、初期設定値のままにしていくことを推奨されています)

ここで三つの変数についての解説をするために立ち止まりましょう

ストップロス

これは注文が手仕舞われる時を貴方が指定する限界値です。これはマーケットが逆行した時の損失の最小化に対して役立ちます。
ストップロスの値は買い注文の時は常に通貨の売り値の下、売り注文の時は常に通貨の買値の上に設定されます。

TrailingStop

トレイリングストップは一定の水準の下(買い注文時)もしくは上(売り注文時)の値に置かれる種類のストップロスオーダーです。この値は変動値として調整されます。
この大変重要な概念についてはこの講義の後で取り上げていこうと思います。

TakeProfit

これは注文が手仕舞われる時を貴方が指定する限界値であるという点でストップロスと似ています。

しかし、二つの相違点があります。

   ・値を追っかけていかないこと。
   ・エクジットの値は通貨の値の下に置く代わりに上に置かなければならないこと(買い注文時)。

zu1.png
図1-ストップロス(逆指値注文)とTake profit(指値注文)
____________________________________________________________________
int Crossed (double line1 , double line2)
  {
   static int last_direction = 0;
   static int current_direction = 0;

   if(line1>line2)current_direction=1; //アップ
   if(line12; //ダウン

   if(current_direction !=last_direction) //変化
   {
      last_direction = current_direction;
      return(last_direction);
   }
   else
   {
     return (0);
   }
 }

以前にお話ししたように、私たちのエキスパートアドバイザーの背後にあるアイディアは短期EMAと長期EMAが交差するのを監視しています。そして交差する方向性を得ること(どちらのEMAが上もしくは下にあるか)で、注文の種類(売りエントリー、買いエントリー、買い手仕舞い、売り手仕舞い)が決定されます。

この目標を達成するために私たちはCrossed関数を作り出します。

Crossed関数は二つのdoubleの値を設定値として持ち、integerの値を返却値として返します。
最初の設定値は監視して欲しいと思う一つ目のラインの値(私たちの場合は短期EMAになります)になり、二つ目の設定値は二つ目の監視してほしいラインの値(長期EMA)になります。

Crossed関数は、二つのラインをCrossed関数が呼び出される度にその二つのラインの状態を記憶するstatic変数の方向を保存することによって監視します。

 ・最新の方向が保存された時に何も変わらなければの値を返します。
 ・方向が変化(ラインが交差)し、かつ最初のラインが二つ目のラインの上にある時はを返します。
 ・方向が変化(ラインが交差)し、かつ最初のラインが二つ目のラインの下にある時はを返します。

メモ:この関数は、いずれ貴方が自分でコードを書いていく時に、どのような二つのラインでも監視することができ、クロスすることを知らせてくれます。

どのように書いたか見ていきましょう。

int Crossed (double line1 , double line2)

上記のコードは関数の宣言です。設定値はdoubleのデータタイプと定め、返却値にはintegerタイプを返すCrossed関数を作り出したいというものです。

この関数を呼び出すとき、貴方は二つのdoubleの設定値を受け渡さなければなりません、そしてそれはintegerタイプの返却値として戻ってくることになります。

Crossed関数を使う前に宣言をしなければなりません。その関数を宣言する場所はどこでも構いません。私はstart()関数の上に置きましたが、それ以外のどの場所からでも宣言することができます。

static int last_direction = 0;
static int current_direction = 0;

ここでは私たちは二つのラインの動向と、最新の方向の値を保持するintegetタイプの二つのstatic変数を宣言しました。私たちはこれらのstatic変数(何回も呼び出されている間もその値を保存する特質をもつ変数)を使ってラインの方向が変化したかどうかをチェックしていきます。

私たちは0を初期値として初期化しました。なぜなら初めて関数を呼び出すときに働いてほしくないからです。(もしCrossed関数が最初の呼び出しで働くようにしたら、エキスパートアドバイザーが私たちがメタトレーダを開くと同時にエントリー注文をすることになってしまいます。)

if(current_direction !=last_direction)//変化

この行は、二つのstatic変数を、一つ前の関数の呼び出しと、現在の呼び出しとの間で変化があるかをチェックすることで比べるものです。
もしlast_directionとcurrent_directionの値が等しくなければ、方向は変化したということを意味します。

last direction = current direction;
return (last_direction);

そしてlast_directionとcurrent_directionが等しくない場合、last_directionの値をcurrent_directionの値を割りあてて変更しなければなりません。
そしてlast_directionの値を返却値として返します。この値はもし最初のラインが二つ目のラインの上にあればを返し、最初のラインが二つ目のラインの下にあればを返します。

else
  {
    return(0);
  }

もしそうでなければ(last_directionとcurrent_directionの値が等しいのならば)、ラインの動向は変わってないことになり、0の値を返却値として返します。

私たちのプログラムはこの関数をstart()関数の本体で呼び出し、返却値をそれに対応する適切な行動を決定するために使います。

次の講義ではどうやって関数を呼び出すのか、大変重要なtrading関数について私たちは知ることになります。

それでは。
Coders'Guru



本日もお疲れ様でした。
何か質問がありましたら聞いて下さいね。




押していただけると凄い励みになりますのでよろしくお願いします。 
人気ブログランキングへ


theme : FXでシステムトレード
genre : 株式・投資・マネー

コメントの投稿

管理者にだけ表示を許可する

管理人 様

お世話になります。
まずは、突然の書き込みにて大変失礼を致します。
私、AF-Partersの鈴木と申します。

「AF-Parters」はFXを中心としたアフィリエイトサービス
でございまして、FXブロガー様を中心に人気となっており
話題を集めております。

弊社のアフィリエイトシステムの特徴と致しまして、
高額アフィリエイト報酬とご希望者にはHP上にてご参加頂いている
パートナー様のご紹介を差し上げる点がございます。

AF-Partersの理念と致しまして、パートナー様、クライアント様の
価値を相互的に向上することを目指しておりますので、
これまで以上にパートナー様には喜んで頂けるのではないかと
考えております。

今後、さらに多くのクライアント様にご参加していただける予定で
ございまして、HPのコンテンツ増強も行って参ります。
是非、この機会に「AF-Parters」をご活用頂ければ幸いです。

パートナーの御登録は下記「AF-Parters」ホームページより可能
となっておりますので、何卒よろしくお願いします。
http://www.affiliatepartners.jp/


───────────────────
 博労町Markets株式会社
 〒541-0059
 大阪府大阪市中央区博労町4-3-1
 ディアコートセンバ7F
 TEL 06-6253-7227(代表)
 FAX 06-6253-7249
 E-mail: info@affiliatepartners.jp
 URL:  http://www.affiliatepartners.jp/
───────────────────

管理人のみ閲覧できます

このコメントは管理人のみ閲覧できます

たにさんへ

ご指摘ありがとうございました。
修正しておきましたのでご覧ください。

僕のミスによりたにさんの貴重な時間を浪費させてすいませんでした。。

それと温かいご声援感謝しています。

どうもありがとうございました。今後ともよろしくお願いします^^
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。