Xây dựng cơ sở dữ liệu định lượng của FMZ với SQLite

Tác giả:Lydia., Tạo: 2022-11-09 11:40:34, Cập nhật: 2023-09-20 10:55:14

img

Tóm tắt

Dữ liệu là nguồn của giao dịch định lượng, làm thế nào để quản lý một lượng lớn dữ liệu hiệu quả là một liên kết rất quan trọng, cơ sở dữ liệu là một trong những giải pháp tốt nhất, ngày nay ứng dụng cơ sở dữ liệu là tiêu chuẩn định lượng cho tất cả các loại giao dịch hàng ngày, giao dịch tần số cao và các chiến lược khác.https://www.fmz.com), bao gồm: cách tạo bảng dữ liệu, lưu trữ dữ liệu, sửa đổi dữ liệu, xóa dữ liệu, dữ liệu tham khảo và cách áp dụng nó trong thực tế.

Cách chọn cơ sở dữ liệu

Những người quen thuộc với nền tảng FMZ Quant nên biết rằng trước khi lưu dữ liệu để tái sử dụng cục bộ, bạn chỉ có thể sử dụng chức năng _G(), tự động lưu thông tin cần thiết mỗi khi bạn ngừng chiến lược. Nhưng nếu bạn muốn lưu dữ liệu định dạng phức tạp hơn, chức năng _G( rõ ràng không áp dụng nhiều, do đó, nhiều người đã quyết định xây dựng cơ sở dữ liệu của riêng mình để giải quyết vấn đề này.

Khi nói đến các cơ sở dữ liệu tự xây dựng, bạn phải nghĩ đến Oracle, MySQL, KDB, OneTick, NoSQL... Đây là các ứng dụng cấp doanh nghiệp rất xuất sắc về cả chức năng và hiệu suất. Tuy nhiên, cũng có một số vấn đề: khó bắt đầu, và cấu hình phức tạp và bảo trì khó khăn. Đối với các nhà giao dịch định lượng bán lẻ, nó giống như bắn ruồi với pháo. Ngay cả khi họ bắt đầu, họ chỉ sử dụng một phần nhỏ các chức năng.

Cơ sở dữ liệu FMZ Quant

Tiếp theo, chúng ta hãy xem xét cơ sở dữ liệu ánh sáng được xây dựng bởi FMZ Quant. DBExec là giao diện hệ thống quản lý dữ liệu quan hệ của FMZ Quant. Nó được phát triển dựa trên SQLite và được viết bằng C. Nó không chỉ có kích thước nhỏ, tiêu thụ tài nguyên ít, mà còn nhanh chóng xử lý. Nó rất phù hợp với những người đam mê phân tích định lượng tài chính để thực hiện quản lý dữ liệu tại địa phương, bởi vì các object khác nhau (như trao đổi, nguồn dữ liệu và giá cả) có thể được chia thành các bảng khác nhau và các mối quan hệ giữa các bảng có thể được xác định. Ngoài ra, người dùng không cần cài đặt và cấu hình chúng riêng biệt. Họ có thể sử dụng chúng trực tiếp bằng cách gọi hàm DBExec)!

Ngoài ra, nó rất dễ dàng để học ngôn ngữ SQLite, và hầu hết các công việc được thực hiện trên cơ sở dữ liệu được hoàn thành bằng các câu lệnh SQLite. Nếu bạn quen thuộc với ngữ pháp cơ bản, bạn có thể đáp ứng hầu hết các yêu cầu.

Ngữ pháp cơ bản

Ngữ pháp của SQLite không nhạy cảm với chữ cái lớn, mặc dù có một số lệnh nhạy cảm với chữ cái lớn, chẳng hạn như GLOB và glob, đại diện cho các ý nghĩa khác nhau. Các lệnh SQLite có thể bắt đầu bằng bất kỳ từ khóa nào, chẳng hạn như SELECT, INSERT, UPDATE, DELETE, ALTER, DROP, v.v., có nghĩa là: trích xuất dữ liệu, chèn dữ liệu, cập nhật dữ liệu, xóa dữ liệu, sửa đổi cơ sở dữ liệu và xóa bảng dữ liệu. Tất cả các lệnh được kết thúc bằng dấu chấm bán chấm tiếng Anh. Sau đây là một hoạt động tạo cơ sở dữ liệu đơn giản, thêm, xóa, thay đổi và kiểm tra:

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

Một cơ sở dữ liệu thường chứa một hoặc nhiều bảng, mỗi bảng được xác định bằng tên, lưu ý rằng các bảng được lưu trữ hệ thống là: kvdb, cfg, log, profit, chart. tức là khi tạo bảng, bạn nên tránh các tên được lưu trữ hệ thống. Hãy chạy mã trên và phát ra những điều sau:

img

Ví dụ về chiến lược

Sau khi học được ngữ pháp cơ bản của SQLite, chúng ta sẽ tấn công trong khi sắt nóng để tạo ra một trường hợp thu thập và sử dụng dữ liệu Tick bằng cách sử dụng cơ sở dữ liệu tích hợp của FMZ Quant.

Bước 1: Cập nhật docker

Đầu tiên, hãy chắc chắn rằng bạn đang sử dụng phiên bản mới nhất của docker. Nếu bạn đã tải xuống và sử dụng docker trước đây, bạn cần phải xóa nó trước, và sau đó tải lại và tái triển khai nó trênhttps://www.fmz.com/m/add-node page.

Bước 2: Xây dựng chiến lược

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

Bước 3: Thực hiện chiến lược

Lấy ví dụ Windows, sau khi chạy chiến lược, một thư mục có tên theo số robot sẽ được tạo trong thư mục \logs\storage của thư mục docker. Mở thư mục, và có một tệp với hậu tố . db3, đó là tệp của cơ sở dữ liệu tích hợp FMZ Quant. Như được hiển thị trong hình sau:

img

Mã trên tạo ra một bảng dữ liệu có tên tick trước tiên, sau đó thêm trường dữ liệu tick vào bảng, sau đó lấy dữ liệu tick từ trao đổi trong vòng lặp, và chèn dữ liệu vào bảng dữ liệu tick. Đồng thời, chúng tôi đánh giá rằng số lượng dữ liệu trong bảng dữ liệu vượt quá 10, sau đó chúng tôi nhảy ra khỏi vòng lặp. Cuối cùng, chúng tôi sử dụng 5 lệnh SQLite để tìm kiếm, xóa và sửa đổi dữ liệu trong bảng dữ liệu tương ứng. Và in chúng ra trong nhật ký, như được hiển thị trong hình sau:

img

Bước 4: Tạo thanh trạng thái

Cuối cùng, chúng tôi thêm một số mã để tạo một thanh trạng thái cho chiến lược bằng cách lấy dữ liệu trong cơ sở dữ liệu FMZ Quant để hiển thị dữ liệu một cách trực quan hơn, mã thêm cho thấy như sau:

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

Mã trên tạo ra một bảng dữ liệu Binance Tick thông qua dữ liệu trong cơ sở dữ liệu.

img

Mã chiến lược đầy đủ

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

Nhấp vào liên kết nàyhttps://www.fmz.com/strategy/388963để sao chép toàn bộ mã chiến lược.

Cơ sở dữ liệu bộ nhớ

Nếu bạn không muốn lưu dữ liệu vào đĩa vĩnh viễn, bạn có thể thêm ký hiệu : trước lệnh SQL để hoạt động trong cơ sở dữ liệu bộ nhớ, và dữ liệu sẽ được đặt lại sau khi robot khởi động lại.

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

Tóm lại

Cơ sở dữ liệu không chỉ có thể chứa dữ liệu khổng lồ, mà còn là giấc mơ của nhiều người đam mê giao dịch định lượng. Việc sử dụng cơ sở dữ liệu không giới hạn ở các ví dụ trong bài viết này. Để biết thêm các phương pháp sử dụng, vui lòng tham khảo hướng dẫn SQLite và các bài viết tiếp theo của FMZ Quant.


Có liên quan

Thêm nữa