FMZ量化交易利用SQLite构建发明者量化数据库
admin
2023-08-01 03:37:46
0

目前不清退的交易所推荐:

1、全球第二大交易所OKX欧意

国区邀请链接: https://www.myts3cards.com/cn/join/1837888   币种多,交易量大!

国际邀请链接:https://www.okx.com/join/1837888 注册简单,交易不需要实名,新用户能开合约,币种多,交易量大!

2、老牌交易所比特儿现改名叫芝麻开门 :https://www.gate.win/signup/649183

全球最大交易所币安,国区邀请链接:https://accounts.binance.com/zh-CN/register?ref=16003031  币安注册不了IP地址用香港,居住地选香港,认证照旧,邮箱推荐如gmail、outlook。支持币种多,交易安全!

买好币上KuCoin:https://www.kucoin.com/r/af/1f7w3  CoinMarketCap前五的交易所,注册友好操简单快捷!

FMZ量化交易平台邀请链接:https://www.fmz.com/

摘要

数据是量化交易的源头,如何高效地管理大量数据是非常关键的环节,数据库是最佳的解决方案之一,现如今数据库的应用已经是各类日内交易、高频交易等策略的量化标准配置。本篇我们来研究一下发明者量化(FMZ.COM)内置的数据库,内容包括:如何创建数据表、存储数据、修改数据、删除数据、引用数据以及如何应用于实战。

如何选择数据库

熟悉发明者量化平台的应该知道,在这之前要想把数据保存到本地复用,只能用_G()函数,每次停止策略时,_G()函数会自动保存需要的信息。但如果想要保存更多更复杂的格式化数据,_G()函数显然就不太适用了,于是很多人想到了自建数据库来解决这个问题。

提到自建数据库,想必大家能想到Oracle、MySQL、KDB、OneTick、NoSQL…这些都是非常优秀的企业级别的应用,不管是功能还是性能都非常强大。但也面临几个问题:上手难度大,配置繁琐维护起来麻烦,这对于量化交易散户来说,有点用大炮打苍蝇的感觉,即使上手也只是用到很少一部分功能。

发明者量化内置数据库

接下来让我们认识一下发明者量化内置的轻型数据库,DBExec是发明者量化内置的一个关系型数据管理系统接口,基于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。也就是说在创建表时,应该避开系统保留的名字。让我们运行上面的代码,输出以下内容:
393b1a026bfb876e4273393b1a026bfb876e4273

策略实例

了解了SQLite的基础语法,我们趁热打铁使用发明者量化内置的数据库,创建一个收集和使用Tick数据的实例。

第一步:更新托管者
首先确保您使用的是最新版本的托管者,如果之前下载使用过托管者,需要先删除,并在 https://www.fmz.com/m/add-node 页面重新下载和部署。

第二步:创建策略

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

第三步:运行策略
以Windows为例,运行策略之后,会在托管者目录的“\\logs\\storage”目录中生成一个以机器人编号命名的文件夹,打开该文件夹,里面有一个以“.db3”作为后缀的文件,这个文件就是发明者量化内置数据库的文件。以下图所示:
39b811e1f9df0a2911f939b811e1f9df0a2911f9
上面的代码首先创建了一个以“tick”命名的数据表,然后给该表添加tick数据字段,接着在循环中从交易所获取tick数据,并把这些数据插入到“tick”数据表中,同时判断该数据表中的数据量超过10个就跳出循环。最后分别用5个SQLite命令查询、删除、修改数据表中的数据。并在日志中打印出来,以下图所示:
395a055a194ff230e4a739b811e1f9df0a2911f9
第四步:创建状态栏
最后我们增加一些代码,通过获取发明者量化数据库中的数据,给策略创建一个状态栏,把数据更直观的展示出来,新增代码如下:

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

上面的代码通过数据库中的数据,创建了一个“币安Tick数据”表。其中数据库中的“columns”字段代表状态栏中的“行”,“values”字段代表状态栏中的“列”。如下图所示:
392321ea08e47fb0fc5439b811e1f9df0a2911f9

完整策略代码

/*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/265906 即可复制完整策略代码。

内存数据库

如果操作的数据不希望永久保存到磁盘,可以在SQL语句前加上:符号就可以在内存数据库里操作, 机器人重启后数据重置

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

总结

数据库不仅可以承载海量数据,更能承载众多量化交易爱好者的宽客梦想。对于数据库的使用绝非仅限于本文的例子,更多使用方法可以参考SQLite教程,以及发明者量化后续推出的系列文章。

FMZ量化交易平台邀请链接:https://www.fmz.com/

全球最大交易所币安,国区邀请链接:https://accounts.binance.com/zh-CN/register?ref=16003031  币安注册不了IP地址用香港,居住地选香港,认证照旧,邮箱推荐如gmail、outlook。支持币种多,交易安全!

买好币上KuCoin:https://www.kucoin.com/r/af/1f7w3  CoinMarketCap前五的交易所,注册友好操简单快捷!

目前不清退的交易所推荐:

1、全球第二大交易所OKX欧意,邀请链接:https://www.myts3cards.com/cn/join/1837888 注册简单,交易不需要实名,新用户能开合约,币种多,交易量大!。

2、老牌交易所比特儿现改名叫芝麻开门 :https://www.gate.win/signup/649183

买好币上币库:https://www.kucoin.com/r/1f7w3

火必所有用户现在可用了,但是要重新注册账号火币:https://www.huobi.com

全球最大交易所币安,

国区邀请链接:https://accounts.suitechsui.mobi/zh-CN/register?ref=16003031 支持86手机号码,网页直接注册。

相关内容

热门资讯

Windows 11 和 10... Windows 11/10 文件夹属性中缺少共享选项卡 – 已修复 1.检查共享选项卡是否可用 右键...
事件 ID 7034:如何通过... 点击进入:ChatGPT工具插件导航大全 服务控制管理器 (SCM) 负责管理系统上运行的服务的活动...
Radmin VPN Wind... Radmin VPN 是一款免费且用户友好的软件,旨在牢固地连接计算机以创建一个有凝聚力的虚拟专用网...
Hive OS LOLMine... 目前不清退的交易所推荐: 1、全球第二大交易所OKX欧意 国区邀请链接: https://www.m...
如何修复 Steam 内容文件... Steam 内容文件锁定是当您的 Steam 文件无法自行更新时出现的错误。解决此问题的最有效方法之...
Hive OS 部署 PXE ... 目前不清退的交易所推荐: 1、全球第二大交易所OKX欧意 国区邀请链接: https://www.m...
如何在电报Telegram中隐... 点击进入:ChatGPT工具插件导航大全 在Android上的电报中隐藏您的电话号码 您可以通过切换...
farols1.1.501.0... faro ls 1.1.501.0(64bit)可以卸载,是一款无需连接外部PC机或笔记本计算机即可...
在 iCloud 上关闭“查找... 如果您是 Apple 的长期用户,您肯定会遇到过 Find My 应用程序,它本机安装在 iPhon...
在 Windows 11 中打... 什么是链路状态电源管理? 您可以在系统控制面板的电源选项中看到链接状态电源管理。它是 PCI Exp...