乐趣区

关于dolphindb:干货丨如何用时序数据库寻找相似的历史k线

有网友发问应该用什么样的数据库 / 数据结构 / 算法来计算某支股票的类似 K 线? 具体的问题形容是,假如给出某股某段行情 K 线(单位 / 日),从任何其余股票历史中匹配出与之最为类似的某段历史 K 线,并给出类似度值(单位 /%),并以此排序,获取最为类似的 N 个后果。

咱们能够应用 k 线的间隔以及股票日回报的相关性来掂量 k 线类似度,应用 Tushare 提供的沪深股票 2008 年到 2017 年的日线行情数据来做试验。如何把 Tushare 数据导入到 DolphinDB database 能够参考教程如何应用 DolphinDB 解决 Tushare 金融数据。

Tushare 提供的沪深股票日线行情数据蕴含以下字段:

 名称            形容
ts_code            股票代码
trade_date    交易日期
open            开盘价
high            最高价
low            最低价
close            收盘价
pre_close    昨收价
change            涨跌额
pct_change    涨跌幅
vol            成交量(手)amount            成交额(千元)

上面将以漫步者(股票代码为 002351.SZ)为例,介绍如何在历史数据中,找出与漫步者 2016 年 9 月 1 日到 2016 年 9 月 30 日最为类似的 10 段历史 k 线。

首先,把漫步者 2016 年 9 月 1 日到 2016 年 9 月 30 日的日线行情数据加载到内存。

code="002351.SZ"// 漫步者
edifier=select * from loadTable("dfs://daily_line","hushen_daily_line") where ts_code=code,date(trade_date) between 2016.09.01:2016.09.30

把股票数据加载到内存中。

num=exec count(*) from edifier
stock=select * from loadTable("dfs://daily_line","hushen_daily_line")

1. 应用 k 线的间隔掂量类似度

两段 k 线之间的间隔能够用股票日回报的差的平方和来计算。间隔越小示意 k 线的类似度越高。

def square_sum(x,y):sum2(x-y)
corrTable1=select ts_code,move(date(trade_date),num-1)as beginDate,date(trade_date) as endDate,moving(square_sum{edifier.pct_change},pct_change,num) as distance from stock context by ts_code

下面代码应用的 moving 是 DolphinDB 的模板函数,示意在大小为 num,边界为 beginDate 和 endDate 的滚动窗口中计算两段 k 线之间的间隔。square_sum{edifier.pct_change} 是 DolphinDB 中的局部利用,用于固定函数的局部参数。

找出与漫步者 2016 年 9 月 1 日到 2016 年 9 月 30 日最为类似的 10 段历史 k 线。

mostCorrelated1=select * from corrTable1 where isValid(distance),rank(distance,true) between 0:10 order by distance
ts_code            beginDate    endDate            distance
300073.SZ    2016.08.02    2016.08.29    67.024
600995.SH    2017.07.06    2017.08.02    70.8713
600549.SH    2010.12.17    2011.01.14    73.514
600627.SH    2008.07.07    2008.08.07    73.59
600367.SH    2010.12.17    2011.01.14    76.447
600867.SH    2011.07.28    2011.08.24    76.5449
002253.SZ    2010.05.21    2010.06.22    79.2845
002382.SZ    2015.01.06    2015.02.02    79.5101
300266.SZ    2014.07.07    2014.09.17    80.1772
600706.SH    2017.06.05    2017.07.14    80.5079

定义一个函数 getReturn,取出类似股票在 beginDate 和 endDate 之间的日回报。

def getReturn(t, row): exec pct_change/100 from t where ts_code= row.ts_code, date(trade_date) between row.beginDate : row.endDate

把每只类似股票的日回报数据保留到同一个回报矩阵中,每列示意一只股票在相应时间段中的日回报,并应用图表展现。

retMatrix1 = each(getReturn{stock}, mostCorrelated1).rename!(mostCorrelated1.ts_code)
plot(retMatrix1,,"应用最短 k 线间隔找出类似历史 k 线") 

下面的代码通过 each 模板函数取出最类似的 10 只股票的日回报,并以股票代码来命名每一列。

应用最短 k 线间隔计算出来的股票蕴含当升科技(30073.SZ)、文山电力(600995.SH)、厦门钨业(600549.SH)、上电股份(600627.SH)、红星倒退(600367.SH)、通化东宝(600867.SH)、川大智胜(002253.SZ)、蓝帆医疗(002382.SZ)、兴源环境(300266.SZ)和曲江文旅(600706.SH)。

2. 应用股票日回报相关性掂量类似度

股票日回报的相关性是掂量 k 线类似度很好的指标。

corrTable2=select ts_code,move(date(trade_date),num-1)as beginDate,date(trade_date) as endDate,moving(corr{edifier.pct_change},pct_change,num) as corr from stock context by ts_code

找出与漫步者 2016 年 9 月 1 日到 2016 年 9 月 30 日最为类似的 10 段历史 k 线。

mostCorrelated2=select * from corrTable2 where rank(corr,false) between 0:10 order by corr desc
ts_code            beginDate    endDate            corr
600367.SH    2010.12.17    2011.01.14    0.8824
600549.SH    2010.12.17    2011.01.14    0.8806
300073.SZ    2016.08.02    2016.08.29    0.8749
002294.SZ    2014.02.26    2014.03.25    0.8729
600995.SH    2017.07.06    2017.08.02    0.8723
600486.SH    2010.12.17    2011.01.14    0.8721
002382.SZ    2015.01.06    2015.02.02    0.8718
002253.SZ    2010.05.21    2010.06.22    0.8708
000939.SZ    2008.03.21    2008.04.18    0.8706
600627.SH    2008.07.07    2008.08.07    0.8692

同样地,把类似股票的日回报数据保留到回报矩阵中。

retMatrix2 = each(getReturn{stock}, mostCorrelated2).rename!(mostCorrelated2.ts_code)
plot(retMatrix,,"应用股票日回报相关性找出类似历史 k 线") 

应用股票日回报相关性计算出来的股票蕴含红星倒退(600367.SH)、厦门钨业(600549.SH)、当升科技(300073.SZ)、信立泰(002294.SZ)、文山电力(600995.SH)、扬农化工(600486.SH)、蓝帆医疗(002382.SZ)、川大智胜(002253.SZ)、凯迪生态(000939.SZ)和上电股份(600627.SH)。

3. 性能剖析

咱们应用的是沪深股票 2008 年到 2017 年的日线行情数据,共 530 万的数据。应用第一种办法仅需 7 秒,应用第二种办法仅需 3 秒,性能极佳。

退出移动版