Caratteristiche del linguaggio mql5, sottigliezze e tecniche - pagina 201

 
Quando si chiama una macro, si può non specificare alcun parametro (ometterlo), a volte si vuole specificatamente permettere a una macro di lavorare con un parametro non specificato.


Per questi casi, ecco alcune macro ausiliarie.

1. a volte volete determinare all'interno della vostra macro se un parametro è stato impostato o meno. IS_PARAMETER_SET(p) definisce un'espressione che restituisce vero se p è impostato (anche se la variabile stringa ==NULL).

Attenzione: l'espressione è valutata dopo la pre-elaborazione in fase di compilazione!!!, cioè non può essere usata per implementare qualcosa come #ifdef IS_PARAMETER_SET(p) #else (questo vale anche per altre macro sotto)

2. Se avete bisogno di convertire esplicitamente il valore di un parametro in una stringa, per evitare un errore di compilazione con un parametro non specificato, potete usare __EVAL_STR(p). Se p non è specificato o definito esplicitamente con un letterale NULL, restituisce "". Non applicabile a matrici, strutture e classi.

La conversione esplicita di un parametro in un numero è __EVAL_NON_STR(p). Se p non è impostato, restituisce 0. Non funziona quando p è una stringa!

Codice ed esempi di utilizzo:

//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:

Il seguente codice sul conto demoRannForex-Server può riprodurre immediatamente questa situazione eseguendo questo consulente.


Risultato.


A proposito, lo script mostra (non sempre la prima volta) un bug nell'esecuzione sincrona di OrderSend.

Dopo che OrderSend viene eseguito per alcune decine/centinaia di millisecondi, il prezzo dell'ordine è quello vecchio, e non quello che è stato piazzato con successo da OrderSend.


Tornando all'argomento dei biglietti identici, possiamo trarre alcune conclusioni.

  1. Se un ordine limite parziale è sospeso, la scheda "Ordini e compravendite" non mostrerà la compravendita generata.
  2. Su una copertura, un singolo ordine può generare più operazioni IN con prezzi diversi. Il risultato sarà un prezzo di apertura frazionato (relativo ai pip) della posizione.
  3. Puoi chiudere la posizione generata senza rimuovere la Put parziale. Ma se dopo che l'ordine pendente è scattato, allora verrà aperto un trade con il ticket, uguale al ticket della posizione, che è stato chiuso prima. Cioè, ci può essere una situazione in cui si chiude una posizione con un certo biglietto. E poi una posizione riappare con lo stesso ticker.
  4. L'esecuzione parziale può essere implementata in modo diverso, a seconda del software del broker. Quanto sopra è un'implementazione standard di MT5.

Se qualcuno è riuscito a riprodurlo su un altro server di trading, per favore condivida il nome.

Stringa di ricerca: Oshibka 010.

Torniamo di nuovo alla questione dell'esecuzione parziale.

1. Si prega di chiarire il punto 3: "Puoi chiudere la posizione che hai formato senza rimuovere l'Esecuzione parziale. Ma se dopo che l'ordine è scattato, si aprirà un trade con un ticket uguale al ticket della posizione che hai chiuso prima. Cioè, ci può essere una situazione in cui si chiude una posizione con un certo biglietto. E poi una posizione appare di nuovo con lo stesso biglietto"
In questo caso, POSITION_IDENTIFIER era uguale a POSITION_TICKET o no?

2. Prima nel thread "POSITION_TICKET != POSITION_IDENTIFIER" hai dimostrato una logica diversa di MT5.

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

fxsaber:

Conclusioni

Se assumiamo che questo è un comportamento normale di MT5, e non una peculiarità dell'hack del broker, allora

  • ORDER_STATE_PARTIAL non esiste negli ordini storici.
  • Gli ordini che vengono eseguiti hanno sempre lo stato ORDER_STATE_FILLED.
  • Quando un ordine viene eseguito parzialmente, un nuovo ordine a mercato corrispondente viene creato dal server di trading (ORDER_REASON_CLIENT - anche se l'ordine iniziale viene piazzato automaticamente (EXPERT)).
  • Il vecchio ordine live (il biglietto non è cambiato) rimane in sospeso con un volume ridotto (ORDER_VOLUME_CURRENT).
  • Il vecchio ordine live in questo caso ha lo stato ORDER_STATE_PARTIAL. In realtà, questo flag è il risultato del confronto tra ORDER_VOLUME_CURRENT e ORDER_VOLUME_INITIAL.
  • Tutte le posizioni aperte ricevono ID == OrderTicket. Dove OrderTicket è il biglietto generato dal server commerciale.
  • Un trade ha sempre esattamente un ordine storico e il suo stato è ORDER_STATE_FILLED.
  • Ogni ordine storico eseguito ha esattamente un trade.
  • L'ORDER_VOLUME_INITIAL di qualsiasi ordine eseguito è uguale al volume per cui è stato eseguito. Cioè anche l'ordine iniziale che è stato cancellato ha un ORDER_VOLUME_INITITAL che è uguale al volume del trade che ha generato.
  • Il tempo dell'ordine iniziale (che è stato eseguito parzialmente) non cambia e non è uguale al tempo del suo scambio.
  • La tabella della storia è ordinata per tempo dell'ordine (ORDER_TIME_SETUP) ma non per tempo dell'affare. Quindi se facciamo HistorySelect da DEAL_TIME, non possiamo ottenere l'ordine corrispondente nella tabella della storia.
  • HistorySelectByPosition restituisce sempre l'insieme necessario di affari/ordini.
  • È possibile calcolare lo slippage per qualsiasi trade.

Nella vostra esperienza, c'è un modello generale, in quali casi/modalità di funzionamento si applica MT5?

3. In definitiva, ci sono mai state situazioni reali in cui "POSITION_TICKET != POSITION_IDENTIFIER"?

POSITION_TICKET != POSITION_IDENTIFIER
POSITION_TICKET != POSITION_IDENTIFIER
  • 2018.02.12
  • www.mql5.com
зная id позиции можно ли без перебора узнать тикет позиции...
 
mktr8591:
Quando si chiama una macro, è possibile omettere un parametro (lasciarlo fuori), e a volte si vuole specificatamente permettere a una macro di lavorare con un parametro non specificato.
Risulta che un parametro non specificato in qualsiasi macro è trattato dal compilatore come una stringa vuota?
 
fxsaber:
Quindi risulta che un parametro non specificato in qualsiasi macro è trattato dal compilatore come una stringa vuota?

In un certo senso, sì, anche se forse "come uno spazio vuoto" è una parola migliore. Difficile da articolare chiaramente :-(.

Ma #p si trasforma sicuramente in stringa ==""

 
mktr8591:

In un certo senso, sì, anche se forse "come uno spazio vuoto" è una parola migliore. Difficile da articolare chiaramente :-(.

Ma #p si trasforma sicuramente in stringa ==""

Grazie, sfumatura interessante.

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

Torniamo di nuovo alla questione delle prestazioni parziali.

1. Si prega di chiarire il punto 3: "È possibile chiudere una posizione formata senza rimuovere l'opzione di vendita parziale. Ma se dopo che l'ordine è scattato, si aprirà un trade con un ticket uguale al ticket della posizione che hai chiuso prima. Cioè, ci può essere una situazione in cui si chiude una posizione con un certo biglietto. E poi una posizione appare di nuovo con lo stesso biglietto"
In questo caso, POSITION_IDENTIFIER era uguale a POSITION_TICKET o no?

2. Prima, nel ramo "POSITION_TICKET != POSITION_IDENTIFIER" hai dimostrato una logica diversa di MT5.

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

Nella vostra esperienza, avete mostrato un modello generale in quali casi/modalità di funzionamento si applica lo schema MT5?

3. In definitiva, ci sono mai state situazioni reali in cui "POSITION_TICKET != POSITION_IDENTIFIER"?

Entrambi i link parlano di diverse implementazioni dell'esecuzione parziale. Questo è determinato dal software del broker, non da MT5.

Non è mai stato riscontrato alcun errore tra il biglietto e l'ID.

 
Grazie.
 

Forum sul trading, sistemi di trading automatico e test di strategia

Biblioteche: Uso

fxsaber, 2021.05.01 14:17

GetMicrosecondCount può produrre un valore inferiore a quello della chiamata precedente (senza overflow di ULONG). Esempi di tali situazioni.
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

Ogni linea è ottenuta da diversi EA su tre terminali MT4.

E su MT5 questo genere di cose accade, ma molto meno frequentemente su MT4.

Fate attenzione.

 
I commenti non relativi a questo argomento sono stati spostati in "Domande dai principianti di MQL5 MT5 MetaTrader 5".
Motivazione: