Discussão do artigo "Como acessar o banco de dados MySQL a partir do MQL5 (MQL4)"

 

Novo artigo Como acessar o banco de dados MySQL a partir do MQL5 (MQL4) foi publicado:

Este artigo descreve o desenvolvimento de uma interface entre o banco de dados MySQL e a linguagem MQL. Ele discute soluções práticas existentes e oferece uma maneira mais conveniente de implementar uma biblioteca para trabalhar com o bancos de dados. O artigo contém uma descrição detalhada das funções, a estrutura da interface, exemplos e algumas características específicas de se trabalhar com o MySQL. Quanto às soluções de software, encontramos em anexo no artigo os arquivos de bibliotecas dinâmicas, documentação e exemplos de script para as linguagem MQL4 e MQL5.

O problema de interação entre o MQL e com os bancos de dados não são novos, no entanto, é algo ainda relevante. O uso de bancos de dados podem aumentar consideravelmente as possibilidades do MetaTrader: armazenamento e análise do histórico de preços, copiar negociações de uma plataforma de negociação para outra, fornecer cotações/negociações em tempo real, realizar cálculos computacionais analíticos ​​no lado do servidor e/ou usar uma agenda, monitoramento remoto e controle de contas utilizando a tecnologia web.

De qualquer forma, houve muitas tentativas para se beneficiar da combinação do MQL e MySQL, algumas soluções estão disponíveis na Base de código.

Por exemplo, o projeto "MySQL wrapper -biblioteca para MetaTrader 4", do qual muitos programadores iniciaram seus próprios desenvolvimentos adicionando mais recursos. Na minha opinião, um dos inconvenientes desta solução é atribuição de arrays especiais para a leitura de dados a partir do banco de dados.

Outro projeto "MySQL logger 1 - EA para MetaTrader 4" é altamente especializado, ele não utiliza o wrapper para acessar a biblioteca padrão libmysql.dll. Portanto ele não funciona no MetaTrader4 build 600+, uma vez que os caracteres do tipo char foram substituídos por wchar_t, e a utilização do tipo int, em vez da estrutura do ponteiro TMYSQL fez com que houvessem vazamentos de memória no projeto (a memória alocada não podia ser controlada/liberada).

Outro projeto interessante é o projeto "EAX_Mysql - MySQL library - biblioteca para MetaTrader 5". É uma implementação muito boa. A lista de desvantagens indicadas pelo autor impõe algumas restrições ao seu uso.

Qualquer um que nunca precisou usa bancos de dados em seus projetos MQL tem duas opções: ou desenvolver sua própria solução e saber cada parte dela, ou usar / adaptar qualquer solução de terceiros, aprender a usá-la e detectar todos os seus defeitos que podem dificultar de alguma maneira o seu projeto.

Eu enfrentei tal necessidade enquanto eu desenvolvia um robô de negociação bem complexo. Tendo procurado por projetos existentes e estudado um número muito grande de soluções, eu percebi que nenhuma das implementações encontradas poderiam me ajudar a levar o meu robô de negociação para o "nível profissional".

Além disso, houve também soluções absurdas, por exemplo: as operações DML/DDL (inserir/atualizar/remover dados, criar objetos/excluir do banco de dados) foram realizadas utilizando a libmysql.dll padrão, e a seleção de dados (SELECT) foi realmente implementada como um solicitação HTTP (utilizando inet.dll) para um script PHP localizado no servidor web no lado do servidor MySQL. As consultas em SQL foram escritas no script em PHP.

Em outras palavras, para executar o projeto, era preciso manter os seguintes componentes disponíveis, configurado e em execução: servidor MySQL, o servidor web Apache/IIS, os scripts PHP/ASP no lado do servidor... Uma combinação de um número bem grande de tecnologias. É claro que, em algumas circunstâncias, isto pode ser aceitável, mas apenas quando a tarefa é a de selecionar os dados a partir do banco de dados - isto é um absurdo. Além disso, o suporte de uma solução tão complicada é demorada.

A maioria das soluções não tinha problemas na inserção de dados, criação de objetos e similares. O problema foi a seleção de dados, como os dados devem ser devolvidos para o ambiente de chamada.

Eu pensei em usar arrays para este fim, mas era pouco prático e inconveniente, simplesmente porque durante o desenvolvimento/depuração/suporte do projeto principal, as consultas selecionadas para o banco de dados podem ser alteradas, enquanto que você também deve controlar a alocação de memória correta para os arrays... Bom, isto pode e deve ser evitado.

A seguir eu discuto a interface MQL <-> MySql que é baseada em uma abordagem típica utilizada em Oracle PL/SQL, MS SQL T-SQL, AdoDB - trabalhando com cursores. Esta interface foi desenvolvida com objetivo de facilitar a programação e manutenção, além de minimizar seus componentes. Ela é implementada como um DLL wrapper para a biblioteca padrão libmysql.dll e um conjunto de funções de interface como um arquivo em ".mqh".


1. A Interface MQL <-> MySQL

A interação entre o terminal MetaTrader (através dos programas MQL) pode ser implementada com a ajuda dos componentes abaixo:

O esquema de interação MQL e MySQL

Autor: Eugeniy Lugovoy

 
DB = MySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag);

Isso não criará uma grande carga ao chamar cada tick?????

Não seria mais lógico conectar-se ao banco de dados no init e depois usar o identificador para acesso?

 
DKeN:

Isso não criará uma grande carga ao chamar cada tick?????

Não seria mais lógico conectar-se ao banco de dados no init e depois usar o identificador para acesso?

Saudações. Para Expert Advisors e Indicadores, a conexão com o banco de dados é feita na função de inicialização. Não há recomendações no artigo sobre como estabelecer uma conexão com o banco de dados em cada tick. São fornecidos apenas exemplos de scripts, e os scripts, como você sabe, não têm inicialização.
 

Eugene, obrigado pelo artigo. Material interessante sobre DBMS.

Estou com um problema.

Tenho o MetaTrader5, x64, versão 975.

Ao executar o script "MySQL-001", recebo um erro:

RL      1       12:41:22.443    MySQL-001       'C:\Program Files\MetaTrader5\MQL5\libraries\MQLMySQL.dll' is not 64-bit version
PG      1       12:41:22.474    MySQL-001 (AUDCAD.e,M1) Cannot load 'C:\Program Files\MetaTrader5\MQL5\libraries\MQLMySQL.dll'
DK      2       12:41:23.677    MySQL-001 (AUDCAD.e,M1) Cannot call 'cMySqlVersion', '..\libraries\MQLMySQL.dll' is not loaded
ID      2       12:41:23.677    MySQL-001 (AUDCAD.e,M1) unresolved import function call

O motivo é que, pelo que entendi, o sistema está tentando carregar uma biblioteca de 64 bits...

 
denkir:

Eugene, obrigado pelo artigo. Material interessante sobre DBMS.

Estou com um problema.

Tenho o MetaTrader5, x64, versão 975.

Ao executar o script "MySQL-001", recebo um erro:

O motivo, pelo que entendi, é que o sistema está tentando carregar uma biblioteca de 64 bits...

Sim, o projeto está compilado para x32, pois trabalho principalmente com terminais de 32 bits. Entendo o problema, vou compilá-lo e testá-lo no MT5 x64 nos próximos dias.

Obrigado pelo comentário.

 

Versão da biblioteca para Metatrader 5 - x64

- O projeto MQLMySQL.DLL foi recompilado para x64 (os códigos-fonte não foram corrigidos).

- O LibMySQL.DLL padrão foi retirado da última distribuição estável do MySQL v5.6.21 x64

Na verdade, para aqueles que tentaram executar o projeto no MT5 x64, você pode substituir apenas o conteúdo do diretório MQL5\Libraries. O código-fonte dos programas MQL não precisa ser corrigido ou recompilado.

Agradeço novamente ao Denis (denkir) por sua observação, esqueci-me dos usuários do x64.

Arquivos anexados:
 

Eu o li e chorei. Não tenho nada contra o autor. Espero que ele trate as críticas adequadamente. De qualquer forma:

1. Por que escrever um wrapper na forma de outra DLL, se tudo funciona bem sem ele? A linguagem MQL não está no estágio de desenvolvimento em que se encontra para escrever tais muletas que, muitas vezes, se transformam em armadilhas.

2. Por que, como resultado de todo esse trabalho, não foi escrita uma classe que tenha tudo o que é necessário e que elimine as deficiências dos antecessores, aos quais o autor se refere?

3) Eu gostaria de observar especialmente o seguinte:

string SQL;
SQL = "INSERT INTO EURUSD(Ask,Bid) VALUES (1.3601,1.3632);";
SQL = SQL + "INSERT INTO EURUSD(Ask,Bid) VALUES (1.3621,1.3643);";
SQL = SQL + "INSERT INTO EURUSD(Ask,Bid) VALUES (1.3605,1.3629);";

Na verdade, tudo é muito mais simples:

string SQL="INSERT INTO EURUSD(Ask,Bid) VALUES (1.3601,1.3632),(1.3621,1.3643),(1.3605,1.3629);";

Em geral, o artigo é escrito no estilo "Veja o que eu posso fazer!" em vez de "Veja e aprenda como isso deve ser feito".

 
avoitenko:

Eu o li e chorei. Não tenho nada contra o autor. Espero que ele trate as críticas adequadamente. De qualquer forma:

1. Por que escrever um wrapper na forma de outra DLL, se tudo funciona bem sem ele? A linguagem MQL não está no estágio de desenvolvimento em que se encontra para escrever tais muletas que, muitas vezes, se transformam em armadilhas.

2. Por que, como resultado de todo esse trabalho, não foi escrita uma classe que tenha tudo o que é necessário e que elimine as deficiências dos antecessores, aos quais o autor se refere?

3) Eu gostaria de observar especialmente o seguinte:

Na verdade, tudo é muito mais simples:

Em geral, o artigo foi escrito no estilo "Veja o que eu posso fazer!" em vez de "Veja e aprenda como isso deve ser feito".

Vou responder na ordem.

Devo dizer que o projeto foi iniciado há muito tempo, quando a linguagem MQL não estava no estágio atual de desenvolvimento e a MQL4 não tinha classes, nem estruturas.

E a solução de software tinha que funcionar tanto para MQL4 quanto para MQL5 com custos mínimos para a transição de MQL4 para MQL5 (se necessário). O projeto estava sendo finalizado até recentemente.

É por isso que o projeto não foi implementado como uma aula. Você quer uma classe? Sem problemas - escreva-a! Ninguém o proíbe.

Agora, com relação a 3 INSERTs em vez de um. Eu o escrevi dessa forma (e isso é copyright) pelos seguintes motivos:

- ele não viola o padrão geralmente aceito SQL'92, SQL'2000 (sua variante - peculiaridades de sintaxe exatamente MySQL bulk insert);

- será mais fácil para um programador novato nessa área ler e entender;

- demonstração da execução de exatamente 3 instruções INSERT, não uma.

As instruções múltiplas podem incluir qualquer operação DML/DDL/DCL; seu exemplo se limita à operação INSERT em uma tabela.

P.S. O artigo foi escrito em um estilo "Pegue e use".

 

Obrigado! Examinarei sua solução em profundidade, pois ela pode ser mais estável do que depender apenas da MQL.

Para sua informação, há uma ponte somente para MQL4 que escrevi há algum tempo para o MT4 build 600+: https://www.mql5.com/pt/code/11114

MySQL for new MQL4 (tested in build 600)
MySQL for new MQL4 (tested in build 600)
  • votos: 12
  • 2014.02.10
  • Sergey
  • www.mql5.com
Connecting to MySQL server from new MQL4
 
lukins:

Obrigado! Examinarei sua solução em profundidade, pois ela pode ser mais estável do que depender apenas da MQL.

Para sua informação, há uma ponte somente para MQL4 que escrevi há algum tempo para o MT4 build 600+: https://www.mql5.com/pt/code/11114

Obrigado por seu tempo lendo este artigo. Também verifiquei o seu(https://www.mql5.com/pt/code/11114), encontrei essa solução há muito tempo (antes do MT4 build 600) e gostei da ideia de tornar o MQL e o MySQL amigáveis. Mas só há uma coisa que não quero usar: matrizes para recuperar os dados do banco de dados. É por isso que criei essa solução para ser usada com o MT4 e o MT5.

Além disso, esqueci de adicionar o projeto baseado em x64 ao artigo, portanto, você pode baixá-lo aqui mesmo, na discussão. Nada foi alterado nos códigos-fonte, apenas a DLL foi recompilada para x64.

Boa sorte,

Eugênio

MySQL for new MQL4 (tested in build 600)
MySQL for new MQL4 (tested in build 600)
  • votos: 12
  • 2014.02.10
  • Sergey
  • www.mql5.com
Connecting to MySQL server from new MQL4
Arquivos anexados:
 
Para plataformas x64, use as seguintes bibliotecas (com discussão)
Arquivos anexados: