avatar of 发明者量化-小小梦 发明者量化-小小梦
focar em Mensagem privada
4
focar em
1271
Seguidores

Usando SQLite para construir um banco de dados quantitativo de inventores

Criado em: 2021-03-26 17:09:32, atualizado em: 2024-12-05 21:56:39
comments   5
hits   2295

[TOC]

Usando SQLite para construir um banco de dados quantitativo de inventores

resumo

Dados são a fonte da negociação quantitativa. Como gerenciar eficientemente grandes quantidades de dados é um elo crítico. O banco de dados é uma das melhores soluções. Hoje em dia, a aplicação do banco de dados se tornou uma configuração padrão quantitativa para várias negociações intraday, negociações de alta frequência e outras estratégias. . Neste artigo, estudaremos o banco de dados interno do Inventor Quantitative (FMZ.COM), incluindo: como criar tabelas de dados, armazenar dados, modificar dados, excluir dados, referenciar dados e como aplicá-los em combate real.

Como escolher um banco de dados

Aqueles que estão familiarizados com a Inventor Quantitative Platform devem saber que antes disso, se você quiser salvar dados localmente para reutilização, você pode usar apenas a função _G(). Toda vez que você parar a estratégia,_A função G() salvará automaticamente as informações necessárias. Mas se você quiser salvar dados formatados mais complexos,_A função G() obviamente não é muito aplicável, então muitas pessoas pensaram em criar seu próprio banco de dados para resolver esse problema.

Quando se trata de bancos de dados autocriados, todos provavelmente pensam em Oracle, MySQL, KDB, OneTick, NoSQL… Todos esses são excelentes aplicativos de nível empresarial, com funções e desempenho muito poderosos. No entanto, ele também enfrenta vários problemas: é difícil começar, a configuração é incômoda e a manutenção é problemática. Para os comerciantes quantitativos de varejo, isso é um pouco como usar um canhão para matar uma mosca. Mesmo que eles comecem, eles use apenas uma pequena parte das funções.

Banco de dados quantitativo integrado do Inventor

Em seguida, vamos dar uma olhada no banco de dados leve construído no InventorQuant. DBExec é uma interface de sistema de gerenciamento de dados relacional construída no InventorQuant. Ele é desenvolvido com base em SQLite e é escrito em C. Ele não é apenas pequeno em tamanho e baixo em consumo de recursos , mas também A velocidade de processamento é rápida e é muito adequada para entusiastas de análise quantitativa financeira implementarem o gerenciamento de dados localmente, porque diferentes “objetos” (como bolsas, fontes de dados, preços) podem ser divididos em diferentes tabelas e relacionamentos podem ser definidos entre as mesas. Além disso, os usuários não precisam instalar e configurar separadamente, eles podem usá-lo diretamente chamando a função DBExec()!

Além disso, o custo de aprendizado da linguagem SQLite é muito baixo, e a maior parte do trabalho realizado no banco de dados é feito por instruções SQLite. Estar familiarizado com a sintaxe básica pode suprir a maioria das necessidades. A seguir está a sintaxe básica do SQLite.

Sintaxe básica

A sintaxe do SQLite não diferencia maiúsculas de minúsculas, mas alguns comandos diferenciam maiúsculas de minúsculas, como GLOB e glob, que têm significados diferentes. As instruções SQLite podem começar com qualquer palavra-chave, como SELECT, INSERT, UPDATE, DELETE, ALTER, DROP, etc., que significam respectivamente: extrair dados, inserir dados, atualizar dados, excluir dados, modificar banco de dados e excluir tabela de dados. Todas as declarações terminam com ponto e vírgula. A seguir está uma operação simples de criação, adição, exclusão, modificação, consulta e outras operações de banco de dados:

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

Um banco de dados geralmente contém uma ou mais tabelas. Cada tabela tem um nome. Deve-se notar que as tabelas reservadas do sistema são: kvdb, cfg, log, profit, chart. Ou seja, ao criar uma tabela, você deve evitar nomes reservados pelo sistema. Vamos executar o código acima, que imprimirá o seguinte: Usando SQLite para construir um banco de dados quantitativo de inventores

Exemplos de estratégia

Agora que conhecemos a sintaxe básica do SQLite, podemos usar o banco de dados interno do InventorQuant para criar um exemplo de coleta e uso de dados do Tick.

Etapa 1: atualize seu host Primeiro, certifique-se de que você está usando a versão mais recente do host. Se você baixou e usou o host antes, você precisa excluí-lo primeiro e então baixá-lo novamente e implantá-lo em https://www.fmz.com/ página m/add-node.

Etapa 2: Crie uma estratégia

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);
}

Etapa 3: execute a estratégia Tomando o Windows como exemplo, após executar a política, uma pasta nomeada após o número do robô será gerada no diretório “\logs\storage” do diretório do host. Abra a pasta e haverá um arquivo com o sufixo “.db3 ” nele. , este arquivo é o arquivo do banco de dados quantificado integrado do inventor. Conforme mostrado na figura a seguir: Usando SQLite para construir um banco de dados quantitativo de inventores O código acima primeiro cria uma tabela de dados chamada “tick”, então adiciona um campo de dados de tick à tabela, então obtém dados de tick da exchange em um loop e insere esses dados na tabela de dados “tick”. Se a quantidade de dados na tabela de dados exceder 10, o loop será saltado. Por fim, cinco comandos SQLite são usados ​​para consultar, excluir e modificar os dados na tabela de dados. E imprima no log, conforme mostrado na figura a seguir: Usando SQLite para construir um banco de dados quantitativo de inventores Etapa 4: Crie a barra de status Por fim, adicionamos algum código para criar uma barra de status para a estratégia, obtendo dados do Inventor Quantitative Database para exibir os dados de forma mais intuitiva. O código recém-adicionado é o seguinte:

    // 创建状态栏
    let table = {
        type: 'table',
        title: '币安Tick数据',
        cols: allDate.columns,
        rows: allDate.values
    }
    LogStatus('`' + JSON.stringify(table) + '`');

O código acima cria uma tabela “Binance Tick Data” usando os dados do banco de dados. O campo “colunas” no banco de dados representa as “linhas” na barra de status, e o campo “valores” representa as “colunas” na barra de status. Conforme mostrado na figura a seguir: Usando SQLite para construir um banco de dados quantitativo de inventores

Código de estratégia completo

/*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) + '`');
}

Clique neste link https://www.fmz.com/strategy/388963 para copiar o código de estratégia completo.

Banco de dados na memória

Se você não quiser salvar os dados permanentemente no disco, você pode adicionar:Os símbolos podem ser operados no banco de dados de memória e os dados são redefinidos após o robô ser reiniciado

DBExec(":select 1,2,3");

Resumir

O banco de dados não só pode conter grandes quantidades de dados, mas também os sonhos quantitativos de muitos entusiastas de negociação quantitativa. O uso de bancos de dados não se limita aos exemplos deste artigo. Para mais métodos de uso, consulte o tutorial do SQLite e a série subsequente de artigos lançados pela Inventor Quantitative.