[TOC]
Los datos son la fuente del comercio cuantitativo. Cómo gestionar de forma eficiente grandes cantidades de datos es un eslabón fundamental. La base de datos es una de las mejores soluciones. Hoy en día, la aplicación de bases de datos se ha convertido en una configuración estándar cuantitativa para diversas operaciones intradía y operaciones de alta frecuencia. y otras estrategias. . En este artículo, estudiaremos la base de datos incorporada de Inventor Quantitative (FMZ.COM), incluyendo: cómo crear tablas de datos, almacenar datos, modificar datos, eliminar datos, hacer referencia a datos y cómo aplicarlos en combate real.
Quienes estén familiarizados con la Plataforma cuantitativa Inventor deben saber que antes de esto, si desea guardar datos localmente para reutilizarlos, solo puede usar la función _G(). Cada vez que detenga la estrategia,_La función G() guardará automáticamente la información requerida. Pero si desea guardar datos con formatos más complejos,_La función G() obviamente no es muy aplicable, por lo que muchas personas pensaron en construir su propia base de datos para resolver este problema.
Cuando se habla de bases de datos autoconstruidas, probablemente todos piensan en Oracle, MySQL, KDB, OneTick, NoSQL… Todas ellas son excelentes aplicaciones de nivel empresarial, con funciones y rendimiento muy potentes. Sin embargo, también se enfrenta a varios problemas: es difícil empezar, la configuración es complicada y el mantenimiento es problemático. Para los comerciantes cuantitativos minoristas, esto es un poco como usar un cañón para matar una mosca. Incluso si comienzan, no podrán hacerlo. Utilice sólo una pequeña parte de las funciones.
A continuación, echemos un vistazo a la base de datos liviana integrada en InventorQuant. DBExec es una interfaz de sistema de administración de datos relacional integrada en InventorQuant. Está desarrollada en base a SQLite y está escrita en C. No solo es pequeña en tamaño y consume pocos recursos. , pero también la velocidad de procesamiento es rápida y es muy adecuada para que los entusiastas del análisis cuantitativo financiero implementen la gestión de datos localmente, porque diferentes “objetos” (como bolsas, fuentes de datos, precios) se pueden dividir en diferentes tablas y se pueden definir relaciones. Entre las mesas. Además, los usuarios no necesitan instalarlo y configurarlo por separado, ¡pueden usarlo directamente llamando a la función DBExec()!
Además, el costo de aprendizaje del lenguaje SQLite es muy bajo y la mayor parte del trabajo realizado en la base de datos se realiza mediante declaraciones SQLite. Estar familiarizado con la sintaxis básica puede satisfacer la mayoría de las necesidades. A continuación, se muestra la sintaxis básica de SQLite.
La sintaxis de SQLite no distingue entre mayúsculas y minúsculas, pero algunos comandos sí lo hacen, como GLOB y glob, que tienen significados diferentes. Las declaraciones de SQLite pueden comenzar con cualquier palabra clave, como SELECT, INSERT, UPDATE, DELETE, ALTER, DROP, etc., que significan respectivamente: extraer datos, insertar datos, actualizar datos, eliminar datos, modificar base de datos y eliminar tabla de datos. Todas las declaraciones terminan con punto y coma. A continuación se muestra una sencilla creación de base de datos, adición, eliminación, modificación, consulta y otras operaciones:
function main() {
// 创建:如果“users”表不存在就创建一个,“id”是整数且自动增加,“name”是文本形式且不为空
Log(DBExec('CREATE TABLE IF NOT EXISTS "users" (id INTEGER PRIMARY KEY AUTOINCREMENT, name text not NULL);'));
// 增加:
Log(DBExec("INSERT INTO users(name) values('张三')"));
Log(DBExec("INSERT INTO users(name) values('李四')"));
// 删除:
Log(DBExec("DELETE FROM users WHERE id=1;"));
// 修改
Log(DBExec("UPDATE users SET name='王五' WHERE id=2"));
// 查询
Log(DBExec('select 2, ?, ?, ?, ?', 'ok', true,9.8,null));
Log(DBExec('select * from kvdb'));
Log(DBExec('select * from cfg'));
Log(DBExec('select * from log'));
Log(DBExec('select * from profit'));
Log(DBExec('select * from chart'));
Log(DBExec("selEct * from users"));
}
Una base de datos normalmente contiene una o más tablas. Cada tabla tiene un nombre. Cabe señalar que las tablas reservadas para el sistema son: kvdb, cfg, log, profit, chart. Es decir, al crear una tabla, se deben evitar los nombres reservados del sistema. Ejecutemos el código anterior, que imprimirá lo siguiente:
Ahora que conocemos la sintaxis básica de SQLite, podemos usar la base de datos incorporada de InventorQuant para crear un ejemplo de recopilación y uso de datos de Tick.
Paso 1: Actualiza tu host En primer lugar, asegúrese de estar usando la última versión del host. Si ya ha descargado y usado el host antes, primero debe eliminarlo y luego volver a descargarlo e implementarlo en https://www.fmz.com/ Página m/add-node.
Paso 2: Crea una estrategia
function main() {
// 订阅合约
_C(exchange.SetContractType, 'swap');
// 创建数据表
DBExec('CREATE TABLE IF NOT EXISTS "tick" (id INTEGER PRIMARY KEY AUTOINCREMENT,'.concat(
'High FLOAT not NULL,',
'Low FLOAT not NULL,',
'Sell FLOAT not NULL,',
'Buy FLOAT not NULL,',
'Last FLOAT not NULL,',
'Volume INTEGER not NULL,',
'Time INTEGER not NULL);'
));
// 获取10个tick数据
while (true) {
let tick = exchange.GetTicker();
// 在tick表中增加数据
DBExec(`INSERT INTO tick(High, Low, Sell, Buy, Last, Volume, Time) values(${tick.High}, ${tick.Low}, ${tick.Sell}, ${tick.Buy}, ${tick.Last}, ${tick.Volume}, ${tick.Time})`);
// 查询所有数据
let allDate = DBExec('select * from tick');
if (allDate.values.length > 10) {
break;
}
Sleep(1000);
}
// 查询所有数据
Log(DBExec('select * from tick'));
// 查询第一个数据
Log(DBExec('select * from tick limit 1'));
// 查询前两个数据
Log(DBExec('select * from tick limit 0,2'));
// 删除第一个数据
Log(DBExec('DELETE FROM tick WHERE id=1;'));
// 修改第二个数据
Log(DBExec('UPDATE tick SET High=10000 WHERE id=2'));
// 查询所有数据
let allDate = DBExec('select * from tick')
Log(allDate);
}
Paso 3: Ejecutar la estrategia Si tomamos Windows como ejemplo, después de ejecutar la política, se generará una carpeta con el nombre del número del robot en el directorio “\logs\storage” del directorio del host. Abra la carpeta y habrá un archivo con el sufijo “.db3”. “ en él, este archivo es el archivo de la base de datos incorporada cuantificada del inventor. Como se muestra en la siguiente figura: El código anterior primero crea una tabla de datos llamada “tick”, luego agrega un campo de datos de ticks a la tabla, luego obtiene datos de ticks del intercambio en un bucle e inserta estos datos en la tabla de datos “tick”. Si la cantidad de datos en la tabla de datos excede 10, se saltará el bucle. Finalmente, se utilizan cinco comandos SQLite para consultar, eliminar y modificar los datos en la tabla de datos. E imprimirlo en el registro, como se muestra en la siguiente figura: Paso 4: Crea la barra de estado Por último, añadimos un código para crear una barra de estado para la estrategia obteniendo datos de la base de datos cuantitativa de Inventor para mostrar los datos de forma más intuitiva. El código recién añadido es el siguiente:
// 创建状态栏
let table = {
type: 'table',
title: '币安Tick数据',
cols: allDate.columns,
rows: allDate.values
}
LogStatus('`' + JSON.stringify(table) + '`');
El código anterior crea una tabla “Binance Tick Data” utilizando los datos de la base de datos. El campo “columnas” de la base de datos representa las “filas” en la barra de estado, y el campo “valores” representa las “columnas” en la barra de estado. Como se muestra en la siguiente figura:
/*backtest
start: 2020-07-19 00:00:00
end: 2020-08-17 23:59:00
period: 15m
basePeriod: 15m
exchanges: [{"eid":"Binance","currency":"LTC_USDT"}]
*/
function main() {
Log(DBExec('DROP TABLE tick;'));
// 订阅合约
_C(exchange.SetContractType, 'swap');
// 创建数据表
DBExec('CREATE TABLE IF NOT EXISTS "tick" (id INTEGER PRIMARY KEY AUTOINCREMENT,'.concat(
'High FLOAT not NULL,',
'Low FLOAT not NULL,',
'Sell FLOAT not NULL,',
'Buy FLOAT not NULL,',
'Last FLOAT not NULL,',
'Volume INTEGER not NULL,',
'Time INTEGER not NULL);'
));
// 获取10个tick数据
while (true) {
let tick = exchange.GetTicker();
// 在tick表中增加数据
DBExec(`INSERT INTO tick(High, Low, Sell, Buy, Last, Volume, Time) values(${tick.High}, ${tick.Low}, ${tick.Sell}, ${tick.Buy}, ${tick.Last}, ${tick.Volume}, ${tick.Time})`);
// 查询所有数据
let allDate = DBExec('select * from tick');
if (allDate.values.length > 10) {
break;
}
Sleep(1000);
}
// 查询所有数据
Log(DBExec('select * from tick'));
// 查询第一个数据
Log(DBExec('select * from tick limit 1'));
// 查询前两个数据
Log(DBExec('select * from tick limit 0,2'));
// 删除第一个数据
Log(DBExec('DELETE FROM tick WHERE id=1;'));
// 修改第二个数据
Log(DBExec('UPDATE tick SET High=10000 WHERE id=2'));
// 查询所有数据
let allDate = DBExec('select * from tick')
Log(allDate);
// 创建状态栏
let table = {
type: 'table',
title: '币安Tick数据',
cols: allDate.columns,
rows: allDate.values
}
LogStatus('`' + JSON.stringify(table) + '`');
}
Haga clic en este enlace https://www.fmz.com/strategy/388963 para copiar el código de estrategia completo.
Si no desea guardar los datos de forma permanente en el disco, puede agregarlos:
Los símbolos se pueden operar en la base de datos de memoria y los datos se restablecen después de reiniciar el robot.
DBExec(":select 1,2,3");
La base de datos no sólo puede contener cantidades masivas de datos, sino que también puede contener los sueños cuantitativos de muchos entusiastas del trading cuantitativo. El uso de bases de datos no se limita a los ejemplos de este artículo. Para conocer más métodos de uso, consulte el tutorial de SQLite y la serie de artículos posteriores publicados por Inventor Quantitative.