Use o SQLite para construir o banco de dados quântico FMZ

Autora:Ninabadass, Criado: 2022-04-24 11:32:35, Atualizado: 2022-04-24 16:21:38

Use o SQLite para construir o banco de dados quântico FMZ [TOC]

Resumo

Os dados são a fonte da negociação quantitativa. É muito importante gerenciar eficientemente uma grande quantidade de dados. O banco de dados é uma das melhores soluções. Hoje em dia, a aplicação do banco de dados tornou-se a configuração quantitativa padrão de várias estratégias de negociação diária, negociação de alta frequência e outras estratégias.FMZ.COM), incluindo: como criar tabelas de dados, salvar dados, modificar dados, excluir dados e dados de referência, bem como como como utilizá-los na prática.

Como selecionar o banco de dados

Aqueles que estão familiarizados com a FMZ Quant Trading Platform devem ter sabido que antes disso, se você quiser salvar dados para local para reutilização, você só pode usar 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 cada vez mais complexos, a função _G( obviamente não é adequada, então muitas pessoas pensam em construir seu próprio banco de dados para resolver o problema.

Quando se trata de bancos de dados auto-construídos, todo mundo pode pensar em Oracle, MySQL, KDB, OneTick, NoSQL... Estes são todos excelentes aplicativos de nível empresarial, tanto em termos de função quanto de desempenho. Mas também há alguns problemas: é difícil começar, e a configuração e a manutenção são difíceis. Para os investidores de varejo na negociação quantitativa, é um pouco como quebrar uma mosca na roda. Mesmo se você já começar com esses aplicativos, apenas algumas funções deles serão usadas.

Base de dados integrada FMZ Quant

Em seguida, vamos conhecer o banco de dados leve integrado do FMZ Quant. O DBExec é uma interface de sistema de gerenciamento de dados relacional incorporada no FMZ Quant. Ele é desenvolvido com base no SQLite e escrito em C. Ele não é apenas de tamanho pequeno, com baixa ocupação de recursos, mas também tem uma velocidade de processamento muito rápida. É muito adequado para entusiastas da análise quantitativa financeira implementarem o gerenciamento de dados localmente, porque pode dividir diferentes objetos (como plataformas, fontes de dados, preços) em diferentes tabelas e definir as relações entre as tabelas. Além disso, os usuários não precisam instalá-lo e configurá-lo separadamente; desde que eles chamem a função DBExec (((), ele pode ser usado diretamente!

Além disso, o custo de aprender a linguagem SQLite é muito baixo, e a maioria do trabalho realizado no banco de dados é feito por instruções SQLite. A maioria das necessidades pode ser atendida familiarizando-se com a sintaxe básica. A seguir está a sintaxe básica do SQLite.

Sintaxe básica

A sintaxe do SQLite é insensible a minúsculas e pequenas, mas alguns comandos são sensíveis a minúsculas e pequenas, como GLOB e glob, que têm significados diferentes. As instruções do 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 instruções terminam com um ponto e vírgula.

function main() {
    // create: if the table of "users" do not exist, create one; "id" is integer and increases automatically; "name" is in form of text and not null 
    Log(DBExec('CREATE TABLE IF NOT EXISTS "users" (id INTEGER PRIMARY KEY AUTOINCREMENT, name text not NULL);'));
    
    // add: 
    Log(DBExec("INSERT INTO users(name) values('A')"));
    Log(DBExec("INSERT INTO users(name) values('B')"));
    
    // delete: 
    Log(DBExec("DELETE FROM users WHERE id=1;"));
    
    // modify:
    Log(DBExec("UPDATE users SET name='C' WHERE id=2"));
    
    // query:
    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 uma identificação de nome, deve-se notar que as tabelas reservadas ao sistema são: kvdb, cfg, log, lucro, gráfico. Ou seja, ao criar tabelas, você deve evitar nomes reservados ao sistema.img

Exemplo de estratégia

Depois de conhecer a sintaxe básica do SQLite, vamos atacar enquanto o ferro está quente; use o banco de dados quantitativo integrado do FMZ Quant para criar uma instância de coleta e uso de dados do Tick.

Passo 1: atualização do dockerPrimeiro, certifique-se de que você está usando a versão mais recente de um docker. Se você já baixou e usou um docker antes, você precisa excluí-lo primeiro, e baixá-lo e implantá-lo novamente na página (https://www.fmz.com/m/add-node).

Passo 2: criar uma estratégia

function main() {
    // set contract 
    _C(exchange.SetContractType, 'swap');
    
    // create the data table 
    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);'
    ));
    
    // obtain 10 tick data 
    while (true) {
        let tick = exchange.GetTicker();
        // add data in the tick table 
        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})`);
        // query all data
        let allDate = DBExec('select * from tick');
        if (allDate.values.length > 10) {
            break;
        }
        Sleep(1000);
    }
    
    // query all data 
    Log(DBExec('select * from tick'));
    
    // query the first data 
    Log(DBExec('select * from tick limit 1'));
    
    // query the first two data 
    Log(DBExec('select * from tick limit 0,2'));
    
    // delete the first data 
    Log(DBExec('DELETE FROM tick WHERE id=1;'));
    
    // modify the second data 
    Log(DBExec('UPDATE tick SET High=10000 WHERE id=2'));
    
    // query all data 
    let allDate = DBExec('select * from tick')
    Log(allDate);
}

Passo 3: estratégia de operaçãoTome o Windows como exemplo. Após executar a estratégia, uma pasta com o nome do bot ID será gerada no dicionário \logs\storage do diretório do docker; abra a pasta e haverá um arquivo com .db3 como sufixo; este arquivo é o arquivo do banco de dados integrado FMZ Quant. Como mostrado na figura a seguir:img

O código acima primeiro cria uma tabela de dados chamada tick, em seguida, adiciona o campo de dados de tick à tabela, em seguida, obtém os dados de tick da plataforma no loop e insere esses dados na tabela de dados tick, e ao mesmo tempo Se for julgado que a quantidade de dados na tabela de dados excede 10, ele sairá do loop. Finalmente, use cinco comandos SQLite para consultar, excluir e modificar os dados na tabela de dados. E imprima-o no log, como mostrado na imagem a seguir:img

Passo 4: criar a barra de estadoFinalmente, adicionamos alguns pedaços de código para criar uma barra de status para a estratégia, obtendo os dados no banco de dados FMZ Quant para exibir os dados de forma mais intuitiva.

    // create a status bar 
    let table = {
        type: 'table',
        title: 'Binance Tick data',
        cols: allDate.columns,
        rows: allDate.values
    }
    LogStatus('`' + JSON.stringify(table) + '`');

O código acima cria uma tabela Binance Tick Data a partir dos dados na base de dados. O campo colunas na base de dados representa a linha horizontal na barra de status, e o campo valores representa a linha vertical na barra de status. Como mostrado abaixo:img

Código de origem da estratégia completa

/*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;'));
    // set contract 
    _C(exchange.SetContractType, 'swap');

    // establish the data table 
    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);'
    ));

    // obtain 10 tick data 
    while (true) {
        let tick = exchange.GetTicker();
        // add data in the tick table
        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})`);
        // query all data 
        let allDate = DBExec('select * from tick');
        if (allDate.values.length > 10) {
            break;
        }
        Sleep(1000);
    }

    // query all data 
    Log(DBExec('select * from tick'));

    // query the first data 
    Log(DBExec('select * from tick limit 1'));

    // query the first two data 
    Log(DBExec('select * from tick limit 0,2'));

    // delet the first data 
    Log(DBExec('DELETE FROM tick WHERE id=1;'));

    // modify the second data
    Log(DBExec('UPDATE tick SET High=10000 WHERE id=2'));

    // query all data 
    let allDate = DBExec('select * from tick')
    Log(allDate);

    // create the status bar 
    let table = {
        type: 'table',
        title: 'Binance Tick data',
        cols: allDate.columns,
        rows: allDate.values
    }
    LogStatus('`' + JSON.stringify(table) + '`');
}

Clique no link:https://www.fmz.com/strategy/265906, e você pode copiar o código fonte completo.

Base de dados em memória

Se os dados operados não quiserem ser salvos permanentemente no disco, pode adicionar o:símbolo antes da instrução SQL para operar no banco de dados em memória, e os dados serão reiniciados após o bot ser reiniciado.

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

Conclusão

O banco de dados não só pode transportar dados maciços, mas também carrega os sonhos de muitos entusiastas de negociação quantitativa. O uso do banco de dados não é, de forma alguma, limitado aos exemplos mencionados no artigo. Para mais métodos de uso, você pode consultar o tutorial do SQLite e a série de artigos que serão postados no FMZ Quant mais tarde.


Mais.