初心者の方からの質問 MQL5 MT5 MetaTrader 5 - ページ 1207

 

mql5 (ヘッジ)

2つの条件下でポジションを 閉じる アルゴリズムを実装するには?

1ケース2つのポジションが開いている場合、より多くの利益がある方を閉じる...2ケース。2つ以上のオープンポジションがある場合、...の値を平均してクローズします。

今、私はこれらのポジションを閉じるために2つの方法を持っています。

1の場合、利益でポジションを比較し、より多くの利益を得た方を決済します。2の場合、平均化により、すべてのポジションをエクイティで決済します。

これらの方法は別々にうまく機能しますが、2つの事象のうちの1つが両方の方法の分布に該当するため、一緒に使うことはできません。

なんとか切り離すことができない。その結果、両案件ともほぼエクイティで、すべてのポジションをクローズしています。このため、最初のケースでは、目的のポジションを削除して開き直すことになります。

その結果見開き2枚、ダブルコミッション。悔しいです)))

注文やポジションを設定する仕組みは次のようになります。SELL用(さらにSELL 用のみ)。

指値注文。販売限度額(SELL_LIMIT

の位置づけになります。売り(常に注文と注文の間)

ストップオーダー販売停止

図表を添付します。

ポジションをクローズする。

1. ストップオーダーが発動された 場合、つまり2つ以上のポジションが同時に表示された場合、より高い利益を上げている1つのポジションを決済する必要があります...(20)

2.指値 注文が発動された場合、つまり2つ以上のポジションが同時に開かれた場合、それらの平均値(by Equity)はクローズされるべき... (15)

質問です。この2つのメソッドを分離して、それぞれのイベントだけを処理するようにするにはどうしたらよいでしょうか?

もしかしたら、この2つの条件を処理する他の方法があるのかもしれません。

私が使っている手法の例

//+---------------------------------------------------------------------+
//|  -- ЗАКРЫВАЕМ ОДНУ ИЗ ДВУХ ПОЗИЦИЙ С НИЗУ, ГДЕ ПРОФИТ БОЛЬШЕ ЧЕМ ---|
//+---------------------------------------------------------------------+ 
ulong ticket_n=ULONG_MAX;  double profit=DBL_MIN;

     if(invert_close == true) //Проверка на наличие 2х и более поз.
     {
     int positions=PositionsTotal();
     for(int i=PositionsTotal()-1; i>=0; i--)
     {
     ulong tmp_ticket=PositionGetTicket(i);
     if(ticket_n!=0)
     {
     double tmp_profit=PositionGetDouble(POSITION_PROFIT);
     if(tmp_profit>profit+Prof_eqw_niz)// допустим 20
     {
     ticket_n=tmp_ticket;
     profit=tmp_profit;
     }
     }
     }
//-----------
     if(ticket_n!=ULONG_MAX)
     m_trade.PositionClose(ticket_n);
     invert_close = false;
     Print("------  ЗАКРЫЛИ ТОЛСТУЮ ---------");
     }       

//+---------------------------------------------------------------------+
//|                     Э К В И Т И   ДЛЯ SELL_LIMIT                    |
//+---------------------------------------------------------------------+
   npos_ALL=0; NPos_ALL(npos_ALL);
   if (npos_ALL>=Metod_Eqw && m_account.Equity()>= m_account.Balance()+Prof_eqw)//Допустим 15
   {
   CloseAllPositions();
   Print("------  ЗАКРЫЛИ ВСЕ ---------");
   }
Совершение сделок - Торговые операции - Справка по MetaTrader 5
Совершение сделок - Торговые операции - Справка по MetaTrader 5
  • www.metatrader5.com
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением текущими позициями путем их модификации или закрытия. Платформа позволяет удобно просматривать торговую историю на счете, настраивать оповещения о событиях на рынке и многое другое. Открытие позиций...
ファイル:
 
Vladpedro:


ポジションはEAが動作するシンボルで開かれるのですか?マジックナンバーは使われていますか?
 
Vladimir Karputov:
ポジションはEAが動作するシンボルで開かれるのですか?マジックナンバーを使用

はい、現在のシンボルで。 はい、マジックを使用します。

 
Vladpedro:

はい、現在のキャラクターで。 はい、マジックを使用します。

2つ目の条件について説明します。(2つ以上のポジションが開いている場合は、その値の平均値で閉じる...)

 
Vladimir Karputov:

2つ目の条件について説明してください。(2つ以上のポジションが開いている場合、その値の平均でクローズ します。)

つまり、2つ以上のポジションが開いていて、純資産が残高よりも 任意の値(例えば15)だけ大きい場合、すべてのポジションがクローズされます。

例えば、3つのポジションを開設し、1つ目のポジションは現在の損失が-10、2つ目のポジションは利益が-5、3つ目のポジションは利益が+30、合計+15で、すべてのポジションを決済することができます。

平均利益が+15に達しない場合、ポジションはそれぞれの設定されたSLまたはTPで閉じられます。(これはポジションを閉じるための 第3の条件のようなものですが、特に問題はないので省略しました)。

 
Vladpedro:

つまり、2つ以上のポジションが開いていて、純資産が残高よりも 任意の値(例えば15)だけ大きい場合、すべてのポジションがクローズされます。

例えば、3つのポジションが開いており、1つ目のポジションは現在の損失が-10、2つ目のポジションは利益が-5、3つ目のポジションは+30+合計が+15で、すべてのポジションを閉じることができます。

平均利益が+15に達しない場合、ポジションはそれぞれの設定されたSLまたはTPで閉じられます。(これはポジションを閉じるための 第三の条件のようなものですが、特に問題はないので省略しました)。

以下は、2つの条件でのコードの全容です。

//+------------------------------------------------------------------+
//|                                       Closing Two conditions.mq5 |
//|                              Copyright © 2020, Vladimir Karputov |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2020, Vladimir Karputov"
#property version   "1.00"
/*
   barabashkakvn Trading engine 3.116
*/
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
//---
CPositionInfo  m_position;                   // object of CPositionInfo class
CTrade         m_trade;                      // object of CTrade class
CSymbolInfo    m_symbol;                     // object of CSymbolInfo class
//--- input parameters
input double   InpProfitTarget      = 15;       // Profit target, in deposit money (if Positions > 2)
input ulong    InpDeviation         = 10;       // Deviation, in points (1.00045-1.00055=10 points)
input ulong    InpMagic             = 200;      // Magic number
//---
bool     m_need_close_all           = false;    // close all positions
ulong    m_need_close_ticket        = ULONG_MAX;// close one position
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(!m_symbol.Name(Symbol())) // sets symbol name
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: CSymbolInfo.Name");
      return(INIT_FAILED);
     }
//---
   m_trade.SetExpertMagicNumber(InpMagic);
   m_trade.SetMarginMode();
   m_trade.SetTypeFillingBySymbol(m_symbol.Name());
   m_trade.SetDeviationInPoints(InpDeviation);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(m_need_close_all)
     {
      if(IsPositionExists())
        {
         CloseAllPositions();
         return;
        }
      else
         m_need_close_all=false;
     }
//---
   if(m_need_close_ticket!=ULONG_MAX)
     {
      //--- close one position
      if(m_position.SelectByTicket(m_need_close_ticket))
        {
         m_trade.PositionClose(m_need_close_ticket); // close a position
         return;
        }
      else
         m_need_close_ticket=ULONG_MAX;
     }
//--- calculate all positions
   int total=0;
   for(int i=PositionsTotal()-1; i>=0; i--)
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
            total++;

   if(total==2)
     {
      //--- conditon 1
      ulong tmp_ticket=ULONG_MAX;
      double tmp_profit=DBL_MIN;
      for(int i=PositionsTotal()-1; i>=0; i--)
         if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
            if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
              {
               double profit=m_position.Commission()+m_position.Swap()+m_position.Profit();
               if(profit>tmp_profit)
                 {
                  tmp_profit=profit;
                  tmp_ticket=m_position.Ticket();
                 }
              }
      //---
      if(tmp_ticket!=ULONG_MAX)
         m_need_close_ticket=tmp_ticket;
     }
   else
     {
      if(total>2)
        {
         //--- conditon 2
         double profit=0;
         for(int i=PositionsTotal()-1; i>=0; i--)
            if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
               if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
                  profit+=m_position.Commission()+m_position.Swap()+m_position.Profit();
         //---
         if(profit>=InpProfitTarget)
            m_need_close_all=true;
        }
     }
  }
//+------------------------------------------------------------------+
//| Is position exists                                               |
//+------------------------------------------------------------------+
bool IsPositionExists(void)
  {
   for(int i=PositionsTotal()-1; i>=0; i--)
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
            return(true);
//---
   return(false);
  }
//+------------------------------------------------------------------+
//| Close all positions                                              |
//+------------------------------------------------------------------+
void CloseAllPositions(void)
  {
   for(int i=PositionsTotal()-1; i>=0; i--) // returns the number of current positions
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
            m_trade.PositionClose(m_position.Ticket()); // close a position by the specified m_symbol
  }
//+------------------------------------------------------------------+
ファイル:
 
Vladimir Karputov:

以下は、2つの条件の完全なコードです。

ウラジミールさん、ありがとうございます。 何とかしてみます。

自分なりに解決してみましたが、この2つの条件をどう切り分けるか、よくわかりました。

例えば、こんな感じです。

3つの論理変数を宣言してみましょう。

Pos_1です。

Pos_2_Clos_1。

Pos_2_Clos_All。

1.オープンポジション の数を確認する。

オープンポジションが1つしかない場合、SELLは に設定されます。

Pos_1=true; Pos_2_Clos_1=false; Pos_2_Clos_All=false です

2つのポジションが開かれ、資本金額がプラスである場合(これはSELL_STOP注文がトリガーされたときのみ発生する可能性があります、このイベントに論理値を割り当てます。

Pos_1=false ; Pos_2_Clos_1=true; Pos_2_Clos_All=false です。

2つのポジションが開設され、資本金額がマイナスである場合(これはSELL_LIMIT注文がトリガーされた場合にのみ発生する可能性があります)。

Pos_1=false ; Pos_2_Clos_1=false; Pos_2_Clos_All=true です

それだけのような気もしますが...。論理変数を調べて、独自のcloseメソッドに代入すればいいのですが、なぜかうまくいきませんでした...。

私はまだヘタなプログラマーなので、もしかしたらどこかでミスをしたのかもしれませんが...。

ありがとうございました)

Совершение сделок - Торговые операции - Справка по MetaTrader 5
Совершение сделок - Торговые операции - Справка по MetaTrader 5
  • www.metatrader5.com
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением текущими позициями путем их модификации или закрытия. Платформа позволяет удобно просматривать торговую историю на счете, настраивать оповещения о событиях на рынке и многое другое. Открытие позиций...
 

ウラジーミル・カルプトフ

Vladimir、私はこれで困っています。 SELL_STOP注文がトリガーされたとき、すべてがOKです。 大きな利益を持つ1つのポジションだけがクローズされるのです。

しかし、SELL_LIMITがトリガーされると、すべてが不正にクローズされ、すべてのオープンポジションの合計ではなく、より高い利益を得たポジションがクローズされるように見えます。

以前にも同じようなエラーがありましたが、今は私のせいかもしれない、もしかしたら正しく計算してポジションを開いていないのかもしれないと思い始めています。

私の用意したテスト用コードを見て、エラーがあるかどうか確認してください。でも、もしかしたらあなたのコードにも矛盾があるかもしれませんし、私が正しく説明していないかもしれません。私にとっての平均利益は何でしょうか?

今アルゴリズムの解析を始めてみて、以前お伝えしたよりも、もう少し複雑な結果になっていることに気づきました。

3つ目の条件であるSLでポジションをクローズ する場合、最初の2つの条件のアルゴリズムにエラーが発生する場合があります。

SEL_STOPの場合はきちんと実行されるので、SELL_LIMITの場合のみ、ポジションクローズの完全なアルゴリズムをもう一度説明します。とりあえず置いておこう。

1.最初にSLを指定したオープンポジションSELLが1 つありますが、SELL_LIMITより高いので、SELL_LIMITの前にSLは発動しないことになります。

2.SELL_LIMITが発動し、SLが設定された2つ目の 売り ポジションが あり、これも次のSELL_LIMITまでに決済できない。

SELL_LIMIT注文がトリガーされた場合、新たなSELL_LIMIT注文が発注されました。(いつも)

4.SELL_LIMITのオープンポジションの数は1-3 であったり、それ以上であったりしますが、それはすべてSLがどの程度立っているかによります。最大で3つある場合を考えてみましょう。(SLに限定することができる)

次に、ポジションを閉じるときのシナリオです。

オープンポジションの場合。2、1つまたはすべてのポジションを閉じるには、2つのシナリオのみが 可能です。

1.Equityで、残高より15以上多い場合(全てのポジションを決済)、(m_account.Equity()>= m_account.Balance()+15) 平均していくつかのポジションを決済するという意味でした。

2.自分のSLで(1ポジションはクローズ)。

3. 残りの1ポジションは、どのような条件を適用すればよいのか分からないため、以前に設定されていた場合は、終了条件をクリア する必要があります。

SELL_LIMITのシナリオを繰り返すか、SEL_STOPまで降りてきて、別のクローズ状態になることもあります。

4.3つのポジションが あった場合、それらも クローズ(m_account.Equity()>= m_account.Balance()+15) またはそのうちの1つがSLを 発動し、2つのポジションが残ります。

このルールは、終了条件が定義されていないポジションが1つ残るまで適用される...

Совершение сделок - Торговые операции - Справка по MetaTrader 5
Совершение сделок - Торговые операции - Справка по MetaTrader 5
  • www.metatrader5.com
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением текущими позициями путем их модификации или закрытия. Платформа позволяет удобно просматривать торговую историю на счете, настраивать оповещения о событиях на рынке и многое другое. Открытие позиций...
ファイル:
 
Vladpedro:

ウラジーミル・カルプトフ

Vladimir、私はこれで困っています。 私のSELL_STOP注文がトリガーされたとき、すべてがOKです。 大きな利益を持つ1つのポジションだけが閉鎖されています。

しかし、SELL_LIMITがトリガーされると、注文が不正確に閉じられ、すべてのオープンポジションの合計ではなく、最も高い利益を持つポジションが閉じられるように見えます。

以前にも同じようなエラーがありましたが、今は私のせいかもしれない、もしかしたら正しく計算してポジションを開いていないのかもしれないと思い始めています。

私のテスト用の準備したコードを確認し、エラーを見つけることができるかどうか確認してください。 多分、あなたのコードと条件に矛盾があります。 または、私はそれらを正しく説明していないかもしれません... 私にとって平均利益は何ですか?

一般的に、どの保留注文が トリガーになるかは重要ではありません。実際、私たちはポジションを持って終わり、その後、ポジションの利益を計算します。

 
Vladimir Karputov:

どの注文が トリガーされたかに違いはありません - 結局のところ、私たちはポジションを取得し、そのポジションの利益をカウントします。

何の違いもないのです。注文やポジションを設定する際に、ポジションには自分の、注文には自分の「コメント」を割り当てているので、その違いがあるのではないかと疑っています。その結果、あるポジションに注文が移動すると、その注文のコメントが継承される。

そして、コメントでポジションを確認すると、コメントが違うという混乱がありました。 それを修正しました。

Equityによって引き起こされたSELL_LIMITの条件に対して、どのようにポジションがクローズされるのか、あなたのコードには見当たりませんし、理解もしていません。

if(total==2)
   {
//-------------------------------------------------------- conditon 1
      ulong tmp_ticket=ULONG_MAX;
      double tmp_profit=DBL_MIN;
      for(int i=PositionsTotal()-1; i>=0; i--)
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
      if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
      {
      double profit=m_position.Commission()+m_position.Swap()+m_position.Profit();
      if(profit>tmp_profit)
      {
      tmp_profit=profit;
      tmp_ticket=m_position.Ticket();
      }
      }
      //---
      if(tmp_ticket!=ULONG_MAX)
      m_need_close_ticket=tmp_ticket;
      }
      else
      {
      if(total==2)
        {
//--------------------------------------------------------- conditon 2
        double profit=0;
        for(int i=PositionsTotal()-1; i>=0; i--)
        if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
        if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
        profit+=m_position.Commission()+m_position.Swap()+m_position.Profit();
//--------
       if(profit>=InpProfitTarget)
        m_need_close_all=true;
        }
        }

すべてのポジションがクローズ可能かどうかをチェックし、そのためのフラグが設定されているようです。

が、CloseAllPositions()の 中で。

if(m_need_close_all)
   {
   if(IsPositionExists())
   {
   CloseAllPositions();
   return;
   }
   else
   m_need_close_all=false;
   }

何かが足りない

 if(m_account.Equity()>= m_account.Balance()+15)

SELL_LIMITが発生した場合、すべてのポジションをクローズするためのチェックは行われません。

もしかして、この同じm_account.Equity()>= m_account.Balance()+15は、何か別の方法で実装されているのでしょうか?

あるいは、平均化の説明が間違っていなかったからかもしれません。

理由: