Fragen von Anfängern MQL5 MT5 MetaTrader 5 - Seite 1207

 

mql5 (Hecke)

Wie lässt sichein Algorithmus zum Schließen von Positionen unter zwei Bedingungen implementieren?

1 Fall. Wenn 2 Positionen offen sind, dann schließen Sie diejenige mit mehr Gewinn als... 2 Fall. Wenn es 2 oder mehr offene Positionen gibt, dann schließen Sie, indem Sie den Durchschnittswert der...

Jetzt habe ich zwei Möglichkeiten, diese Positionen zu schließen,

Für den Fall 1 vergleichen Sie die Positionen nach Gewinn und schließen diejenige mit dem höchsten Gewinn, für den Fall 2 schließen Sie alle Positionen nach Eigenkapital, indem Sie den Durchschnitt bilden.

Diese Methoden funktionieren getrennt gut, aber nicht zusammen, weil eines der beiden Ereignisse in die Verteilung beider Methoden fällt.

Es gelingt mir nicht, sie zu trennen. Infolgedessen werden beide Fälle größtenteils auf Eigenkapitalbasis mit der Schließung aller Positionen abgeschlossen. Dies führt dazu, dass im ersten Fall die gewünschte Position gelöscht und neu geöffnet wird.

Das Ergebnis ist. Doppelseite, doppelte Provision. Es ist frustrierend)))

Das Schema für die Einstellung von Aufträgen und Positionen sieht folgendermaßen aus: Für SELL (und weiterhin nur für SELL).

Limitierter Auftrag. VERKAUF_LIMIT

Position. SELL(immer zwischen den Aufträgen)

Bestellung anhalten.VERKAUF_STOP

Ich füge die Tabelle bei.

Schließung von Positionen.

1. wenn eine Stop-Order ausgelöst wird, d.h. zwei oder mehr Positionen gleichzeitig auftauchen, sollten Sie eine Position schließen, die einen höheren Gewinn als... (20)

2. wenn eine Limit-Order ausgelöst wurde, d.h. zwei oder mehr Positionen gleichzeitig eröffnet wurden, sollte ihr Durchschnittswert (nach Eigenkapital) geschlossen werden... (15)

Frage. Wie kann man diese beiden Methoden trennen, so dass sie nur ihr eigenes Ereignis behandeln?

Vielleicht gibt es eine andere Methode, um diese beiden Bedingungen zu behandeln?

Beispiele für die von mir verwendeten Methoden.

//+---------------------------------------------------------------------+
//|  -- ЗАКРЫВАЕМ ОДНУ ИЗ ДВУХ ПОЗИЦИЙ С НИЗУ, ГДЕ ПРОФИТ БОЛЬШЕ ЧЕМ ---|
//+---------------------------------------------------------------------+ 
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
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением текущими позициями путем их модификации или закрытия. Платформа позволяет удобно просматривать торговую историю на счете, настраивать оповещения о событиях на рынке и многое другое. Открытие позиций...
Dateien:
 
Vladpedro:


Werden Positionen durch das Symbol eröffnet, mit dem der EA arbeitet? Wird die magische Zahl verwendet?
 
Vladimir Karputov:
Werden Positionen durch das Symbol eröffnet, mit dem der EA arbeitet? Magische Zahl wird verwendet

Ja, durch das aktuelle Symbol. Ja, Magie wird verwendet.

 
Vladpedro:

Ja, durch den aktuellen Charakter. Ja, Magie wird verwendet.

Erklären Sie die zweite Bedingung, was bedeutet sie?(Wenn 2 oder mehr Positionen offen sind, dann schließen Sie durch Mittelwertbildung über den Wert... )

 
Vladimir Karputov:

Erläutern Sie die zweite Bedingung, was bedeutet sie?(Wenn 2 oder mehr Positionen offen sind, schließen Sie durch Mittelwertbildung über den Wert... )

Das bedeutet: Wenn zwei oder mehr Positionen offen sind und das Eigenkapital um einen beliebigen Wert (z.B. 15) größer ist als der Saldo, dann werden alle Positionen geschlossen.

Zum Beispiel werden drei Positionen eröffnet: Die erste hat einen aktuellen Verlust von -10, die zweite einen Gewinn von -5, die dritte einen Gewinn von +30 und insgesamt +15, alle Positionen können geschlossen werden.

Wenn ein durchschnittlicher Gewinn von +15 nicht erreicht wurde, werden die Positionen um ihren eigenen voreingestellten SL oder TP geschlossen. (Dies ist sozusagen die dritte Bedingung für das Schließen von Positionen, aber da es keine Probleme damit gibt, habe ich sie weggelassen).

 
Vladpedro:

Das bedeutet: Wenn zwei oder mehr Positionen offen sind und das Eigenkapital um einen beliebigen Wert (z. B. 15) größer ist als der Saldo, werden alle Positionen geschlossen.

Beispiel: Drei Positionen sind offen, die erste hat einen aktuellen Verlust von -10, die zweite einen Gewinn von -5, die dritte hat eine +30+ Summe von +15, alle Positionen können geschlossen werden.

Wenn ein durchschnittlicher Gewinn von +15 nicht erreicht wurde, werden die Positionen um ihren eigenen voreingestellten SL oder TP geschlossen. (dies ist sozusagen die dritte Bedingung für das Schließen von Positionen, aber es gibt kein Problem damit, deshalb habe ich es weggelassen).

Hier ist der vollständige Code für zwei Bedingungen:

//+------------------------------------------------------------------+
//|                                       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
  }
//+------------------------------------------------------------------+
Dateien:
 
Vladimir Karputov:

Hier ist der vollständige Code für die beiden Bedingungen:

Danke, Vladimir, ich werde versuchen, das herauszufinden.

Ich habe versucht, das Problem auf meine Weise zu lösen, ich verstehe, wie man diese beiden Bedingungen trennen kann.

Zum Beispiel.

Lassen Sie uns drei logische Variablen deklarieren.

Pos_1;

Pos_2_Clos_1;

Pos_2_Clos_All;

1. Überprüfen Sie die Anzahl der offenen Stellen.

Wenn wir nur 1 offene Position haben, wird SELL auf gesetzt:

Pos_1=true ; Pos_2_Clos_1=false; Pos_2_Clos_All=false;

Wenn 2 Positionen geöffnet sind und der Eigenkapitalbetrag positiv ist (dies kann nur auftreten, wenn die SELL_STOP-Order ausgelöst wird), weisen Sie diesem Ereignis einen logischen Wert zu

Pos_1=false ; Pos_2_Clos_1=true; Pos_2_Clos_All=false;

Wenn 2 Positionen eröffnet werden und der Eigenkapitalbetrag negativ ist (dies kann nur vorkommen, wenn ein SELL_LIMIT-Auftrag ausgelöst wird), dann

Pos_1=false ; Pos_2_Clos_1=false; Pos_2_Clos_All=true;

Das scheint alles zu sein... Sie können nach logischen Variablen suchen und sie Ihrer eigenen Abschlussmethode zuweisen, aber aus irgendeinem Grund hat es bei mir nicht funktioniert...

Ich bin ein lausiger Programmierer, aber vielleicht habe ich irgendwo einen Fehler gemacht...

Danke für die Hilfe)

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

Wladimir Karputow:

Vladimir, ich habe Probleme damit. Wenn SELL_STOP-Aufträge ausgelöst werden, ist alles in Ordnung. Nur eine Position mit größerem Gewinn wird geschlossen,

Aber wenn SELL_LIMIT ausgelöst wird, wird alles falsch geschlossen, nicht durch die Summe aller offenen Positionen, sondern es sieht so aus, als ob die Position mit dem höheren Gewinn geschlossen wird.

Ich hatte einen ähnlichen Fehler vor, jetzt fange ich an zu denken, vielleicht ist es mein Fehler, vielleicht habe ich nicht berechnen und offene Positionen richtig.

Bitte überprüfen Sie meinen testbereiten Code und sehen Sie nach, ob Sie Fehler haben, aber vielleicht gibt es auch einige Ungereimtheiten in Ihrem Code, oder vielleicht habe ich sie nicht richtig erklärt... Wie hoch ist der durchschnittliche Gewinn für mich?

Ich habe nun begonnen, den Algorithmus zu analysieren und festgestellt, dass er in seinen Auswirkungen etwas komplizierter ist, als ich Ihnen zuvor gesagt habe.

Die dritte Bedingung, wenn Sie eine Position durch ihren SL schließen, kann Fehler im Algorithmus der ersten beiden Bedingungen verursachen.

Ich beschreibe noch einmal den kompletten Algorithmus der Positionsschließung nur für den Fall SELL_LIMIT, da der Fall SEL_STOP korrekt ausgeführt wird. Lassen wir es erst einmal dabei bewenden.

1. Wir haben zunächst eine offene Position SELL, die einen SL hat, der aber höher ist als SELL_LIMIT, was bedeutet, dass der SL nicht vor SELL_LIMIT aktiviert wird.

2. SELL_LIMIT hat ausgelöst und es gibt eine zweite SELL-Position mit eigenem SL, die ebenfalls nicht vor dem nächsten SELL_LIMIT geschlossen werden kann

Wenn der SELL_LIMIT-Auftrag ausgelöst wurde, ist ein neuer SELL_LIMIT-Auftrag erteilt worden. (immer)

4. Die Anzahl der offenen SELL_LIMIT-Positionen kann1-3 oder mehr betragen, je nachdem, wie weit sie im SL stehen. Dies ist der Fall, wenn es höchstens drei sind. (Ich kann dies auf SL beschränken)

Nun zu den Szenarien für die Schließung von Positionen.

Wenn offene Stellen. 2, sind nur zwei Szenarien für die Schließung einer oder aller Positionen möglich

1. Mit Equity, wenn es mehr als Saldo um 15 ist(alle Positionen sind geschlossen), (m_account.Equity()>= m_account.Balance()+15) meinte ich, mehrere Positionen durch Mittelwertbildung zu schließen.

2. Durch eigene SL (eine Position ist geschlossen).

3. Die verbleibende Position muss nun von den Schließungsbedingungen befreit werden, falls diese zuvor festgelegt wurden, da wir nicht wissen, welche Bedingung auf sie anzuwenden ist.

Er kann das SELL_LIMIT-Szenario wiederholen, oder er kann auf SEL_STOP zurückgehen und zu einer anderen Close-Bedingung übergehen.

4. Wenn es drei Positionen gab, schließen wir sie auch (m_account.Equity()>= m_account.Balance()+15) oder eine davon löst SL aus und zwei Positionen bleiben übrig.

Wenden Sie diese Regel an, bis nur noch eine Position übrig ist, für die keine Abschlussbedingungen definiert wurden...

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

Wladimir Karputow:

Vladimir, ich habe Probleme damit. Wenn SELL_STOP-Aufträge ausgelöst werden, ist alles in Ordnung. Nur eine Position mit größerem Gewinn wird geschlossen,

Aber wenn SELL_LIMIT ausgelöst wird, schließt der Auftrag nicht nach der Summe aller offenen Positionen, sondern scheint die Position mit dem höchsten Gewinn zu schließen.

Ich hatte einen ähnlichen Fehler vor, jetzt beginne ich zu denken, vielleicht ist es mein Fehler, vielleicht habe ich nicht berechnen und offene Positionen richtig.

Bitte überprüfen Sie meinen testbereiten Code und sehen Sie, ob Sie Fehler finden können, aber vielleicht gibt es eine Inkonsistenz in Ihrem Code und Bedingungen. Oder vielleicht habe ich sie nicht richtig erklärt... was ist der durchschnittliche Gewinn für mich.

Im Allgemeinen spielt es keine Rolle, welcher schwebende Auftrag ausgelöst wird - wir erhalten eine Position und berechnen dann den Gewinn der Position.

 
Vladimir Karputov:

Es macht keinen Unterschied, welche Pending-Order ausgelöst wurde - schließlich erhalten wir eine Position und zählen dann den Gewinn der Position

Es macht keinen Unterschied. Ich habe den Verdacht, dass es einen Unterschied gibt, weil ich beim Einstellen von Aufträgen und Positionen den Positionen eigene "Kommentare" und den Aufträgen eigene Kommentare zugewiesen habe. Wenn also ein Auftrag auf eine Position verschoben wird, erbt er den Kommentar des Auftrags.

Als wir dann die Positionen über die Kommentare überprüften, gab es ein Durcheinander... die Kommentare waren unterschiedlich. Das habe ich korrigiert.

Ich habe in Ihrem Code nicht gefunden oder verstehe nicht, wie die Positionen für die von Equity ausgelöste Bedingung SELL_LIMIT geschlossen werden.

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;
        }
        }

Es scheint, dass wir geprüft haben, ob alle Positionen geschlossen werden können, und das Flag dafür gesetzt ist

sondern in der FunktionCloseAllPositions();

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

es fehlt etwas.

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

Für den Fall - SELL_LIMIT hat ausgelöst - gibt es keine Prüfung für das Schließen aller Positionen.

Vielleicht ist das gleichem_account.Equity()>= m_account.Balance()+15auf eine andere Weise implementiert?

Oder vielleicht liegt es daran, dass ich die Mittelwertbildung nicht falsch erklärt habe.

Grund der Beschwerde: