English Русский 中文 Español Deutsch Português
ユニバーサル Expert Advisor におけるトレードシグナルの送信

ユニバーサル Expert Advisor におけるトレードシグナルの送信

MetaTrader 4 | 17 2月 2016, 08:58
343 0
Igor Kim
Igor Kim

はじめに


私はいくらか前に"The Development of a Universal Expert Advisor"というテーマで Expert Advisor の開発プロセスを普遍化し分類しようと決めました。これは主要なユニットブリックの開発の一定の基準を考案することを意味し、それは後に建築キットのように Expert Advisor を構築するのに使用することができるものです。このタスクは部分的に実装されました。私はユニバーサルな EA のストラクチャと異なるインディケータのシグナルを普遍的に利用する考えを提示しました。本稿では、この作業を続行していきます。Expert Advisor におけるトレードシグナルとアイテム管理を形成し送信するプロセスを普遍化しようと思います。この文脈でアイテムとは処理 - 「売り」または「買い」、を指します。以降の話はすべてそういった処理を意味します。本稿は未決注文の「指値買い注文」、「指値売り注文」、「逆指値買い」には触れませんが、文末でこの私のアプローチ方法がそれらにも簡単に応用可能であることをお目にかけます。

トレードシグナルの分類


トレードシグナルには複数タイプがあります。

  1. 買い
  2. 売り
  3. 追加買い(平均化)
  4. 追加売り(平均化)
  5. 完全買いクローズ
  6. 完全売りクローズ
  7. 部分的買いクローズ
  8. 部分的売りクローズ

トレードシグナルのポジションとオーダー管理ユニットへの形成からの平均化と部分的クローズについての判断を変える場合、このリストは以下のように短くなります。

  1. 買い
  2. 売り
  3. 買いクローズ
  4. 売りクローズ
  5. ノーアクション(EA の通常処理はそのようなシグナルを必要とします)

こう仮定すると、EA の処理スキームは次のようになります。

  1. シグナルアイテムがトレードシグナルを作成します。
  2. トレードシグナルはポジション管理ユニットに入ります。それは新規オープン、平均化、部分的または完全クローズを判断し、短縮されたトレードシグナルをトレードシグナル処理のプログラムユニットに送信します。
  3. トレードシグナル処理ユニットは直接トレード処理を行います。

本稿では特に、トレードシグナル形成の異なる方法と、それをポジション管理ユニット、すなわちポイント1および2で説明されるユニット間のインターフェース、に送信する方法について述べます。


1 ポジションにおけるスイングトレード


そのようなトレードの意味は次のようなものです。:新規ポジションオープン前に前回ポジションはクローズしなければならない。新規ポジションは前ポジションとは逆である。全ポジションが買いであったら、売りをオープンする、またはその逆。この場合、ポジションオープンおよびクローズのタイミングは一致します。クローズシグナルが省略されるのはそのためです。よって、スイングトレードを実装するには、トレードシグナルを3つ送信するだけです。すなわち、売り、買い、なにもしない、の3つです。これらシグナルは int 変数を1つ使用して送信されます。たとえば以下です。

1 - 買い
0 - ノーアクション
-1 - 売り

そして市況分析とトレードシグナル作成が別の関数に書き込まれます。たとえば GetTradeSignal() です。

//+----------------------------------------------------------------------------+
//|  Returns trading signal:                                                   |
//|     1 - buy                                                                |
//|     0 - do nothing                                                         |
//|    -1 - sell                                                               |
//|  Parameters:                                                               |
//|    sym - name of the instrument ("" - current symbol)                      |
//|    tf  - timeframe                ( 0 - current timeframe)                 |
//+----------------------------------------------------------------------------+
int GetTradeSignal(string sym="", int tf=0)
  {
   int bs=0;
   if (sym=="") sym=Symbol();
 
   // Block of analysis assigning a value to the variable bs
 
   return(bs);
  }
//+----------------------------------------------------------------------------+

これは上述の整数値を返します。この関数のアクティブ化はポジション管理ユニットで直接ひじょうにに簡単に行われます。


//+----------------------------------------------------------------------------+
//|  Positions management                                                      |
//+----------------------------------------------------------------------------+
void ManagePositions() 
  {
   double sl=0, tp=0;
   int    bs=GetTradeSignal();
 
   if(bs>0) 
     {
      if(ExistPositions("", OP_SELL)) 
          ClosePositions("", OP_SELL);
      if(!ExistPositions("", OP_BUY))
        {
          if(StopLoss!=0)
              sl=Ask-StopLoss*Point;
          if(TakeProfit!=0) 
              tp=Ask+TakeProfit*Point;
          OpenPosition("", OP_BUY, sl, tp);
        }
     }
   if(bs<0)
     {
       if(ExistPositions("", OP_BUY)) 
           ClosePositions("", OP_BUY);
       if(!ExistPositions("", OP_SELL))
         {
           if(StopLoss!=0)
               sl=Bid+StopLoss*Point;
           if(TakeProfit!=0) 
               tp=Bid-TakeProfit*Point;
           OpenPosition("", OP_SELL, sl, tp);
         }
     }
  }
//+----------------------------------------------------------------------------+

この場合、整数タイプの単独ローカル変数 bs が 2 つのプログラムユニット間のリンカの役割を果たします。1 ポジションによるスイングトレード向け例のソースコードのテキスト全体はファイル e-SampleSwing.mq4 にあります。



1 ポジションにおけるシンプルなトレーディング


このケースはもう少し複雑です。マーケットで各時点においてポジションがただ 1 つだけであったとしても、そのクローズは別のポジションのオープンと関連はありません。正常なポジション管理にシグナルを5種類、すなわち売り、買い、買いクローズ、売りクローズ、ノーアクション、のすべてが必要なのはそのためです。それらは割り当てられた以下の値の整数タイプの変数1つで送信されます。

2 - 売りポジションクローズ


1 - 買い


0 - ノーアクション


-1 - 売り


-2 - 買いポジションクローズ



ポジション管理ユニットは 1 つの関数に書き込まれます。

//+----------------------------------------------------------------------------+
//|  Positions management                                                      |
//+----------------------------------------------------------------------------+
void ManagePositions() 
  {
    double sl=0, tp=0;
    int    bs=GetTradeSignal();
 
    if(ExistPositions()) 
      {
        if(bs==2) 
            ClosePositions("", OP_SELL);
        if(bs==-2) 
            ClosePositions("", OP_BUY);
      } 
    else 
      {
        if(bs==1) 
          {
            if(StopLoss!=0) 
                sl=Ask-StopLoss*Point;
            if(TakeProfit!=0) 
                tp=Ask+TakeProfit*Point;
            OpenPosition("", OP_BUY, sl, tp);
          }
        if(bs==-1) 
          {
            if(StopLoss!=0) 
                sl=Bid+StopLoss*Point;
            if(TakeProfit!=0) 
                tp=Bid-TakeProfit*Point;
            OpenPosition("", OP_SELL, sl, tp);
          }
      }
  }
//+----------------------------------------------------------------------------+

1 ポジションによるシンプルなトレード向け例のソースコードのテキスト全体はファイル e-SampleSimple.mq4 にあります。

1変数にトレードシグナルを送信することのデメリットは同時に複数シグナルを送信することができない点です(シリアルインターフェースのデメリット)。たとえべば、両方向をオープンすることはできない、既存ポジションのクローズと同時にオープンできない、前ポジションをクローズすることができない、などです。1 つのシグナルを 2 つの整数に分割することで部分的にこのデメリットを取り除くことは可能です。

シグナル分割方法は 3 とおりあります。

  1. 1 つの変数でオープンし、別の変数でクローズする。オープンとクローズを組合せることができます。すなわち、スイングトレードを行うことができるのですが、両方向をオープンしたり、逆方向のポジションをクローズすることはできません。
  2. 「買い」ポジション(オープンおよびクローズ)は1つの変数で、「売り」ポジション(オープンおよびクローズ)は別の変数とする。両方向でポジションをオープンし、全ポジションを一度にクローズすることができますが、同時にオープンとクローズを行うことはできません。たとえば、売りまたは買いポジション、すなわち再オープンは不可です。
  3. 1つの変数で「買い」をオープンし「売り」をクローズし、別の変数で「売り」をオープンし「買い」をクローズする。両方向をオープンし、全ポジションをクローズすることができますが、スイングトレードは行うことができません。

2 番目のバリアントを実装してみます。というのも再オープンはかなり稀であるためです。スプレッドで資金を失いたい人はいません。2 番目のバリアントを実装する方法は複数あります。

1. 2 とおりの関数が 2 つのローカル変数に値を返す。1 つの関数が買いシグナルを作成し、2 番目の関数が売りシグナルを作成します。

//+----------------------------------------------------------------------------+
//|  Returns trading signal for long positions:                                |
//|     1 - buy                                                                |
//|     0 - do nothing                                                         |
//|    -1 - close BUY                                                          |
//|  Parameters:                                                               |
//|    sym - name of the instrument ("" - current symbol)                      |
//|    tf  - timeframe                ( 0 - current timeframe)                 |
//+----------------------------------------------------------------------------+
int GetTradeSignalBuy(string sym="", int tf=0)
  {
    int bs=0;
    if(sym=="")
        sym=Symbol();
 
    // Block of analysis assigning a value to the variable bs
 
    return(bs);
  }
 
//+----------------------------------------------------------------------------+
//|  Returns trading signal for short positions:                               |
//|     1 - sell                                                               |
//|     0 - do nothing                                                         |
//|    -1 - close SELL                                                         |
//|  Parameters:                                                               |
//|    sym - name of the instrument ("" - current symbol)                      |
//|    tf  - timeframe                ( 0 - current timeframe)                 |
//+----------------------------------------------------------------------------+
int GetTradeSignalSell(string sym="", int tf=0)
  {
    int bs=0;
    if(sym=="")
        sym=Symbol();
 
    // Block of analysis assigning a value to the variable bs
 
    return(bs);
  }
 
//+----------------------------------------------------------------------------+
//|  Positions management                                                      |
//+----------------------------------------------------------------------------+
void ManagePositions()
  {
    double sl=0, tp=0;
    int    bs=GetTradeSignalBuy();
    int    ss=GetTradeSignalSell();
 
    if(ExistPositions())
      {
        if(bs<0)
            ClosePositions("", OP_BUY);
        if(ss<0)
            ClosePositions("", OP_SELL);
      }
    if(!ExistPositions())
      {
        if(bs>0)
          {
            if(StopLoss!=0)
                sl=Ask-StopLoss*Point;
            if(TakeProfit!=0)
                tp=Ask+TakeProfit*Point;
            OpenPosition("", OP_BUY, sl, tp);
          }
        if(ss>0)
          {
            if(StopLoss!=0)
                sl=Bid+StopLoss*Point;
            if(TakeProfit!=0)
                tp=Bid-TakeProfit*Point;
            OpenPosition("", OP_SELL, sl, tp);
          }
      }
  }
//+----------------------------------------------------------------------------+

これはトレードシグナルを作成し送信するのにシンプルで便利な方法ですが、シグナルユニットは2種類の関数に分割され、そのことでおそらく処理速度は落ちることでしょう。



2. 2 つのグローバル変数が 1 つの関数の値を取得する。

//+----------------------------------------------------------------------------+
BuySignal=0;
SellSignal=0;
 
//+----------------------------------------------------------------------------+
//|  Creates trading signals.                                                  |
//|  Parameters:                                                               |
//|    sym - name of the instrument ("" - current symbol)                      |
//|    tf  - timeframe              ( 0 - current timeframe)                   |
//+----------------------------------------------------------------------------+
void FormTradeSignals(string sym="", int tf=0)
  {
    if(sym=="") sym=Symbol();
 
    // Block of analysis assigning a value to the variable BuySignal and SellSignal
  }
 
//+----------------------------------------------------------------------------+
//|  Positions management                                                      |
//+----------------------------------------------------------------------------+
void ManagePositions()
  {
    double sl=0, tp=0;
 
    FormTradeSignals();
    if(ExistPositions())
      {
        if(BuySignal<0)
            ClosePositions("", OP_BUY);
        if(SellSignal<0)
            ClosePositions("", OP_SELL);
      }
    if(!ExistPositions())
      {
        if(BuySignal>0)
          {
            if(StopLoss!=0)
                sl=Ask-StopLoss*Point;
            if(TakeProfit!=0)
                tp=Ask+TakeProfit*Point;
            OpenPosition("", OP_BUY, sl, tp);
          }
        if(SellSignal>0)
          {
            if(StopLoss!=0)
                sl=Bid+StopLoss*Point;
            if(TakeProfit!=0)
                tp=Bid-TakeProfit*Point;
            OpenPosition("", OP_SELL, sl, tp);
          }
      }
  }
//+----------------------------------------------------------------------------+

このソースコードから明らかなのは、グローバル変数の理解は最初の方法とたいして変わらないことです。明確なメリットはシグナルモードが1つの関数内にあることです。



3. 2 つのローカル変数が参照によって 1 つの関数に渡される。

//+----------------------------------------------------------------------------+
//|  Returns trading signals.                                                  |
//|  Parameters:                                                               |
//|    bs  - BUY signal                                                        |
//|    ss  - SELL signal                                                       |
//|    sym - name of the instrument ("" - current symbol)                      |
//|    tf  - timeframe                ( 0 - current timeframe)                 |
//+----------------------------------------------------------------------------+
void GetTradeSignals(int& bs, int& ss, string sym="", int tf=0)
  {
    if(sym=="")
        sym=Symbol();
 
    // Block of analysis assigning a value to variables bs and ss
  }
 
//+----------------------------------------------------------------------------+
//|  Positions management                                                      |
//+----------------------------------------------------------------------------+
void ManagePositions()
  {
    double sl=0, tp=0;
    int    bs=0, ss=0;
 
    GetTradeSignals(bs, ss);
    if(ExistPositions())
      {
        if(bs<0)
            ClosePositions("", OP_BUY);
        if(ss<0)
            ClosePositions("", OP_SELL);
      }
    if(!ExistPositions())
      {
        if(bs>0)
          {
            if(StopLoss!=0)
                sl=Ask-StopLoss*Point;
            if(TakeProfit!=0)
                tp=Ask+TakeProfit*Point;
            OpenPosition("", OP_BUY, sl, tp);
          }
        if(ss>0)
          {
            if(StopLoss!=0)
                sl=Bid+StopLoss*Point;
            if(TakeProfit!=0)
                tp=Bid-TakeProfit*Point;
            OpenPosition("", OP_SELL, sl, tp);
          }
      }
  }
//+----------------------------------------------------------------------------+

4. 2エレメントの配列それがグローバルであれば、関数内部で初期化されます。ローカルであれば、参照により渡されます。ここではすべてが簡単です。2つの変数の代わりに1つの配列というわけです。参照によるグローバルエレメントとローカルエレメントについては前にお話し済みです。新しいことは何もありません。

そして最後に、トレードシグナルを送信し、それを4つの変数に分けるフルバリューの並列インターフェースを作成します。ポジション管理のためにシグナルはすべて2つの上阿智を持ちます。:存在または不在です。論理タイプの変数を取り上げるのはそのためです。シグナルを組合せ、4つの変数を使用して無制限にそれを送信することが可能です。以下は論理タイプのエレメント 4 つの配列を持つコード例です。

//+----------------------------------------------------------------------------+
//|  Returns trading signals.                                                  |
//|  Parameters:                                                               |
//|    ms  - array of signals                                                  |
//|    sym - name of the instrument ("" - current symbol)                      |
//|    tf  - timeframe                ( 0 - current timeframe)                 |
//+----------------------------------------------------------------------------+
void GetTradeSignals(bool& ms[], string sym="", int tf=0)
  {
    if(sym=="")
        sym=Symbol();
 
    // Block of analysis filling ms array:
    // ms[0]=True;   // Buy
    // ms[1]=True;   // Sell
    // ms[2]=True;   // Close Buy
    // ms[3]=True;   // Close Sell
  }
 
//+----------------------------------------------------------------------------+
//|  Positions management                                                      |
//+----------------------------------------------------------------------------+
void ManagePositions()
  {
    bool   ms[4]={False, False, False, False};
    double sl=0, tp=0;
 
    GetTradeSignals(ms);
    if(ExistPositions())
      {
        if(ms[2])
            ClosePositions("", OP_BUY);
        if(ms[3])
            ClosePositions("", OP_SELL);
      }
    if(!ExistPositions())
      {
        if(ms[0])
          {
            if(StopLoss!=0)
                sl=Ask-StopLoss*Point;
            if(TakeProfit!=0)
                tp=Ask+TakeProfit*Point;
            OpenPosition("", OP_BUY, sl, tp);
          }
        if(ms[1])
          {
            if(StopLoss!=0)
                sl=Bid+StopLoss*Point;
            if(TakeProfit!=0)
                tp=Bid-TakeProfit*Point;
            OpenPosition("", OP_SELL, sl, tp);
          }
      }
  }
//+----------------------------------------------------------------------------+

ローカル変数を用いた実装、1つの関数への参照による受け渡し、グローバル変数を用いて1つの関数内での初期化により問題が発生することはありません。ただし、値による4つのローカル変数の初期化、4つの異なる関数による返しはとても合理的とは言えません。



メインポジションのサポート


シグナルがやってくると、ポジションが 1 つオープンします。それがメインポジションとなります。メインポジションに対する他のシグナルエントリーはすべて無視されます。追加ポジションはシグナルにオープンされ、メインポジションに対応しています。メインポジションのクローズ時には、すべての追加ポジションもクローズします。

この方法に対するトレードシグナル送信は1、2、または4つの変数を使用して実装されます。これはすべて以前にお話し済みです。出会う可能性のある問題は、連携の成立方法です。:1つのシグナルのあるポジションへの連携です。1ポジションにおけるトレードの場合、この問題は関数 ExistPositions() を用いてポジションの存在を単に確認することで解決しました。ポジションが存在すれば、エントランスシグナルは省略され、ポジションが存在しなければ、エントランスシグナルが処理されるのです。

異なる方法があります。

  1. エントランスの間にポーズを設ける。もっとも簡単な実現方法;
  2. 1バー - 1 エントランス。最初の方法のバリエーション実現はこれも簡単です。
  3. シグナル列挙、シグナルの配列とオーダーのティック制御。これは信頼性に疑問のあるもっとも難しい実装です。

以下は最初の方法についてのコード例です。

//+----------------------------------------------------------------------------+
extern int PauseBetweenEntrys=3600;    // Pause between entrances in seconds
 
//+----------------------------------------------------------------------------+
//|  Positions management                                                      |
//+----------------------------------------------------------------------------+
void ManagePositions()
  {
    bool   ms[4]={False, False, False, False};
    double sl=0, tp=0;
 
    GetTradeSignals(ms);
    if(ExistPositions())
      {
        if(ms[2])
            ClosePositions("", OP_BUY);
        if(ms[3])
            ClosePositions("", OP_SELL);
      }
    if(SecondsAfterOpenLastPos()>=PauseBetweenEntrys)
      {
        if(ms[0])
          {
            if(StopLoss!=0)
                sl=Ask-StopLoss*Point;
            if(TakeProfit!=0)
                tp=Ask+TakeProfit*Point;
            OpenPosition("", OP_BUY, sl, tp);
          }
        if(ms[1])
          {
            if(StopLoss!=0)
                sl=Bid+StopLoss*Point;
            if(TakeProfit!=0)
                tp=Bid-TakeProfit*Point;
            OpenPosition("", OP_SELL, sl, tp);
          }
      }
  }
 
//+----------------------------------------------------------------------------+
//|  Returns number of seconds after the last position is opened.              |
//|  Parameters:                                                               |
//|    sym - name of the instrument ("" - current symbol)                      |
//|    op  - operation              (-1 - any position)                        |
//|    mn  - MagicNumber            (-1 - any magic number)                    |
//+----------------------------------------------------------------------------+
datetime SecondsAfterOpenLastPos(string sym="", int op=-1, int mn=-1)
  {
    datetime oot;
    int      i, k=OrdersTotal();
 
    if(sym=="") sym=Symbol();
        for(i=0; ik; i++)
          {
            if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
              {
                if(OrderSymbol()==sym)
                  {
                    if(OrderType()==OP_BUY || OrderType()==OP_SELL)
                      {
                        if(op0 || OrderType()==op)
                          {
                            if(mn0 || OrderMagicNumber()==mn)
                              {
                                if(ootOrderOpenTime())
                                    oot=OrderOpenTime();
                              }
                          }
                      }
                 }
             }
        }
      return(CurTime()-oot);
  }
//+----------------------------------------------------------------------------+

メインポジションのサポートを持つ方法向けソースコード例のフルテキストはファイル e-SampleMain.mq4 にあります。


平均化を伴うスイングトレード


エントランスシグナルがやってくると、ポジションが 1 つオープンします。最初のポジションの方向にある以降のシグナルすべてを基に新しい追加ポジションがオープンします。既存ポジションの逆方向のシグナルが来ると、ポジションはすべてクローズし、シグナル方向のポジションが1つオープンします。トレードシグナルは繰り返します。

1ポジションにおけるスイングトレードに対するトレードシグナルの送信と実行についてお話してきました。この例を採用して追加ポジションをオープンするオプション実装を行います。1シグナル - 1ポジションの連携を行うために、1バーの期間によるエントランス可能性に制限を行います。1バー - 1 エントランス。

//+----------------------------------------------------------------------------+
//|  Positions management                                                      |
//+----------------------------------------------------------------------------+
void ManagePositions()
  {
    double sl=0, tp=0;
    int    bs=GetTradeSignal();
 
    if(bs>0)
      {
        if(ExistPositions("", OP_SELL))
            ClosePositions("", OP_SELL);
        if(NumberOfBarLastPos()>0)
          {
            if(StopLoss!=0)
                sl=Ask-StopLoss*Point;
            if(TakeProfit!=0)
                tp=Ask+TakeProfit*Point;
            OpenPosition("", OP_BUY, sl, tp);
          }
      }
    if(bs<0)
      {
        if(ExistPositions("", OP_BUY))
            ClosePositions("", OP_BUY);
        if(NumberOfBarLastPos()>0)
          {
            if(StopLoss!=0)
                sl=Bid+StopLoss*Point;
            if(TakeProfit!=0)
                tp=Bid-TakeProfit*Point;
            OpenPosition("", OP_SELL, sl, tp);
          }
      }
  }
 
//+----------------------------------------------------------------------------+
//|  Returns the bar number of the last position opening or -1.                |
//|  Parameters:                                                               |
//|    sym - name of the instrument ("" - current symbol)                      |
//|    tf  - timeframe                ( 0 - current timeframe)                 |
//|    op  - operation                (-1 - any position)                      |
//|    mn  - MagicNumber              (-1 - any magic number)                  |
//+----------------------------------------------------------------------------+
int NumberOfBarLastPos(string sym="", int tf=0, int op=-1, int mn=-1)
  {
    datetime oot;
    int      i, k=OrdersTotal();
 
    if(sym=="")
        sym=Symbol();
    for(i=0; ik; i++)
      {
        if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
          {
            if(OrderSymbol()==sym)
              {
                if(OrderType()==OP_BUY || OrderType()==OP_SELL)
                  {
                    if(op0 || OrderType()==op)
                      {
                        if(mn0 || OrderMagicNumber()==mn)
                          {
                            if(ootOrderOpenTime()) oot=OrderOpenTime();
                          }
                      }
                  }
             }
         }
     }
   return(iBarShift(sym, tf, oot, True));
  }
//+----------------------------------------------------------------------------+

平均化を伴うスイングトレード向け例のソースコードのテキスト全体はファイル e-SampleSwingAdd.mq4 にあります。


ポートフォリオ戦術


トレードシグナルそれぞれに対してはポジションが1つオープンし、他のポジションに関係なくサポートされます。

一目でこれはソフトウェアの実装面ではトレードシグナル実行のもっとも複雑なバリアントです。トレードシグナル送信以外に、ここでは1ポートフォリオまたは別のポートフォリオへのシグナル所属を送信する必要があります。ただし、シグナルをポートフォリオを構成するグループに分ける場合、個別グループはシンプルな1ポジションのトレードです。グループを1ポートフォリオにコンバインする方法は明確です。:各グループにユニークな番号を付け、サイクル内で全グループの検索を設定します。以下が4つのシグナルグループ例です。

//+----------------------------------------------------------------------------+
//|  Returns trading signals.                                                  |
//|  Parameters:                                                               |
//|    ms  - array of signals                                                  |
//|    ns  - number of a signal                                                |
//|    sym - name of the instrument ("" - current symbol)                      |
//|    tf  - timeframe              ( 0 - current timeframe)                   |
//+----------------------------------------------------------------------------+
void GetTradeSignals(bool& ms[], int ns, string sym="", int tf=0)
  {
    if (sym=="") sym=Symbol();
 
    // Switching signal groups using operators switch or if
    // Block of analysis fulfilling the array ms:
    // ms[0]=True;   // Buy
    // ms[1]=True;   // Sell
    // ms[2]=True;   // Close Buy
    // ms[3]=True;   // Close Sell
  }
 
//+----------------------------------------------------------------------------+
//|  Positions management                                                      |
//+----------------------------------------------------------------------------+
void ManagePositions()
  {
    bool   ms[4];
    double sl=0, tp=0;
    int    i;
 
    for(i=0; i4; i++)
      {
        ArrayInitialize(ms, False);
        GetTradeSignals(ms, i);
        if(ExistPositions("", -1, MAGIC+i))
          {
            if(ms[2]) ClosePositions("", OP_BUY, MAGIC+i);
            if(ms[3]) ClosePositions("", OP_SELL, MAGIC+i);
          }
        if(!ExistPositions("", -1, MAGIC+i))
          {
            if(ms[0])
              {
                if(StopLoss!=0)
                    sl=Ask-StopLoss*Point;
                if(TakeProfit!=0)
                    tp=Ask+TakeProfit*Point;
                OpenPosition("", OP_BUY, sl, tp, MAGIC+i);
              }
            if(ms[1])
              {
                if(StopLoss!=0)
                    sl=Bid+StopLoss*Point;
                if(TakeProfit!=0)
                    tp=Bid-TakeProfit*Point;
                OpenPosition("", OP_SELL, sl, tp, MAGIC+i);
              }
          }
      }
  }
//+----------------------------------------------------------------------------+

プロファイル戦術向け例のソースコードのテキスト全体はファイル e-SampleCase.mq4 にあります。


オーダー用トレードシグナル


未決注文の処理に必要なトレードシグナルのリストを見ます。

  1. 指値買い注文設定
  2. 指値売り注文設定
  3. 逆指値買い設定
  4. 逆指値売り設定
  5. 指値買い注文削除
  6. 指値売り注文削除
  7. 逆指値買い削除
  8. 逆指値売り削除
  9. 指値買い注文修正
  10. 指値売り注文修正
  11. 逆指値買い修正
  12. 逆指値売り修正

未決注文では同時に4件以上のトレードシグナルを送信したいと思うのは簡単に推測できます。EA の論理がポジションとオーダーの両方の処理を必要とすればどうなるでしょうか?

以下は拡張した全トレードシグナルの完全なリストです。

  1. 買いオープン
  2. 売りオープン
  3. 指値買い注文設定
  4. 指値売り注文設定
  5. 逆指値買い設定
  6. 逆指値売り設定
  7. 買いクローズ
  8. 売りクローズ
  9. 指値買い注文削除
  10. 指値売り注文削除
  11. 逆指値買い削除
  12. 逆指値売り削除
  13. 指値買い注文修正
  14. 指値売り注文修正
  15. 逆指値買い修正
  16. 逆指値売り修正

16とおりものトレードシグナルです!2バイトです!バイナリナンバーとしてシグナル送信をする考え方もありますが、それは文字列において、です。たとえば、 00101... でここではポジションゼロまたはポジション 1 が一定のシグナルを管理することになります。ただし、サブ文字列やシグナルのデコードにはいろいろややこしい可能性があります。そのため、もっとも便利な解決法はシグナル数に等しいエレメント番号を持つ配列です。その上、配列エレメントをもっと便利に参照するにはインデックスを定数として定義することです。MQL4 にはすでに OP_BUY, OP_SELL などが入っています。簡単に続けることができます。

#define OP_CLOSEBUY         6
#define OP_CLOSESELL        7
#define OP_DELETEBUYLIMIT   8
#define OP_DELETESELLLIMIT  9
#define OP_DELETEBUYSTOP   10
#define OP_DELETESELLSTOP  11
#define OP_MODIFYBUYLIMIT  12
#define OP_MODIFYSELLLIMIT 13
#define OP_MODIFYBUYSTOP   14
#define OP_MODIFYSELLSTOP  15

そして配列エレメント:ms[0] and ms[13] の代わりに、ms[OP_BUY] または ms[OP_MODIFYSELLLIMIT] を参照します。これは好みの問題です。私は簡潔でシンプルなコードを好ましく思います。それが数字を選ぶ理由です。

続けます。すべて簡単でうまくいっているようです!が、設定オーダーの価格レベル、ポジションに対するストップおよびテイクプロフィットレベルも必要です。というのも、トレードシグナルはどれも特定のストップおよびテイクプロフィット、オーダー設定の価格レベルに関する情報を持つためです。ただ、トレードシグナルと一緒にこの情報を渡す方法は?私は次のような解決方法を提供します。

  1. シグナル数に等しい行番号と 3 列を持つ二次元配列を宣言します。
  2. 第1列はシグナル不在の場合、ゼロ値を指し、ポジション(オーダー設定の価格レベル)に対するシグナルが存在する場合はゼロ値以外を指します。
  3. 第2列はストップです。
  4. 第3列はテイクプロフィットレベルです。

オーダーを持つトレードのソースコード例のフルテキストはファイル e-SampleOrders.mq4 にあります。

指値買い注文、指値売り注文が複数必要な場合はどうなるのでしょうか?そしてポジションをオープンするには?このような場合、本稿『ポートフォリオ戦術』項で説明した通りを行います。すなわち、ポジションを持つプロフィール戦術とマジックナンバーによるオーダー特定を行うのです。

おわりに


まとめます。

  1. 変数を1つ用いてシグナル送信を行うことには、いくらかシリアルインターフェースのデメリットがあります。それは各時点で単独のシグナルしか送信できないことです。
  2. 並列インターフェースの実装は、大きな数値の変数に導き、その管理を複雑にしますが、同時に数十のシグナル送信が可能となります。

よって、1つ、また別のトレードシグナル送信方法の使用は都合によって判断すべきです。


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

添付されたファイル |
b-Positions.mqh (20.13 KB)
e-SampleCase.mq4 (7.12 KB)
e-SampleMain.mq4 (7.94 KB)
e-SampleOrders.mq4 (14.71 KB)
e-SampleSimple.mq4 (6.88 KB)
トレーダー個々の心理状態 トレーダー個々の心理状態
金融マーケットにおけるトレーダーのふるまいのポートレートA. Elder.著"Как играть и выигрывать на бирже(『証券取引の投機方法と勝利方法』)"からの私独自のメニュー
最適化の罠にはまらない方法? 最適化の罠にはまらない方法?
本稿はテスターの最適化結果をよりよく理解する方法のメソッドについて説明します。また『有害な最適化』を避けるアドバイスも提供します。
Linux を利用したトレーディング Linux を利用したトレーディング
本稿ではオンラインで金融市場の状況を見守るためのインディケータの使用法を説明します。
Linux デスクトップでの MetaTrader 4 クライアントターミナル実行 Linux デスクトップでの MetaTrader 4 クライアントターミナル実行
MetaTrader 4 クライアントターミナルをそこで実行するために非エミュレータワインを用いた段階的な Linux デスクトップ設定の説明