Perguntas de Iniciantes MQL5 MT5 MetaTrader 5 - página 856

 
Алексей Барбашин:

Hmmm... Provavelmente não olhei muito cuidadosamente para o API, mas não vi tal função.... E provavelmente seria útil.

Quaisquer outras dicas... talvez a questão seja demasiado... ridícula... Como traduzir um número, por exemplo, duplo, para um char de matriz? Ou seja, em alguns API é necessário passar números como um ponteiro. Os apontadores são passados como matrizes unidimensionais. Com cordas que compreendo, as funções StringToShortArray e StringToCharArray são fornecidas para eles, mas com números ainda não compreendo como convertê-los em arrays de bytes (char).

Talvez algum exemplo?
 
. ... Rick D. ... .:
Talvez algum exemplo?

Não iremos suficientemente longe. Vamos dar uma vista de olhos ao trabalho com o registo. O registo pode armazenar tanto valores de corda como de número (não como uma corda). A passagem de um número para o registo e a devolução de um ponteiro para ele é feita através de matrizes (de acordo com a sua correcção). Será que um exemplo destes funcionaria?

 
pivomoe:

Estudo a história das carraças. Nem sempre se percebe o que se passava no mercado na altura das carraças.

SBER

i=987 2016.06.27 10:00:30.274 Ask=133.91 Bid=133.9 Last=133.9 Vol=50 TICK_FLAG_ASK

i=988 2016.06.27 10:00:30.280 Ask=133.93 Bid=133.9 Last=133.9 Vol=50 TICK_FLAG_ASK

i=989 2016.06.27 10:00:30.280 Ask=133.93 Bid=133.9 Last=133.91 Vol=100 TICK_FLAG_LAST TICK_FLAG_VOLUME TICK_FLAG_BUY TICK_FLAG_SELLL

i=990 2016.06.27 10:00:30.280 Ask=133.93 Bid=133.9 Last=133.92 Vol=300 TICK_FLAG_LAST TICK_FLAG_VOLUME TICK_FLAG_BUY TICK_FLAG_SELL

i=991 2016.06.27 10:00:30.280 Ask=133.93 Bid=133.9 Last=133.92 Vol=100 TICK_FLAG_LAST TICK_FLAG_VOLUME TICK_FLAG_BUY TICK_FLAG_SELL

i=992 2016.06.27 10:00:30.281 Ask=133.94 Bid=133.9 Last=133.92 Vol=100 TICK_FLAG_ASK

1. O que é este misterioso carrapato com bandeiras simultâneasTICK_FLAG_BUY e TICK_FLAG_SELL ? Consegui até encontrar tais carrapatos com um volume de 1 lote.

2. No carrapato 988. Ask=133.93 Bid=133.9 De onde veio o último 133.91 em 989 ?

O que aconteceu no mercado?

Tais questões são melhores para serem colocadas num tópico separado na secção "Negociação de Acções" do fórum.

Em suma, se vir que um tick tem uma bandeira de compra e uma bandeira de venda ao mesmo tempo, significa que o servidor do corretor não está actualizado e que transmite negócios de direcção desconhecida.

Em que servidor observam os carrapatos?
 
Vladimir Karputov:

Por favor, ou reescreva a sua pergunta ou coloque sinais de pontuação, ou melhor ainda acrescente uma imagem do quê, onde e quem. Caso contrário, vejo cartas familiares, mas não consigo compreender o significado ou o seu pensamento.

Aqui está uma fotografia


 
Seric29:

Aqui está uma fotografia.


Então, porquê colocar na minha fotografia (ou a cache é uma loucura?)?

 
Seric29:

Aqui está uma fotografia


Esclareça: Quer mover o rato directamente no terminal e copiar o preço da POSIÇÃO através do clique direito do rato?

 
Алексей Барбашин:

Não iremos suficientemente longe. Vamos dar uma vista de olhos ao trabalho com o registo. O registo pode armazenar tanto valores em minúsculas como valores numéricos (não como um fio). A passagem de um número para o registo e a devolução de um ponteiro para ele é feita através de matrizes (de acordo com a sua correcção). Gostaria de ter um exemplo deste trabalho?

Aí está. Penso que se pode descobrir.
Arquivos anexados:
TestReg.mq5  33 kb
 
. ... Rick D. ... .:
Aqui está. Acho que vai descobrir.

Isso é original! Eu nem sequer tinha pensado nisso. )))

Seguindo o meu exemplo anterior, tentei descobrir o que causa o colapso da memória e do terminal.

Em primeiro lugar, recusei arrays para obter indicações para uma secção de registo aberta. Ou seja, simplesmente passei o uint& phkResult para API. Tudo correu bem e sem erros. A documentação ao mql diz que os tipos simples podem ser passados por referência, que, quando se trabalha com API, é o endereço da variável, ou seja, o ponteiro. Tudo foi bem sucedido nesta parte. Também devolvi os parâmetros NULL e passei-os sem utilizar matrizes.

Além disso, trabalhei para passar o próprio valor para o registo. A descrição da função salientou que deveria passar um cordel com um zero final. Este é exactamente o tipo de corda, por isso na primeira versão eu estava a passar apenas uma variável. Não alterou isto na versão anterior, contando com a mesma. Mas decidi experimentar com arrays e introduzi ushort array e preenchi-o com o valor necessário. Um dos parâmetros ao passá-lo para a função

uint RegSetValueExW(uint hKey, string lpValueName, uint Reserved, uint dwType, ushort &lpData[], uint cbData);

é o tamanho dos dados que estão a ser passados. No seu exemplo, foi assim:

uint cbData = (StringLen(valor)+1)*2;

Aqui tudo é claro. Tomamos o comprimento da corda, adicionamos um zero "final" e multiplicamos por 2 bytes, pelo tamanho do ushort;

Tentei desta forma:

ushort Data[];

StringToShortArray(valor, Dados);

uint cbData = sizeof(Data);

Imagine a minha surpresa quando o tamanho dos dados não era igual ao do exemplo anterior!

Verifiquei o tamanho da matriz e era absolutamente igual a StringLen(valor)+1, mas o tamanho dos dados não era o mesmo... Continuo sem perceber porquê.

Mas não importa.

O problema original no final era obter o valor do registo, porque estava a passar uma variável de corda por referência como um ponteiro. Foi aqui que ocorreu o acidente.

"Se passarmos esta estrutura ou uma referência a ela para uma DLL em vez da própria cadeia, esperaríamos um resultado errado - porque a DLL do sistema aceitará certamente uma cadeia honesta com um carácter zero no final e não esta estrutura" - esta citação tem dez anos e não perdeu a sua relevância.

Portanto, ao passar qualquer valor constante da string, como o nome da secção de registo ou o valor do parâmetro da string, tudo está correcto. E ao passar uma variável de cadeia por referência, como eu fiz, leva ao problema indicado na citação. )))

E quanto ao tamanho recebido, há um exemplo na documentação API, quando em caso de erro "há mais dados", aumentamos o tamanho do buffer de recepção em loop e obtemos dados novamente.

Por isso, é assim.

Mais uma vez obrigado pela ajuda! )))


 
Алексей Барбашин:

Isso é original! Eu nem sequer tinha pensado nisso. )))

A União é conveniente de utilizar. Não é preciso pensar onde está o byte alto e onde está o byte baixo. A União pode mesmo ser utilizada para o REG_BINÁRIO. Descreve a sua estrutura de dados. E adiciona-o à União juntamente com um conjunto de bytes por tamanho da estrutura. Mas penso que não é realmente necessário. Qualquer dado pode ser convertido numa corda e armazenado como uma corda.

A julgar pelo exemplo anterior, tentei compreender o que causou exactamente a queda da memória e do terminal.

Talvez porque a pilha estava a voar, talvez tenha especificado muito tempo em vez de int na descrição da função.

A documentação ao mql diz que tipos simples podem ser passados por referência, que quando se trabalha com API é o endereço de uma variável, ou seja, um ponteiro.

Pode descarregar um link para esta secção de documentação?

uint cbData = sizeof(Data);

Necessita de uint cbData = ArraySize(Data) * 2 se passar ushort array.

e uint cbData = ArraySize(Data) se passar um uchar de array.

No último exemplo, passo a matriz uchar como parâmetro da função API, para total compatibilidade com os dados LPBYTE lpData do vento.

É correcto. Mas acrescenta confusão para converter todos os dados em uma matriz de bytes.

E quanto ao tamanho recebido, a documentação API dá um exemplo, onde em caso de "há mais dados" erro, aumentamos o tamanho do buffer recebido em loop e voltamos a receber dados.

Dê uma vista de olhos ao último código. Na implementação vem primeiro um pedido para obter o tamanho dos dados, depois o tamanho da matriz é definido, depois todos os dados são tomados na sua totalidade.

 
. ... Rick D. ... .:

A União é conveniente de utilizar. Não há necessidade de pensar onde está o byte alto e onde está o byte baixo. Pode usar a União mesmo para REG_BINÁRIO. Descreve a sua estrutura de dados. E adiciona-o à União juntamente com o conjunto de bytes por tamanho da estrutura. Mas penso que não é realmente necessário. Qualquer dado pode ser convertido numa corda e armazenado como uma corda.

Talvez também porque a pilha estava a voar, especificou muito tempo em vez de int na descrição da função.

Pode descarregar um link para esta secção de documentação?

Necessita de uint cbData = ArraySize(Data) * 2 se passar ushort array.

e uint cbData = ArraySize(Data) se passar um uchar de array.

No último exemplo, passo a matriz uchar como um parâmetro de função API, para compatibilidade total com os dados lp do Windows LPBYTE.

É correcto. Mas acrescenta confusão para converter todos os dados em uma matriz de bytes.

Dê uma vista de olhos ao último código. Na implementação vem primeiro um pedido para obter o tamanho dos dados, depois o tamanho da matriz é definido, depois todos os dados são tomados na sua totalidade.

Saudações de novo!

Espero realmente que a nossa discussão neste tópico seja útil não só para os novatos, mas também para os programadores experientes.

Que tal longo. Sim, é um erro meu, mas foi int que foi usado no início. Usei Long porque estou a usar um terminal de 64 bits. Mas tudo funciona bem com a int.

Sobre as indicações. Penso que os seguintes artigos descrevem muito bem tudo isto:https://www.mql5.com/ru/docs/basis/types/this,https://www.mql5.com/ru/docs/runtime/imports.

Admito também o meu erro com o sizeof. Estamos a utilizar uma matriz dinâmica para troca, enquanto que para matrizes dinâmicas o tamanho da matriz simplesmente devolve o tamanho da própria matriz em vez do tamanho dos dados:https://www.mql5.com/ru/docs/basis/operations/other.

Relativamente à obtenção do tamanho completo dos dados. Sim, tem razão. De facto, na primeira chamada a função devolve o tamanho dos dados colocados no parâmetro, pelo que pode passar sem o laço sobre o qual escrevi. Devo ter entendido mal a descrição da função aqui, porque diz que a variável retorna o tamanho dos dados lidos.

Voltemos ao fio... Em princípio, como se verificou, ao receber dados, poderíamos passar a variável por referência, mas primeiro poderíamos inicializá-la com algum valor até ao comprimento máximo. Isto parece-me ser uma muleta, uma vez que depois o próprio valor deve ser cortado desta corda. Obter dados do buffer de matriz é uma variante mais óptima, ou seja, a nossa solução é melhor, na minha opinião )))))

Aqui sobre a passagem de cordel como ponteiro:https://www.mql5.com/ru/forum/103532/page2#comment_2983919

E Andriy fala-nos muito bem do trabalho com dll:https://www.mql5.com/ru/articles/96


Penso que com a vossa ajuda cobrimos inteiramente o tópico de trabalhar não só com o registo, mas também com as nuances da API da biblioteca.

A classe de trabalho com o registo é muito útil para o intercâmbio de dados tanto entre ferramentas de um gráfico como entre gráficos e terminais em geral.

Uma vez neste fórum disseram que a utilização do registo para estes fins equivale a martelar pregos com uma lâmpada e sugeriram a utilização de ficheiros virtuais (mapeamento). Mas não concordo com isto, porque antes de escrever o registo em disco, é apenas um ficheiro virtual. E ao utilizar o atributo REG_OPTION_VOLATILE, o valor será sempre virtual. E é muito conveniente armazenar os dados entre sessões no registo. IMHO.

Документация по MQL5: Основы языка / Типы данных / Ссылки. Модификатор & и ключевое слово this
Документация по MQL5: Основы языка / Типы данных / Ссылки. Модификатор & и ключевое слово this
  • www.mql5.com
В MQL5 параметры простых типов можно передавать как по значению, так и по ссылке, в то время как параметры сложных типов всегда передаются по ссылке. Для указания компилятору на необходимость передачи параметра по ссылке, перед именем параметра ставится знак амперсанда Передача параметра по ссылке означает передачу адреса переменной, поэтому...
Razão: