English Русский 中文 Español Deutsch Português 한국어 Français Italiano Türkçe
トレーダーの黄金則

トレーダーの黄金則

MetaTrader 4トレーディングシステム | 2 12月 2015, 08:13
990 0
Genkov
Genkov

はじめに

トレーダーの主たる課題はマーケットへのエントリータイミングをはかることだけでありません。イグジットのタイミングをはかることもまた必要なことです。トレーダーの黄金則に曰く、「利食い急ぐな、損急げ」。

高度に計算された予測に基づき利益を得るためには、トレードの三原則を理解しなければいけません。

  1. マーケットにエントリーする際のリスクを知ること(初期のストップロス値を決めること)。
  2. 損切りを早く、利益を伸ばすようにすること(システムが要求する前にポジションをクローズしません)。
  3. システムの期待利益を把握すること ー 定期的にテスト調整を行うこと。


利益を伸ばすステップ・バイ・ステップ トレール メソッド

多くが「利益を稼ぐことなど不可能だ、マーケットがどうなるかなんてわからないのだから。」と思っています。しかし、トレードを成功させるのに未来を知ろうとすることが本当に必要なのでしょうか?良いトレードとは、マーケットへエントリーするタイミングを考慮した確かなシステムに基づいておこなうものです。エントリータイミングを計るには、予測能力と、最も高い確率で利益を伸ばすステップ・バイ・ステップ・トレール・メソッドを用いることです。

マーケットへエントリーするチャンスは様々な方法で見つけることができます。例えば、ローソク足パターンや波形パターンなどです。同時に、プロフィットファクターを考慮しなければいけません(利益/損失の割合)。

これは次の要件にもとづく方法です。:トレーダーがポジションをオープンする際に、可能な最小ストップロス値を選択します。その値は様々な方法で決定できます。例えばディポジットの1.5%に設定するなどします。マーケットがストップロスの値幅と同じ利益幅になると、ロットの半分をクローズしますがストップロス値は変更しないのです!

つまりどういうことか言うと、マーケットが逆方向へ動く場合に備えてセーフティネットのようなものをつくるのです。言い換えれば、最小損失を固定することによってリスクを軽減するのです。マーケットが利益方向へ伸びていたのに、しばらくすると反転する時ががきてしまったら、ストップロスを発動します(図1-3)。


図1. ポジションオープン


図2ストップロスの設定

マーケットが反転する場合


図3マーケットが反転しても利益・損失差し引きゼロです。

ポジション トレーリング プログラム コード

ここではオープンポジションをトレールし、実際に2番目の黄金則を適用させることで、最も高い確率で利益を伸ばすプログラムコードを紹介します。

マーケットがしばらく利益方向へ伸び続け事前に仕掛けておいた値、例えば100ピップスに達したらストップロスを利益・損失差し引きゼロになるレベルにリセットします。以降のリセットはあらかじめ決めておいた間隔、例えば50ピップスごとにおこないます。ストップロスはバー1本ごとに変更し動かすことができますが、ブローカーは頻繁なリセットを好みません。特に短期足でのリセットを嫌います。ライブラリフォルダのエラーファイル(stdlib.mq4)にあるエラーメッセージ # 8 error="too frequent requests"(エラー=要求が頻繁すぎます)はまさにこのケースを示すものです。

次のストップロスを決定する方法は、フィボナッチレベルにもとづくプライスポジションによって選択します。適応するフィボナッチレベルは、ベガス・トンネル法を使用し構築されます。

フィボナッチレベルの計算はLevelFibo()レベル母関数を用います。

//+------------------------------------------------------------------+
   void LevelFibo()
   {
   double Fb1,Fb2,Fb3,Fb4,Fb5,Fb6,Fb7,Fb8,Fb9,Fb10,Fb11,Fb12,Fb13;
   // "ベガス" チャンネル
   double Ma144_1 = iMA(NULL,0,144,0,MODE_EMA,PRICE_CLOSE,1);
   double Ma169_1 = iMA(NULL,0,169,0,MODE_EMA,PRICE_CLOSE,1);
   // "ベガス" チャンネル中央値
   double MedVegas=NormalizeDouble((Ma144_1+Ma169_1)/2,Digits); 
   // "ベガス"法を使用しフィボナッチレベル値を計算
   Fb1=MedVegas-377*Point;     Fb12=MedVegas+377*Point;
   Fb2=MedVegas-233*Point;     Fb11=MedVegas+233*Point;
   Fb3=MedVegas-144*Point;     Fb10=MedVegas+144*Point;
   Fb4=MedVegas-89*Point;      Fb9=MedVegas+89*Point;
   Fb5=MedVegas-55*Point;      Fb8=MedVegas+55*Point;
   Fb6=MedVegas-34*Point;      Fb7=MedVegas+34*Point;
   }
//+------------------------------------------------------------------+

買いポジションのストップロスを計算すると、利益は最初のバーの最大値High[1]とポジションオープンレベル OrderOpenPrice()との差になります。ストップロスレベルは最初のバーの最小値Low[1]と関係する"最も近い"フィボナッチレベルとして定義します(Fig. 4)。


図4買いポジションのストップロス計算

売りポジションのストップロスを計算すると、利益はポジションオープンレベル OrderOpenPrice()と最初のバーの最大値High[1]との差になります(Fig. 5)。


図5売りポジションのストップロス計算

買いポジションでは、ストップロス値はフィボナッチレベルに基づきます。最初のローソク足の安値に基づいており、ある分割関数で表します。

関数コードは以下です。

//+---------------------------------------------------------------------+
//| 最初のローソク足安値にもとづくフィボナッチレベルを用いた                    |
//| 買いポジションのストップロス値を明示する関数(テーブル)                   |
//+---------------------------------------------------------------------+
 void StopLevelFiboBuy()
   {
   if(Low[1]>Fb12)                                newSL_B=Fb12-100*Point;
   if(Low[1]<=Fb12 && Low[1]>(Fb12+Fb11)/2)       newSL_B=(Fb12+Fb11)/2;
   if(Low[1]<=(Fb12+Fb11)/2 && Low[1]>Fb11)       newSL_B=Fb11;
   if(Low[1]<=Fb11 && Low[1]>(Fb11+Fb10)/2)       newSL_B=(Fb11+Fb10)/2;
   if(Low[1]<=(Fb10+Fb11)/2 && Low[1]>Fb10)       newSL_B=Fb10;
   if(Low[1]<=Fb10 && Low[1]>(Fb10+Fb9)/2)        newSL_B=Fb9;
   if(Low[1]<=(Fb10+Fb9)/2 && Low[1]>Fb9)         newSL_B=Fb8;
   if(Low[1]<=Fb9  && Low[1]>Fb8)                 newSL_B=Fb7;
   if(Low[1]<=Fb8  && Low[1]>Fb7)                 newSL_B=(Fb7+MedVegas)/2;
   if(Low[1]<=Fb7  && Low[1]>MedVegas)            newSL_B=Fb6;
   if(Low[1]<=MedVegas && Low[1]>(MedVegas+Fb6)/2)newSL_B=Fb6;
   if(Low[1]<=(MedVegas+Fb6)/2 && Low[1]>Fb6)     newSL_B=Fb5;
   if(Low[1]<=Fb6  && Low[1]>Fb5)                 newSL_B=Fb4;
   if(Low[1]<=Fb5  && Low[1]>Fb4)                 newSL_B=(Fb3+Fb4)/2;
   if(Low[1]<=Fb4  && Low[1]>Fb3)                 newSL_B=Fb3;
   if(Low[1]<=Fb3  && Low[1]>(Fb3+Fb2)/2)         newSL_B=(Fb3+Fb2)/2;
   if(Low[1]<=(Fb3+Fb2)/2  && Low[1]>Fb2)         newSL_B=Fb2;
   if(Low[1]<=Fb2  && Low[1]>(Fb2+Fb1)/2)         newSL_B=(Fb1+Fb2)/2;
   if(Low[1]<=(Fb2+Fb1)/2 && Low[1]>Fb1)          newSL_B=Fb1;
   if(Low[1]<=Fb1)                                newSL_B=Fb1-100*Point;
   }
//+------------------------------------------------------------------+

売りポジションにおける最初のStopLevelFiboSell() 関数ローソク足の最大値にもとづくフィボナッチレベルで計算されるストップロス値のテーブルは以下のコードです。

//+----------------------------------------------------------------------+
//| 最初のローソク足高値にもとづくフィボナッチレベルを用いた                     |
//| 売りポジションのストップロス値を明示する関数(テーブル)                     |
//+----------------------------------------------------------------------+
 void StopLevelFiboSell()
   {
   if(High[1]<=Fb12 && High[1]>(Fb12+Fb11)/2)        newSL_S=Fb12+100*Point;
   if(High[1]<=Fb12 && High[1]>Fb11)                 newSL_S=Fb12;
   if(High[1]<=Fb11 && High[1]>Fb11+Fb10)            newSL_S=Fb11;
   if(High[1]<=Fb10 && High[1]>(Fb10+Fb9)/2)         newSL_S=(Fb11+Fb10)/2;
   if(High[1]<=Fb9  && High[1]>Fb8)                  newSL_S=(Fb10+Fb9)/2;
   if(High[1]<=Fb8  && High[1]>Fb7)                  newSL_S=Fb9;
   if(High[1]<=Fb7  && High[1]>MedVegas)             newSL_S=Fb8;
   if(High[1]<=MedVegas && High[1]>MedVegas)         newSL_S=Fb7;
   if(High[1]<=(MedVegas+Fb6)/2 && High[1]>Fb6)      newSL_S=MedVegas;
   if(High[1]<=Fb6  && High[1]>Fb5)                  newSL_S=MedVegas;
   if(High[1]<=Fb5  && High[1]>Fb4)                  newSL_S=Fb6;
   if(High[1]<=Fb4  && High[1]>Fb3)                  newSL_S=Fb5;
   if(High[1]<=Fb3  && High[1]>Fb2)                  newSL_S=Fb4;
   if(High[1]<=Fb2  && High[1]>(Fb2+Fb1)/2)          newSL_S=(Fb2+Fb3)/2;
   if(High[1]<(Fb2+Fb1)/2   && High[1]>Fb1)          newSL_S=Fb2;
   if(High[1]<Fb1)                                   newSL_S=(Fb2+Fb1)/2;
   }
//+------------------------------------------------------------------+

フィボナッチレベル計算関数を上記2つの属性関数に加えることが適切でしょう。それは添付のデモファイルにあります。

さて、2関数のコンビネーションあるいはこれらのレベルにおけるストップロスレベル識別関数のLevelFibo()計算関数を有効にすることを見ていきました。このコンビネーションは使えます。関数が一緒に機能します。これで、トレール中の関数呼び出し数が減りました。2つの変わりに1つは残るでしょうが。

コンビネーションすると、以下の通りになります。

//+----------------------------------------------------------------------+
//| 最初のローソク足安値にもとづくフィボナッチレベルを用いた                     |
//| 買いポジションのストップロス値を明示する関数(テーブル)                     |
//+----------------------------------------------------------------------+
   void StoplevelFiboBuy()
   {
   double Fb1,Fb2,Fb3,Fb4,Fb5,Fb6,Fb7,Fb8,Fb9,Fb10,Fb11,Fb12,Fb13;
   double Ma144_1 = iMA(NULL,0,144,0,MODE_EMA,PRICE_CLOSE,1);
   double Ma169_1 = iMA(NULL,0,169,0,MODE_EMA,PRICE_CLOSE,1);
   double MedVegas=NormalizeDouble((Ma144_1+Ma169_1)/2,Digits); 
   Fb1=MedVegas-377*Point;     Fb12=MedVegas+377*Point;
   Fb2=MedVegas-233*Point;     Fb11=MedVegas+233*Point;
   Fb3=MedVegas-144*Point;     Fb10=MedVegas+144*Point;
   Fb4=MedVegas-89*Point;      Fb9=MedVegas+89*Point;
   Fb5=MedVegas-55*Point;      Fb8=MedVegas+55*Point;
   Fb6=MedVegas-34*Point;      Fb7=MedVegas+34*Point;
   if(Low[1]>Fb12)                                newSL_B=Fb12-100*Point;
   if(Low[1]<=Fb12 && Low[1]>(Fb12+Fb11)/2)       newSL_B=(Fb12+Fb11)/2;
   if(Low[1]<=(Fb12+Fb11)/2 && Low[1]>Fb11)       newSL_B=Fb11;
   if(Low[1]<=Fb11 && Low[1]>(Fb11+Fb10)/2)       newSL_B=(Fb11+Fb10)/2;
   if(Low[1]<=(Fb10+Fb11)/2 && Low[1]>Fb10)       newSL_B=Fb10;
   if(Low[1]<=Fb10 && Low[1]>(Fb10+Fb9)/2)        newSL_B=Fb9;
   if(Low[1]<=(Fb10+Fb9)/2 && Low[1]>Fb9)         newSL_B=Fb8;
   if(Low[1]<=Fb9  && Low[1]>Fb8)                 newSL_B=Fb7;
   if(Low[1]<=Fb8  && Low[1]>Fb7)                 newSL_B=(Fb7+MedVegas)/2;
   if(Low[1]<=Fb7  && Low[1]>MedVegas)            newSL_B=Fb6;
   if(Low[1]<=MedVegas && Low[1]>(MedVegas+Fb6)/2)newSL_B=Fb6;
   if(Low[1]<=(MedVegas+Fb6)/2 && Low[1]>Fb6)     newSL_B=Fb5;
   if(Low[1]<=Fb6  && Low[1]>Fb5)                 newSL_B=Fb4;
   if(Low[1]<=Fb5  && Low[1]>Fb4)                 newSL_B=(Fb3+Fb4)/2;
   if(Low[1]<=Fb4  && Low[1]>Fb3)                 newSL_B=Fb3;
   if(Low[1]<=Fb3  && Low[1]>(Fb3+Fb2)/2)         newSL_B=(Fb3+Fb2)/2;
   if(Low[1]<=(Fb3+Fb2)/2  && Low[1]>Fb2)         newSL_B=Fb2;
   if(Low[1]<=Fb2  && Low[1]>(Fb2+Fb1)/2)         newSL_B=(Fb1+Fb2)/2;
   if(Low[1]<=(Fb2+Fb1)/2 && Low[1]>Fb1)          newSL_B=Fb1;
   if(Low[1]<=Fb1)                                newSL_B=Fb1-100*Point;
   }
// ----------------------------------------------------------------------+

ポジション・トレールのメインコマンド・コードを、現在バーのプライス値に関して、上記の関数を実行するためのシークエンスであるエキスパートアドバイザーのフラグメントとして表します。ステップ・バイ・ステップ・トレールは、適当なオープンオーダーを選択したらスタートします。

トレール・コードの短いフラグメントは以下の通りです。

//+------------------------------------------------------------------+
//| トレール・オープン・ポジション                                       |
//+------------------------------------------------------------------+
for(int i=OrdersTotal()-1; i>=0; i--)
  {
   if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
     {Print("オーダーセレクションエラー = ",GetLastError());}
   if(OrderSymbol()==Symbol())
     {
      if(OrderType()==OP_BUY)
        {
         if(OrderMagicNumber()==Magic)
           {
            // ----------------------------------------------------------------------+
            if((High[1]-OrderOpenPrice())>=SL_B*Point && OrderLots()==0.2)Close_B_lot();
            // ----------------------------------------------------------------------+
            if((High[1]-OrderOpenPrice())/Point>=100 && OrderLots()==0.1 && OrderStopLoss()<OrderOpenPrice())
              {
               Print(" 1 - ストップロスシフト");
               if(!OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()+2*Point,OrderTakeProfit(),0,Aqua))
                 {
                  Print(" オーダー修正 # ",OrderTicket()," エラー # ",GetLastError());
                 }
               return;
              }
            // ----------------------------------------------------------------------+
            if((High[1]-OrderOpenPrice())>=120*Point && OrderOpenPrice()>Ma144_1-144*Point)
              {
               StoplevelFiboBuy();
               newSL_B=newSL_B+21*Point;
               if((Bid-newSL_B)/Point<StopLevel)newSL_B=Bid-StopLevel*Point;
               if(newSL_B>OrderStopLoss() && (Bid-newSL_B)/Point>StopLevel)
                 {
                  Print("ストップロス2ndシフト");
                  Modyf_B_lot();
                 }
              }
            // ----------------------------------------------------------------------+
            if((High[1]-OrderOpenPrice())>=200*Point && (High[1]-OrderOpenPrice())<=250*Point)
              {
               StoplevelFiboBuy();
               if((Bid-newSL_B)/Point<StopLevel)newSL_B=Bid-StopLevel*Point;
               if(newSL_B>OrderStopLoss() && (Bid-newSL_B)/Point>StopLevel)
                 {
                  Print(" レベルオーダーによる3rdシフト # ",OrderTicket());
                  Modyf_B_lot();
                 }
              }
            // ----------------------------------------------------------------------+
            if((High[1]-OrderOpenPrice())>=250*Point && OrderOpenPrice()>Ma144_1-144*Point)
              {
               StoplevelFiboBuy();
               newSL_B=newSL_B+10*Point;
               if((Bid-newSL_B)/Point<StopLevel) newSL_B=Bid-StopLevel*Point;
               if(newSL_B>OrderStopLoss() && (Bid-newSL_B)/Point>StopLevel)
                 {
                  Print(" レベルオーダーによる4thシフト # ",OrderTicket());
                  Modyf_B_lot();
                 }
              }
            // ----------------------------------------------------------------------+
            if((High[1]-OrderOpenPrice())>=300*Point && (High[1]-OrderOpenPrice())<=350*Point)
              {
               StoplevelFiboBuy();
               newSL_B=newSL_B+20*Point;
               if((Bid-newSL_B)/Point<StopLevel) newSL_B=Bid-StopLevel*Point;
               if(newSL_B>OrderStopLoss() && (Bid-newSL_B)/Point>StopLevel)
                 {
                  Print(" オーダーレベルによる 5thシフト # ",OrderTicket());
                  Modyf_B_lot();
                 }
              }
            // ----------------------------------------------------------------------+
            ...
           }
        }
     }
  }

ステップバイステップトレールのシークエンスはデモ・エキスパートアドバイザーの添付バージョンにある8ステップで構成しています。

以下は買いポジショントレーリングのデモ・エキスパートアドバイザーがおこなうステップのスクリーンショットです。ポジションは"上げ三法"モデルが形成された事実にもとづきオープンされました。上げ三法を形成するローソク足の中に"反転のハンマー"あるのが分かりますね。このことが買いポジションをオープンするシグナルの信頼性を強めてくれます。


図6買いポジショントレールの例

"ベガス"インディケーターは白色背景画面のスクリーンショットにみえるフィボナッチラインのようなものです。MQL4のウェブサイトで見ることができます。: https://www.mql5.com/ja/code/7148

少しだけ横に引き伸ばされた黒色背景画面のスクリーンショットにも同じようなものが見えます。:

図7モニター画面のスクリーンショット(買いデモバージョン)

図8売りポジショントレールの例

デモ・エキスパートアドバイザーの運用を表示するために、仮のテスト用パラメータをインストールします。図9、10のとおりです。


図9Demo_trail_Buy.mql エキスパートアドバイザーテスト用パラメータ


図10Demo_trail_Sell.mql エキスパートアドバイザーテスト用パラメータ

注意: デモエキスパートアドバイザーと一緒にファイルが本稿に添付されています。買い・売りポジションをトレールするミニ・ロボットです。ここではポジションをダブルロットでオープンしています。しかしストップロスが利益・損失差し引きゼロのレベルまで到達すると、将来の値動きが正しい方向へむかい新たなポジションを追加する可能性もあることでしょう。


まとめ

紹介したオーダートレール例は、フィボナッチの動的レベルを用いたストップロスオーダーの移動方法が良い結果をもたらす、ということを示しています。この方法はトレードで実際に利用することをお勧めできます。

動的フィボナッチレベル識別関数:

  • LevelFiboKgd.mq4
  • StopLevelFiboBuy.mq4
  • StopLevelFiboSell.mq4
  • デモファイル:
  • Demo_trail_Buy_v1.mq4 – 買い用デモファイル
  • Demo_trail_Sell_v1.mq4 - 売り用デモファイル

MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/1349

添付されたファイル |
LevelFiboKgd.mq4 (1.96 KB)
MQL5 Market 一周年 MQL5 Market 一周年
MQL5 Marketがサービスを開始して、1年が経過しました。新しいサービスをMetaTrader5プラットフォームにおけるテクニカルインジケーターやトレーディングシステムの巨大ストアに変える困難な一年でした。
非標準タイムフレームでエキスパートアドバイザーをテストするには 非標準タイムフレームでエキスパートアドバイザーをテストするには
これは簡単なことではありません。”超”簡単なことです。非標準タイムフレームでエキスパートアドバイザーをテストすることは可能です!必要なことは、標準タイムフレームのデータを非標準タイムフレームのデータに置き換えることだけです。加えて、非標準タイムフレームのデータをいくつか使ってエキスパートアドバイザーをテストすることもできます。
MQL5クラウドネットワーク:まだ計算しているのですか? MQL5クラウドネットワーク:まだ計算しているのですか?
MQL5クラウドネットワークのサービスが開始してから、一年と半年ほど経過しました。この先進的な出来事はアルゴリズムによるトレーディングの新しい時代を開きました。今では、クリック数回で、トレーディング戦略の最適化のために自由に何千ものCPUを使用することができます。
MQL4を使ってRSSニュースフィードを読むには MQL4を使ってRSSニュースフィードを読むには
本稿は、HTMLタグ分析関数を使って、MQL4でRSSマークアップ言語を読む方法について書かれています。ニュース・インディケーターか、MQL4言語のRSSリーダーに使用することができるワークピースの作成にチャレンジします。