Características da linguagem mql5, subtilezas e técnicas - página 201

 
Ao chamar uma macro, não se pode especificar qualquer parâmetro (omiti-lo), por vezes deseja-se permitir especificamente que uma macro trabalhe com um parâmetro não especificado.


Para tais casos, aqui estão algumas macros auxiliares.

1. por vezes pretende determinar dentro da sua macro se um parâmetro foi ou não definido. IS_PARAMETER_SET(p) define uma expressão, que retorna verdadeiro se p for definido (mesmo que a variável string ===NULL).

Atenção: a expressão é avaliada após o pré-processamento em tempo de compilação!!!, ou seja, não pode ser usada para implementar algo como #ifdef IS_PARAMETER_SET(p) #else (isto também se aplica a outras macros abaixo)

2. Se precisar de converter explicitamente um valor de parâmetro para uma string, para evitar um erro de tempo de compilação com um parâmetro não especificado, pode usar __EVAL_STR(p). Se p não for especificado ou definido explicitamente com NULL literal, retorna "". Não aplicável a arrays, estruturas e classes.

A conversão explícita de um parâmetro para um número é __EVAL_NON_STR(p). Se p não estiver definido, devolve 0. Não funciona quando p é uma corda!

Código e exemplos de utilização:

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

O seguinte código na conta de demonstração doRannForex-Server pode reproduzir imediatamente esta situação executando este conselheiro.


Resultado.


A propósito, o guião mostra (nem sempre da primeira vez) um erro na execução síncrona da OrderSend.

Após a OrderSend ser executada durante alguns dez/centenas de milissegundos, o preço da encomenda é o preço antigo, não o que foi colocado com sucesso pela OrderSend.


Voltando ao tema de bilhetes idênticos, podemos tirar algumas conclusões.

  1. Se uma ordem parcial de limite estiver pendurada, a guia "Ordens e comércios" não mostrará o comércio gerado.
  2. Numa cobertura, uma única ordem pode gerar múltiplas transacções IN com preços diferentes. O resultado será um preço de abertura fracionário (relativo a pips) da posição.
  3. Pode fechar a posição gerada sem remover o Put Parcial. Mas se depois disso a ordem pendente for accionada, então uma troca será aberta com o bilhete, igual ao bilhete da posição, que foi fechada antes. Ou seja, pode haver uma situação em que se fecha uma posição com um determinado bilhete. E depois reaparece uma posição com o mesmo ticker.
  4. A execução parcial pode ser implementada de forma diferente, dependendo do software do corretor. O acima exposto é uma implementação padrão do MT5.

Se alguém o conseguiu reproduzir noutro servidor comercial, por favor partilhe o nome.

Cadeia de pesquisa: Oshibka 010.

De volta à questão da execução parcial.

1. Esclareça no ponto 3: "Pode encerrar a posição que formou sem retirar a Execução Parcial. Mas se depois disso a ordem for accionada, uma troca será aberta com um bilhete igual ao bilhete da posição que fechou antes. Ou seja, pode haver uma situação em que se fecha uma posição com um determinado bilhete. E depois aparece novamente uma posição com o mesmo bilhete"
Neste caso, o POSITION_IDENTIFIER foi igual ou não ao POSITION_TICKET?

2. Anteriormente no fio "POSITION_TICKET != POSITION_IDENTIFIER" demonstrou uma lógica MT5 diferente.



fxsaber:

Conclusões

Se assumirmos que este é um comportamento normal do MT5, e não uma peculiaridade do hack do corretor, então

  • ORDER_STATE_PARTIAL não existe em ordens históricas.
  • As ordens que são executadas têm sempre o estatuto de ORDER_STATE_FILLED.
  • Quando uma ordem é parcialmente executada, uma nova ordem de mercado correspondente é criada pelo servidor de negociação (ORDER_REASON_CLIENT - mesmo que a ordem inicial seja colocada automaticamente (EXPERT)).
  • A antiga ordem ao vivo (o bilhete não é alterado) permanece pendente com um volume reduzido (ORDER_VOLUME_CURRENT).
  • A antiga ordem ao vivo neste caso recebe o estatuto ORDER_STATE_PARTIAL. Na verdade, esta bandeira é o resultado da comparação de ORDER_VOLUME_CURRENT e ORDER_VOLUME_INITIAL.
  • Todas as posições em aberto recebem ID == OrderTicket. Onde OrderTicket é o bilhete gerado pelo servidor comercial.
  • Um comércio tem sempre exactamente uma ordem histórica e o seu estatuto é ORDER_STATE_FILLED.
  • Cada ordem histórica executada tem exactamente uma transacção.
  • O ORDER_VOLUME_INITIAL de qualquer ordem executada é igual ao volume pelo qual foi executada. Isto é, mesmo a ordem inicial que foi cancelada tem um ORDER_VOLUME_INITITAL que é igual ao volume do comércio que desovou.
  • O tempo da ordem inicial (que foi parcialmente executada) não muda e não é igual ao tempo da sua negociação.
  • A tabela do histórico é ordenada por tempo de ordem (ORDER_TIME_SETUP) mas não por tempo de negócio. Portanto, se fizermos HistorySelect da DEAL_TIME, não podemos obter a ordem correspondente na tabela de história.
  • HistorySelectByPosition devolve sempre o conjunto necessário de acordos/ordens.
  • É possível calcular o deslizamento para qualquer comércio.

Na sua experiência, existe algum padrão geral em que casos/modos de trabalho que o MT5 utiliza?

3. Em última análise, alguma vez houve situações reais onde "POSITION_TICKET != POSITION_IDENTIFIER" ?

POSITION_TICKET != POSITION_IDENTIFIER
POSITION_TICKET != POSITION_IDENTIFIER
  • 2018.02.12
  • www.mql5.com
зная id позиции можно ли без перебора узнать тикет позиции...
 
mktr8591:
Ao chamar uma macro, é possível omitir um parâmetro (deixá-lo de fora), e por vezes pretende-se permitir especificamente que uma macro trabalhe com um parâmetro não especificado.
Acontece que um parâmetro não especificado em qualquer macro é tratado pelo compilador como uma cadeia vazia?
 
fxsaber:
Então, acontece que um parâmetro não especificado em qualquer macro é tratado pelo compilador como uma cadeia vazia?

De certa forma, sim, embora talvez "como um espaço vazio" seja uma palavra melhor. Difícil de articular claramente :-(.

Mas #p definitivamente transforma-se em cordel ==""".

 
mktr8591:

De certa forma, sim, embora talvez "como um espaço vazio" seja uma palavra melhor. Difícil de articular claramente :-(.

Mas #p definitivamente transforma-se em cordel ==""".

Obrigado, nuance interessante.

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

Voltando novamente à questão do desempenho parcial.

1. Por favor esclarecer no ponto 3: "É possível fechar uma posição formada sem remover a Opção de Venda Parcial. Mas se depois disso a ordem for accionada, uma troca será aberta com um bilhete igual ao bilhete da posição que fechou antes. Ou seja, pode haver uma situação em que se fecha uma posição com um determinado bilhete. E depois aparece novamente uma posição com o mesmo bilhete"
Neste caso, o POSITION_IDENTIFIER foi igual ou não ao POSITION_TICKET?

2. Anteriormente, no ramo "POSITION_TICKET != POSITION_IDENTIFIER", demonstrou uma lógica diferente do MT5.



Na sua experiência, mostrou algum padrão geral em que casos/modos de funcionamento se aplica o esquema MT5?

3. Em última análise, alguma vez houve situações reais onde "POSITION_TICKET != POSITION_IDENTIFIER" ?

Ambos os links falam de diferentes implementações de execução parcial. Isto é determinado pelo software do corretor, não pelo MT5.

Nunca foi encontrado qualquer desfasamento entre bilhete e identificação.

 
Obrigado.
 

Fórum sobre comércio, sistemas de comércio automatizados e testes estratégicos

Bibliotecas: Utilização

fxsaber, 2021.05.01 14:17

GetMicrosecondCount pode produzir um valor inferior ao da chamada anterior (sem ULONG overflow). Exemplos de tais situações.
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

Cada linha é obtida por diferentes EAs em três terminais MT4.

E no MT5 este tipo de coisas acontece, mas muito menos frequentemente no MT4.

Tenham cuidado.

 
Comentários não relacionados com este tópico foram transferidos para "Perguntas dos principiantes do MQL5 MT5 MetaTrader 5".