Fehler, Irrtümer, Fragen - Seite 540

 

Mein Expert Advisor, der derzeit an der Meisterschaft teilnimmt, führt aufgrund eines Fehlers in der Standard-CTrade-Bibliothek falsche Aktionen aus.

Ich verwende die Funktion PositionClose, um Positionen zu schließen. Aber diese Funktion schließt nicht nur Positionen, sondern eröffnet auch selbst Trades!

Die Funktion wird wie folgt verwendet:

//--- Объект класса СTrade
CTrade mytrade;
//--- Объект класса СPositionInfo
CPositionInfo myposition;

//+------------------------------------------------------------------+
//| Проверяет и если нужно, закрывает открытую позицию               |
//+------------------------------------------------------------------+
bool ClosePosition(string ptype,double clp)
  {
   bool R=false, marker=false; int i;
     
      if(myposition.Select(_Symbol)==true)
        {
         if(myposition.Symbol()==_Symbol)
           {
            //--- Делаем попытки закрыть позицию, если позиция не закрылась с первого раза
              for (i=5; i>=1; i--) 
                {R=mytrade.PositionClose(_Symbol,50,5); if (R == true && myposition.Select(_Symbol)==false) break;}
               if(i >= 1) 
                 {//--- запрос успешно выполнен
                  Alert("Открытая позиция была успешно закрыта!!");
                  marker=true;
                 }
               else
                 {
                  Alert("Запрос на закрытие позиции не выполнен - ошибка: ",mytrade.ResultRetcodeDescription());
                 }
            //  }
           }
        }
      return(marker);
     }

PositionClose führt dazu, dass manchmal unnötige Aufträge eröffnet werden.

In diesem Fall wurde zuerst das Kaufgeschäft geschlossen und dann ein zusätzliches Verkaufsgeschäft in gleicher Höhe eröffnet. Außerdem hat AccountInfoDouble(ACCOUNT_FREEMARGIN) diesen zusätzlichen Handel nicht bemerkt. Denn es folgte ein Handel mit einer größeren Partie, für die aber laut dem verwendeten MM nicht genug Geld vorhanden war.

Mir ist klar, dass ich die MQL-Funktionen vielleicht nicht optimal nutze. Aber die Tatsache, dass eine Funktion in der MQL-eigenen Bibliothek, die für das Schließen von Geschäften gedacht ist, von sich aus Geschäfte öffnet, passt nicht in meine Vorstellung vom akzeptablen Verhalten von Funktionen.

 
masharov:

Ich weiß, dass ich die MQL-Funktionen möglicherweise nicht optimal nutze. Aber die Tatsache, dass eine MQL-eigene Bibliotheksfunktion, die für das Schließen von Geschäften gedacht ist, von sich aus Geschäfte öffnet, passt nicht in meine Vorstellung vom akzeptablen Verhalten von Funktionen.

Lesen Sie den Artikel Trading Events in MetaTrader 5:

Handelsereignisse und Änderungen im Handelsverlauf werden über unabhängige Kanäle gemeldet. Wenn Sie eine Kaufanfrage mit der Funktion OrderSend() senden, können Sie sofort das Ticket der Bestellung erkennen, das erstellt wurde, wenn die Anfrage erfolgreich geprüft wurde. Gleichzeitig kann es aber sein, dass der Auftrag selbst noch nicht im Client-Terminal erscheint und der Versuch, ihn mit der Funktion OrderSelect() auszuwählen, fehlschlägt.

Siehe auch den Artikel Orders, Positionen und Trades in MetaTrader 5
 
Rosh:

Lesen Sie den Artikel Handelsereignisse in MetaTrader 5:

Siehe auch den Artikel Orders, Positionen und Trades in MetaTrader 5

Ich habe die Funktion OrderSend nicht verwendet. Es wird die Funktion PositionClose aus der Standard-MQL-Bibliothek verwendet, die für die Arbeit mit Aufträgen ausgelegt ist.

In der Hilfe zu dieser Funktion wird nicht beschrieben, dass sie Geschäfte eröffnen kann.

Zitat aus der Referenz:

PositionClose

Schließt eine Position bei dem angegebenen Symbol.

bool PositionClose(
const string symbol, // symbol
ulong abweichung=ULONG_MAX // abweichung
)

Parameter

Symbol

[in] Name des Handelsinstruments, für das die Position geschlossen werden soll.

abweichung=ULONG_MAX

[in] Maximale Abweichung vom aktuellen Kurs (in Punkten).

Zurückgegebener Wert

true - wenn die grundlegende Prüfung der Strukturen erfolgreich war, sonst false.

Hinweis

Die erfolgreiche Beendigung der Methode PositionClose(...) bedeutet nicht immer die erfolgreiche Ausführung einer Handelsoperation. Es ist notwendig, das Ergebnis einer Handelsanfrage (den Rückgabecode des Handelsservers) durch Aufruf der Methode ResultRetcode() zu überprüfen.

 
masharov:

Ich habe die Funktion OrderSend nicht verwendet. Es wird die Funktion PositionClose aus der Standard-MQL-Bibliothek verwendet, die die Arbeit mit Aufträgen vereinfachen soll.

In der Hilfe zu dieser Funktion wird nicht beschrieben, dass sie Geschäfte eröffnen kann.

Zitat aus der Referenz:

PositionClose

Schließt eine Position bei dem angegebenen Symbol.

bool PositionClose(
const string symbol, // symbol
ulong abweichung=ULONG_MAX // abweichung
)

Parameter

Symbol

[in] Name des Handelsinstruments, für das die Position geschlossen werden soll.

abweichung=ULONG_MAX

[in] Maximale Abweichung vom aktuellen Kurs (in Punkten).

Zurückgegebener Wert

true - wenn die grundlegende Prüfung der Strukturen erfolgreich war, sonst false.

Hinweis

Die erfolgreiche Beendigung der Methode PositionClose(...) bedeutet nicht immer die erfolgreiche Ausführung einer Handelsoperation. Das Ergebnis der Ausführung der Handelsanfrage (der Rückgabecode des Handelsservers) muss durch Aufruf der Methode ResultRetcode() überprüft werden.

Es liegt kein Fehler in der Bibliotheksfunktion PositionClose(...) vor. Aber es gibt eine in Ihrem Code. Hier ist das Zitat aus der Referenz.

Успешное окончание работы метода PositionClose(...) не всегда означает успешное совершение торговой операции. 
Необходимо проверять результат выполнения торгового запроса (код возврата торгового сервера) вызовом метода ResultRetcode(). 

Ich zum Beispiel sehe diese Prüfung in Ihrem Code nicht.

 
masharov:

Ich habe die Funktion OrderSend nicht verwendet. Die Funktion PositionClose aus der MQL-Standardbibliothek, die für die Arbeit mit Aufträgen konzipiert ist, wird verwendet.

In der Hilfe zu dieser Funktion wird nicht beschrieben, dass sie Geschäfte eröffnen kann.


Und Sie können sich die Implementierung der Funktion PositionClose ansehen:

bool CTrade::PositionClose(const string symbol,ulong deviation)
  {
   bool   partial_close=false;
   int    retry_count  =10;
   uint   retcode      =TRADE_RETCODE_REJECT;
//--- check stopped
   if(IsStopped(__FUNCTION__)) return(false);
//--- variables
   string action,result;
//--- clean
   ClearStructures();
   do
     {
      //--- checking
      if(PositionSelect(symbol))
        {
         if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
           {
            //--- prepare request for close BUY position
            m_request.type =ORDER_TYPE_SELL;
            m_request.price=SymbolInfoDouble(symbol,SYMBOL_BID);
           }
         else
           {
            //--- prepare request for close SELL position
            m_request.type =ORDER_TYPE_BUY;
            m_request.price=SymbolInfoDouble(symbol,SYMBOL_ASK);
           }
        }
      else
        {
         //--- position not found
         m_result.retcode=retcode;
         return(false);
        }
      //--- setting request
      m_request.action      =TRADE_ACTION_DEAL;
      m_request.symbol      =symbol;
      m_request.deviation   =(deviation==ULONG_MAX) ? m_deviation : deviation;
      m_request.type_filling=m_type_filling;
      m_request.volume      =PositionGetDouble(POSITION_VOLUME);
      //--- check volume
      double max_volume=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
      if(m_request.volume>max_volume)
        {
         m_request.volume=max_volume;
         partial_close=true;
        }
      else
         partial_close=false;
      //--- order check
      if(!OrderCheck(m_request,m_check_result))
        {
         //--- copy return code
         m_result.retcode=m_check_result.retcode;
         if(m_log_level>LOG_LEVEL_NO)
            printf(__FUNCTION__+": %s [%s]",FormatRequest(action,m_request),FormatRequestResult(result,m_request,m_result));
         return(false);
        }
      //--- order send
      if(!OrderSend(m_request,m_result))
        {
         if(--retry_count!=0) continue;
         if(retcode==TRADE_RETCODE_DONE_PARTIAL)
            m_result.retcode=retcode;
         if(m_log_level>LOG_LEVEL_NO)
            printf(__FUNCTION__+": %s [%s]",FormatRequest(action,m_request),FormatRequestResult(result,m_request,m_result));
         return(false);
        }
      retcode=TRADE_RETCODE_DONE_PARTIAL;
      if(partial_close) Sleep(1000);
     }
   while(partial_close);
   if(m_log_level>LOG_LEVEL_ERRORS)
      printf(__FUNCTION__+": %s [%s]",FormatRequest(action,m_request),FormatRequestResult(result,m_request,m_result));
//--- ok
   return(true);
  }
 

Ich dachte, ich müsste den Quellcode der Standardbibliotheken nicht studieren.

Die Hilfe beschreibt nicht die Möglichkeit, Geschäfte mit der Funktion PositionClose zu eröffnen. Die Kontrollen und Schutzmaßnahmen gegen das Öffnen von Geschäften mit der Funktion PositionClose, die Ihr Team entwickelt hat, sollten sich in Grenzen halten. Ich glaube, dass die Standardbibliotheken ein idealer Code sind, der anderen als Vorbild dienen sollte. Daher sollte es nicht notwendig sein, den Code der Bibliotheken zu analysieren, bevor man sie benutzt.

Zitat:

Die MQL5-Standardbibliothek ist in der Sprache MQL5 geschrieben und wurde entwickelt, um das Schreiben von Programmen (Indikatoren, Skripte, Experten) für Endbenutzer zu erleichtern. Die Bibliothek bietet einfachen Zugang zu den meisten internen MQL5-Funktionen.

 
masharov:

Ich dachte, ich müsste den Quellcode der Standardbibliotheken nicht studieren.

Die Hilfe beschreibt nicht die Möglichkeit, Geschäfte mit der Funktion PositionClose zu eröffnen. Die Kontrollen und Schutzmaßnahmen gegen das Öffnen von Geschäften mit der Funktion PositionClose, die Ihr Team entwickelt hat, sollten sich in Grenzen halten. Ich glaube, dass die Standardbibliotheken ein idealer Code sind, der anderen als Vorbild dienen sollte. Daher sollte es nicht erforderlich sein, den Code von Bibliotheken vor deren Verwendung zu analysieren.

Die Unkenntnis des Gesetzes entbindet Sie nicht von Ihrer Verantwortung. Wo in Ihrem Code wird geprüft, ob die Position geschlossen wurde?

            //--- Делаем попытки закрыть позицию, если позиция не закрылась с первого раза
              for (i=5; i>=1; i--) 
                {
                 R=mytrade.PositionClose(_Symbol,50,5); 
                 if (R == true && myposition.Select(_Symbol)==false) break;
                }

Ausdruck

R == true

zeigt nur an, dass die Funktion PositionClose() erfolgreich ausgeführt wurde, aber nicht, dass die Position geschlossen wurde:

Hinweis

Der erfolgreiche Abschluss der Methode PositionClose(...) bedeutet nicht immer die erfolgreiche Ausführung eines Handelsgeschäfts. Es ist notwendig, das Ergebnis der Ausführung einer Handelsanfrage (Rückgabecode des Handelsservers) durch Aufruf der Methode ResultRetcode() zu überprüfen.

Der zweite Ausdruck

myposition.Select(_Symbol)==false)

ist gleichbedeutend mit

PositionSelect(_Symbol)==false)

und bietet auch keine Garantie für asynchrone Handelsvorgänge. Eine Position wurde bereits auf dem Handelsserver geschlossen und das Terminal hat noch keine Nachricht darüber erhalten. Es stellt sich also heraus, dass Sie einen Fehler in Ihrem Code verursacht haben.

Im wirklichen Leben läuft nicht alles so reibungslos ab wie im Testgerät; es kann zu kleinen Verzögerungen zwischen dem Senden einer Handelsanfrage und dem Ergebnis ihrer Ausführung kommen. Jeder löst dieses Problem selbst, für den Anfang würde es nicht schaden, den Rückgabewert mit der Funktion ResultRetcode() zu überprüfen , wie es in der Hilfe beschrieben ist.

 

Nochmals.

Mir ist klar, dass ich die MQL-Funktionen vielleicht nicht optimal nutze. Aber die Tatsache, dass eine Funktion in der MQL-eigenen Bibliothek, die für dasSchließen von Geschäften gedacht ist, von sich aus Geschäfteöffnet, passt nicht in meine Vorstellung vom akzeptablen Verhalten von Funktionen.

Alles, was Sie sagen, gilt für den Abschluss von Geschäften. Ja, der EA prüft Schließpositionen nicht optimal. Aber das erlaubt es nicht, dass eine Funktion, die für die Schließung von Geschäften gedacht ist, diese selbständig öffnet.

Die Hilfe sagt:

PositionClose

Schließt die Position entsprechend dem angegebenen Symbol.

Es werden keine Bedingungen beschrieben, dass die Funktion einen Handel eröffnen kann. Die Empfehlung, den Returncode zu prüfen, dient ebenfalls nur dazu, zusätzlich zu prüfen, ob der Handel abgeschlossen ist oder nicht.

 
masharov:

Nochmals.

Ich weiß, dass ich die MQL-Funktionen möglicherweise nicht optimal nutze. Aber die Tatsache, dass die Funktion in der MQL-eigenen Bibliothek, die für dasSchließen von Geschäften gedacht ist, von sich aus Geschäfteöffnet, passt nicht in meine Vorstellung vom akzeptablen Verhalten von Funktionen.
Es gibt keine Funktion zum Schließen einer Position, sondern nur die Funktion zum Senden einer Kauf- oder Verkaufsanfrage (und das Ergebnis - Eröffnung oder Schließung einer Position - ist unbekannt). In Ihrem Fall werden aufgrund eines algorithmischen Fehlers wiederholte Anfragen gesendet, ohne zu prüfen, ob die vorherige Anfrage ausgeführt wurde.
 
Rosh:
Es gibt keine Positionsschließungsfunktion, sondern nur die Funktion, eine Kauf- oder Verkaufsanfrage zu senden (und das Ergebnis - die Eröffnung oder Schließung einer Position - ist unbekannt). In Ihrem Fall werden aufgrund eines algorithmischen Fehlers wiederholte Anfragen gesendet, ohne zu prüfen, ob die vorherige Anfrage ausgeführt wurde.

Die Hilfe hat diese Funktion

MQL5 Referenz / Standardbibliothek / Handelsklassen / CTrade / PositionClose

Schließt die Position durch das angegebene Symbol.

Dem Benutzer sollte es egal sein, wie die Funktion auf der unteren Ebene implementiert ist. Da diese Funktion existiert, hat MetaQuotes garantiert, dass sie kein nicht standardisiertes Verhalten aufweist, das nicht in der Hilfe beschrieben ist.

Die MQL5-Standardbibliothek ist in MQL5 geschrieben und soll das Schreiben von Programmen (Indikatoren, Skripte und Expert Advisors) durch Endbenutzer erleichtern. Die Bibliothek bietet einfachen Zugang zu den meisten internen MQL5-Funktionen.

Grund der Beschwerde: