Simulación de mercado: Iniciando SQL en MQL5 (I)
Introducción
Hola a todos y bienvenidos a un artículo más de la serie sobre cómo construir un sistema de repetición/simulador.
En el artículo anterior, Simulación de mercado (Parte 24): Iniciando SQL (VII), cerramos lo que considero la base de la base, necesaria para que tú, querido lector, incluso sin ninguna experiencia en SQL, puedas, como mínimo, seguir lo que vamos a hacer de ahora en adelante. Esto se debe a que estamos entrando en una nueva fase del desarrollo del sistema de repetición/simulador, en la que saber SQL será primordial para que puedas seguir este y los próximos artículos.
No te preocupes si todavía estás empezando en SQL y solo tienes como base lo que se explicó en los artículos anteriores. Ese material, si se emplea bien y se comprende correctamente, ya será suficiente para hacer gran parte de lo que realmente necesitamos. En este primer momento, mi verdadera intención es mantenernos dentro de SQLite, puesto que viene integrado en MetaTrader 5, lo que facilita mucho su uso sin que necesitemos recurrir a una DLL ni siquiera a sockets.
Muy bien, si ya usas SQLite en tus programas con MQL5, este artículo no va a aportar nada a lo que ya sabes hacer. Pero, si todavía estás empezando en este mundo, en el que usar bases de datos es algo que debe considerarse seriamente, y no sabes cómo hacerlo usando MQL5, creo que lo mejor es que te acomodes en el sillón y sigas este artículo. Porque aquí veremos cómo empezar a usar una base de datos SQL usando MQL5 para ello. Solo que no usaremos una base de datos cualquiera. Usaremos SQLite. Y, como viste en los artículos anteriores, podemos hacer bastante dentro del sistema. Todo ello con un mínimo de esfuerzo en MQL5.
Creando la base de datos SQL mediante MQL5
Muy bien. Lo primero que habrá que hacer será crear una base de datos. Como viste en los artículos anteriores, hacerlo es algo bastante simple y sin ninguna dificultad. Podemos hacerlo directamente desde MetaEditor, desde el prompt o con un programa específico para editar scripts en SQL. Pero quiero que tú, querido lector, aprendas y entiendas que no necesitamos hacerlo así. Podemos hacerlo directamente mediante programación, usando uno u otro lenguaje para ello.
Si buscas, encontrarás a mucha gente explicando distintas maneras de hacer lo mismo, utilizando para ello lenguajes diferentes. Pero, si prestas la debida atención, notarás que, en el fondo, en la esencia de lo que se está haciendo, todo se desarrolla para hacerse con SQL. Y es en este punto donde las cosas empiezan a ponerse interesantes. Esto se debe a que, si entiendes estos principios, podrás traducir algo hecho en JAVA, por ejemplo, para hacerlo aquí en MQL5. El motivo es que, al final, quien realmente tratará los datos y actuará sobre los registros será el código en SQL. JAVA solo servirá para proporcionar una interfaz más amigable para un determinado tipo de usuario.
Encontrarás el mismo tipo de planteamiento en VBA, donde usamos Excel para presentar los datos que se obtendrán directamente mediante SQL. Por eso es tan importante comprender cómo funciona realmente el código en SQL. Porque, al final, estarás usando SQL. El lenguaje que sirva de apoyo a SQL solo servirá para presentar los datos que SQL nos proporcionará.
Contar con esta visión de cómo funcionan realmente las cosas te ayudará bastante de ahora en adelante. Entonces, vamos a comenzar por el principio más básico de todos: crear un archivo de base de datos en SQLite usando, para ello, MQL5. Como la intención aquí es explicar esto de la forma más didáctica posible, vamos a usar algo lo más simple posible. Es decir, vamos a usar un script en MQL5. Esto se debe a que un script puede entenderse con mayor claridad y probarse con más facilidad. El primer código que usaremos puede verse a continuación:
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. #property description "Basic script for SQL database written in MQL5" 04. #property version "1.00" 05. #property script_show_inputs 06. //+------------------------------------------------------------------+ 07. input string user01 = "DataBase01"; //FileName 08. //+------------------------------------------------------------------+ 09. void OnStart() 10. { 11. string szFileName = user01 + ".sqlite"; 12. int handleDB; 13. 14. if ((handleDB = DatabaseOpen(szFileName, DATABASE_OPEN_CREATE | DATABASE_OPEN_READWRITE)) == INVALID_HANDLE) 15. { 16. Print("Unable to create or open the file ", szFileName); 17. return; 18. } 19. DatabaseClose(handleDB); 20. Print("Database file saved successfully.."); 21. } 22. //+------------------------------------------------------------------+
Código en MQL5
Este es el código más simple posible para abrir, o incluso crear, un archivo de base de datos. Todo ello usando MQL5 junto con SQLite. Observa que es algo muy fácil de entender. En la línea siete, permites que el usuario del script indique el nombre de la base de datos que se va a crear o abrir. Ten en cuenta que no estamos indicando la extensión del archivo que se va a usar. Esto se debe a que después indicaremos cuál será la extensión que se utilizará. La extensión que se utilizará se indica en la línea 11. Observa que allí usamos el nombre que nos indicará el usuario del script y lo unimos con otra string que, en este caso, será la extensión del nombre del archivo.
Es importante tener en cuenta que podemos usar cualquier extensión. Pero te sugiero que uses una que indique el tipo de archivo que vamos a usar. Para una base de datos SQL, lo más común es usar .DB o, en el caso de SQLite, .sqlite como extensión, dado que podremos estar usando elementos propios de SQLite. Esto se explicó en los artículos anteriores. Ante cualquier duda, revísalos, así como las referencias que contienen, para comprender mejor el tema.
Bien, como vamos a tratar archivos, necesitamos un identificador. Este se declara en la línea 12. Ya en la línea 14, usamos la función DatabaseOpen, que forma parte de MQL5, para abrir o incluso crear el archivo de base de datos. En este punto, hay un detalle importante que conviene observar. Podrás crear un archivo de base de datos en tres ubicaciones diferentes. Todo ello usando esta misma función DatabaseOpen. Las ubicaciones son las siguientes: la primera, en memoria, es decir, una vez que la base de datos se cierre, dejará de existir. Esto resulta muy útil en determinadas situaciones. Pero, en nuestro caso, no lo utilizaremos, al menos por ahora. La segunda ubicación,
al igual que la tercera, dependerá de los argumentos que se pasen a la función DatabaseOpen. Observa que, en el código mostrado, estamos usando los argumentos DATABASE_OPEN_CREATE y DATABASE_OPEN_READWRITE. Esto hará que el archivo de base de datos se cree en algún lugar de la carpeta MQL5\Files. Digo en algún lugar porque, en el nombre que indique el usuario, podría incluir un nombre de directorio válido. Y, si eso ocurre, deberás ir al directorio indicado por el usuario. De cualquier forma, ese directorio estará dentro de la carpeta MQL5\Files, precisamente por los argumentos indicados.
Sin embargo, esta ubicación puede ser distinta si, junto con los argumentos que vimos en el código, añades también el argumento DATABASE_OPEN_COMMON. Esto hará que la carpeta deje de ser MQL5\Files y pase a ser COMMON\Files. Ahora bien, no sé dónde está esa carpeta COMMON, ¿cómo puedo acceder a ella? Este tipo de duda es bastante común. Entonces, querido lector, si no sabes dónde se encuentra esa carpeta, bastará con ir a la siguiente ruta dentro de tu disco local:
C:\Users\<UserName>\AppData\Roaming\MetaQuotes\Terminal
En esa ubicación, encontrarás la carpeta COMMON y, dentro de ella, la carpeta Files. Recuerda sustituir el valor <UserName> por el nombre del usuario que haya iniciado sesión en Windows.
Si no se permite la creación o el acceso al archivo especificado, en el terminal de MetaTrader 5 se imprimirá el mensaje que aparece en la línea 16. Justo después, en la línea 17, el script se cerrará. Pero, si todo ha funcionado perfectamente, en la línea 19 cerraremos el archivo de base de datos y, en la línea 20, imprimiremos un mensaje en el terminal de MetaTrader 5 indicando que todo se completó correctamente. Como resultado, en MetaEditor podrás abrirlo y ver algo parecido a lo que se muestra en la siguiente imagen.

En este punto, ya podemos usar SQL mediante MetaEditor. Sin embargo, vamos a usarlo mediante MQL5. Aun así, puedes usar MetaEditor, o incluso los programas mostrados durante la explicación de SQL en los artículos anteriores, para seguir lo que se hará mediante MQL5. Es importante que, en estos primeros pasos, en los que estarás aprendiendo a usar SQLite en MQL5, tengas alguna manera de seguir lo que se va haciendo. Para ello, conocer lo básico de SQL será de gran ayuda. Así que usa el material de apoyo presente en los artículos anteriores para acelerar aún más tu aprendizaje. Porque lo que haremos aquí será bastante interesante.
Muy bien, ahora que ya sabemos cómo crear o abrir un archivo de base de datos SQL, podemos pasar a la siguiente etapa. Pero antes, déjame aclarar algo que quizá te genere dudas. Cuando diga que vamos a abrir un archivo, acceder a datos y añadir o ajustar registros en SQL, quiero que tengas presente que estaremos usando SQLite. Esto se debe a que, para hacer las mismas cosas que se harán aquí, pero usando otra implementación de SQL, como por ejemplo MySQL o SQL Server, la forma de hacerlas es ligeramente distinta. No confundas las cosas.
Solo hay un SQL, que es el lenguaje que se usa. Tipos de implementación hay varios, y cada uno nos permite hacer más o menos cosas. Aquí trabajaremos exclusivamente con SQLite, al menos en este comienzo de la implementación. En el futuro, puede que cambie de idea. Pero, si eso ocurre, te explicaré cómo migrar de SQLite a otra implementación de SQL. Pero no hace falta que tengas miedo de aprender SQL. Porque el lenguaje SQL siempre será el mismo, independientemente de la aplicación o implementación que lo utilice.
Creando las primeras tablas
Tal como se hizo para explicar los comandos SQL, aquí haremos algo muy parecido. Esto es para que la transición entre la programación en SQL puro y SQL integrado en otro código sea fluida. En este caso, el código que recibirá esos comandos es MQL5. Pues bien, por fortuna, los desarrolladores de MQL5 hicieron un excelente trabajo y lo dejaron todo bastante simple de comprender y utilizar. Así, realmente necesitarás aprender a usar seis funciones, de todas las disponibles en MQL5, para trabajar con bases de datos. Pero entonces, ¿las otras funciones son innecesarias? No, no he dicho eso. He dicho que necesitas aprender a usar seis funciones. Y, sabiendo trabajar con esas seis y conociendo un poco de SQL, podrás desenvolverte perfectamente en cualquier situación que involucre bases de datos. Al menos en lo que respecta a trabajar con SQLite, que está incluido en MQL5.
Si vas a usar SQLite mediante una DLL, la forma de hacer las cosas será un poco distinta. Esto se debe a que, en ese caso, harás las llamadas directamente mediante el SQLite incluido en la DLL. Entonces, si ese es tu caso concreto, te sugiero que estudies la documentación sobre cómo usar SQLite mediante una DLL, porque las cosas difieren un poco de lo que veremos aquí.
Muy bien, entonces veamos cuáles son las funciones que necesitaremos aprender a usar. Dos de ellas ya se han mostrado, que son: DatabaseOpen y DatabaseClose. Pero también necesitaremos DatabaseExecute, DatabasePrepare, DataBaseReadBind y DatabaseFinalize. Por supuesto, saber usar las demás funciones te ayudará bastante en muchos momentos. Pero, con estas seis, ya podremos construir casi cualquier cosa con mucha facilidad. Siempre que, claro está, ya tengas una buena base en programación SQL.
Con las cosas que mostré en los artículos anteriores, al menos ya podrás hacer algunas cosas bastante interesantes. Además, claro está, podrás hacer algunas cosas que muchos no sabrían hacer como tú podrás hacerlas. Pero, como prometí, iré haciendo las cosas poco a poco, para que todos puedan seguir y entender lo que va ocurriendo.
Bien. Como debes de haber visto en los artículos anteriores, cualquier cosa que vayamos a hacer estará, de algún modo, ligada a tablas. Así que vamos a empezar por lo más básico sobre este asunto. De este modo, nuestro nuevo script puede verse a continuación.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. #property description "Basic script for SQL database written in MQL5" 04. #property version "1.00" 05. #property script_show_inputs 06. //+------------------------------------------------------------------+ 07. input string user01 = "DataBase01"; //FileName 08. //+------------------------------------------------------------------+ 09. void OnStart() 10. { 11. string szFileName = user01 + ".sqlite", 12. szRequestSQL; 13. int handleDB; 14. 15. if ((handleDB = DatabaseOpen(szFileName, DATABASE_OPEN_CREATE | DATABASE_OPEN_READWRITE)) == INVALID_HANDLE) 16. { 17. Print("Unable to create or open the file ", szFileName); 18. return; 19. } 20. szRequestSQL = "CREATE TABLE IF NOT EXISTS tb_Symbol(id PRIMARY KEY, symbol NOT NULL UNIQUE);"; 21. if (!DatabaseExecute(handleDB, szRequestSQL)) 22. { 23. Print("Request execution failed."); 24. DatabaseClose(handleDB); 25. return; 26. } 27. DatabaseClose(handleDB); 28. Print("Database file saved successfully."); 29. } 30. //+------------------------------------------------------------------+
Código en MQL5
Cuando este script se ejecute en MetaTrader 5, obtendrás el resultado que se muestra a continuación:

Vaya, qué bien. Pero ¿cómo se hizo esto? Simple. Todo lo que hicimos fue usar algo que vimos en los artículos anteriores, donde expliqué SQL. Solo que, aquí, hicimos todo mediante MQL5. ¿Cómo? Tomando como base el script que vimos en el apartado anterior, apenas añadimos unas pocas líneas más al código. Con un detalle: este código todavía no está correctamente estructurado. Aquí, mi intención es mostrarte cómo podemos hacer las mismas cosas que vimos antes. Así, añadimos la línea 12, que es una string que recibirá el comando SQL que queremos ejecutar. En la línea 20, indicamos cuál es ese comando. En este caso, le pediremos a SQL que cree una tabla llamada tb_Symbol, en caso de que no exista en la base de datos.
Justo después, usando la función DatabaseExecute, le decimos a SQLite que ejecute el comando SQL. Si este procedimiento falla, en la línea 23 se imprimirá un mensaje en el terminal de MetaTrader 5. Como la base de datos está abierta, necesitamos cerrarla. Esto se hace en la línea 24. Ya en la línea 25, finalizamos la ejecución del script en MetaTrader 5.
Ahora, presta atención a una cosa. Todo comando que queramos enviar para que SQLite lo ejecute, cuando estemos usando SQLite incluido en MetaTrader 5, lo haremos mediante DatabaseExecute. Sin embargo, esto solo es adecuado cuando queremos dar órdenes a SQL. Cuando queramos hacer consultas, necesitaremos usar también las demás funciones. Observa cómo todo va encajando, para que podamos desarrollar lo que necesitamos.
Entonces, antes de pasar a ver cómo trabajar con consultas, vamos a hacer que este script en MQL5 sea un poco más versátil y, en consecuencia, más adecuado para usar la base de datos que estamos creando. Como las cosas pueden estructurarse de otra manera, podemos convertir este mismo script en una clase. Aunque, en este momento, parezca simple, esto ya ayudará bastante, ya que podremos hacer el código más reutilizable y, en consecuencia, más seguro y estable. Entonces, el mismo código visto antes pasa a ser el que se muestra a continuación, solo que ahora usando clases para ello.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. #property description "Basic script for SQL database written in MQL5" 04. #property version "1.00" 05. #property script_show_inputs 06. //+------------------------------------------------------------------+ 07. input string user01 = "DataBase01"; //FileName 08. //+------------------------------------------------------------------+ 09. class C_DB_SQLite 10. { 11. private : 12. int m_handleDB; 13. public : 14. //+------------------------------------------------------------------+ 15. C_DB_SQLite(const string szFileName) 16. :m_handleDB(INVALID_HANDLE) 17. { 18. if ((m_handleDB = DatabaseOpen(szFileName, DATABASE_OPEN_CREATE | DATABASE_OPEN_READWRITE)) == INVALID_HANDLE) 19. { 20. Print("Unable to create or open the file ", szFileName); 21. return; 22. } 23. } 24. //+------------------------------------------------------------------+ 25. ~C_DB_SQLite() 26. { 27. DatabaseClose(m_handleDB); 28. Print("Closing Database..."); 29. } 30. //+------------------------------------------------------------------+ 31. bool Command(const string szRequestSQL) 32. { 33. bool ret = DatabaseExecute(m_handleDB, szRequestSQL); 34. Print("Request execution: ", (ret ? "Success" : "Failed"), "..."); 35. return ret; 36. } 37. //+------------------------------------------------------------------+ 38. }; 39. //+------------------------------------------------------------------+ 40. void OnStart() 41. { 42. C_DB_SQLite *DB; 43. 44. DB = new C_DB_SQLite(user01 + ".sqlite"); 45. 46. (*DB).Command("CREATE TABLE IF NOT EXISTS tb_Symbol(id PRIMARY KEY, symbol NOT NULL UNIQUE);"); 47. 48. delete DB; 49. } 50. //+------------------------------------------------------------------+
Código en MQL5
Observa que ahora tenemos una estructura mucho más elaborada para trabajar con la base de datos. Esto se debe a que, independientemente de lo que vayamos a hacer, siempre que enviemos comandos a una base de datos, los enviaremos a la base correcta, sin importar si tenemos una o decenas de bases abiertas. El comando siempre se enviará a la base correcta. Esto se debe a que ahora las funciones se usan dentro de la clase creada entre las líneas 9 y 38. Y eso que apenas estamos empezando. Aun así, ya contamos con toda la seguridad que nos ofrece una clase.
Por ejemplo, no podrás usar un identificador sin que haya sido inicializado. Y, como la inicialización se realiza mediante el constructor de la clase, tenemos la garantía de que siempre estaremos usando un identificador adecuado. Esto puede verse en la línea 33, donde usamos el identificador para enviar el comando a SQL.
Ahora quiero que prestes atención a algo. Muchos pueden considerar innecesario usar, o incluso crear, una clase para encapsular el sistema de comunicación con SQLite. Pero pensemos un poco, y quizá esto te haga cambiar de idea. Puedes pensar lo siguiente: ¿por qué debería crear una clase solo para usar SQLite incluido en MetaTrader 5? Es mucho más fácil usar directamente las funciones de MQL5 para ello. Sobre todo porque no voy a hacer un uso intensivo de SQL en mis programas. Bien, visto desde esa perspectiva, debo estar de acuerdo contigo, querido lector. Pero veamos esto de una forma un poco más amplia. MQL5 nos permite acceder de forma fácil y simple a SQLite incluido en MetaTrader 5. De acuerdo. Pero no debemos limitarnos a ello.
Si desarrollas toda una gama de aplicaciones, o incluso un sistema que use SQLite incluido en MetaTrader 5, haciendo uso únicamente de las funciones de MQL5, en algún momento quedarás limitado a usar única y exclusivamente el SQLite de MetaTrader 5. No podrás usar una compilación propia de SQLite en una DLL, hecha exclusivamente para ti. Y lo peor: si, en algún momento, decides usar otra implementación de SQL, ya sea MySQL, SQL Server o cualquier otra, te dará mucho trabajo tener que rehacer todo tu código para cubrir las dependencias necesarias. Esto se debe a que MySQL y SQL Server, que acabo de mencionar, no utilizan un sistema de archivos al que puedas acceder usando MQL5. Incluso podrás usar MQL5, pero tendrás que recurrir a otra herramienta cuyo uso ya mostré en esta serie. La herramienta en cuestión serían los sockets.
Es decir, para acceder a bases de datos que usan una arquitectura cliente-servidor, tendrás que usar sockets para ello. Si tu implementación se concibió, desde el principio, para usar un sistema de clases con el fin de ocultar cómo se implementa todo, lo único que necesitarás hacer será modificar la clase, ampliándola o adaptándola para que pueda proporcionar el soporte necesario para que se produzca la comunicación vía sockets. Esto simplifica enormemente todo el desarrollo. Porque, si necesitas cambiar la implementación de SQL, del SQLite usado en MetaTrader 5 a un SQLite propio compilado en una DLL, será sencillo realizar esa tarea.
Lo mismo se aplica si necesitas cambiar la implementación. Al pasar de SQLite, que se basa en archivos, a un SQL basado en cliente-servidor, no tendrás grandes problemas. Bastará con cambiar la forma en que funciona la clase, y el resto del código se beneficiará de los cambios. Así de simple. Entonces, no subestimes las ventajas de desarrollar una aplicación pensando en cambiar, en el futuro, la forma en que funciona. Recuerda: la tecnología cambia con el tiempo. Hacer que una implementación quede bloqueada o ligada de forma intrínseca a algo no es una buena elección.
Entendiendo algunas cosas
Antes de continuar, quiero mostrarte algo, querido lector. Porque es muy importante que entiendas esto. Hagamos lo siguiente. En los artículos anteriores, creamos una relación entre tablas para tener una base de datos relacional. Expliqué cómo podías hacerlo, así como las ventajas y desventajas de este modo de estructurar la base de datos de forma relacional. Pero, cuando vamos a trabajar con muchos comandos SQL, mediante SQLite incluido en MetaTrader 5, tendremos que tomar algunas precauciones. O mejor dicho, necesitamos idear una forma de hacer esto con mayor seguridad.
Lo que mostraré nos obligará a tomar algunas decisiones en el próximo artículo. Así que observa con calma el siguiente código en MQL5, que se muestra a continuación:
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. #property description "Basic script for SQL database written in MQL5" 04. #property version "1.00" 05. #property script_show_inputs 06. //+------------------------------------------------------------------+ 07. input string user01 = "DataBase01"; //FileName 08. //+------------------------------------------------------------------+ 09. class C_DB_SQLite 10. { 11. private : 12. int m_handleDB; 13. public : 14. //+------------------------------------------------------------------+ 15. C_DB_SQLite(const string szFileName) 16. :m_handleDB(INVALID_HANDLE) 17. { 18. if ((m_handleDB = DatabaseOpen(szFileName, DATABASE_OPEN_CREATE | DATABASE_OPEN_READWRITE)) == INVALID_HANDLE) 19. { 20. Print("Unable to create or open the file ", szFileName); 21. return; 22. } 23. } 24. //+------------------------------------------------------------------+ 25. ~C_DB_SQLite() 26. { 27. DatabaseClose(m_handleDB); 28. Print("Closing Database..."); 29. } 30. //+------------------------------------------------------------------+ 31. bool Command(const string szRequestSQL) 32. { 33. bool ret = DatabaseExecute(m_handleDB, szRequestSQL); 34. Print("Request execution: ", (ret ? "Success" : "Failed"), "..."); 35. return ret; 36. } 37. //+------------------------------------------------------------------+ 38. }; 39. //+------------------------------------------------------------------+ 40. void OnStart() 41. { 42. C_DB_SQLite *DB; 43. 44. DB = new C_DB_SQLite(user01 + ".sqlite"); 45. 46. (*DB).Command("PRAGMA FOREIGN_KEYS = ON;"); 47. (*DB).Command("CREATE TABLE IF NOT EXISTS tb_Symbols" 48. "(" 49. "id PRIMARY KEY," 50. "symbol NOT NULL UNIQUE" 51. ");"); 52. (*DB).Command("CREATE TABLE IF NOT EXISTS tb_Quotes" 53. "(" 54. "of_day NOT NULL," 55. "price NOT NULL," 56. "fk_id NOT NULL," 57. "FOREIGN KEY (fk_id) REFERENCES tb_Symbols(id)" 58. ");"); 59. delete DB; 60. } 61. //+------------------------------------------------------------------+
Código en MQL5
Observa cómo se colocan los comandos dentro del código MQL5. Esto es para que podamos ejecutar comandos SQL. No es raro que, al escribir tantas cosas, terminemos cometiendo algún error. Ahora, observa el script que se muestra a continuación:
01. PRAGMA FOREIGN_KEYS = ON; 02. 03. CREATE TABLE IF NOT EXISTS tb_Symbols 04. ( 05. id PRIMARY KEY, 06. symbol NOT NULL UNIQUE 07. ); 08. 09. CREATE TABLE IF NOT EXISTS tb_Quotes 10. ( 11. of_day NOT NULL, 12. price NOT NULL, 13. fk_id NOT NULL, 14. FOREIGN KEY (fk_id) REFERENCES tb_Symbols(id) 15. );
Código en SQLite
Compara este script con el anterior. Observa que, aunque este último use SQL puro y su sintaxis pueda analizarse durante la escritura, no tenemos la misma facilidad cuando insertamos strings directamente en el código MQL5. Esto permite que MQL5 haga que SQLite incluido en MetaTrader 5 funcione correctamente. Es decir, si, al escribir el código SQL dentro de una string en el código MQL5, cometemos un error de tecleo, SQL no ejecutará correctamente nuestro código. Y podrías terminar echando toda la culpa a MQL5, o incluso a MetaTrader 5, lo cual sería un gran error. Sin embargo, observa que, en ambos códigos, estamos creando una base de datos con tablas relacionadas. Y, si por casualidad, en algún punto, escribes el nombre de la tabla tb_Symbols como tb_Symbol, el resultado será completamente distinto del que se muestra en la siguiente figura.

Observa que, si intentas ver en MetaEditor esta misma estructura que aparece en la figura anterior, no lo conseguirás. Ya hablé de esto en otro artículo. Si no entiendes lo que está ocurriendo aquí, te aconsejo revisar los artículos en los que expliqué SQL y cómo obtener los programas necesarios para hacer un mejor uso del sistema SQL.
Pero la cuestión que quiero resaltar aquí es precisamente esta. Al mirar el código SQL dentro de una string, este puede contener errores que no percibirás con facilidad. Sin embargo, si usas un editor capaz de analizar el código SQL, será mucho más simple detectar esas fallas. Como puedes ver a continuación.

Observa que es mucho más fácil detectar dónde hay alguna falla en el código del script en SQL. Como dije hace un momento, no es raro que tú, como programador, cometas errores al teclear. Entonces, usar las herramientas correctas puede ahorrarte mucho tiempo tratando de entender por qué un código funciona o no. Porque, la mayoría de las veces, el error está precisamente al teclear algún comando.
Consideraciones finales
En este artículo, comenzamos a explorar el uso de SQL dentro de un código MQL5. Vimos cómo podemos crear una base de datos. O, mejor dicho, cómo podemos crear un archivo de base de datos en SQLite, utilizando, para ello, recursos o procedimientos incluidos en el lenguaje MQL5. Vimos también cómo crear una tabla y, después, cómo crear una relación entre tablas mediante una clave primaria y una clave foránea. Todo esto usando, nuevamente, MQL5. Vimos lo sencillo que es crear un código que, en el futuro, podrá portarse a otras implementaciones de SQL, usando una clase que nos ayude a ocultar la implementación creada.
Y lo más importante de todo: vimos que, en diversos momentos, podemos correr el riesgo de que algo no salga bien al usar SQL. Esto se debe a que, dentro del código MQL5, un código SQL se colocará dentro de una STRING. Y el hecho de que esto ocurra hace bastante probable que algo pueda salir mal, haciendo que la ejecución del código SQL dentro de MQL5 resulte problemática debido a un error de tecleo. Sin embargo, podemos y vamos a crear un mecanismo que, además de darnos un mayor grado de libertad, nos permitirá evitar esos problemas, ya que existen editores cuyo propósito es permitirnos leer con más facilidad el código de un script en SQL.
Entonces, en el próximo artículo, vamos a crear un mecanismo para facilitar esa portabilidad. Muchos, con algo de experiencia, ya deben de estar imaginando de qué se trata. Pero, si no es tu caso, no te preocupes. En el próximo artículo, veremos cómo se hará esto. Y vamos a seguir en nuestro campo de trabajo con SQL, solo que ahora usando MQL5 como base de ejecución. Esto para que MetaTrader 5 pueda hacer que nuestro sistema de repetición/simulador empiece a usar bases de datos en sus actividades. Así que, sigue estudiando, y nos vemos en el próximo artículo, donde esto será aún más interesante.
| Archivo | Descripción |
|---|---|
| Experts\Expert Advisor.mq5 | Demuestra la interacción entre Chart Trade y el Asesor Experto (es necesario el Mouse Study para la interacción) |
| Indicators\Chart Trade.mq5 | Crea la ventana para configurar la orden a ser enviada (es necesario el Mouse Study para la interacción) |
| Indicators\Market Replay.mq5 | Crea los controles para la interacción con el servicio de repetición/simulador (es necesario el Mouse Study para la interacción) |
| Indicators\Mouse Study.mq5 | Permite la interacción entre los controles gráficos y el usuario (necesario tanto para operar el sistema de repetición/simulador como en el mercado real) |
| Services\Market Replay.mq5 | Crea y mantiene el servicio de repetición y simulación de mercado (archivo principal de todo el sistema) |
| Code VS C++\Servidor.cpp | Crea y mantiene un socket servidor desarrollado en C++ (versión MiniChat) |
| Code in Python\Server.py | Crea y mantiene un socket en Python para la comunicación entre MetaTrader 5 e Excel |
| Indicators\Mini Chat.mq5 | Permite implementar un minichat mediante un indicador (requiere el uso de un servidor para funcionar) |
| Experts\Mini Chat.mq5 | Permite implementar un minichat mediante un Asesor Experto (requiere el uso de un servidor para funcionar) |
| Scripts\SQLite.mq5 | Demuestra el uso de un script SQL mediante MQL5 |
| Files\Script 01.sql | Demuestra la creación de una tabla simple, con clave foránea |
| Files\Script 02.sql | Demuestra la adición de valores en una tabla |
Traducción del portugués realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/pt/articles/13062
Advertencia: todos los derechos de estos materiales pertenecen a MetaQuotes Ltd. Queda totalmente prohibido el copiado total o parcial.
Este artículo ha sido escrito por un usuario del sitio web y refleja su punto de vista personal. MetaQuotes Ltd. no se responsabiliza de la exactitud de la información ofrecida, ni de las posibles consecuencias del uso de las soluciones, estrategias o recomendaciones descritas.
Utilizando redes neuronales en MetaTrader
Simulación de mercado (Parte 24): Iniciando SQL (VII)
Particularidades del trabajo con números del tipo double en MQL4
Descarga de datos del Fondo Monetario Internacional en Python
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso