Questions from Beginners MQL5 MT5 MetaTrader 5 - page 856

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

Hmmm... I probably didn't look at the API very carefully, but I didn't see such a function.... And it would probably be handy.

Any other tips... perhaps the question is too ... ridiculous... How do I translate a number, e.g. double, into an array char? That is, in some API it's required to pass numbers as a pointer. Pointers are passed as one-dimensional arrays... With strings I understand, the StringToShortArray and StringToCharArray functions are provided for them, but with numbers I still don't understand how to convert them to byte arrays (char).

Maybe some example?
 
. ... Rick D. ... .:
Maybe some example?

We won't go far enough. Let's take a look at working with the registry. The registry can store both string and number values (not as a string). Passing a number to the registry and getting back a pointer to it is done through arrays (according to your correction). Would such an example work?

 
pivomoe:

I study the history of ticks. It doesn't always work out what was going on in the market at the time of the ticks.

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_SELL

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. What is this mysterious tick with simultaneous flagsTICK_FLAG_BUY and TICK_FLAG_SELL ? I was even able to find such ticks with a volume of 1 lot.

2. On the tick 988. Ask=133.93 Bid=133.9 Where did Last 133.91 come from on 989 ?

What happened on the market?

Such questions are better to be posted in a separate thread in the "Stock Trading" section of the forum.

In short, if you see that a tick has a buy flag and a sell flag at the same time, it means that broker's server is not updated and it broadcasts deals of unknown direction.

On which server do you watch the ticks?
 
Vladimir Karputov:

Please either rewrite your question or put punctuation marks, or better yet add a picture of what, where and who. Otherwise, I see familiar letters, but I can't understand the meaning or your thought.

Here is a picture


 
Seric29:

Here's a picture.


So, why put in my picture (or is the cache crazy?)?

 
Seric29:

Here is a picture


Clarify: Do you want to move the mouse directly in the terminal and copy the price of the POSITION via the right mouse click?

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

We won't go far enough. Let's take a look at working with the registry. The registry can store both string and number values (not as a string). Passing a number to the registry and getting back a pointer to it is done through arrays (according to your correction). Would an example like this work?

There you go. I think you can figure it out.
Files:
TestReg.mq5  33 kb
 
. ... Rick D. ... .:
Here you go. I think you'll figure it out.

That's original! I hadn't even thought about it. )))

Following my previous example I tried to figure out what causes memory and terminal crash.

First of all, I refused arrays to get pointers to an open registry section. That is, I simply passed uint& phkResult into API. Everything went well and no errors. The documentation to mql says that the simple types can be passed by reference, which, when working with API, is the address of the variable, i.e. pointer. Everything was successful in this part. I've returned the NULL parameters too and passed them without using arrays.

Further, I worked on passing the value itself to the register. The function description has pointed out that it should pass a string with a trailing zero at the end. This is exactly the string type, so in the first version I was passing just a variable. You did not change this in the previous version relying on the same. But I decided to experiment with arrays and introduced ushort array and filled it with the necessary value. One of the parameters when passing it to the function

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

is the size of data being passed. In your example it was like this:

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

Everything is clear here. We take the length of the string, add an "ending" zero and multiply by 2 bytes, by the ushort size;

I tried it this way:

ushort Data[];

StringToShortArray(value, Data);

uint cbData = sizeof(Data);

Imagine my surprise when the size of the data was not equal to the previous example!

I checked the array's size and it was absolutely equal to StringLen(value)+1, but the data size was not the same... I still don't understand why.

But never mind.

The original problem in the end was getting the value from the registry, because I was passing a string variable by reference as a pointer. This is where the crash occurred.

"If you pass this structure or a reference to it in a DLL instead of the string itself, you can't expect a correct result - because the system DLL will certainly accept an honest string with a zero character at the end and not this structure" - this quote is ten years old, it hasn't lost its relevance.

Therefore, when passing any string constant value, such as registry section name or string parameter value, everything is correct. And when passing a string variable by reference, as I did, leads to the problem indicated in the quote. )))

And what about received size, there's an example in API documentation, when in case of error "there's more data" we increase receiving buffer size in loop and get data again.

So it goes like this.

Thanks again for the help! )))


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

That's original! I hadn't even thought about it. )))

Union is convenient to use. You don't have to think where is the high byte and where is the low byte. Union can even be used for REG_BINARY. You describe your data structure. And you add it into Union together with an array of bytes by structure size. But I think you do not really need it. Any data can be converted into a string and stored as a string.

Judging by the previous example, I tried to understand what exactly caused the memory and terminal crash.

Perhaps because the stack was flying, you may have specified long instead of int in function description.

The documentation to mql says that simple types can be passed by reference, which when working with API is the address of a variable, i.e. a pointer.

Can you download a link to this section of documentation?

uint cbData = sizeof(Data);

You need uint cbData = ArraySize(Data) * 2 if you pass ushort array.

and uint cbData = ArraySize(Data) if you pass an array uchar.

In last example I pass uchar array as API function parameter, for full compatibility with wind's LPBYTE lpData.

It is correct. But it adds fuss to convert all data into a byte array.

And as for received size, API documentation gives an example, where in case of "there is more data" error we increase received buffer size in loop and receive data again.

Take a look at the last code. There in the implementation first comes a request to get the size of the data, then the size of the array is set, then all the data is taken in its entirety.

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

Union is convenient to use. There is no need to think where is the high byte and where is the low byte. You can use Union even for REG_BINARY. You describe your data structure. And you add it into Union together with the array of bytes by structure size. But I think you do not really need it. Any data can be converted into a string and stored as a string.

Maybe also because the stack was flying, you specified long instead of int in the function description.

Can you download a link to this section of documentation?

You need uint cbData = ArraySize(Data) * 2 if you pass ushort array.

and uint cbData = ArraySize(Data) if you pass an array uchar.

In the last example, I pass the uchar array as an API function parameter, for full compatibility with the Windows LPBYTE lpData.

It is correct. But it adds fuss to convert all the data into a byte array.

Take a look at the last code. There in the implementation first comes a request to get the size of the data, then the size of the array is set, then all the data is taken in its entirety.

Greetings again!

I really hope that our discussion in this thread will be useful not only for newbies, but also for experienced programmers.

What about long. Yes, it is my mistake but it was int that was used at first. I used Long because I'm using a 64-bit terminal. But everything works well with int.

About pointers. I think the following articles describe it all very well:https://www.mql5.com/ru/docs/basis/types/this,https://www.mql5.com/ru/docs/runtime/imports.

I admit my mistake with sizeof too. We are using a dynamic array for exchange, while for dynamic arrays sizeof simply returns the size of the array itself instead of the data size:https://www.mql5.com/ru/docs/basis/operations/other.

Regarding getting the full size of the data. Yes, you are right. Indeed, when called for the first time, the function returns the size of the data placed in the parameter, so you can do without the loop I wrote about. I must have misunderstood the function description here, because it says that the variable returns the size of the data read.

Let's get back to string... In principle, as it turned out, when receiving data, we could pass the variable by reference but first we could initialize it with some value up to maximum length. This seems to me to be a crutch as afterwards the value itself should be cut out of this string. Getting data from array buffer is more optimal variant, i.e. our solution is better in my opinion ))).

Here about passing of string as a pointer:https://www.mql5.com/ru/forum/103532/page2#comment_2983919

And Andriy tells us about work with dll very well:https://www.mql5.com/ru/articles/96


I think that with your help we entirely covered the topic of working not only with the registry, but with the nuances of library API.

The class of working with the registry is very useful for exchanging data both between tools on one chart and between charts and terminals in general.

Once on this forum they said that using the registry for these purposes is tantamount to hammering nails with a light bulb and suggest using virtual files (mapping). But I don't agree with this, because before writing the registry to disk it is just a virtual file. And when using REG_OPTION_VOLATILE attribute the value will always be virtual. And it is very convenient to store inter-session data in the registry. IMHO.

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