How to dynamically create a lookup table?

 

I am looking for a way to create a lookup table. 

Currently my logic is as folows:

uint MagicScan(const ulong Magic = 0)
 {
   int s = 0; 
   for (s=0;s<EATotal;s++) 
     if(System[s].GetMagic() == Magic)
       {
          return s;
       }
       
  return 0;
 }

This function returns the index of the System array given the Magic number.

This all works fine and dandy. However, this function runs ArraySize(System) times in OnTick as well as other On* handlers. So it is in fact quite an expensive function considering when from within OnInit both magic numbers, and to which index the magic number belongs to is known. So a simple lookup table sounds like a no-brainer to me.

I can not seem to picture how this seemingly simple task is written in code. How to dynamically create a list where the input (Magic number) returns an index without looping.

To solve this i have been looking at CList but most likely i am lacking the OOP knowledge.

Any pointers will be appreciated.

 
Enrique Dangeroux: However, this function runs ArraySize(System) times in OnTick as well as other On* handlers. So it is in fact quite an expensive function

So stop doing that.

  1. Remember the index when you add the MN.
  2. Why do you need more than one MN? That just allows you to differentiate the EAs orders from other EAs.
    1. EAs : Don't do per tick that you can do per bar, or on open.
      If you are waiting for a level, don't reevaluate, wait until price reaches it (or a new bar starts and you recalculate.)
      If you are waiting for an order to close, only look when OrdersTotal (or MT5 equivalent) has changed.
                How to get backtesting faster ? - MT4 - MQL4 programming forum 2017.08.07

    2. Indicators: Code it properly so it only recomputes bar zero (after the initial run.)
                How to do your lookbacks correctly. 2016.05.11
      Or, reduce Tools → Options (control+O) → Charts → Max bars in chart to something reasonable (like 1K.)

 
Enrique Dangeroux:

I am looking for a way to create a lookup table. 

Currently my logic is as folows:

This function returns the index of the System array given the Magic number.

This all works fine and dandy. However, this function runs ArraySize(System) times in OnTick as well as other On* handlers. So it is in fact quite an expensive function considering when from within OnInit both magic numbers, and to which index the magic number belongs to is known. So a simple lookup table sounds like a no-brainer to me.

I can not seem to picture how this seemingly simple task is written in code. How to dynamically create a list where the input (Magic number) returns an index without looping.

To solve this i have been looking at CList but most likely i am lacking the OOP knowledge.

Any pointers will be appreciated.

Look at CHashMap.

In your MT5, there is an example how to use it in MQL5\Scripts\UnitTests\Generic\TestHashMap.mq5

Documentation on MQL5: Standard Library / Generic Data Collections / CHashMap
Documentation on MQL5: Standard Library / Generic Data Collections / CHashMap
  • www.mql5.com
CHashMap - Generic Data Collections - Standard Library - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Alain Verleyen:

Look at CHashMap.

In your MT5, there is an example how to use it in MQL5\Scripts\UnitTests\Generic\TestHashMap.mq5

Thanks Alain. Exactly what i was looking for. Unfortunately, in my use case it is slower then my crutch.

CHashmap

2021.02.05 12:45:35.834 Trader (GBPAUD,H1)      67686479 ticks copied
2021.02.05 12:45:35.834 Trader (GBPAUD,H1)      Calculating history from 2020.02.29 00:00
2021.02.05 12:46:46.329 Trader (GBPAUD,H1)      Done in 70 seconds

Crutch

2021.02.05 12:48:20.767 Trader (GBPAUD,H1)      67686803 ticks copied
2021.02.05 12:48:20.767 Trader (GBPAUD,H1)      Calculating history from 2020.02.29 00:00
2021.02.05 12:49:26.444 Trader (GBPAUD,H1)      Done in 65 seconds

For larger maps Chashmap will be faster for sure, however in my case the the map will be no larger then 10. 

 

Hash map is usually what's appropriate. 

However, sometimes it's appropriate to use parts of the magic number as different codes.
For example, if you are sure to have just up to 10 magic numbers, maybe you want to make sure each magic has a last (or first) distinct digit.

If you can handle that, you might be having the direct index to the array.

For instance:
Magic1: nnnnnnnnn1 - (goes to ind 1)
Magic2: nnnnnnnnn2 - (goes to ind 2)

Or if you will need more than 10, you can use the last byte of magic as an hex for up to 256 indexes.

Etc.

 

Thanks. Researching more it seems there is no alternative but to somehow try something similar like you suggest. 

Reason: