SQLite로 FMZ의 양적 데이터베이스를 구축

저자:리디아, 창작: 2022-11-09 11:40:34, 업데이트: 2023-09-20 10:55:14

img

요약

데이터는 양적 거래의 원천입니다, 효율적으로 많은 양의 데이터를 관리하는 방법은 매우 중요한 링크입니다, 데이터베이스는 최고의 솔루션 중 하나입니다, 요즘 데이터베이스의 응용은 모든 종류의 일일 거래, 고주파 거래 및 기타 전략의 양적 표준입니다. 이 기사에서는 FMZ Quant의 내장 데이터베이스를 연구 할 것입니다 (https://www.fmz.com), 데이터 테이블을 만드는 방법, 데이터를 저장하는 방법, 데이터를 수정하는 방법, 데이터를 삭제하는 방법, 참조 데이터 및 실제 적용 방법을 포함합니다.

데이터베이스를 선택하는 방법

FMZ 퀀트 플랫폼에 익숙한 사람들은 로컬 재사용을 위해 데이터를 저장하기 전에 전략을 중지 할 때마다 필요한 정보를 자동으로 저장하는 _G() 함수를 사용할 수 있음을 알아야합니다. 그러나 점점 더 복잡한 포맷 된 데이터를 저장하고 싶다면 _G() 함수가 분명히 적용되지 않습니다. 따라서 많은 사람들이이 문제를 해결하기 위해 자신의 데이터베이스를 구축하기로 결정했습니다.

자체 구축 된 데이터베이스에 관해서, 당신은 오라클, MySQL, KDB, OneTick, NoSQL을 생각해야합니다... 기능과 성능 모두에서 매우 우수한 기업 수준의 응용 프로그램입니다. 그러나, 또한 몇 가지 문제가 있습니다: 시작하는 것이 어렵고, 구성이 번거롭고 유지 보수가 어렵습니다. 소매 양적 거래자에게는 대포로 파리를 쏘는 것과 같습니다. 시작하더라도 기능의 작은 부분을 사용합니다.

FMZ Quant의 기본 데이터베이스

다음으로, FMZ Quant에 의해 구축된 라이트 데이터베이스를 살펴보자. DBExec는 FMZ Quant의 내장형 관계 데이터 관리 시스템 인터페이스이다. 그것은 SQLite를 기반으로 개발되어 C 언어로 작성되었습니다. 그것은 크기가 작고 자원의 소비가 적을뿐만 아니라 처리 속도가 빠르다. 그것은 다른 객체 (거래소, 데이터 소스 및 가격과 같은) 를 다른 테이블로 나누고 테이블 간의 관계를 정의 할 수 있기 때문에 데이터 관리를 로컬로 구현하는 금융 양적 분석 애호가에게 매우 적합합니다. 또한 사용자는 개별적으로 설치하고 구성 할 필요가 없습니다. DBExec) 함수를 호출하여 직접 사용할 수 있습니다!

또한, SQLite 언어를 배우는 것은 매우 쉬우며, 데이터베이스에서 수행되는 대부분의 작업은 SQLite 명령어에 의해 완료됩니다. 기본 문법을 알고 있다면 대부분의 요구 사항을 충족 할 수 있습니다. 다음은 SQLite의 기본 문법입니다.

기초 문법

SQLite의 문법은 대문자 민감하지 않지만, GLOB와 glob와 같은 대문자 민감한 명령어도 있지만, 서로 다른 의미를 나타냅니다. SQLite 명령어는 SELECT, INSERT, UPDATE, DELETE, ALTER, DROP 등과 같은 모든 키워드로 시작할 수 있습니다. 데이터 추출, 데이터 삽입, 데이터 업데이트, 데이터 삭제, 데이터베이스 수정 및 데이터 테이블 삭제. 모든 명령어는 영어 반점으로 종료됩니다. 다음은 간단한 데이터베이스 생성, 추가, 삭제, 변경 및 검사 작업입니다.

function main() {
    // Create: If the "users" table does not exist, create one, "id" is an integer and is incremented automatically, "name" is in text form and is not empty
    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('Zhang San')"));
    Log(DBExec("INSERT INTO users(name) values('Li Si')"));
    
    // Delete:
    Log(DBExec("DELETE FROM users WHERE id=1;"));
    
    // Modify:
    Log(DBExec("UPDATE users SET name='Wang Wu' WHERE id=2"));
    
    // Search:
    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입니다. 즉 테이블을 만들 때 시스템 예약 이름을 피해야합니다. 위의 코드를 실행하고 다음을 출력하십시오.

img

전략 예제

SQLite의 기본 문법을 배웠을 때, 우리는 FMZ Quant의 내장 데이터베이스를 사용하여 Tick 데이터를 수집하고 사용하는 인스턴스를 만들기 위해 철이 뜨거울 때 타격을 가합니다.

단계 1: 도커를 업데이트합니다.

먼저, 당신이 docker의 최신 버전을 사용하고 있는지 확인합니다. 당신이 다운로드 하 고 전에 docker를 사용 한 경우, 당신은 먼저 삭제 해야 합니다, 그리고 다시 다운로드 하 고 다시 배치https://www.fmz.com/m/add-node page.

2단계: 전략을 수립하라

function main() {
    // Subscribe contracts
    _C(exchange.SetContractType, 'swap');
    
    // Create 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);'
    ));
    
    // Get 10 pieces of tick data
    while (true) {
        let tick = exchange.GetTicker();
        // Add data to 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})`);
        // Search all data
        let allDate = DBExec('select * from tick');
        if (allDate.values.length > 10) {
            break;
        }
        Sleep(1000);
    }
    
    // Search all data
    Log(DBExec('select * from tick'));
    
    // Search the first data
    Log(DBExec('select * from tick limit 1'));
    
    // Search first two pieces of 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'));
    
    // Search all data
    let allDate = DBExec('select * from tick')
    Log(allDate);
}

3단계: 전략 실행

예를 들어 윈도우를 들자면, 전략을 실행한 후, 로봇 번호의 이름을 가진 폴더가 도커 디렉토리의 \로그\스토리지 디렉토리에 생성됩니다. 폴더를 열면 FMZ 퀀트 내장 데이터베이스의 파일인 . db3 후자를 가진 파일이 있습니다. 다음 그림에서 보여준 것처럼:

img

위 코드는 먼저 tick이라는 데이터 테이블을 생성하고, 다음에는 테이블에 틱 데이터 필드를 추가하고, 이후 루프의 교환에서 틱 데이터를 가져와 tick 데이터 테이블에 데이터를 삽입합니다. 동시에, 우리는 데이터 테이블의 데이터 양이 10을 초과한다고 판단하고, 루프에서 뛰어납니다. 마지막으로 5개의 SQLite 명령어를 사용하여 데이터 테이블의 데이터를 각각 검색, 삭제 및 수정합니다. 그리고 다음 그림과 같이 로그에 인쇄합니다:

img

단계 4: 상태 표시줄 생성

마지막으로 우리는 더 시각적으로 데이터를 표시하기 위해 FMZ 퀀트 데이터베이스에서 데이터를 획득하여 전략의 상태 표시줄을 만들기 위해 코드를 추가합니다. 추가 코드는 다음과 같습니다.

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

위의 코드는 데이터베이스의 데이터를 통해 Binance Tick data 테이블을 생성합니다. 데이터베이스의 columns 필드는 상태 표시줄의 줄을 나타냅니다. 그리고 values 필드는 상태 표시줄의 columns을 나타냅니다. 아래 그림과 같이:

img

전체 전략 코드

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

    // Create 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 pieces of tick data
    while (true) {
        let tick = exchange.GetTicker();
        // Add data to 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})`);
        // Search all data
        let allDate = DBExec('select * from tick');
        if (allDate.values.length > 10) {
            break;
        }
        Sleep(1000);
    }

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

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

    // Search first two pieces of 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'));

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

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

이 링크를 클릭하세요.https://www.fmz.com/strategy/388963전체 전략 코드를 복사하기 위해서요.

메모리 데이터베이스

데이터를 영구적으로 디스크에 저장하고 싶지 않다면, SQL 명령어 앞에 : 기호를 추가하여 메모리 데이터베이스에서 작동할 수 있습니다. 로봇이 다시 시작되면 데이터가 다시 설정됩니다.

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

요약

데이터베이스는 대용량 데이터를 수송할 수 있을 뿐만 아니라 많은 양적 거래 애호가들의 꿈도 수송할 수 있다. 데이터베이스의 사용은 이 문서의 예로로 한정되어 있지 않다. 더 많은 사용 방법에 대해서는 SQLite 튜토리얼과 FMZ Quant의 후속 기사를 참조하십시오.


관련

더 많은