Merkmale der Sprache mql5, Feinheiten und Techniken - Seite 201

 
Wenn Sie ein Makro aufrufen, dürfen Sie keinen Parameter angeben (auslassen). Manchmal möchten Sie einem Makro ausdrücklich erlauben, mit einem nicht angegebenen Parameter zu arbeiten.


Für solche Fälle gibt es hier einige Hilfsmakros.

1. Manchmal möchten Sie innerhalb Ihres Makros feststellen, ob ein Parameter gesetzt wurde oder nicht. IS_PARAMETER_SET(p) definiert einen Ausdruck, der true zurückgibt, wenn p gesetzt ist (auch wenn die String-Variable ==NULL ist).

Achtung: der Ausdruck wird nach der Vorverarbeitung zur Kompilierzeit ausgewertet!!!, d.h. er kann nicht verwendet werden, um etwas wie #ifdef IS_PARAMETER_SET(p) #else zu implementieren (dies gilt auch für andere Makros unten)

2. Wenn Sie einen Parameterwert explizit in eine Zeichenkette umwandeln müssen, um einen Kompilierfehler mit einem nicht spezifizierten Parameter zu vermeiden, können Sie __EVAL_STR(p) verwenden. Wenn p nicht oder explizit mit NULL-Literal definiert ist, wird "" zurückgegeben. Gilt nicht für Arrays, Strukturen und Klassen.

Die explizite Umwandlung eines Parameters in eine Zahl ist __EVAL_NON_STR(p). Wenn p nicht gesetzt ist, wird 0 zurückgegeben. Funktioniert nicht, wenn p ein String ist!

Code und Anwendungsbeispiele:

//Expression returns true if macro's parameter is specified.
#define  IS_PARAMETER_SET(p) ("" != #p || __hlp_macro_func(p))
bool __hlp_macro_func(const string p = NULL) {return "" == p;}
template<typename T> bool __hlp_macro_func(T p)    {return true;}
template<typename T> bool __hlp_macro_func(T& p)   {return true;}
template<typename T> bool __hlp_macro_func(T& p[]) {return true;}


//Expression returns parameter p; if parameter is not specified returns NULL; if p is string returns p
//Error for arrays and objects
#define __EVAL(p) (""==#p?NULL:p+NULL)


//Explicit conversion to string. If parameter is not specified or is constant NULL returns ""
//Error for arrays and objects
#define __EVAL_STR(p) (""==#p || "NULL"==#p? "" :(string)(p+NULL))


//Explicit conversion to number. If parameter is not specified returns 0. Works incorrect if p is string!
//Error for arrays and objects
#define __EVAL_NON_STR(p) ("" == #p? 0 : p+0)


struct S1
  {   int               a; };
class C1
  { int               a; };

void OnStart()
  {
//---
   Print(IS_PARAMETER_SET());                //false
   Print(IS_PARAMETER_SET(""));              //true
   Print(IS_PARAMETER_SET("test"));          //true
   Print(IS_PARAMETER_SET(NULL));            //true
   Print(IS_PARAMETER_SET(0));               //true
   Print(IS_PARAMETER_SET(1));               //true
   string str;
   Print(IS_PARAMETER_SET(str));             //true

   int arr[1];
   Print(IS_PARAMETER_SET(arr));             //true
   S1 _struct;
   Print(IS_PARAMETER_SET(_struct));         //true
   C1 _class;
   Print(IS_PARAMETER_SET(_class));          //true

#define   MACRO1_(a,b)  (IS_PARAMETER_SET(b)?a:-a)
   Print(MACRO1_(1, 0));                     //1
   Print(MACRO1_(1,));                       //-1

#define   MACRO2_(a,b,c)  Print(a," = ",b + c)
#define   MACRO3_(a,b,c)  Print(__EVAL_STR(a)," = ",__EVAL_NON_STR(b) + __EVAL_NON_STR(c))

 //MACRO2_(, 2,);                            // ',' - syntax error, parameter missed
   MACRO3_(, 2,);                            // = 2
   MACRO3_("a", 2, 3);                       // a = 5
  }


 
fxsaber:

Der folgende Code auf demRannForex-Server Demokonto kann diese Situation sofort reproduzieren, indem dieser Advisor ausgeführt wird.


Ergebnis.


Übrigens, das Skript zeigt (nicht immer zum ersten Mal) einen Fehler in der synchronen OrderSend-Ausführung.

Nachdem OrderSend für einige zehn/hundert Millisekunden ausgeführt wurde, ist der Auftragspreis der alte und nicht derjenige, der durch OrderSend erfolgreich erteilt wurde.


Um auf das Thema der identischen Tickets zurückzukommen, können wir einige Schlussfolgerungen ziehen.

  1. Wenn eine Teil-Limit-Order hängt, wird auf der Registerkarte "Aufträge und Abschlüsse" der generierte Abschluss nicht angezeigt.
  2. Bei einem Hedge kann ein einziger Auftrag mehrere IN-Geschäfte mit unterschiedlichen Preisen hervorbringen. Das Ergebnis ist ein Bruchteil des Eröffnungskurses der Position (im Verhältnis zu den Pips).
  3. Sie können die erzeugte Position schließen, ohne den Partial Put zu entfernen. Wenn aber danach die Pending Order ausgelöst wird, wird ein Handel mit dem Ticket eröffnet, das dem Ticket der Position entspricht, die zuvor geschlossen wurde. Das heißt, es kann eine Situation eintreten, in der Sie eine Position mit einem bestimmten Ticket schließen. Und dann taucht eine Position mit demselben Ticker wieder auf.
  4. Die Teilausführung kann je nach Software des Brokers unterschiedlich umgesetzt werden. Die obige Darstellung ist eine Standardimplementierung von MT5.

Wenn es jemandem gelungen ist, das Problem auf einem anderen Handelsserver zu reproduzieren, teilen Sie uns bitte den Namen mit.

Suchbegriff: Oshibka 010.

Nochmals zurück zur Frage der Teilvollstreckung.

1. Bitte klären Sie Punkt 3: "Sie können die von Ihnen gebildete Position schließen, ohne die Teilausführung zu entfernen. Wenn der Auftrag jedoch danach ausgelöst wird, wird ein Handel mit einem Ticket eröffnet, das dem Ticket der zuvor geschlossenen Position entspricht. Das heißt, es kann eine Situation eintreten, in der Sie eine Position mit einem bestimmten Ticket schließen. Und dann erscheint wieder eine Position mit demselben Ticket."
War in diesem Fall POSITION_IDENTIFIER gleich POSITION_TICKET oder nicht?

2. Vorhin im Thread "POSITION_TICKET != POSITION_IDENTIFIER" haben Sie eine andere MT5-Logik demonstriert.

https://www.mql5.com/ru/forum/227423/page2#comment_6543129

fxsaber:

Schlussfolgerungen

Wenn wir davon ausgehen, dass dies ein normales Verhalten von MT5 ist und keine Besonderheit des Broker-Hacks, dann

  • ORDER_STATE_PARTIAL ist in historischen Aufträgen nicht vorhanden.
  • Aufträge, die ausgeführt werden, haben immer den Status ORDER_STATE_FILLED.
  • Wenn ein Auftrag teilweise ausgeführt wird, wird ein entsprechender neuer Marktauftrag vom Handelsserver angelegt (ORDER_REASON_CLIENT - auch wenn der ursprüngliche Auftrag automatisch erteilt wurde (EXPERT)).
  • Der alte Live-Auftrag (das Ticket wird nicht geändert) bleibt mit einem reduzierten Volumen (ORDER_VOLUME_CURRENT) anhängig.
  • Der alte Live-Auftrag hat in diesem Fall den Status ORDER_STATE_PARTIAL. Eigentlich ist dieses Kennzeichen das Ergebnis des Vergleichs von ORDER_VOLUME_CURRENT und ORDER_VOLUME_INITIAL.
  • Alle offenen Positionen erhalten eine ID == OrderTicket. Dabei ist OrderTicket das vom Handelsserver generierte Ticket.
  • Ein Geschäft hat immer genau einen historischen Auftrag, und sein Status ist ORDER_STATE_FILLED.
  • Jeder ausgeführte historische Auftrag hat genau einen Abschluss.
  • Das ORDER_VOLUME_INITIAL eines ausgeführten Auftrags ist gleich dem Volumen, für das er ausgeführt wurde. D.h. selbst der ursprüngliche Auftrag, der storniert wurde, hat ein ORDER_VOLUME_INITITAL, das dem Volumen des von ihm ausgelösten Handels entspricht.
  • Der Zeitpunkt des ursprünglichen Auftrags (der teilweise ausgeführt wurde) ändert sich nicht und ist nicht gleich dem Zeitpunkt seines Abschlusses.
  • Die Historientabelle ist nach Auftragszeit (ORDER_TIME_SETUP), nicht aber nach Geschäftszeit sortiert. Wenn wir also HistorySelect from DEAL_TIME ausführen, können wir die entsprechende Bestellung nicht in die History-Tabelle übernehmen.
  • HistorySelectByPosition liefert immer die erforderliche Menge an Geschäften/Aufträgen.
  • Sie können die Slippage für jeden Handel berechnen.

Gibt es Ihrer Erfahrung nach ein allgemeines Muster, in welchen Fällen/Arbeitsweisen der MT5 verwendet wird?

3. Hat es jemals Situationen gegeben, in denen "POSITION_TICKET != POSITION_IDENTIFIER" war?

POSITION_TICKET != POSITION_IDENTIFIER
POSITION_TICKET != POSITION_IDENTIFIER
  • 2018.02.12
  • www.mql5.com
зная id позиции можно ли без перебора узнать тикет позиции...
 
mktr8591:
Beim Aufruf eines Makros ist es möglich, einen Parameter auszulassen, und manchmal möchte man einem Makro ausdrücklich erlauben, mit einem nicht spezifizierten Parameter zu arbeiten.
Es stellt sich heraus, dass ein nicht spezifizierter Parameter in einem Makro vom Compiler als leerer String behandelt wird?
 
fxsaber:
Es stellt sich also heraus, dass ein nicht spezifizierter Parameter in einem Makro vom Compiler als leerer String behandelt wird?

In gewisser Weise ja, obwohl "wie ein leerer Raum" vielleicht ein besseres Wort ist. Schwierig, sich klar auszudrücken :-(.

Aber #p wird definitiv zu string ==""

 
mktr8591:

In gewisser Weise ja, obwohl "wie ein leerer Raum" vielleicht ein besseres Wort ist. Schwierig, sich klar auszudrücken :-(.

Aber #p wird definitiv zu string ==""

Danke, eine interessante Nuance.

 
Особенности языка mql5, тонкости и приёмы работы
Особенности языка mql5, тонкости и приёмы работы
  • 2021.04.03
  • www.mql5.com
В данной теме будут обсуждаться недокументированные приёмы работы с языком mql5, примеры решения тех, или иных задач...
 
mktr8591:

Noch einmal zurück zur Frage der Teilleistung.

1. Bitte klären Sie Punkt 3: "Sie können eine gebildete Position schließen, ohne die Partial Put Option zu entfernen. Wenn der Auftrag jedoch danach ausgelöst wird, wird ein Handel mit einem Ticket eröffnet, das dem Ticket der zuvor geschlossenen Position entspricht. Das heißt, es kann eine Situation eintreten, in der Sie eine Position mit einem bestimmten Ticket schließen. Und dann erscheint wieder eine Position mit demselben Ticket."
War in diesem Fall POSITION_IDENTIFIER gleich POSITION_TICKET oder nicht?

2. Vorhin im Zweig "POSITION_TICKET != POSITION_IDENTIFIER" haben Sie eine andere Logik des MT5 demonstriert.

https://www.mql5.com/ru/forum/227423/page2#comment_6543129

Gibt es Ihrer Erfahrung nach ein allgemeines Muster, in welchen Fällen/Betriebsarten das MT5-Schema Anwendung findet?

3. Hat es jemals Situationen gegeben, in denen "POSITION_TICKET != POSITION_IDENTIFIER" war?

Beide Links behandeln verschiedene Implementierungen der partiellen Ausführung. Dies wird von der Software des Brokers bestimmt, nicht von MT5.

Es wurde noch nie eine Diskrepanz zwischen Ticket und ID festgestellt.

 
Ich danke Ihnen.
 

Forum zum Thema Handel, automatisierte Handelssysteme und Strategietests

Bibliotheken: Nutzung

fxsaber, 2021.05.01 14:17

GetMicrosecondCount kann einen kleineren Wert ausgeben als beim vorherigen Aufruf (ohne ULONG-Überlauf). Beispiele für solche Situationen.
2021.04.29 06:43:31.915   Alert: NewValue = 296000074313, PrevValue = 296001329284

2021.04.29 06:43:32.149   Alert: NewValue = 296086250613, PrevValue = 296087264090

2021.04.29 06:43:31.868   Alert: NewValue = 295129291901, PrevValue = 295130576710

2021.04.29 06:43:32.180   Alert: NewValue = 295955613012, PrevValue = 295956589070

2021.04.29 06:43:32.180   Alert: NewValue = 295146223171, PrevValue = 295147199454

2021.04.29 06:43:32.149   Alert: NewValue = 295065995432, PrevValue = 295067005968

2021.04.29 06:43:32.149   Alert: NewValue = 295078776581, PrevValue = 295079787357

Jede Linie wird von verschiedenen EAs auf drei MT4-Terminals erzielt.

Und auf dem MT5 kommt so etwas vor, auf dem MT4 dagegen viel seltener.

Seien Sie vorsichtig.

 
Kommentare, die sich nicht auf dieses Thema beziehen, wurden nach "Fragen von MQL5 MT5 MetaTrader 5 Anfängern" verschoben.