【量化数据】使用DiskCache高效、持久化存取股票行情信息,彻底解决行情焦虑!

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

量化交易,数据先行。
可你是不是也经常遇到:行情没下载读取不到,下载了读取不够快,直接订阅行情数量又不够,或者速度不够快。
那么你可以尝试一下下面这个方法。


一、DiskCache是什么,它有什么优势?

DiskCache是一个用Python编写的高效轻量级磁盘和文件缓存库,旨在提供比内存缓存更持久的存储解决方案,同时保持接近内存缓存的访问速度。它特别适用于需要大量临时存储且对性能敏感的应用。
比如我们量化交易需要用到的行情数据,就刚好符合其应用场景。

它是一个纯 Python 的缓存包,可有效利用上 G 空间用于缓存,通过数据库和内存映射文件,缓存性能可以匹配并超越行业标准解决方案。

根据官方(https://github.com/grantjenks/python-diskcache)展示的读写删除时间,可以看到diskcache在读写删除方便均耗时较小。

ProjectdiskcachedbmshelvesqlitedictpickleDB
get25 µs36 µs41 µs513 µs92 µs
set198 µs900 µs928 µs697 µs1,020 µs
delete248 µs740 µs702 µs1,717 µs1,020 µs

二、DiskCache基本操作示例

1. 安装DiskCache

通过pip即可安装DiskCache,使用镜像库可加速安装过程。

pip install diskcache -i https://pypi.tuna.tsinghua.edu.cn/simple

2. DiskCache常用操作

# 导入库文件
from diskcache import Cache

# 实例化缓存对象,指定缓存目录
cache = Cache('/cachedb/cachedb_01')

# 设置缓存项
cache.set('300750', '宁德时代')
cache.set('300250', '初灵信息')
cache.set('300450', '先导智能')
print(list(cache)) # 输出不排序的键名list
print(list(cache.iterkeys())) # 输出排序的键名list
print(cache.peekitem()) # 输出最后一个键值
print(cache.peekitem(last=False)) # 输出第一个键值

# DiskCache支持设置带有过期时间的缓存项,使得数据可以在指定时间后自动失效。
# 设置缓存项,其中expire参数指定过期时间(单位:秒)
cache.set('300750', '宁德时代', expire=5)
# 尝试等待超时后再获取
import time
time.sleep(5)
value = cache.get('300750')
print('Cached value after expiration:', value)  # 输出: Cached value after expiration: None

# 获取缓存项
value = cache.get('300750')
print('Cached value:', value)  # 输出: Cached value: '宁德时代'

# 添加新的缓存
cache.add('300750', '宁德时代', expire=10)

# 删除指定的缓存项
cache.delete('300750')

# 验证缓存项是否已被删除,已删除的返回None
value = cache.get('300750')
print('Cached value:', value)  # 输出: Cached value: None

# 另一种删除方法,返回值为删除的键值
value = cache.pop('300750')

# 检查键是否存在
if '300750' in cache:
    print("'300750' exists in cache")
else:
    print("'300750' does not exist in cache")

# 更新缓存时间
cache.touch('300750', expire=10)

# 手动清理过期缓存
cache.expire()

# 输出键值数量
print('cache.count:',cache.count)

# 输出磁盘容量占用情况
print('cache.volume():',cache.volume())

# 关闭缓存对象
cache.close()

# 删除缓存文件。缓存不会自动删除keys和值。缓存旨在持久化,因此需要手动删除。
import shutil
try:
    shutil.rmtree(cache.directory)
except OSError:  # Windows wonkiness
    pass

三、用DiskCache写入和读取行情信息

我们通常使用DataFrame来存取行情信息。这里我们引用我们的老朋友Ashare库来爬取行情信息,但将行情df写入DiskCache前,我们需要使用pickle先转化一下,当然读取出来也需要再反向转化一下。具体示例如下:

# 导入库文件
from diskcache import Cache

# 实例化缓存对象,指定缓存目录
cache = Cache('/cachedb/cachedb_01')

import pickle
from Ashare import *
code = '300750.sz'
df = get_price(code,frequency='1m',count=250)  #支持'1m','5m','15m','30m','60m'
print('上证指数分钟线\n',df)

# 将df写入cache
df_bytes = pickle.dumps(df)
cache.set(code, df_bytes)
print(cache.get(code))

# 从cache读取为df
df_bytes_from_cache = cache.get(code)
if not df_bytes_from_cache is None:
    df = pickle.loads(df_bytes_from_cache)
print(df)

四、DiskCache的高级操作

1. 指定缓存空间

# 实例化缓存,指定大小限制为300MB
cache = Cache('/cachedb/cachedb_01', size_limit=300*1024*1024)

2. FanoutCache 分片

diskcache可使用diskcache.FanoutCache 自动分片基础数据库。分片是对数据进行水平分区。可用于减少阻塞写入。尽管读和写不会互相阻碍,但写入会阻碍其他写入。分片默认值为8。

from diskcache import FanoutCache
cache=FanoutCache(r"/cachedb/cachedb_01",shards=4,timeout=1)
cache.set('300750', '宁德时代')
print(cache.get('300750'))

cachedb_01文件夹中创建一个具有四个分片和一秒超时的缓存。如果操作花费的时间超过一秒,它们将尝试中止操作。每一个分片大小平均分配,占总空间的四分之一。diskcache的默认大小为1GB。

3. 缓存信息统计

# 获取并打印缓存统计信息
stats = cache.stats(enable=True)  # 需要先启用统计
print("Cache hits:", stats['hits'])
print("Cache misses:", stats['misses'])

总结

我们这里只是简单的介绍了DiskCache的一下主要操作和用法,并对量化需要用到的行情信息读写进行了展示,作为基本应用已经足够用了,基本操作也就这些了。在使用了mysql,sqlite,txt,redis,综合速度和持久化,个人更倾向于DiskCache。

量化交易,数据先行。稳定高效的行情是首要的,将日K行情缓存到DiskCache,再获取当日日K并concat成完整日K,这个是我尝试多种方案后,目前最高效的方法。

更多官方API介绍,请移步官方网站进一步学学。
https://grantjenks.com/docs/diskcache/api.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT里的交易员

分享是一种快乐,打赏是一种肯定

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值