Bibliotecas: CDictionary

 

CDictionary:

Implementação de um dicionário (matriz associativa), em MQL5, baseada em CArrayObj e CList.

Autor: Enrico Lambino

 
Automated-Trading:

Classe CDictionary:

Autor: Enrico Lambino

Olá, Enrico,

Muito bom trabalho, amigo.

Muito obrigado,

Shep

 
Shephard Mukachi:

Oi Enrico,

Muito bom trabalho, amigo.

Muito obrigado,

Shep

De nada. Fiz o upload conforme prometido :)

Além disso, você estava certo sobre a parte da serialização. Eu esqueci o método CreateElement() no CArrayObj. Só é possível salvar e carregar objetos se você souber de antemão que tipo de objetos salvar e carregar, ou se o MQ introduzir um novo recurso que converta string em tipo genérico. É por isso que fiz o upload sem os métodos Save() e Load().

 

Implementação muito inteligente. Bom trabalho! Fiz alguns ajustes para facilitar o trabalho (para minhas necessidades). Em vez de manter vários tipos de dados, essa versão ajustada mantém apenas um, mas não exige a especificação do tipo de dados ao chamar o método get, e também não exige uma entrada de chave de cadeia de caracteres, pois a chave é modelada e convertida em cadeia de caracteres dentro da classe do dicionário. Exemplo:


   CDictionary<double> dict;
   for(int i=0;i<Bars;i++)
      dict.Add(Time[i],Close[i]);
   for(int i=0;i<Bars;i++)
      if(dict[Time[i]] != Close[i])
         Print("Collision Error ",++cnt); 
Arquivos anexados:
Dictionary.mqh  16 kb
 
nicholishen:

Implementação muito inteligente. Bom trabalho! Fiz alguns ajustes para facilitar o trabalho (para minhas necessidades). Em vez de manter vários tipos de dados, essa versão ajustada mantém apenas um, mas não exige a especificação do tipo de dados ao chamar o método get, e também não exige uma entrada de chave de cadeia de caracteres, pois a chave é modelada e convertida em cadeia de caracteres dentro da classe do dicionário. Exemplo:


Versão interessante. Obrigado por compartilhar suas ideias.

As versões anteriores dessa classe tinham Dictionary<T>. Mas, mais tarde, eu a modifiquei. Para minhas próprias necessidades, eu precisava de algo que permitisse armazenar vários tipos de dados ao mesmo tempo, mas também posso ver alguns aplicativos em que sua versão é mais adequada para a tarefa (e menos complicada, eu concordo).

 

Além disso, uso a classe de mesmo nome de @Vasiliy Sokolov, que funciona muito bem. Acabei de ver este, vamos baixá-lo agora

https://www.mql5.com/pt/articles/1334

Рецепты MQL5 - Реализуем ассоциативный массив или словарь для быстрого доступа к данным
Рецепты MQL5 - Реализуем ассоциативный массив или словарь для быстрого доступа к данным
  • 2015.03.23
  • Vasiliy Sokolov
  • www.mql5.com
Эта статья описывает удобный класс для хранения информации - ассоциативный массив или словарь. Благодаря этому классу можно получать доступ к информации по ее ключу. Ассоциативный массив напоминает обычный массив, однако вместо индекса он использует некий уникальный ключ, например, перечисление ENUM_TIMEFRAMES или какой-либо текст. Что...
 

Muito bom trabalho.

Para mim, não entendo a vantagem de estender o CArrayObj, já que a maioria das coisas que podem ser feitas com o CArrayObj são proibidas no CDictionary (como Sort() etc.) e podem causar problemas em caso de mau uso.
Na verdade, o CDictionary não é um CArrayObj (desafia o princípio de herança de Liskov). Portanto, não há uso real do CArrayObj.
Em vez disso, eu estenderia o CObject e teria m_data[] dentro dele.

*-Nova versão do DictionarySingle: Adicionada iteração serial e gerenciamento de memória, algumas pequenas refatorações
Arquivos anexados:
 
Amir Yacoby:

Muito bom trabalho.

Para mim, não entendo a vantagem de estender o CArrayObj, já que a maioria das coisas que podem ser feitas com o CArrayObj são proibidas no CDictionary (como Sort() etc.) e podem causar problemas em caso de mau uso.
Na verdade, o CDictionary não é um CArrayObj (desafia o princípio de herança de Liskov). Portanto, não há uso real do CArrayObj.
Em vez disso, eu estenderia o CObject e teria m_data[] dentro dele.

Presumo que isso se deva ao fato de o MQL não permitir

class SubClass : private SuperClass


Mas não há necessidade de jogar o bebê fora junto com a água do banho. Você poderia simplesmente envolver um objeto CArrayObj em vez de implementá-lo por meio de derivação.
 
nicholishen:

Presumo que isso se deva ao fato de o MQL não permitir

class SubClass : private SuperClass


Mas não há necessidade de jogar o bebê fora junto com a água do banho. Você poderia simplesmente envolver um objeto CArrayObj em vez de implementá-lo por meio de derivação.

O wrapping foi minha primeira opção.
Mas então notei que não é tão trivial, pois m_data_max e m_data_total são ambos protegidos em CArrayObj e têm apenas um getter, e o algoritmo precisa de um setter.
O m_data_max também é usado de forma um pouco diferente em CArrayObj.

Mas enfim,

class SubClass : private SuperClass

é permitido na MQL5, o que pode ser uma solução.
O único motivo que vejo para usar CArrayObj é a liberação de memória, o que é bem simples de fazer.
Porque não vejo nada mais sendo usado em CArrayObj.

Ele é usado principalmente como CObject *m_data[] - e esse não é um motivo suficiente para estendê-lo, na minha opinião.

 
Amir Yacoby:

A primeira opção foi o wrapping.
Mas depois notei que não é tão trivial, pois m_data_max e m_data_total são protegidos em CArrayObj e têm apenas um getter, e o algoritmo precisa de um setter.
O m_data_max também é usado de forma um pouco diferente em CArrayObj.

Mas enfim,

é permitido na MQL5, o que pode ser uma solução.
O único motivo que vejo para usar o CArrayObj é a liberação de memória, o que é bem simples de fazer.
Porque não vejo nada mais sendo usado no CArrayObj.

Ele é usado principalmente como CObject *m_data[] - e esse não é um motivo suficiente para estendê-lo, na minha opinião.

Agradeço suas sugestões. Eu concordo. O uso do CArrayObj é opcional nesse caso.
Há muitas alternativas. Você pode tornar a superclasse privada, como você disse, ou herdar diretamente do CObject (seu código de exemplo), ou ficar no meio do caminho: estender o CArray em vez do CArrayObj para que ele fique seguro contra uso indevido acidental (nenhuma classificação real é feita).
A maioria dos métodos necessários do CArrayObj não é tão difícil de reimplementar. A minha solução é um pouco opinativa (optei por reutilizar o máximo de código possível para essa classe).
Sinta-se à vontade para modificar como achar melhor.

 
Versão atualizada do DictionarySingle - adicionada iteração em série na ordem de adição de objetos, adicionado gerenciamento automático de memória e um pouco de refatoração.
Exemplo de iteração:
   CDictionary<double> dict;
    datetime time[];
   double close[];
   ulong bars=Bars(_Symbol,_Period);
   ArraySetAsSeries(time,true);
   ArraySetAsSeries(close,true);
   CopyTime(_Symbol,_Period,0,Bars(_Symbol,_Period),time);
   CopyClose(_Symbol,_Period,0,Bars(_Symbol,_Period),close);
   for(int i=0;i<20;i++) //Bars(_Symbol,_Period);i++)
     {
      dict.Add(time[i],close[i]);
      //dict.Add(time[i],close[i]*100);
     }

   //--- para frente
   CDictionaryEntry<string> *node=dict.GetFirstNode();
   for(int i=0; node!=NULL; i++)
     {
      printf((string)i+":\t"+node.Value());
      node=dict.GetNextNode();
     }
   //--- para trás
   node=dict.GetLastNode();
   for(int i=0; node!=NULL; i++)
     {
      printf((string)i+":\t"+node.Value());
      node=dict.GetPrevNode();
     }
Arquivos anexados: