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(conststring p = NULL) {return"" == p;}
template<typename T> bool __hlp_macro_func(T p) {returntrue;}
template<typename T> bool __hlp_macro_func(T& p) {returntrue;}
template<typename T> bool __hlp_macro_func(T& p[]) {returntrue;}
//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; };
voidOnStart()
{
//---Print(IS_PARAMETER_SET()); //falsePrint(IS_PARAMETER_SET("")); //truePrint(IS_PARAMETER_SET("test")); //truePrint(IS_PARAMETER_SET(NULL)); //truePrint(IS_PARAMETER_SET(0)); //truePrint(IS_PARAMETER_SET(1)); //truestring str;
Print(IS_PARAMETER_SET(str)); //trueint 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)); //1Print(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
}
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.
Se uma ordem parcial de limite estiver pendurada, a guia "Ordens e comércios" não mostrará o comércio gerado.
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.
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.
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.
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ãoao 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" ?
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?
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ãoao 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.
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:
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.
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.
Conclusões
Se assumirmos que este é um comportamento normal do MT5, e não uma peculiaridade do hack do corretor, então
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" ?
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.
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 ==""".
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.
@fxsaber
Consulte esta edição, por favor: https://www.mql5.com/ru/forum/170952/page201#comment_21964923
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.
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.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.