You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
Greetings,
I'm studying MQL4 and MQL5 for a few years now (I'm not a professional programmer, I'm self educated), but I find hard to understand topics still. Recently, I wanted to store chart object data from a sqlite database to a multi-dimensional array in a project, to minimize disk I/O. As far as I know, I need to declare the array somewhat like this:
But when I try to work with the array, so like to search in it with ArrayBsearch, I need to sort it first:
This way I get an error:
'ArraySort' - constant cannot be modified
At this point, there were no data transaction between the database and the array, the error showed up when I added the array to the code. I tried to comment out each and every data types, same error. I tried ArraySort with a one-dimensional integer type array, to test, all went well. So it is quite sure, the struct declaration, or the struct-based array causes the error.
It is also veird, that I cannot add a string to the struct with that syntax, I get a
'MarkerArray' - structures or classes containing objects are not allowed
built-in: bool ArraySort(void&)
You need to use custom/library sort and binary search functions, as MQL standard library does not handle arrays of structures.
So I included the introsort library to help accomplish the goal. https://www.mql5.com/en/code/41836
Here is a test code that you can use in your project:
Here is a sample output in the 'experts log' after running the above script:
Thank you very much for the detailed explanation. I also checked the 3 links you provided - for the first one, I knew most of it, therefore I did not check back there to realize a structure is considered a variable but as a complex one, but I did check its docs page, to get familiar with the syntax and such, when I was studying its properties. The second one was more or less known for me, but the third one, was quite a deep dive, its more of a complex topic for me at this time.
Last night I was added the complete funcionality with the database approach. I'm currently adding a feature to add masses os records to test performance drop.
I'll review the suggested pages in the near future, if/when I'll decide to change the code to the array approach, if the change is justified by a significant drop in performance, however, I know that would be the best practice, or a more elegant way to solve this problem.
Thank you very much for your guidance. I'll come back to you soon with the outcome.
You need to use custom/library sort and binary search functions, as MQL standard library does not handle arrays of structures.
So I included the introsort library to help accomplish the goal. https://www.mql5.com/en/code/41836
Here is a test code that you can use in your project:
Here is a sample output in the 'experts log' after running the above script:
You need to use custom/library sort and binary search functions, as MQL standard library does not handle arrays of structures.
So I included the introsort library to help accomplish the goal. https://www.mql5.com/en/code/41836
Here is a test code that you can use in your project:
Here is a sample output in the 'experts log' after running the above script:
Woah! Thanks for the example!
I saw template BinarySearch somewhere before, but these are way hard for me to understand, what is happening and why, neither the syntax I get. Guess I should declare it as a standard function which I did. In the meantime (when I realized that I might be able to stick to the array approach with your code) I started to reorganize the whole code, so I created multiple MARKERS table (where I store the data outside runtime, from where it is read back during initialization) for each timeframe, so the struct became simpler, it stores now a datetime, and a string (EnumToString - the flag itself) only. So I adjusted the Less function to manage 2 parameters instead of 3. But the problem came when I started to search (the sort function was successful).
I wanted to search with this:
int index = ArrayBinarySearch(MarkerArray, CueLinePos);
CueLinePos is a datetime type variable to store a cue line. I want to know if the array stores data for the matching datetime (CueLinePos), but I got the following compiler errors:
template parameter ambiguous, could be 'MarkerData' or 'datetime'
see declaration of function 'ArrayBinarySearch'
CueLinePos' - parameter conversion not allowed
'CueLinePos' - variable of the same type expected
Haha! That analogy was hilarious! I try to implement the array approach since that was the original plan. Now that I have a hopeful snippet to play around, I'll be able to accomplish the original goal. Thanks for your guidance!
CueLinePos
You could specialize the 'generic' binary search function for your needs like this:
You could specialize the 'generic' binary search function for your needs like this:
You could specialize the 'generic' binary search function for your needs like this:
Greetings,
I've modified the function as suggested from ArrayBinarySearch --> MarkerArrayBinarySearch and rewritten the expected parameters as you recommended (however I had to use
instead of CueLinePos as you told, since that way it was hiding the global variable. I'm giving value to the CueLinePos variable like this:
but when I try to call the Bsearch function like this:
I get an error:
'[' - objects are passed by reference only.
I tried to add the ampersand before the index like MarkerArray[&index], then I got:
'&' - illegal operation use
'index' - class type expected
'[' - objects are passed by reference only
When I comment out the Print statement, the function always returns 0. A sample output:
/* 2023.08.25 11:10:48.427 [timestamp] [flag] 2023.08.25 11:10:48.427 [0] 2023.08.25 00:40:00 "SBY" 2023.08.25 11:10:48.427 [1] 2023.08.25 00:39:00 "IDL" 2023.08.25 11:10:48.427 [2] 2023.08.25 00:38:00 "SSL" 2023.08.25 11:10:48.427 [3] 2023.08.25 00:37:00 "SBY" 2023.08.25 11:10:48.427 After sort: 2023.08.25 11:10:48.427 [timestamp] [flag] 2023.08.25 11:10:48.427 [0] 2023.08.25 00:37:00 "SBY" 2023.08.25 11:10:48.427 [1] 2023.08.25 00:38:00 "SSL" 2023.08.25 11:10:48.427 [2] 2023.08.25 00:39:00 "IDL" 2023.08.25 11:10:48.427 [3] 2023.08.25 00:40:00 "SBY" 2023.08.25 11:10:48.427 Index of the found element: 0 2023.08.25 11:10:48.427 Current CueLinePos value: 2023.08.25 00:37 */
Maybe the different format in the datetime causes this issue? It is stored in the array as TIME_DATE|TIME_MINUTES|TIME_SECONDS but when I print its value out it comes as TIME_DATE|TIME_MINUTES. And how to solve the pass by reference error?
Thank you in advance, from this point, I can see the finish line.
I asked ChatGPT to evaluate the the function above and it gave the following answer:
" In summary, the provided function is an efficient binary search algorithm that searches for the specified CueLinePos timestamp value within the sorted MarkerData array. If the timestamp is found, the algorithm returns the index of the value; otherwise, it returns -1 to indicate that the desired value is not present in the array."