English Русский 中文 Español Deutsch 日本語 Português 한국어 Italiano Türkçe
Comment accéder à la base de données MySQL à partir de MQL5 (MQL4)

Comment accéder à la base de données MySQL à partir de MQL5 (MQL4)

MetaTrader 5Intégration | 13 janvier 2022, 14:38
585 0
Eugeniy Lugovoy
Eugeniy Lugovoy

Introduction

Le problème de l'interaction de MQL avec les bases de données n'est pas nouveau, mais il est toujours d'actualité. L'utilisation de bases de données peut grandement améliorer les possibilités de MetaTrader : stockage et analyse de l'historique des prix, copie des transactions d'une plateforme de trading à une autre, fourniture de cotations/trades en temps réel, calculs analytiques lourds côté serveur et/ou utilisation d'un planning, suivi et contrôle à distance des comptes à l'aide des technologies web.

Quoi qu'il en soit, il y a eu de nombreuses tentatives pour bénéficier de la combinaison de MQL et MySQL, certaines solutions sont disponibles dans le CodeBase.

Par exemple, « MySQL wrapper - bibliothèque pour MetaTrader 4 » est le projet à partir duquel de nombreux programmeurs commencent leurs propres développements avec d'autres ajouts. À mon avis, l'un des inconvénients de cette solution est l'allocation de tableaux spéciaux pour la lecture des données de la base de données.

Un autre projet « MySQL logger 1 - EA pour MetaTrader 4 » est hautement spécialisé, il n'utilise aucun wrapper pour accéder à la bibliothèque standard libmysql.dll. Par conséquent, cela ne fonctionne pas dans MetaTrader4 Build 600+, car les types de caractères char ont été remplacés par wchar_t, et l'utilisation du type int au lieu du pointeur de structure TMYSQL provoque des fuites de mémoire dans le projet (la mémoire allouée ne peut pas être contrôlée/libéré).

Un autre projet intéressant est « EAX_Mysql - Bibliothèque MySQL - bibliothèque pour MetaTrader 5 ». C'est une très bonne mise en œuvre. La liste des inconvénients énoncés par l'auteur impose certaines restrictions à son utilisation.

Quiconque a besoin d'utiliser des bases de données dans ses projets MQL a deux options : soit développer sa propre solution et en connaître chaque partie, soit utiliser/adapter n'importe quelle solution tierce, apprendre à l'utiliser et détecter tous ses défauts qui peuvent entraver son projet.

J'ai été confronté à une telle nécessité et aux deux options tout en développant un robot de trading assez complexe. Après avoir parcouru des projets existants et étudié un très grand nombre de solutions, je me suis rendu compte qu'aucune des implémentations trouvées ne pouvait aider à amener mon robot de trading au « niveau professionnel ».

De plus, il y avait aussi des solutions absurdes, par exemple : Les opérations DML/DDL (insertion/mise à jour/suppression de données, création/suppression d'objets dans la base de données) ont été effectuées à l'aide de la norme libmysql.dll, et la sélection de données (SELECT) a en fait été implémentée en tant que requête HTTP (en utilisant inet.dll) vers un PHP script situé sur le serveur web côté serveur MySQL. Les requêtes SQL ont été écrites dans le script PHP.

En d'autres termes, pour exécuter le projet, il fallait garder les composants suivants disponibles, configurés et en cours d'exécution : Serveur MySQL, serveur web Apache/IIS, scripts PHP/ASP côté serveur... Une combinaison d'un assez grand nombre de technologies. Bien sûr, dans certaines circonstances, cela peut être acceptable, mais lorsque la seule tâche consiste à sélectionner des données dans la base de données, cela n'a aucun sens. De plus, la prise en charge d'une solution aussi lourde prend du temps.

La plupart des solutions n'avaient aucun problème pour insérer des données, créer des objets, etc. Le problème était la sélection des données, car les données devaient être renvoyées à l'environnement appelant.

Je pensais que l'utilisation de tableaux à cette fin était peu pratique et peu convenable, simplement parce qu'au cours du développement/débogage/prise en charge du projet principal, les requêtes sélectionnées dans la base de données peuvent être modifiées, tandis que vous devez également contrôler l'allocation de mémoire correcte pour les tableaux. . Eh bien, cela peut et doit être évité.

L'interface MQL <-> MySql discutée ci-après est basée sur une approche typique utilisée dans Oracle PL/SQL, MS SQL T-SQL, AdoDB - utilisation de curseurs. Cette interface a été développée en ciblant la facilité de programmation et de maintenance, ainsi qu'un minimum de composants. Il est implémenté en tant que wrapper de DLL dans la bibliothèque standard libmysql.dll et un ensemble de fonctions d'interface en tant que fichier .mqh.


1. Interface MQL <-> MySQL

L'interaction entre le terminal MetaTrader (via les programmes MQL) peut être mise en œuvre à l'aide des composants ci-dessous :

 schéma d'interaction MQL et MySQL

1. La bibliothèque d'interface MQLMySQL.mqh. Elle est ajoutée au projet à l'aide du répertoire #include et peut être modifiée à votre convenance.

Elle contient les directives d'import des fonctions de la bibliothèque dynamique MQLMySQL.dll, ainsi que les fonctions d'appel et de gestion des erreurs.

2. La bibliothèque dynamique MQLMySQL.dll. C'est un wrapper pour accéder aux fonctionnalités de la bibliothèque standard libmysql.dll.

De plus, la bibliothèque MQLMySQL.dll traite les résultats des opérations et l'accès partagé aux connexions et curseurs de la base de données. Cela signifie que vous pouvez créer et utiliser plusieurs connexions à la fois (à partir d'un ou plusieurs programmes MQL), garder quelques curseurs ouverts, avec des requêtes vers une ou plusieurs bases de données. Les mutex sont utilisés pour séparer l'accès aux ressources partagées.

3. La bibliothèque dynamique standard libmysql.dll est un pilote d'accès natif. Vous pouvez la copier à partir de n'importe quelle distribution de base de données MySql dans C:\Windows\Sytem32 ou <Terminal>\MQL5\Libraries (pour MetaTrader 4 dans <Terminal>\MQL4\Libraries).

En fait, elle est chargée d'envoyer des requêtes à la base de données et d'en récupérer les résultats.

Attardons-nous sur les points principaux, tels que : l'ouverture/fermeture de la connexion, l'exécution de requêtes DML/DDL et la sélection de données.

1.1. Ouverture et fermeture de la connexion

La fonction MySqlConnect a été implémentée pour ouvrir la connexion avec la base de données MySQL :

Type

Nom

Paramètres

Description

int

MySqlConnect

Cette fonction implémente la connexion avec la base de données et renvoie un identifiant de connexion. Cet identifiant sera requis pour interroger la base de données.

En cas d'échec de connexion, la valeur de renvoi est « -1 ». Pour les détails de l'erreur, vérifiez les variables MySQLErrorNumber et MySqlErrorDescription.

En règle générale, cette fonction est appelée lors de la gestion de l'événement OnInit() dans le programme MQL.

chaîne pHost

Le nom DNS ou l'adresse IP du serveur MySQL

chaîne pUser

Utilisateur de la base de données (par exemple, root)

chaîne pPassword

Le mot de passe de l'utilisateur de la base de données

chaîne pDatabase

Le nom de la base de données

int pPort

Le port TCP/IP de la base de données (généralement 3306)

chaîne pSocket

Le socket Unix (pour les systèmes basés sur Unix)

int pClientFlag

La combinaison d’indicateurs spéciaux (généralement 0)

La fonction d'interface MySqlDisconnect a été implémentée pour fermer la connexion :

Type

Nom Paramètres Description

vide

MySqlDisconnect

Cette fonction ferme la connexion avec la base de données MySQL.

En règle générale, cette fonction est appelée lors de la gestion de l'événement OnDeinit() dans le programme MQL.

int pConnection

Identifiant de connexion

Il est à noter que la base de données MySQL peut fermer la connexion d'elle-même en cas de panne matérielle, de congestion du réseau ou de timeout (lorsqu'aucune requête n'est envoyée à la base de données pendant une longue période).

Les développeurs utilisent souvent l'événement OnTick() pour écrire des données dans la base de données. Cependant, lorsque le week-end arrive et que le marché est fermé, la connexion est toujours « suspendue ». Dans ce cas, MySQL fermera son timeout (la valeur par défaut est de 8 heures).

Et le lundi, quand le marché est ouvert, des erreurs sont trouvées dans le projet. Il est donc fortement recommandé de vérifier la connexion et/ou de se reconnecter à la base de données après un intervalle de temps inférieur au timeout spécifié dans les paramètres du serveur MySQL.

1.2. Exécution de requêtes DML/DDL

Les opérations DML sont utilisées pour les manipulations de données (Data Manipulation Language). Les manipulations de données incluent l'ensemble d'instructions suivant : INSÉRER, METTRE À JOUR et SUPPRIMER.

Les opérations DDL sont utilisées pour la définition des données (Data Definition Language). Cela inclut la création (CREATE) des objets de la base de données (tables, affichages, procédures stockées, triggers, etc.) et leur modification (ALTER) et suppression (DROP).

Ce ne sont pas toutes les instructions DML/DDL. De plus, le DCL (Data Control Language) est utilisé pour séparer l'accès aux données, mais nous n'approfondirons pas les fonctionnalités du SQL. Chacune de ces commandes peut être exécutée à l'aide de la fonction d'interface MySqlExecute :


Type

Nom

Paramètres

Description

bool

MySqlExecute

Cette fonction peut être utilisée pour exécuter des instructions SQL non SELECT, après que la connexion à la base de données ait été établie avec succès (à l'aide de la fonction MySqlConnect ).

En cas d'exécution réussie de la commande, la fonction renvoie vrai, sinon - faux. Pour les détails de l'erreur, utilisez MySQLErrorNumber et MySqlErrorDescription.

int pConnection

Identifiant de connexion

chaîne pQuery

Requête SQL

En tant que requête SQL, vous pouvez également utiliser la commande USE pour sélectionner la base de données. Je voudrais mentionner l'utilisation de requêtes multi-instructions. C'est un ensemble de commandes SQL séparées par le caractère « ; ».

Pour activer le mode multi-instructions, la connexion avec la base de données doit être ouverte avec l’indicateur CLIENT_MULTI_STATEMENTS :

...
int ClientFlag = CLIENT_MULTI_STATEMENTS; // Setting the multi-statements flag
int DB; 

DB = MySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag); // Connection to the database

if (DB == -1)
   {
    // Handling the connection error
   }
...

// Preparing a SQL query to insert data (3 rows in one query)
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);";
...

if (!MySqlExecute(DB,SQL)) 
   {
    // Showing an error message
   }
...

Dans ce fragment, 3 entrées seront insérées dans la table EURUSD avec un seul appel à la base de données. Chacune des requêtes stockées dans la variable SQL est séparée par « ; ».

Cette approche peut être utilisée pour des insertions/mises à jour/suppressions fréquentes ; un ensemble de commandes nécessaires est combiné en un seul « package », soulageant ainsi le trafic réseau et améliorant les performances de la base de données.

La syntaxe INSERT dans MySQL est assez bien développée en termes de gestion des exceptions.

Par exemple, si la tâche consiste à déplacer l'historique des prix, une table doit être créée pour les paires de devises avec la clé primaire de type datetime, car la date et l'heure d'une barre sont uniques. De plus, il convient de vérifier si les données d'une barre particulière existent dans la base de données (pour améliorer la stabilité de la migration des données). Avec MySQL, cette vérification n'est pas requise, car l'instruction INSERT prend en charge ON DUPLICATE KEY.

En termes plus simples, si une tentative est faite pour insérer des données et que la table a déjà une entrée avec la même date et la même heure, l'instruction INSERT peut être ignorée ou remplacée par UPDATE pour cette ligne (voir. http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html).

1.3. Sélection de données

L'instruction SQL SELECT est utilisée pour récupérer les données de la base de données. La séquence d'actions ci-dessous est utilisée pour sélectionner les données et récupérer le résultat de la sélection :

  1. Préparation de l'instruction SELECT.
  2. Ouverture du curseur.
  3. Obtention du nombre de lignes renvoyées par la requête.
  4. Boucle et récupération de chaque ligne de la requête.
  5. Récupération des données dans les variables MQL à l'intérieur de la boucle.
  6. Fermeture du curseur.

Bien sûr, il s'agit d'un schéma général, donc toutes les opérations ne sont pas nécessaires pour chaque cas. Par exemple, si vous voulez vous assurer qu'une ligne existe dans la table (quel que soit le critère), il suffira de préparer une requête, d'ouvrir un curseur, d'obtenir le nombre de lignes et de fermer le curseur. En fait, les parties obligatoires sont - la préparation de l'instruction SELECT, l'ouverture et la fermeture du curseur.

Qu'est-ce qu'un curseur ? Il s'agit d'une référence à la zone de mémoire de contexte, en fait - l'ensemble de valeurs résultant. Lorsque vous envoyez la requête SELECT, la base de données alloue de la mémoire pour le résultat et crée un pointeur vers une ligne que vous pouvez déplacer d'une ligne à une autre. Ainsi il est possible d'accéder à toutes les lignes dans l'ordre d'une file d'attente définie par la requête (clause ORDER BY de l'instruction SELECT).

Les fonctions d'interface suivantes sont utilisées pour la sélection des données :

Ouverture du curseur :

Type

Nom

Paramètres

Description

int

MySqlCursorOpen

Cette fonction ouvre un curseur pour la requête SELECT et renvoie un identifiant de curseur en cas de succès. Sinon, la fonction renvoie « -1 ». Pour connaître la cause de l'erreur, utilisez les variables MySQLErrorNumber et MySqlErrorDescription.

int pConnection

Identifiant de connexion à la base de données

chaîne pQuery

Requête SQL (l'instruction SELECT)

Obtention du nombre de lignes renvoyées par la requête :

Type

Nom

Paramètres

Description

int

MySqlCursorRows

Cette fonction renvoie le nombre de lignes sélectionnées par la requête.

int pCursorID

L'identifiant du curseur renvoyé par MySqlCursorOpen

Récupération de la ligne de requête :

Type

Nom

Paramètres

Description

bool

MySqlCursorFetchRow

Récupère une ligne de l'ensemble de données renvoyé par la requête. Après une exécution réussie, vous pouvez récupérer les données dans les variables MQL. La fonction renvoie vrai en cas de succès, sinon elle renvoie faux.

int pCursorID

L'identifiant du curseur renvoyé par MySqlCursorOpen

Récupérer des données dans des variables MQL après avoir récupéré la ligne de requête :

Type

Nom

Paramètres

Description

int

MySqlGetFieldAsInt

Cette fonction renvoie la représentation de la valeur du champ de table à l'aide du type de données int.

int pCursorID

L'identifiant du curseur renvoyé par MySqlCursorOpen

int pField

Le numéro de champ dans la liste SELECT (la numérotation commence par 0)

double

MySqlGetFieldAsDouble

Cette fonction renvoie la représentation de la valeur du champ de table à l'aide du type de données double.

int pCursorID

L'identifiant du curseur renvoyé par MySqlCursorOpen

int pField

Le numéro de champ dans la liste SELECT (la numérotation commence par 0)

datetime

MySqlGetFieldAsDatetime

Cette fonction renvoie la représentation de la valeur du champ de table à l'aide du type de données datetime.

int pCursorID

L'identifiant du curseur renvoyé par MySqlCursorOpen

int pField

Le numéro de champ dans la liste SELECT (la numérotation commence par 0)

chaîne

MySqlGetFieldAsString

Cette fonction renvoie la représentation de la valeur du champ de table à l'aide du type de données chaîne.

int pCursorID

L'identifiant du curseur renvoyé par MySqlCursorOpen

int pField

Le numéro de champ dans la liste SELECT (la numérotation commence par 0)


Toutes les données renvoyées par MySQL ont une représentation native (présentées sans types sous forme de chaînes).

Par conséquent, en utilisant ces fonctions, vous pouvez convertir les données sélectionnées dans le type souhaité. Le seul inconvénient est la spécification du numéro de colonne (la numérotation commence à partir de 0) dans la liste SELECT au lieu de son nom. Cependant, lors du développement d'une application, la préparation de l'instruction SELECT et l'obtention des résultats se font presque toujours sur une seule page, vous pouvez donc voir la requête SELECT lorsque vous prescrivez la logique d'extraction des données.

Ainsi, vous connaissez toujours les numéros des champs de la liste SELECT (cette approche est également utilisée lors de l'accès aux données à l'aide d'AdoDB). Eh bien, cette partie peut encore être révisée à l'avenir. Mais cela aura peu d'impact sur la fonctionnalité de la solution développée.

Fermeture du curseur :

Type

Nom

Paramètres

Description

vide

MySqlCursorClose

Cette fonction ferme le curseur spécifié et libère la mémoire.

int pCursorID

L'identifiant du curseur renvoyé par MySqlCursorOpen

La fermeture d'un curseur est une opération critique. N'oubliez pas de fermer les curseurs.

Imaginez que vous ouvrez le curseur et oubliez de le fermer. Supposons que les données soient récupérées vers le curseur à chaque tick lors de la gestion de l'événement OnTick(), et chaque fois qu'un nouveau curseur est ouvert, de la mémoire lui est allouée (à la fois côté client et côté serveur). À un moment donné, le serveur refusera le service car la limite de curseurs ouverts est atteinte, ce qui pourrait provoquer un débordement de la mémoire tampon.

Bien sûr, c'est exagéré, un tel résultat est possible en travaillant directement avec libmysql.dll. Cependant, la bibliothèque dynamique MQLMySQL.DLL distribue de la mémoire pour les curseurs et refusera d'ouvrir un curseur qui dépasse la limite autorisée.

Lors de la mise en œuvre de tâches réelles, il suffit de garder 2-3 curseurs ouverts. Chaque curseur peut gérer une mesure cartésienne de données ; l'utilisation simultanée de deux-trois curseurs (imbriqués, par exemple, lorsqu'un curseur dépend paramétriquement d'un autre curseur) couvre deux ou trois dimensions. C'est parfaitement bien pour la plupart des tâches. De plus, pour la mise en œuvre de sélection de données complexes, vous pouvez toujours utiliser ces objets pour représenter la base de données (VIEW), les créer côté serveur et leur envoyer des requêtes depuis le code MQL comme vers des tables.

1.4. Information additionnelle

Les éléments suivants peuvent être mentionnés comme fonctionnalités supplémentaires :

1.4.1. Lecture de données à partir d'un fichier .INI

Type

Nom

Paramètres

Description

Chaîne

ReadIni

Renvoie la valeur d'une clé de la section donnée du fichier INI.

chaîne pFileName

Le nom du fichier INI

chaîne pSection

Le nom de la section

chaîne pKey

Le nom de la clé


Souvent stocker des informations sur les connexions à la base de données (adresse IP du serveur, port, nom d'utilisateur, mot de passe, etc.) directement dans le code MQL (ou paramètres de l'Expert Advisor, indicateur de script) n'est pas rationnel, car le serveur peut être déplacé, son adresse peut changer dynamiquement, etc. Vous devrez modifier le code MQL dans ce cas. Ainsi, toutes ces données devraient mieux être stockées dans le fichier .INI standard, alors que seul son nom devrait être écrit dans le programme MQL. Ensuite, utilisez la fonction ReadINI pour lire les paramètres de connexion et les utiliser.

Par exemple, le fichier INI contient les informations suivantes :

[MYSQL]
Server = 127.0.0.1
User = root
Password = Adm1n1str@t0r
Database = mysql
Port = 3306

Pour obtenir l'adresse IP du serveur, exécutez la commande suivante :

string vServer = ReadIni("C:\\MetaTrader5\\MQL5\\Experts\\MyConnection.ini", "MYSQL", "Server");

Le fichier INI se trouve dans C:\MetaTrader5\MQL5\Experts et s'appelle « MyConnection.ini », vous accédez à la clé Serveur de la section MYSQL. Dans un fichier INI, vous pouvez stocker les paramètres sur différents serveurs utilisés dans votre projet.

1.4.2. Traçage des zones à problèmes

Dans la bibliothèque, l’interface fournit le mode trace, qui peut être activé pour le débogage des requêtes SQL n'importe où dans un programme MQL.

Spécifiez les éléments suivants dans la zone à problème :

SQLTrace = true;

puis

SQLTrace = false;

Si vous activez le traçage au début du programme MQL et ne le désactivez pas, tous les appels à la base de données seront enregistrés. Le Journal est conservé dans la console du terminal (à l'aide de la commande Imprimer).


2. Exemples

Cette section fournit quelques exemples de connexion et d'utilisation des bibliothèques développées. Consultez-les et estimez l'utilisabilité de la solution logicielle.

L’exemple MySQL-003.mq5 montre ce qui suit : connexion à une base de données (les paramètres de connexion sont stockés dans le fichier .ini), création d'une table, insertion de données (également à l'aide d'instructions multiples) et déconnexion de la base de données.

//+------------------------------------------------------------------+
//|                                                    MySQL-003.mq5 |
//|                                   Copyright 2014, Eugene Lugovoy |
//|                                              https://www.mql5.com |
//| Inserting data with multi-statement (DEMO)                       |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, Eugene Lugovoy."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

#include <MQLMySQL.mqh>

string INI;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
 string Host, User, Password, Database, Socket; // database credentials
 int Port,ClientFlag;
 int DB; // database identifier
 
 Print (MySqlVersion());

 INI = TerminalInfoString(TERMINAL_PATH)+"\\MQL5\\Scripts\\MyConnection.ini";
 
 // reading database credentials from INI file
 Host = ReadIni(INI, "MYSQL", "Host");
 User = ReadIni(INI, "MYSQL", "User");
 Password = ReadIni(INI, "MYSQL", "Password");
 Database = ReadIni(INI, "MYSQL", "Database");
 Port     = (int)StringToInteger(ReadIni(INI, "MYSQL", "Port"));
 Socket   = ReadIni(INI, "MYSQL", "Socket");
 ClientFlag = CLIENT_MULTI_STATEMENTS; //(int)StringToInteger(ReadIni(INI, "MYSQL", "ClientFlag"));  

 Print ("Host: ",Host, ", User: ", User, ", Database: ",Database);
 
 // open database connection
 Print ("Connecting...");
 
 DB = MySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag);
 
 if (DB == -1) { Print ("Connection failed! Error: "+MySqlErrorDescription); } else { Print ("Connected! DBID#",DB);}
 
 string Query;
 Query = "DROP TABLE IF EXISTS `test_table`";
 MySqlExecute(DB, Query);
 
 Query = "CREATE TABLE `test_table` (id int, code varchar(50), start_date datetime)";
 if (MySqlExecute(DB, Query))
    {
     Print ("Table `test_table` created.");
     
     // Inserting data 1 row
     Query = "INSERT INTO `test_table` (id, code, start_date) VALUES ("+(string)AccountInfoInteger(ACCOUNT_LOGIN)+",\'ACCOUNT\',\'"+TimeToString(TimeLocal(), TIME_DATE|TIME_SECONDS)+"\')";
     if (MySqlExecute(DB, Query))
        {
         Print ("Succeeded: ", Query);
        }
     else
        {
         Print ("Error: ", MySqlErrorDescription);
         Print ("Query: ", Query);
        }
     
     // multi-insert
     Query =         "INSERT INTO `test_table` (id, code, start_date) VALUES (1,\'EURUSD\',\'2014.01.01 00:00:01\');";
     Query = Query + "INSERT INTO `test_table` (id, code, start_date) VALUES (2,\'EURJPY\',\'2014.01.02 00:02:00\');";
     Query = Query + "INSERT INTO `test_table` (id, code, start_date) VALUES (3,\'USDJPY\',\'2014.01.03 03:00:00\');";
     if (MySqlExecute(DB, Query))
        {
         Print ("Succeeded! 3 rows has been inserted by one query.");
        }
     else
        {
         Print ("Error of multiple statements: ", MySqlErrorDescription);
        }
    }
 else
    {
     Print ("Table `test_table` cannot be created. Error: ", MySqlErrorDescription);
    }
 
 MySqlDisconnect(DB);
 Print ("Disconnected. Script done!");
}

L’exemple MySQL-004.mq5 montre une sélection de données à partir d'une table créée par le script « MySQL-003.mq5 ». 

//+------------------------------------------------------------------+
//|                                                    MySQL-004.mq5 |
//|                                   Copyright 2014, Eugene Lugovoy |
//|                                              https://www.mql5.com |
//| Select data from table (DEMO)                                    |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, Eugene Lugovoy."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

#include <MQLMySQL.mqh>

string INI;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
 string Host, User, Password, Database, Socket; // database credentials
 int Port,ClientFlag;
 int DB; // database identifier
 
 Print (MySqlVersion());

 INI = TerminalInfoString(TERMINAL_PATH)+"\\MQL5\\Scripts\\MyConnection.ini";
 
 // reading database credentials from INI file
 Host = ReadIni(INI, "MYSQL", "Host");
 User = ReadIni(INI, "MYSQL", "User");
 Password = ReadIni(INI, "MYSQL", "Password");
 Database = ReadIni(INI, "MYSQL", "Database");
 Port     = (int)StringToInteger(ReadIni(INI, "MYSQL", "Port"));
 Socket   = ReadIni(INI, "MYSQL", "Socket");
 ClientFlag = (int)StringToInteger(ReadIni(INI, "MYSQL", "ClientFlag"));  

 Print ("Host: ",Host, ", User: ", User, ", Database: ",Database);
 
 // open database connection
 Print ("Connecting...");
 
 DB = MySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag);
 
 if (DB == -1) { Print ("Connection failed! Error: "+MySqlErrorDescription); return; } else { Print ("Connected! DBID#",DB);}
 
 // executing SELECT statement
 string Query;
 int    i,Cursor,Rows;
 
 int      vId;
 string   vCode;
 datetime vStartTime;
 
 Query = "SELECT id, code, start_date FROM `test_table`";
 Print ("SQL> ", Query);
 Cursor = MySqlCursorOpen(DB, Query);
 
 if (Cursor >= 0)
    {
     Rows = MySqlCursorRows(Cursor);
     Print (Rows, " row(s) selected.");
     for (i=0; i<Rows; i++)
         if (MySqlCursorFetchRow(Cursor))
            {
             vId = MySqlGetFieldAsInt(Cursor, 0); // id
             vCode = MySqlGetFieldAsString(Cursor, 1); // code
             vStartTime = MySqlGetFieldAsDatetime(Cursor, 2); // start_time
             Print ("ROW[",i,"]: id = ", vId, ", code = ", vCode, ", start_time = ", TimeToString(vStartTime, TIME_DATE|TIME_SECONDS));
            }
     MySqlCursorClose(Cursor); // NEVER FORGET TO CLOSE CURSOR !!!
    }
 else
    {
     Print ("Cursor opening failed. Error: ", MySqlErrorDescription);
    }
    
 MySqlDisconnect(DB);
 Print ("Disconnected. Script done!");
}

Les exemples ci-dessus contiennent la gestion des erreurs typique utilisée dans les projets réels.

En fait, chaque requête utilisée dans un programme MQL doit être déboguée dans n'importe quel client MySQL (PHPMyAdmin, DB Ninja, console MySQL). Personnellement, j'utilise et recommande un logiciel professionnel pour le développement de bases de données Quest TOAD pour MySQL.


Conclusion

Cet article ne décrit pas les détails de l'implémentation de MQLMySQL.DLL développé dans l'environnement Microsoft Visual Studio 2010 (C/C++). Cette solution logicielle est conçue pour une utilisation pratique et compte plus de 100 implémentations réussies dans divers domaines du développement de logiciels MQL (de la création de systèmes de trading complexes à la publication Web).

  • Les versions des bibliothèques pour MQL4 et MQL5 sont jointes ci-dessous. Les pièces jointes incluent également un fichier zip avec le code source de MQLMySQL.DLL ;
  • La documentation est incluse dans les archives ;
  • Pour utiliser les exemples, n'oubliez pas de préciser les paramètres de connexion à votre base de données dans le fichier \Scripts\MyConnection.ini.

Traduit du russe par MetaQuotes Ltd.
Article original : https://www.mql5.com/ru/articles/932

Assistant MQL5 : Exécuter des ordres, des stop-loss et des prises de bénéfices sur les prix calculés. Extension de la bibliothèque standard Assistant MQL5 : Exécuter des ordres, des stop-loss et des prises de bénéfices sur les prix calculés. Extension de la bibliothèque standard
Cet article décrit l'extension MQL5 Standard Library, qui permet de créer des Expert Advisors, de passer des ordres, des Stop Loss et des Take Profits à l'aide de l'assistant MQL5 en fonction des prix reçus des modules inclus. Cette approche n'applique aucune restriction supplémentaire sur le nombre de modules et ne provoque pas de conflits dans leur travail commun.
Construire une start-up de technologie sociale, Première partie Envoyez des Tweets sur vos signaux MetaTrader 5 Construire une start-up de technologie sociale, Première partie Envoyez des Tweets sur vos signaux MetaTrader 5
Aujourd’hui, nous allons apprendre à lier un terminal MetaTrader 5 à Twitter afin de pouvoir tweeter les signaux de trading de vos EA. Nous développons un système d’aide à la décision sociale en PHP basé sur un service Web RESTful. Cette idée vient exceptionnellement d’une conception du trading automatique appelée trading assisté par ordinateur. Nous voulons que les capacités cognitives des traders humains filtrent les signaux de trading qui, autrement, seraient automatiquement mis sur le marché par les Experts Advisors.
Comment préparer un compte de trading pour la migration vers l'hébergement virtuel Comment préparer un compte de trading pour la migration vers l'hébergement virtuel
Le terminal client MetaTrader est parfait pour automatiser les stratégies de trading. Il dispose de tous les outils nécessaires pour les développeurs de robots de trading, notamment un puissant langage de programmation MQL4/MQL5 basé sur le langage C++, un environnement de développement MetaEditor pratique et un testeur de stratégie multithread qui prend en charge l'informatique distribuée dans le réseau cloud MQL5. Dans cet article, vous découvrirez comment déplacer votre terminal client vers l'environnement virtuel avec tous les éléments personnalisés.
Récits de Robots de Trading : Est-ce moins plus que ca ? Récits de Robots de Trading : Est-ce moins plus que ca ?
Il y a deux ans, dans « La Dernière Croisade », nous avons passé en revue une méthode intéressante mais actuellement peu utilisée pour afficher des informations sur le marché - des graphiques de points et de figures. Maintenant, je vous suggère d’essayer d’écrire un robot de trading basé sur les modèles détectés sur le graphique de points et de figures.