(MQL question for you advanced gurus) Is there a better way to make a two-dimensional object array using the standard library?

 

Here's an example script I made for tracking groups of symbols by using the standard library to create two dimensional objects arrays. Can anyone tell me if there is a better way? Thanks! :)

 

#include <Arrays\ArrayObj.mqh>
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CSymbol : public CObject
{
private:
   string            m_symbol;
public:
                     CSymbol(const string symbol):m_symbol(symbol){}
   string            Symbol()    const { return m_symbol;                              }
   double            Ask()       const { return SymbolInfoDouble(m_symbol,SYMBOL_ASK); }
   double            Bid()       const { return SymbolInfoDouble(m_symbol,SYMBOL_BID); }          
};
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CSymbolGroup : public CArrayObj
{
public:
   void              Add(const string symbol)   { this.Add(new CSymbol(symbol));       }
   CSymbol          *operator[](const int index) const { return((CSymbol*)At(index));  }
};
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CSymbolMaster : public CArrayObj
{
public:              
   CSymbolGroup     *operator[](const int index) const { return((CSymbolGroup*)At(index)); }
};
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   CSymbolMaster Master;
   CSymbolGroup  *group;
   //--- Group 1
   group = new CSymbolGroup;
   group.Add("EURUSD");
   group.Add("USDJPY");
   group.Add("EURGBP");
   Master.Add(group);
   //--- Group 2
   group = new CSymbolGroup;
   group.Add("EURJPY");
   group.Add("GBPJPY");
   group.Add("CADCHF");
   Master.Add(group);
  
   for(int i = 0; i < Master.Total();i++)
   {
      Print("Group ",i+1);
      for(int j = 0; j < Master[i].Total();j++)
      {
         Print(Master[i][j].Symbol(),
               " Bid = ",Master[i][j].Bid(),
               " | Ask = ",Master[i][j].Ask()
               );
      }
   }  
}
//+------------------------------------------------------------------

/* OUTPUT--

Group 1

EURUSD Bid = 1.06009 | Ask = 1.06015

USDJPY Bid = 114.194 | Ask = 114.205

EURGBP Bid = 0.85037 | Ask = 0.85048

Group 2

EURJPY Bid = 121.058 | Ask = 121.072

GBPJPY Bid = 142.348 | Ask = 142.372

CADCHF Bid = 0.76893 | Ask = 0.76914

*/ 

 
This snippet gathers name, ask & bid prices of each symbols of the marketwatch.
void ListPrices()
{
int total = SymbolsTotal(true);
string instrument[];
string symname;
double Ask[], Bid[];
for(int i=0;i<total;i++)
{
   symname = SymbolName(i,true); SymbolSelect(symname,true);
   ArrayResize(Ask,ArraySize(Ask)+1); ArrayResize(Bid,ArraySize(Bid)+1); ArrayResize(instrument,ArraySize(instrument)+1);
   Ask[i] =  SymbolInfoDouble(symname,SYMBOL_ASK); Bid[i] = SymbolInfoDouble(symname,SYMBOL_BID); instrument[i] = symname;      
   printf("Ask : %g, Bid : %g, Name : %s",Ask[i],Bid[i],instrument[i]);
}
}
Returns :
2017.02.20 20:47:46.375 x (x,H1)        Ask : 1.06147, Bid : 1.06134, Name : EURUSD
2017.02.20 20:47:46.375 x (x,H1)        Ask : 113.144, Bid : 113.104, Name : USDJPY
2017.02.20 20:47:46.375 x (x,H1)        Ask : 1.24664, Bid : 1.24656, Name : GBPUSD
2017.02.20 20:47:46.375 x (x,H1)        Ask : 1.3101, Bid : 1.30978, Name : USDCAD
2017.02.20 20:47:46.375 x (x,H1)        Ask : 1.39051, Bid : 1.39028, Name : EURCAD
If you wish to use it for the whole list, feel free to switch the true/false flags for SymbolsTotal, SymbolName & SymbolSelect.

It may fill symbols dependencies when watching for prices - just like the tester do ; so they're added in the marketwatch - yet you can filter the thing.
 
Icham Aidibe:
This snippet gathers name, ask & bid prices of each symbols of the marketwatch.
void ListPrices()
{
int total = SymbolsTotal(true);
string instrument[];
string symname;
double Ask[], Bid[];
for(int i=0;i<total;i++)
{
   symname = SymbolName(i,true); SymbolSelect(symname,true);
   ArrayResize(Ask,ArraySize(Ask)+1); ArrayResize(Bid,ArraySize(Bid)+1); ArrayResize(instrument,ArraySize(instrument)+1);
   Ask[i] =  SymbolInfoDouble(symname,SYMBOL_ASK); Bid[i] = SymbolInfoDouble(symname,SYMBOL_BID); instrument[i] = symname;      
   printf("Ask : %g, Bid : %g, Name : %s",Ask[i],Bid[i],instrument[i]);
}
}
Returns :
2017.02.20 20:47:46.375 x (x,H1)        Ask : 1.06147, Bid : 1.06134, Name : EURUSD
2017.02.20 20:47:46.375 x (x,H1)        Ask : 113.144, Bid : 113.104, Name : USDJPY
2017.02.20 20:47:46.375 x (x,H1)        Ask : 1.24664, Bid : 1.24656, Name : GBPUSD
2017.02.20 20:47:46.375 x (x,H1)        Ask : 1.3101, Bid : 1.30978, Name : USDCAD
2017.02.20 20:47:46.375 x (x,H1)        Ask : 1.39051, Bid : 1.39028, Name : EURCAD
If you wish to use it for the whole list, feel free to switch the true/false flags for SymbolsTotal, SymbolName & SymbolSelect.

It may fill symbols dependencies when watching for prices - just like the tester do ; so they're added in the marketwatch - yet you can filter the thing.

Thanks for the reply, but I was just using the above as an example... I need a jagged object array, and this is quite effective but I don't want to keep declaring a separate class for every Object array and have to overload the operator. Is there a way to implement this using a template? 

Reason: