English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
MQL5'ten (MQL4) MySQL Veritabanına Nasıl Erişilir

MQL5'ten (MQL4) MySQL Veritabanına Nasıl Erişilir

MetaTrader 5Entegrasyon | 14 Ocak 2022, 10:53
184 0
Eugeniy Lugovoy
Eugeniy Lugovoy

Giriş

MQL'nin veritabanları ile etkileşim sorunu yeni değil, ancak yine de alakalıdır. Veritabanlarının kullanımı MetaTrader'ın olanaklarını büyük ölçüde artırabilir: fiyat geçmişinin saklanması ve analizi, alım satımların bir alım satım platformundan diğerine kopyalanması, gerçek zamanlı teklifler/takaslar sağlanması, sunucu tarafında ve/veya bir program kullanılarak yoğun analitik hesaplamalar, web teknolojilerini kullanarak hesapların izlenmesi ve uzaktan kontrolü.

Ayrıca, MQL ve MySQL kombinasyonundan faydalanmak için birçok girişimde bulunuldu; CodeBase'de bazı çözümler mevcut.

Örneğin "MySQL sarmalayıcı - MetaTrader 4 için kitaplık", birçok programcının ek eklemelerle kendi geliştirmelerine başladığı projedir. Bence bu çözümün dezavantajlarından biri, veri tabanından veri okumak için özel dizilerin tahsis edilmesidir.

"MySQL günlükçü+1 - MetaTrader 4 için EA" adlı başka bir proje oldukça uzmanlaşmıştır, libmysql.dll standart kitaplığına erişmek için sarmalayıcı kullanmaz. Bu nedenle MetaTrader4 Build 600+ sürümünde çalışmaz, çünkü char karakter türleri wchar_t ile değiştirilmiştir ve TMYSQL yapı işaretçisi yerine int türünün kullanılması projede bellek sızıntılarına neden olur (tahsis edilen bellek kontrol edilemez/serbest bırakılamaz).

Bir başka ilginç proje ise "EAX_Mysql - MySQL kitaplığı - MetaTrader 5 için kitaplık". Bu oldukça iyi bir uygulamadır. Yazar tarafından belirtilen dezavantajlar listesi, kullanımına bazı kısıtlamalar getirmektedir.

MQL projelerinde veritabanlarını kullanmaya ihtiyaç duyan herkesin iki seçeneği vardır: ya kendi çözümlerini geliştirmek ve her bir parçasını bilmek ya da herhangi bir üçüncü taraf çözümünü kullanmak/uyarlamak, nasıl kullanılacağını öğrenmek ve projelerini engelleyebilecek tüm kusurlarını tespit etmek.

Oldukça karmaşık bir alım satım robotu geliştirirken böyle bir zorunluluk ve iki seçenekle karşılaştım. Mevcut projeleri araştırdıktan ve çok sayıda çözüm üzerinde çalıştıktan sonra, bulunan uygulamaların hiçbirinin alım satım robotumu "profesyonel seviyeye" getirmeye yardımcı olamayacağını fark ettim.

Ayrıca saçma çözümler de vardı, örneğin: DML/DDL işlemleri (veri ekleme/güncelleme/silme, veritabanına nesne oluşturma/bırakma) standart libmysql.dll kullanılarak yapıldı ve veri seçimi (SELECT) aslında MySQL sunucusu tarafında web sunucusunda bulunan bir PHP script dosyasına (inet.dll kullanılarak) bir HTTP isteği olarak uygulandı. SQL sorguları PHP script dosyasına yazılmıştır.

Başka bir deyişle, projeyi çalıştırmak için aşağıdaki bileşenlerin kullanılabilir, yapılandırılmış ve çalışır durumda tutulması gerekiyordu: MySQL sunucusu, Apache/IIS web sunucusu, sunucu tarafında PHP/ASP script dosyaları... Oldukça fazla sayıda teknolojinin bir kombinasyonu. Elbette, bazı durumlarda bu kabul edilebilir, ancak tek görev veri tabanından veri seçmek olduğunda bu saçmalıktır. Ek olarak, böyle hantal bir çözümü desteklemek zaman alıcıdır.

Çözümlerin çoğunda veri ekleme, nesne oluşturma ve benzerlerinde sorun yoktu. Sorun, verilerin çağrı ortamına döndürülmesi gerektiği için veri seçimiydi.

Dizileri bu amaç için kullanmanın pratik ve elverişsiz olduğunu düşündüm, çünkü ana projenin geliştirilmesi/hata ayıklaması/desteklenmesi sırasında, veritabanına yönelik seçme sorguları değiştirilebilirken, diziler için doğru bellek tahsisini de kontrol etmelisiniz. Yani, bu kaçınılabilir ve kaçınılmalıdır.

Aşağıda tartışılan MQL <-> MySql arabirimi, Oracle PL/SQL, MS SQL T-SQL, AdoDB imleçlerin kullanımında kullanılan tipik bir yaklaşıma dayanmaktadır. Bu arayüz, programlama ve bakım kolaylığı ile minimum bileşen hedeflenerek geliştirilmiştir. Standart libmysql.dll kitaplığına bir DLL sarmalayıcısı olarak uygulanır ve bir .mqh dosyası olarak bir dizi arabirim işlevi vardır.


1. MQL <-> MySQL Arayüzü

MetaTrader terminali (MQL programları aracılığıyla) arasındaki etkileşim, aşağıdaki bileşenlerin yardımıyla uygulanabilir:

MQL ve MySQL etkileşiminin şeması

1. Arabirim kitaplığı MQLMySQL.mqh. #include dizini kullanılarak projeye eklenir ve zevkinize göre değiştirilebilir.

MQLMySQL.dll dinamik kitaplığının içe aktarma işlevlerinin yanı sıra bunları çağırma ve hataları işleme işlevleri için yönergeleri içerir.

2. MQLMySQL.dll dinamik kitaplığı. Standart kitaplık libmysql.dll'nin işlevselliğine erişmek için bir sarmalayıcıdır.

Ayrıca, MQLMySQL.dll kitaplığı, işlemlerin sonuçlarını ve veritabanı bağlantılarına ve imleçlere paylaşılan erişimi işler. Bu, aynı anda birden çok bağlantı oluşturup kullanabileceğiniz (bir veya daha fazla MQL programından), bir veya daha fazla veritabanına sorgularla birlikte birkaç imleci açık tutabileceğiniz anlamına gelir. Muteksler, paylaşılan kaynaklara erişimi ayırmak için kullanılır.

3. Standart dinamik kitaplık libmysql.dll, yerel bir erişim sürücüsüdür. C:\Windows\System32 veya <Terminal>\MQL5\Libraries içindeki herhangi bir MySql veritabanı dağıtımından kopyalayabilirsiniz (<Terminal>\MQL4\Libraries içinde MetaTrader 4 için).

Aslında, veritabanına sorgular göndermekten ve sonuçları almaktan sorumludur.

Bağlantının açılması/kapatılması, DML/DDL sorgularının yapılması ve veri seçimi gibi ana noktalar üzerinde duralım.

1.1. Bağlantıyı Açma ve Kapatma

MySqlConnect işlevi, MySQL veritabanıyla bağlantı açmak için uygulandı:

Tür

Ad

Parametreler

Açıklama

int

MySqlConnect

Bu işlev, veritabanıyla bağlantı kurar ve bir bağlantı tanımlayıcısı döndürür. Bu kimlik, veritabanını sorgulamak için gerekli olacaktır.

Bağlantı hatası durumunda dönüş değeri "-1"dir. Hata ayrıntıları için MySQLErrorNumber ve MySqlErrorDescription değişkenlerini kontrol edin.

Genellikle bu işlev, MQL programında OnInit() olayı işlenirken çağrılır.

dize pHost

MySQL sunucusunun DNS adı veya IP adresi

dize pUser

Veritabanı kullanıcısı (örneğin kök)

dize pPassword

Veritabanı kullanıcısının parolası

dize pDatabase

Veritabanının adı

int pPort

Veritabanının TCP/IP bağlantı noktası (genellikle 3306)

dize pSocket

Unix soketi (Unix tabanlı sistemler için)

int pClientFlag

Özel bayrakların kombinasyonu (genellikle 0)

Bağlantıyı kapatmak için MySqlDisconnect arabirim işlevi uygulanmıştır:

Tür

Adı Parametreler Açıklama

boş

MySqlDisconnect

Bu fonksiyon MySQL veritabanı ile bağlantıyı kapatır.

Genellikle bu işlev, MQL programında OnDeinit() olayı işlenirken çağrılır.

int pConnection

Bağlantı tanımlayıcı

Unutulmamalıdır ki, bir donanım arızası, ağ tıkanıklığı veya zaman aşımı (veritabanına uzun süre sorgu gönderilmediğinde) durumunda MySQL veritabanı bağlantıyı kendiliğinden kapatabilir.

Geliştiriciler genellikle veritabanına veri yazmak için OnTick() olayını kullanır. Ancak, hafta sonu geldiğinde ve piyasa kapandığında, bağlantı hala "devam eder". Bu durumda MySQL, zaman aşımına uğradığında kapanır (varsayılan 8 saattir).

Pazartesi günü piyasa açıkken projede hatalar bulunur. Bu nedenle, MySQL sunucusunun ayarlarında belirtilen zaman aşımı süresinden daha küçük bir zaman aralığından sonra bağlantıyı kontrol etmeniz ve/veya veritabanına yeniden bağlanmanız şiddetle tavsiye edilir.

1.2. DML/DDL Sorgularının Yürütülmesi

DML işlemleri veri manipülasyonları için kullanılır (Data Manipulation Language). Veri manipülasyonları aşağıdaki ifadeleri içerir: EKLE, GÜNCLLE ve SİL.

DDL işlemleri veri tanımlaması için kullanılır (Data Definition Language). Bu, veritabanı nesnelerinin (tablolar, görünümler, saklı yordamlar, tetikleyiciler vb.) oluşturulmasını (CREATE) ve bunların değiştirilmesini (ALTER) ve silinmesini (DROP) içerir.

Bunların hepsi DML/DDL deyimleri değildir, ayrıca DCL (Data Control Language) veri erişimini ayırmak için kullanılır, ancak SQL'in özelliklerini ayrıntılı olarak incelemeyeceğiz. Bu komutlardan herhangi biri MySqlExecute arayüz işlevi kullanılarak yürütülebilir:


Tür

Ad

Parametreler

Açıklama

bool

MySqlExecute

Bu işlev, veritabanına bağlantı başarıyla kurulduktan sonra (MySqlConnect işlevini kullanarak) SQL'in SELECT olmayan deyimlerini yürütmek için kullanılabilir.

Komutun başarılı bir şekilde yürütülmesi durumunda işlev doğru, aksi takdirde yanlış döndürür. Hata ayrıntıları için MySQLErrorNumber ve MySqlErrorDescription kullanın.

int pConnection

Bağlantı tanımlayıcı

dize pQuery

SQL Sorgusu

SQL sorgusu olarak, veritabanını seçmek için USE komutunu da kullanabilirsiniz. Çok ifadeli sorguların kullanımından bahsetmek istiyorum. ";" karakteriyle ayrılmış bir dizi SQL komutudur.

Çoklu ifade modunu etkinleştirmek için, veritabanı ile bağlantı CLIENT_MULTI_STATEMENTS bayrağı ile açılmalıdır:

...
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
   }
...

Bu parçada, veritabanına yapılan tek bir çağrı ile EURUSD tablosuna 3 giriş eklenecektir. SQL değişkeninde depolanan sorguların her biri ";" ile ayrılır.

Bu yaklaşım, sık ekleme/güncelleme/silme için kullanılabilir; bir dizi gerekli komut tek bir "paket" içinde birleştirilir, böylece ağ trafiği rahatlatılır ve veritabanı performansı iyileştirilir.

MySQL'deki INSERT sözdizimi, istisna işleme açısından oldukça iyi geliştirilmiştir.

Örneğin görev fiyat geçmişini taşımaksa bir çubuğun tarih ve saati benzersiz olduğundan, tarih saat türünün birincil anahtarı ile döviz çiftleri için bir tablo oluşturulmalıdır. Ayrıca herhangi bir çubuktaki verilerin veritabanında olup olmadığı kontrol edilmelidir (veri geçişinin kararlılığını artırmak için). MySQL ile bu kontrol gerekli değildir, çünkü INSERT ifadesi ON DUPLICATE KEY'i destekler.

Daha basit bir deyişle, veri ekleme girişiminde bulunulursa ve tablo aynı tarih ve saate sahip bir girişe sahipse INSERT ifadesi yok sayılabilir veya bu satır için UPDATE ile değiştirilebilir (bkz. http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html)

1.3. Veri Seçimi

SQL SELECT ifadesi, veritabanından veri almak için kullanılır. Aşağıdaki işlem sırası, verileri seçmek ve seçim sonucunu almak için kullanılır:

  1. SELECT ifadesinin hazırlanması.
  2. İmleci açma.
  3. Sorgu tarafından döndürülen satır sayısını alma.
  4. Sorgunun her satırını döngüleme ve alma.
  5. Döngü içindeki MQL değişkenlerine veri getirme.
  6. İmleci kapatma.

Elbette bu genel bir şemadır, bu nedenle her durum için tüm işlemler gerekli değildir. Örneğin tabloda bir satırın (herhangi bir kritere göre) olduğundan emin olmak istiyorsanız bir sorgu hazırlamanız, bir imleç açmanız, satır sayısını almanız ve imleci kapatmanız yeterli olacaktır. Aslında, zorunlu kısımlar SELECT ifadesini hazırlamak, imleci açmak ve kapatmaktır.

İmleç nedir? Bu bağlam bellek alanına bir referanstır; aslında sonuçta ortaya çıkan değerler kümesidir. SELECT sorgusunu gönderdiğinizde, veritabanı sonuç için bellek ayırır ve bir satırdan diğerine taşıyabileceğiniz bir satıra bir işaretçi oluşturur. Böylece, sorgu tarafından tanımlanan bir sıradaki tüm satırlara (SELECT ifadesinin ORDER BY yan tümcesi) erişmek mümkündür.

Veri seçimi için aşağıdaki arayüz işlevleri kullanılır:

İmleci açma:

Tür

Ad

Parametreler

Açıklama

int

MySqlCursorOpen

Bu işlev, SELECT sorgusu için bir imleç açar ve başarılı olması durumunda bir imleç tanımlayıcısı döndürür. Aksi takdirde, işlev "-1" döndürür. Hatanın nedenini bulmak için MySQLErrorNumber ve MySqlErrorDescription değişkenlerini kullanın.

int pConnection

Veritabanı ile bağlantı tanımlayıcısı

dize pQuery

SQL sorgusu (SELECT ifadesi)

Sorgu tarafından döndürülen satır sayısını alma:

Tür

Ad

Parametreler

Açıklama

int

MySqlCursorRows

Bu işlev, sorgu tarafından seçilen satır sayısını döndürür.

int pCursorID

MySqlCursorOpen tarafından döndürülen imleç tanımlayıcısı

Sorgu satırı getiriliyor:

Tür

Ad

Parametreler

Açıklama

bool

MySqlCursorFetchRow

Sorgu tarafından döndürülen veri kümesinden bir satır getirir. Başarılı yürütmeden sonra verileri MQL değişkenlerine alabilirsiniz. İşlev başarılıysa doğru, aksi takdirde yanlış döndürür.

int pCursorID

MySqlCursorOpen tarafından döndürülen imleç tanımlayıcısı

Sorgu satırını getirdikten sonra verileri MQL değişkenlerine getirme:

Tür

Ad

Parametreler

Açıklama

int

MySqlGetFieldAsInt

Bu işlev, int veri türünü kullanarak tablo alanı değerinin temsilini döndürür.

int pCursorID

MySqlCursorOpen tarafından döndürülen imleç tanımlayıcısı

int pField

SEÇ listesindeki alan numarası (numaralandırma 0 ile başlar)

double

MySqlGetFieldAsDouble

Bu işlev, çift veri türünü kullanarak tablo alanı değerinin temsilini döndürür.

int pCursorID

MySqlCursorOpen tarafından döndürülen imleç tanımlayıcısı

int pField

SEÇ listesindeki alan numarası (numaralandırma 0 ile başlar)

tarihsaat

MySqlGetFieldAsDatetime

Bu işlev, tarih saat veri türünü kullanarak tablo alanı değerinin temsilini döndürür.

int pCursorID

MySqlCursorOpen tarafından döndürülen imleç tanımlayıcısı

int pField

SEÇ listesindeki alan numarası (numaralandırma 0 ile başlar)

dize

MySqlGetFieldAsString

Bu işlev, dize veri türünü kullanarak tablo alanı değerinin temsilini döndürür.

int pCursorID

MySqlCursorOpen tarafından döndürülen imleç tanımlayıcısı

int pField

SEÇ listesindeki alan numarası (numaralandırma 0 ile başlar)


MySQL tarafından döndürülen tüm veriler yerel temsile sahiptir (türler olmadan dizeler olarak sunulur).

Bu nedenle, bu işlevleri kullanarak seçilen verileri istediğiniz türe çevirebilirsiniz. Tek dezavantajı, SELECT listesinde adı yerine sütun numarasının (numaralandırma 0'dan başlar) belirtilmesidir. Ancak bir uygulama geliştirirken, SELECT ifadesinin hazırlanması ve sonuçların alınması neredeyse her zaman bir sayfadadır; bu nedenle veri getirme mantığını yazarken SELECT sorgusunu görebilirsiniz.

Böylece SELECT listesindeki alanların numaralarını her zaman bilirsiniz (bu yaklaşım, AdoDB kullanılarak verilere erişilirken de kullanılır). Ayrıca, bu kısım gelecekte daha da revize edilebilir. Ancak bunun geliştirilen çözümün işlevselliği üzerinde çok az etkisi olacaktır.

İmleci kapatma:

Tür

Ad

Parametreler

Açıklama

boş

MySqlCursorClose

Bu işlev belirtilen imleci kapatır ve belleği serbest bırakır.

int pCursorID

MySqlCursorOpen tarafından döndürülen imleç tanımlayıcısı

Bir imleci kapatmak kritik bir işlemdir. İmleçleri kapatmayı unutmayın.

İmleci açtığınızı ve kapatmayı unuttuğunuzu hayal edin. OnTick() olayı işlenirken her onay işareti ile imlece veri alındığını ve her yeni imleç açıldığında, bunun için bellek ayrıldığını (hem istemci tarafında hem de sunucu tarafında) varsayalım. Bir noktada, sunucu, açık imleç sınırına ulaşıldığından hizmeti reddeder ve bu, arabellek taşmasına neden olabilir.

Elbette bu abartılıdır; böyle bir sonuç libmysql.dll ile doğrudan çalışırken mümkündür. Ancak, MQLMySQL.DLL dinamik kitaplığı imleçler için belleği dağıtır ve izin verilen sınırı aşan bir imleci açmayı reddeder.

Gerçek görevleri uygularken 2-3 imleci açık tutmak yeterlidir. Her imleç bir Kartezyen veri ölçümünü işleyebilir; aynı anda iki-üç imleç kullanmak (örneğin biri parametrik olarak başka bir imlece bağlı olduğunda iç içe geçmiş) iki veya üç boyutu kapsar. Bu, çoğu görev için oldukça iyidir. Ayrıca, karmaşık veri seçiminin uygulanmasında, bu nesneleri her zaman veritabanını temsil etmek (VIEW) için kullanabilir, bunları sunucu tarafında oluşturabilir ve MQL kodundan tablolara sorgular gönderebilirsiniz.

1.4. Ek Bilgiler

Ek özellikler olarak şunlardan bahsedilebilir:

1.4.1. Bir .INI dosyasından veri okuma

Tür

Ad

Parametreler

Açıklama

Dize

ReadIni

INI dosyasının verilen bölümünün bir anahtarının değerini döndürür.

dize pDosyaAdı

INI dosyasının adı

dize pSection

Bölüm adı

dize pKey

Anahtar adı


Genellikle veritabanına bağlantılar hakkında bilgileri (sunucunun IP adresi, bağlantı noktası, kullanıcı adı, şifre vb.) doğrudan MQL kodunda (veya Expert Advisor'ın parametreleri, komut dosyası göstergesi) depolamak mantıklı değildir, çünkü sunucu taşındı, adresi dinamik olarak değişebilir vb. Bu durumda MQL kodunu değiştirmeniz gerekecektir. Bu nedenle, tüm bu veriler standart .INI dosyasında saklanmalı, MQL programında sadece adı yazılmalıdır. Ardından, bağlantı parametrelerini okumak ve bunları kullanmak için ReadINI işlevini kullanın.

Örneğin INI dosyası aşağıdaki bilgileri içerir:

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

Sunucunun IP adresini almak için aşağıdakileri yürütün:

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

INI dosyası C:\MetaTrader5\MQL5\Experts konumunda bulunur ve "MyConnection.ini" olarak adlandırılır, MYSQL bölümünün Sunucu anahtarına erişirsiniz. Bir INI dosyasında, projenizde kullanılan çeşitli sunuculara ait ayarları saklayabilirsiniz.

1.4.2. Sorunlu Alanları İzleme

Arabirim kitaplığında, bir MQL programında herhangi bir yerde SQL sorgularında hata ayıklamak için etkinleştirilebilen izleme modu bulunur.

Sorun alanında şunları belirtin:

SQLTrace = true;

ve ardından

SQLTrace = false;

MQL programının başlangıcında izlemeyi etkinleştirir ve devre dışı bırakmazsanız veritabanına yapılan tüm çağrılar günlüğe kaydedilir. Günlük, terminal konsolunda tutulur (Yazdır komutu kullanılarak).


2. Örnekler

Bu bölüm, geliştirilen kitaplıkların bağlantı ve kullanımına ilişkin birkaç örnek sunmaktadır. Bunları görün ve yazılım çözümünün kullanılabilirliğini tahmin edin.

MySQL-003.mq5 örneği şunları gösterir: bir veritabanına bağlanma (bağlantı parametreleri .ini dosyasında saklanır), bir tablo oluşturma, veri ekleme (ayrıca çoklu ifadeler) ve veritabanından bağlantının kesilmesi.

//+------------------------------------------------------------------+
//|                                                    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!");
}

Örnek MySQL-004.mq5 "MySQL-003.mq5" komut dosyası tarafından oluşturulan bir tablodan veri seçimini gösterir. 

//+------------------------------------------------------------------+
//|                                                    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!");
}

Yukarıdaki örnekler, gerçek projelerde kullanılan tipik hata işlemeyi içerir.

Aslında, bir MQL programında kullanılan her sorgu, herhangi bir MySQL istemcisinde (PHPMyAdmin, DB Ninja, MySQL konsolu) hata ayıklanmalıdır. Şahsen veritabanı geliştirme için profesyonel yazılımlar kullanıyorum ve MySQL için Quest TOAD yazılımını tavsiye ediyorum.


Sonuç

Bu makale, Microsoft Visual Studio 2010 (C/C++) ortamında geliştirilen MQLMySQL.DLL uygulamasının ayrıntılarını açıklamamaktadır. Bu yazılım çözümü pratik kullanım için tasarlanmıştır ve MQL yazılım geliştirmenin çeşitli alanlarında (karmaşık alım satım sistemlerinin oluşturulmasından web yayıncılığına kadar) 100'den fazla başarılı uygulamaya sahiptir.

  • MQL4 ve MQL5 kitaplıklarının sürümleri aşağıda eklenmiştir. Ekler ayrıca MQLMySQL.DLL kaynak kodunu içeren bir zip dosyası içerir;
  • Dokümantasyon arşivlerde yer almaktadır;
  • Örnekleri kullanmak için, \Scripts\MyConnection.ini dosyasında veritabanınıza bağlantı parametrelerini belirtmeyi unutmayın.

MetaQuotes Ltd tarafından Rusçadan çevrilmiştir.
Orijinal makale: https://www.mql5.com/ru/articles/932

Ekli dosyalar |
MQLMySQL_for_MQL4.zip (1124.85 KB)
MQLMySQL_for_MQL5.zip (1125.19 KB)
MQL5 Sihirbazı: Hesaplanan Fiyatlardan Talimatlar, Zarar Durdur ve Kar Al uygulama. Standart Kitaplık Uzantısı MQL5 Sihirbazı: Hesaplanan Fiyatlardan Talimatlar, Zarar Durdur ve Kar Al uygulama. Standart Kitaplık Uzantısı
Bu makale, MQL5 Sihirbazını kullanarak Expert Advisor'lar oluşturmanıza, talimat vermenize, Zarar Durdurmanıza ve dahil edilen modüllerden alınan fiyatlara göre Kar Almanıza olanak tanıyan MQL5 Standart Kitaplık uzantısını açıklar. Bu yaklaşım, modül sayısı üzerinde herhangi bir ek kısıtlama uygulamamakta ve ortak çalışmalarında çakışmalara neden olmamaktadır.
Bir Sosyal Teknoloji Girişimi Kurmak, Bölüm I: MetaTrader 5 Sinyallerinizi Tweetleyin Bir Sosyal Teknoloji Girişimi Kurmak, Bölüm I: MetaTrader 5 Sinyallerinizi Tweetleyin
Bugün, EA'larınızın alım satım sinyallerini tweetleyebilmeniz için bir MetaTrader 5 terminalini Twitter ile nasıl bağlayacağınızı öğreneceğiz. PHP'de RESTful web servisine dayalı bir Sosyal Karar Destek Sistemi geliştiriyoruz. Bu fikir, bilgisayar destekli alım satım adı verilen belirli bir otomatik alım satım anlayışından gelmektedir. İnsan yatırımcılarının bilişsel yeteneklerinin, aksi takdirde Expert Advisor'lar tarafından otomatik olarak piyasaya sürülecek olan alım satım sinyallerini filtrelemesini istiyoruz.
Sanal Barındırmaya Geçiş için Alım Satım Hesabı Nasıl Hazırlanır? Sanal Barındırmaya Geçiş için Alım Satım Hesabı Nasıl Hazırlanır?
MetaTrader istemci terminali, alım satım stratejilerini otomatikleştirmek için mükemmeldir. Alım satım robotu geliştiricileri için gerekli tüm araçlara sahiptir: güçlü C++ tabanlı MQL4/MQL5 programlama dili, kullanışlı MetaEditor geliştirme ortamı ve MQL5 Cloud Network'te dağıtılmış hesaplamayı destekleyen çok kanallı strateji test cihazı. Bu makalede, istemci terminalinizi tüm özel öğelerle birlikte sanal ortama nasıl taşıyacağınızı öğreneceksiniz.
Alım Satım Robotlarının Hikayeleri: Daha Az mı Daha Fazla mı? Alım Satım Robotlarının Hikayeleri: Daha Az mı Daha Fazla mı?
İki yıl önce "Son Haçlı Seferi"nde piyasa bilgilerini görüntülemek için oldukça ilginç ancak şu anda yaygın olarak kullanılmayan bir yöntem olan nokta ve şekil grafiklerini inceledik. Şimdi nokta ve şekil grafiğinde tespit edilen formasyonlara göre bir alım satım robotu yazmaya çalışmanızı öneririm.