暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

DolphinDB SQL 案例教程

1279

本教程重点介绍了一些常见场景下的 SQL 编写案例,通过优化前后性能对比或正确编写方法介绍,说明 DolphinDB SQL 脚本的使用技巧,案例分四类:条件过滤相关案例分布式表相关案例分组计算相关案例元编程相关案例,共计22个应用实例,案例中用到的测试数据为基于真实数据结构模拟的2000只股票快照数据。

由于篇幅有限,此处选取了1个案例进行展示,点击推送底部 阅读原文 查看完整案例内容 👇👇


计算股票组合的价值 

场景:进行指数套利交易回测时,计算给定股票组合的价值。

当数据量极大时,一般数据分析系统进行回测时,对系统内存及速度的要求极高。以下案例,展现了使用 DolphinDB SQL 语言可极为简洁地进行此类计算。

为了简化起见,假定某个指数仅由两只股票组成:AAPL 与 FB。模拟数据如下:

syms = take(`AAPL, 6) join take(`FB, 5)time = 2019.02.27T09:45:01.000000000 + [146, 278, 412, 445, 496, 789, 212, 556, 598, 712, 989]prices = 173.27 173.26 173.24 173.25 173.26 173.27 161.51 161.50 161.49 161.50 161.51quotes = table(take(syms, 100000) as Symbol,                take(time, 100000) as Time,                take(prices, 100000) as Price)weights = dict(`AAPL`FB, 0.6 0.4)ETF = select Symbol, Time, Price*weights[Symbol] as weightedPrice from quotes

优化前:

首先,需要将原始数据表的3列(时间,股票代码,价格)转换为同等长度但是宽度为指数成分股数量加1的数据表,然后向前补充空值(forward fill NULLs),进而计算每行的指数成分股对指数价格的贡献之和。示例如下:

timer {    colAAPL = array(DOUBLE, ETF.Time.size())    colFB = array(DOUBLE, ETF.Time.size())        for(i in 0:ETF.Time.size()) {        if(ETF.Symbol[i] == `AAPL) {            colAAPL[i] = ETF.weightedPrice[i]            colFB[i] = NULL        }        if(ETF.Symbol[i] == `FB) {            colAAPL[i] = NULL            colFB[i] = ETF.weightedPrice[i]        }    }        ETF_TMP1 = table(ETF.Time, ETF.Symbol, colAAPL, colFB)    ETF_TMP2 = select last(colAAPL) as colAAPL, last(colFB) as colFB from ETF_TMP1 group by time, Symbol    ETF_TMP3 = ETF_TMP2.ffill()        t1 = select Time, rowSum(colAAPL, colFB) as rowSum from ETF_TMP3}

以上代码块耗时 713 ms

优化后:

使用 pivot by 子句根据时间、股票代码对于数据表重新排序,将时间作为行,股票代码作为列,然后使用ffill 函数填充 NULL 元素,使用 avg 函数计算均值,最后 rowSum 函数计算每个时间点的股票价值之和,仅需以下一行代码,即可实现上述所有步骤。示例如下:

timer t2 = select rowSum(ffill(last(weightedPrice))) from ETF pivot by Time, Symbol

查询耗时 23 ms

each(eqObj, t1.values(), t2.values()) //true

与优化前写法相比,优化后写法查询性能提升约 30 倍。

此例中,仅以两只股票举例说明,当股票数量更多时,使用循环遍历的方式更为繁琐,而且性能极低。

pivot by 是 DolphinDB SQL 独有的功能,是对标准SQL语句的拓展,可以将表中两列或多列的内容按照两个维度重新排列,亦可配合数据转换函数使用。不仅编程简洁,而且无需产生中间过程数据表,有效避免了内存不足的问题,极大地提升了计算速度。

以下是与此场景类似的另外一个案例,属于物联网典型场景

场景:假设一个物联网场景中存在三个测点进行实时数据采集,期望针对每个测点分别计算一分钟均值,再对同一分钟的三个测点均值求和。

首先,产生模拟数据,示例如下:

N = 10000t = table(take(`id1`id2`id3, N) as id,           rand(2021.01.01T00:00:00.000 +  100000 * (1..10000), N) as time,           rand(10.0, N) as value)

使用 bar 函数对时间做一分钟聚合,并使用 pivot by 子句根据分钟、测点对数据表重新排序,将分钟作为行,测点作为列,然后使用 ffill 函数填充 NULL 元素,使用 avg 函数计算均值,然后再使用 rowSum 函数计算每个时间点的测点值之和。最后使用 group by 子句结合 interval 函数对于缺失值进行填充。

timePeriod = 2021.01.01T00:00:00.000 : 2021.01.01T01:00:00.000timer result = select sum(rowSum) as v from (               select rowSum(ffill(avg(value))) from t                where id in `id1`id2`id3, time                between timePeriod                pivot by bar(time, 60000) as minute, id)                group by interval(minute, 1m, "prev") as minute

查询耗时 12 ms


DolphinDB SQL 案例教程 完整目录

  • 1 测试环境说明

  • 2 条件过滤相关案例

    • 2.3.1 过滤条件与序列无关

    • 2.3.2 过滤条件与序列有关

    • 2.1 where 条件子句使用 in 关键字

    • 2.2 分组数据过滤

    • 2.3 where 条件子句使用逗号或 and

  • 3 分布式表相关案例

    • 3.1 分区剪枝

    • 3.2 group by 并行查询

    • 3.3 分组查询使用 map 关键字

  • 4 分组计算相关案例

    • 4.1 查询最新的 N 条记录

    • 4.2 计算滑动 VWAP

    • 4.3 计算累积 VWAP

    • 4.4 计算 N 股 VWAP

    • 4.5 分段统计股票价格变化率

    • 4.6 计算不同连续区间的最值

    • 4.7 不同聚合方式计算指标

    • 4.8 计算股票收益波动率

    • 4.9 计算股票组合的价值

    • 4.10 根据成交量切分时间窗口

    • 4.11 股票因子归整

    • 4.12 根据交易额统计单子类型

  • 5 元编程相关案例

    • 5.1 动态生成 SQL 语句案例 1

    • 5.2 动态生成 SQL 语句案例 2

点击推送底部 阅读原文 查看完整案例内容 👇👇


关于我们

DolphinDB是一款专为海量时序数据设计的数据库产品,将编程语言、数据库和分布式计算从底层进行一体化设计,开创性地解决了快速开发、高速运行和简单部署三者难以兼顾的难题,为海量结构化数据的快速存储、检索、 分析及计算量身订做一站式解决方案。


DolphinDB目前被广泛应用于金融市场全域(低频、中频和高频)的数据存储、数据清洗、因子分析、策略回测、实时计算等场景中。在物联网领域,尤其是化工、电力、能源、水务等行业,DolphinDB通过联合各行业头部集成商,将DolphinDB集成到行业解决方案中,实现海量数据的存储和实时计算,为用户提供性能优异的整体解决方案。

Explore More


文章转载自DolphinDB智臾科技,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论