[TOC]
Данные являются источником количественной торговли. Как эффективно управлять большими объемами данных — это критическое звено. База данных — одно из лучших решений. В настоящее время применение базы данных стало количественной стандартной конфигурацией для различных внутридневных торгов, высокочастотных торгов и другие стратегии. В этой статье мы изучим встроенную базу данных Inventor Quantitative (FMZ.COM), в том числе: как создавать таблицы данных, хранить данные, изменять данные, удалять данные, ссылаться на данные и как применять их в реальных боевых действиях.
Те, кто знаком с Inventor Quantitative Platform, должны знать, что до этого, если вы хотите сохранить данные локально для повторного использования, вы можете использовать только функцию _G(). Каждый раз, когда вы останавливаете стратегию,_Функция G() автоматически сохранит необходимую информацию. Но если вы хотите сохранить данные в более сложном формате,_Функция G(), очевидно, не очень применима, поэтому многие задумались о создании собственной базы данных для решения этой проблемы.
Когда речь заходит о самостоятельно созданных базах данных, каждый, вероятно, вспоминает Oracle, MySQL, KDB, OneTick, NoSQL… Все это превосходные приложения корпоративного уровня с очень мощными функциями и производительностью. Однако он также сталкивается с несколькими проблемами: его трудно запустить, конфигурация громоздка, а обслуживание хлопотно. Для розничных количественных трейдеров это немного похоже на использование пушки, чтобы убить муху. Даже если они начнут, они будут используйте только небольшую часть функций.
Далее рассмотрим облегченную базу данных, встроенную в InventorQuant. DBExec — это интерфейс реляционной системы управления данными, встроенный в InventorQuant. Он разработан на основе SQLite и написан на языке C. Он не только небольшой по размеру и потребляет мало ресурсов , но также скорость обработки высокая и очень подходит для энтузиастов финансового количественного анализа для локальной реализации управления данными, поскольку различные «объекты» (такие как биржи, источники данных, цены) могут быть разделены на различные таблицы и могут быть определены взаимосвязи между столами. Кроме того, пользователям не нужно устанавливать и настраивать его отдельно, они могут использовать его напрямую, вызывая функцию DBExec()!
Кроме того, стоимость изучения языка SQLite очень низкая, а большая часть работы, выполняемой в базе данных, выполняется с помощью операторов SQLite. Знакомство с базовым синтаксисом может удовлетворить большинство потребностей. Ниже приведен базовый синтаксис SQLite.
Синтаксис SQLite не чувствителен к регистру, но некоторые команды чувствительны к регистру, например GLOB и glob, которые имеют разное значение. Операторы SQLite могут начинаться с любого ключевого слова, например, SELECT, INSERT, UPDATE, DELETE, ALTER, DROP и т. д., что соответственно означает: извлечение данных, вставка данных, обновление данных, удаление данных, изменение базы данных и удаление таблицы данных. Все утверждения заканчиваются точкой с запятой. Ниже приведено простое создание базы данных, добавление, удаление, изменение, запрос и другие операции:
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"));
}
База данных обычно содержит одну или несколько таблиц. Каждая таблица имеет имя. Следует отметить, что зарезервированными в системе таблицами являются: kvdb, cfg, log, profit, chart. То есть при создании таблицы следует избегать зарезервированных в системе имен. Давайте запустим приведенный выше код, который выведет следующее:
Теперь, когда мы знаем базовый синтаксис SQLite, мы можем использовать встроенную базу данных InventorQuant для создания примера сбора и использования данных Tick.
Шаг 1: Обновите свой хост Во-первых, убедитесь, что вы используете последнюю версию хоста. Если вы уже скачивали и использовали хост, вам нужно сначала удалить его, а затем снова скачать и развернуть на https://www.fmz.com/ страница m/add-node.
Шаг 2: Создайте стратегию
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);
}
Шаг 3: Запустите стратегию
Если взять Windows в качестве примера, то после запуска политики в каталоге “\logs\storage” каталога хоста будет создана папка с именем, соответствующим номеру робота. Откройте папку, и там будет файл с расширением “.db3 ” в нем. , этот файл является файлом квантифицированной встроенной базы данных изобретателя. Как показано на следующем рисунке:
Приведенный выше код сначала создает таблицу данных с именем «tick», затем добавляет поле данных тика в таблицу, затем получает данные тика из биржи в цикле и вставляет эти данные в таблицу данных «tick». Если объем данных в таблице данных превышает 10, цикл будет пропущен. Наконец, пять команд SQLite используются для запроса, удаления и изменения данных в таблице данных. И распечатайте это в журнале, как показано на следующем рисунке:
Шаг 4: Создание строки состояния
Наконец, мы добавляем код для создания строки состояния для стратегии, получая данные из количественной базы данных Inventor, чтобы отображать данные более интуитивно. Новый добавленный код выглядит следующим образом:
// 创建状态栏
let table = {
type: 'table',
title: '币安Tick数据',
cols: allDate.columns,
rows: allDate.values
}
LogStatus('`' + JSON.stringify(table) + '`');
Приведенный выше код создает таблицу «Binance Tick Data», используя данные из базы данных. Поле «столбцы» в базе данных представляет «строки» в строке состояния, а поле «значения» представляет «столбцы» в строке состояния. Как показано на следующем рисунке:
/*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) + '`');
}
Нажмите на эту ссылку https://www.fmz.com/strategy/388963, чтобы скопировать полный код стратегии.
Если вы не хотите сохранять данные на диск навсегда, вы можете добавить:
Символы могут работать в базе данных памяти, и данные сбрасываются после перезапуска робота.
DBExec(":select 1,2,3");
База данных может не только хранить огромные объемы данных, но и воплощать в жизнь мечты многих энтузиастов количественной торговли. Использование баз данных не ограничивается примерами в этой статье. Для получения дополнительных методов использования, пожалуйста, обратитесь к учебнику SQLite и последующей серии статей, выпущенных Inventor Quantitative.