关于数据库:活用向量数据库普通散户也能找到潜力股

8次阅读

共计 5092 个字符,预计需要花费 13 分钟才能阅读完成。

✏️ 编者按:

在股市里,光是一支股票,其 K 线、状态、指标就曾经含有丰盛的信息,更何况股市里有大几千支股票,各种信息令人目迷五色。一般散户到底如何全盘剖析,选出一支潜力股?

向量搜寻畛域的技术大牛、业余股民老莫给出了他的答案:他尝试将简单的数组转化成向量,而后应用开源向量数据库 Milvus 辅助剖析股票 ,为「选股」这一世纪难题给出了量化剖析选股的思考角度。当今时代,各个领域的数据体量和品种呈几何式增长,为了剖析海量的结构化与非结构化数据, 将数据转化成高维向量并进行向量类似度剖析 已逐步成为一种卓有成效的形式。

本文转载自知乎用户 @yhmo,已取得原作者受权。

🤫 小声揭示 🤫

关注公众号并回复「炒股源码」

获取本文辅助选股源代码!

猜测:Milvus 数据库或者能够帮忙选股?

Milvus 数据库是什么?

在我的项目主页上,是这样介绍 Milvus 的:Milvus 向量数据库专为向量查问与检索设计,可能为万亿级向量数据建设索引。你能够应用 Milvus 向量数据库搭建合乎本人场景需要的向量类似度检索系统,比方图片检索系统、视频检索系统、音频检索系统、分子式检索系统、举荐零碎、智能问答机器人、DNA 序列分类零碎、文本搜索引擎……

那么 Milvus 向量数据库就只能做这些事件么?

Milvus 向量数据库具备计算和检索向量类似度的性能,只有你能把生存中的事物用数字向量示意进去,那么,Milvus 向量数据库就能帮你在这些向量中进行含糊搜寻和匹配。

股票就是一种跟数字强相干的事物。笔者不禁联想,Milvus 数据库能在股市上有所作为么?

玩过股票的人应该有领会,散户选股是件令人特地头疼的事件,各种蜡烛图、曲线、数字经常让人目迷五色、莫衷一是。而且股市里有大几千只股票,一个人根本无法看全,基本上只能关注其中几只。

股票的蜡烛图,是以每个交易日的 4 个数值(开盘价、最高价、最低价、收盘价)画出的图形。这 4 个数值就是一组数字,而一组数字在数学上能够转化成一个数字向量。剖析这个向量,或者就得出些令人惊喜的后果,并且能帮忙咱们大幅晋升剖析效率!

带着这些猜测,笔者在业余时间做了一些尝试:

原理

笔者初步的想法是:假如有 n 个交易日数据,咱们把每个交易日的 4 个价格开展,造成 4n 个数值,作为一条向量,它的维度就是 4n。

例如,某只股票最近 3 个交易日的数据如下:

那么,咱们就能够把这些数据转换为一条 12 维的向量:

[20.82, 21.45, 20.53, 21.15, 21.28, 21.37, 21.01, 21.05, 20.73, 21.35, 20.67, 21.25]

如果有另一只股票,其最近 3 个交易日数据如下:

同样,咱们能够把这些数据转换为一条 12 维的向量:

[6.32, 6.58, 6.28, 6.56, 6.30, 6.53, 6.26, 6.36, 6.18, 6.39, 6.13, 6.31]

这两只股票在这 3 个交易日里类似度是多少?咱们不能间接用这两条 12 维向量做比拟,因为前一只股票 20 多块,后一只 6 块多,这两条向量的模长不同,间接计算间隔毫无意义。

笔者是这么解决的:咱们将每条向量的 12 个数值别离减去它们的最小值,而后做归一化,再进行比对。

做这些比对有何意义呢?咱们得拿出一个逻辑使得这些比对变得有意义。咱们常常说股票里有“主力”、有“庄家”,这两个词可能含意不同,但他们都能决定或影响股价的涨跌。要管制股价涨跌,手里必须得有筹码,而且手里的筹码与流通股的比例越高,控制力越强。短时间内,庄家是很难获取足够的筹码的,所以庄家会有一个较长时间的吸筹,短则一两个月,长则几个月甚至一年,在这段时间里上上下下各种洗盘。在股价腾飞之前,其状态或多或少有肯定的法则。咱们要比对的,就是这个吸筹期间的股价状态。

下一个问题是,谁跟谁比?咱们是拿最近的 n 天的状态,跟历史上产生大涨之前的 n 天状态比。哪只股不重要,咱们是要遍历整个市场中的每只股,看它们最近 n 天的状态,是否和历史上产生大涨之前 n 天状态类似。如果类似,那么咱们有理由认为,这只股有可能近期会产生大涨。

 筹备工作

历史数据怎么来?能够关注“数据即服务”微信公众号(非广告),点击公众号左下角的“下载”选项能够下载到“股票历史行情”,本文下载到的历史数据是从 A 股开市到 2020 年 7 月 24 号的:

其文件格式是 xls,笔者用 Python 转换为 csv 格局。

最新数据怎么来?这要借助于一个 Python 库 Tushare(https://tushare.pro/document/2)。比方要拉取某只股票最新的数据,Python 代码如下:

import tushare
def fetch_stock(dir, stock_id, date):
 current_path = dir + str(date) + "/"
if not os.path.exists(current_path):
 os.mkdir(current_path)

 data = tushare.get_hist_data(stock_id, start='2010-01-01', end=str(date))
# print(data)
 csv_path = current_path + stock_id + ".csv"
if os.path.exists(csv_path):
 os.remove(csv_path)
 data.to_csv(csv_path, encoding="utf-8", index=True, mode='a')
 print('save csv:', csv_path)

提取数据

下一步就是开始提取“历史上产生大涨之前的 n 天状态”了。笔者这里把 n 设为 100,也就是 100 个交易日,大概是 5 个月工夫。而后把“大涨”的规范定义一下,笔者是这么定义的:在 5 个交易日里股价上涨了 40%,就认为是“大涨”,并且在大涨之前 100 天里最初 10 天的均价低于头 10 天的均价(这是因为笔者心愿失去那些从底部涨起的股票)。依据这个定义,笔者在历史数据中一共找出了将近 3000 个股票,这里笔者疏忽掉了 ST 股(Special treatment,财务状况或其它情况出现异常的上市公司股票股票)。

须要留神的是,在笔者之后回溯试验时发现,有些状态并不是那么无效,容易造成误判。比方,上面的一些状态就容易造成误判(有些在大涨前曾经上坡一段时间),须要将这些状态的股票筛除:

通过筛选后,大概剩下不到 1000 个状态,比方上面一些:

能够看到,这些状态的股票基本上都是在股价低位起涨。

而后咱们把这些 1000 条向量(400 维)输出 Milvus 数据库,因为向量数很少所以不须要建索引,暴搜就足够了。向量的 ID 怎么设比拟好?为了不便察看,咱们按如下形式定义向量的 ID:

股票 ID +“00”+ 100 日的最初一个日期

两头加两个“0”是为了把股票 ID 和日期离开,以利于识别。比方,咱们在某只股票 000629 的历史数据中提取到 2015 年 12 月 16 号这天是大涨日,那么咱们把这天的前 100 个交易日的数据转为一条向量,这条向量的 ID 就是:6290020151216

选股

咱们须要写一个 Python 脚本,每天拉取股市里的最新数据。每只股票抽取最近 100 天的数据构建成一条 400 维向量,通过解决(减去最小值,归一化)后,应用 L2 的间隔计算形式,在 Milvus 数据库搜寻出最类似的一条向量。依据间隔做排名,咱们能够失去前 20 名的 20 只股票。

为了验证这个办法的有效性,笔者还做了一些回溯试验。后面咱们说过,拿到的历史数据是截止到 2020 年 7 月份,那咱们能够用 2020 年 8 月份之后的数据来做回溯。同样,咱们能够写一个 Python 脚本遍历 2020 年 8 月份之后每一天的行情,从每天的行情里举荐出 20 只股票,别离察看它们在 5 个交易日以及 10 个交易日之后的涨幅。

比方对于 2021 年 4 月 6 日的行情,计算失去的前 5 名是:

===== 300207 : 欣旺达 ===== 1
id: 6008440020050422 distance: 101.06045532226562
===== 600340 : 华夏幸福 ===== 2
id: 0026950020170608 distance: 118.332275390625
===== 688313 : 仕佳光子 ===== 3
id: 6002730020120717 distance: 124.2621841430664
===== 603283 : 赛腾股份 ===== 4
id: 0008760020100722 distance: 134.43807983398438
===== 603920 : 世运电路 ===== 5
id: 0026280020180719 distance: 135.54197692871094

它们的盈利状况是:

No.1 300207 欣旺达
 5 days growth: 9.86 (-0.47, 1.82, -4.4, 5.89, 7.02,)
 10 days growth: 11.709999999999999 (-0.47, 1.82, -4.4, 5.89, 7.02, 3.16, 0.69, -2.0,)
No.2 600340 华夏幸福
 5 days growth: 4.450000000000001 (10.05, -1.74, -0.29, -0.59, -2.98,)
 10 days growth: 6.040000000000001 (10.05, -1.74, -0.29, -0.59, -2.98, -0.61, -1.08, 3.28,)
No.3 688313 仕佳光子
 5 days growth: -5.04 (-0.23, -0.29, 0.59, -4.2, -0.91,)
 10 days growth: 2.1700000000000004 (-0.23, -0.29, 0.59, -4.2, -0.91, 5.65, 1.16, 0.4,)
No.4 603283 赛腾股份
 5 days growth: -12.1 (-0.42, -2.85, -2.57, -2.11, -4.15,)
 10 days growth: -7.239999999999999 (-0.42, -2.85, -2.57, -2.11, -4.15, 0.69, 1.72, 2.45,)
No.5 603920 世运电路
 5 days growth: -9.040000000000001 (-0.18, -1.58, 1.49, -4.29, -4.48,)
 10 days growth: 2.0599999999999987 (-0.18, -1.58, 1.49, -4.29, -4.48, 10.03, -2.28, 3.35,)

对于第一名的 300207,结果显示它跟 600844 的 2005 年 4 月 22 日的前 100 天类似度间隔为 101,后续 5 到 10 天的盈利为 10% 左右。
咱们先看一下 600844 的 2005 年 4 月 22 日的前 100 天(笔者应用 Python 的 mpl_finance 库以及 Matplotlib 库来绘制蜡烛图):

再来看看 300207 的 2021 年 4 月 6 号之前 100 天的行情:

几乎神似,对不对?

在回溯试验中也看到不少排名靠前,但前期却还持续上涨的股票。比方,下面第 4 名的 603283,在后续 10 个交易日里又持续上涨了 10% 左右。咱们能够想到,尽管和历史上的大涨状态类似,但这只股票还没跌够,还处于上涨趋势中,咱们须要依据其余的因素来判断,比方量价的变动,基本面的变动等等。

 论断

总体来说,笔者的做法大抵是以下几个步骤:

  1. 以某种条件定义股票大涨,依据这些条件在历史数据中提取特色 4n 维向量,输出 Milvus 数据库中;
  2. 从最新的股票行情里遍历每只股票,构建近期的 4n 维向量,大概 4000 条(剔除 ST 股);
  3. 对第 2 步失去的 4000 条向量,在 Milvus 数据库中搜寻最类似的 Top1,只取间隔最小的前若干名;
  4. 对第 3 步失去的前几名若干只股票,做进一步研判。

这样的办法给出的后果并不是相对盈利的,其最大的价值是给咱们提供了一个疾速遍历整个市场做比对的伎俩(在笔者应用了 8 年的苹果笔记本上,拉取近期行情数据大概须要十几分钟,遍历一次 4000 多只股票大概须要 4 分钟,我是一条条搜寻的,如果批量搜应该快很多),它得出的后果能够作为我进一步研判的根据。

对股票感兴趣的敌人,心愿这篇文章可能对他们有帮忙,同时也心愿 Milvus 能在这个畛域有所帮忙。笔者尽管钻研过一段时间的股票,不过属于三脚猫的那种程度,如有不当请多担待。

注:Milvus 数据库利用面十分宽泛,能够解决很多日常生活中的数字问题,不仅限于辅助选股。须要留神的是,本文写于约半年前,文中举荐的五支股票当初有两支跌得很惨,所以本文并不是财经领导类文章,而是一个采纳数据分析办法进行的炒股试验。欢送大家一起摸索更多 Milvus 数据库的打开方式!

正文完
 0