当前位置:网站首页>【量化交易行情不够快?】一文搞定通过Win10 wsl2 +Ubuntu+redis+pickle实现股票行情极速读写
【量化交易行情不够快?】一文搞定通过Win10 wsl2 +Ubuntu+redis+pickle实现股票行情极速读写
2022-08-10 12:42:00 【IT里的交易员】
一文搞定通过Win10 wsl2 +Ubuntu+redis+pickle实现股票行情极速读写
前言
量化交易,行情先行!
对于量化交易,行情数据很重要,可以说很关键。个人做量化,因为网络时延、本地IO开销、电脑速度等原因,获取行情和处理交易的速度和机构托管在机房里的集群交易服务器自然没法比。但,个人量化也可以飞起来,至少比大多数散户可以快很多很多!!
量化交易,行情不快、不准,那可要了命的! 明明量化策划都没问题,可该触发的没触发,不该触发的时候又乱触发,究其原因,都是行情推送惹得祸!
那么,如何实现对行情数据的极速、稳定的访问呢?
笔者之前一直使用Mysql,后来也试过MongoDB,还曾甩开数据库,直接用csv文件读写,但速度都还不够快!直到后来学习到可以将数据缓存到内存里,那速度可真的快得不要不要滴!redis内存数据库的访问速度比mysql快了不止一个等量级,速度胜过各种数据库(没有了IO的开销,直接在内存里读写)。
做量化,行情很重要,自从搭建了这套系统,建立了自己又快有稳的行情库,再也不纠结各种行情获取和速度的问题了!
废话不多说,上方案:
基于个人电脑,我的解决方案是:先给Win10装wsl2,再在wsl2上装Ubuntu,再在Ubuntu上装redis,再让redis自动启动,最后用python 代码开机自动更新redis键值。每日开盘前将日K等行情数据载入redis,完成键值更新。开盘后加上实时行情即可生成当日实时日K,既节约流量消耗,又能提高速度。
提示:以下是本篇文章正文内容,有些细节需要点操作系统功底,我尽可能往简单点说。不会的也没关系,照着步骤操作就是。
一、准备环境分四步
1.1 给Win10装wsl2
硬件开启虚拟化
WSL(Windows Subsystem for Linux)是Windows推出的可让开发人员不需要安装虚拟机(vmware,virtbox)或者设置双系统启动就可以原生支持运行GNU/Linux的系统环境,简称WSL子系统。目前最新的版本是WSL2,在原先的基础上提高了文件系统的性能并添加了完全的的系统调用支持。WSL2使用全新体系架构使其能真正的运行一个Linux内核。
WSL2 是基于Hyper-V(Hyper-V是微软的一款虚拟化产品)的,所以Windows 机器必须支持虚拟化。打开任务管理器查看CPU选项“虚拟化”有没有启用。未开启的,开启虚拟化需要首先在BIOS里进行设置(各品牌主板进入BIOS的方式及设置方法可百度搜索,找到Intel Virtual Technology的选项点enable即可,现在的电脑一般都支持)
软件开启虚拟化及安装适用于Linux系统的Windows 子系统
安装虚拟机功能:
在Win10 的“程序与功能”里找到“启用或关闭Windows功能”,在Hyper-V和适用于Linux系统的Windows 子系统前打钩,安装以上两项后重启。
注意:这里的Win10的版本不能太低,最好在2004以上。通过【Win+R】的快捷键可以快速打开Windows系统的“运行”窗口,然后在这里输入winver,运行后即可看到Windows版本号。
启用虚拟机功能,并将WSL 2 设置为默认版本:
之前的安装完成了WSL。要使用WSL 2 必须先启用“虚拟机平台”可选功能。 计算机需要虚拟化功能才能使用此功能。
以管理员身份打开PowerShell并运行:
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
重启电脑后完成启用WSL 2。
将 WSL 2 设置为默认版本
打开 PowerShell,将 WSL 2 设置为默认版本:
PS C:\Windows\system32> wsl --set-default-version 2
有关与 WSL 2 的主要区别的信息,请访问 https://aka.ms/wsl2
操作成功完成。
PS C:\Windows\system32>
1.2 在wsl2基础上安装Ubuntu
Ubuntu是一个以桌面应用为主的Linux操作系统。前面的如果已经安装完毕,后面就可以进入微软商店Microsoft Store ,搜索Ubuntu,笔者经过比较,最后安装了Ubuntu 20.04.4 LTS。LTS 是 long-term support 的缩写,意为长期支持。有LTS字样一般这个版本比较稳定。
安装完毕就可以打开,设置密码后(密码最好抄下来,有些人用着用着就忘了)进入如下界面即安装成功。因为我们不使用Ubuntu的图形界面,所以到这里就可以了。这样既高效又不占资源。
1.3 给Ubuntu安装redis
安装redis,可参考redis官方网站:
Install Redis on Windows | Redis
https://redis.io/docs/getting-started/installation/install-redis-on-windows/
进入Ubuntu的命令界面,执行以下官方指导命令(我只执行了后两步):
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
sudo apt-get update
sudo apt-get install redis
安装完毕,将redis作为服务启动
sudo service redis-server start
执行redis-cli,输入ping,回复PONG,即标识redis正常运行。
[email protected]:~$ redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379>
redis的命令操作,各位可以百度搜索先熟悉一下简单操作。不想学也没关系,后面用Python代码进行程序操作。
1.4 设置Win10开机后自动启动wsl2的Ubuntu
键盘Win+r 启动运行,输入shell:startup,转到Windows“启动”目录,新建文件wsl2run_Ubuntu_redis.vbs(文件名自命名,扩展名是vbs就行),并保存以下内容。
rem Msgbox "Win10开机自动启动wsl的Ubuntu,并由其启动redis"
Set ws = CreateObject("Wscript.Shell")
ws.run "wsl -d Ubuntu-20.04 -u root /etc/init.wsl start", vbhide
Ubuntu启动后,会自动加载redis服务,所以redis也就自动启动了。
小结:至此,方案中先给Win10装wsl2,再在wsl2上装Ubuntu,再在Ubuntu上装redis,再让redis自动启动的步骤就算完成了。下面是Python的事儿了。
二、利用Python操作redis读写行情数据
2.1 环境准备(下载和安装第三方包)
文中数据格式都是pandas的dataframe,建议安装Anaconda,提前准备好环境。
下面代码使用到redis和pickle两个库,安装命令如下:
pip install redis
pip install pickle
另,本例子中采集行情数据用到Ashare,请提前下载Ashare.py放到一个目录(我们这里假设都放在D:\pythoncode\)下。
行情采集仅是举例,更多行情采集可参考我的另一篇文章(【数据知多少】一文学懂通过Tushare、AKshare、baostock、Ashare、Pytdx获取股票行情数据(含代码)https://blog.csdn.net/popboy29/article/details/125815775)
2.2 爬取行情数据写入redis,并进行读出和删除
这里仅为演示,实操应用代码比较长,恕无法全部展示。但涉及的操作如写入、读出、删除的框架已全部展示,需要扩充应用的,请自行修改。
以下为Python操作redis代码,假设保存在python_run_redis.py里,也放在D:\pythoncode\目录下。
# -*- coding: utf-8 -*-
''' 作者:IT里的交易员_CSDN 用途:将股票行情dataframe数据写入redis,并进行读取和删除。 注意:本文仅为演示,实操应用代码比较长,恕无法全部展示。 '''
# 使用本文代码,需要提前安装以下两个包,并提前下载Ashare包
# pip install redis
# pip install pickle
import time
# time.sleep(5)# 滞后5秒,等待wsl启动Ubuntu 及 redis。仅做测试,可将此行注释。
import redis
import pickle
pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=False)
rs = redis.Redis(connection_pool=pool)
# 下载Ashare.py放到和这个文件相同目录下
from Ashare import get_price
# 计时开始
time11 = time.time()
if 1:
# 提取行情并写入redis
df=get_price('sh000001',frequency='1d',count=1000) #支持'1d'日, '1w'周, '1M'月
print('上证指数日线行情\n',df)
print('r.set 将df写入redis')
df_bytes = pickle.dumps(df)
rs.set('df', df_bytes)
if 1:
# 遍历并redis数据库
rs_keys=rs.scan_iter()
for key in rs_keys:
print('redis现有键',key)
if 1:
# 读取键值
df_bytes_from_redis = rs.get(key)
if not df_bytes_from_redis is None:
df = pickle.loads(df_bytes_from_redis)
print('提取redis现有键值到df',df)
if 1:
# 删除键值
rs.delete(key)
print('redis现有键',key,'已删除')
# 计时结束
time21 = time.time()
print("Python操作redis耗时:",time21-time11,'秒')
经测试,写入、读出及删除结果如下:
1.采集1000条上证指数日线行情并写入redis,结果如下:
上证指数日线行情
open high low close volume
2018-06-27 2842.396 2854.258 2798.800 2813.178 1.294208e+10
2018-06-28 2799.904 2825.987 2782.446 2786.897 1.183579e+10
2018-06-29 2789.811 2848.372 2782.381 2847.418 1.256717e+10
2018-07-02 2841.580 2845.680 2756.815 2775.557 1.370350e+10
2018-07-03 2774.570 2786.888 2722.449 2786.888 1.424985e+10
... ... ... ... ... ...
2022-08-01 3246.616 3264.304 3225.553 3259.959 2.922048e+10
2022-08-02 3231.262 3231.262 3155.187 3186.266 3.941762e+10
2022-08-03 3188.891 3217.550 3159.457 3163.674 3.248857e+10
2022-08-04 3179.428 3190.999 3155.704 3189.039 2.608989e+10
2022-08-05 3195.227 3228.886 3184.455 3227.027 2.746837e+10
[1000 rows x 5 columns]
r.set 将df写入redis
Python操作redis耗时: 0.259993314743042 秒
2.从redis读出刚才写入的dataframe数据,结果如下:
redis现有键 b'df'
提取redis现有键值到df open high low close volume
2018-06-27 2842.396 2854.258 2798.800 2813.178 1.294208e+10
2018-06-28 2799.904 2825.987 2782.446 2786.897 1.183579e+10
2018-06-29 2789.811 2848.372 2782.381 2847.418 1.256717e+10
2018-07-02 2841.580 2845.680 2756.815 2775.557 1.370350e+10
2018-07-03 2774.570 2786.888 2722.449 2786.888 1.424985e+10
... ... ... ... ... ...
2022-08-01 3246.616 3264.304 3225.553 3259.959 2.922048e+10
2022-08-02 3231.262 3231.262 3155.187 3186.266 3.941762e+10
2022-08-03 3188.891 3217.550 3159.457 3163.674 3.248857e+10
2022-08-04 3179.428 3190.999 3155.704 3189.039 2.608989e+10
2022-08-05 3195.227 3228.886 3184.455 3227.027 2.746837e+10
[1000 rows x 5 columns]
Python操作redis耗时: 0.027001142501831055 秒
3.删除刚才的数据,结果如下:
redis现有键 b'df'
redis现有键 b'df' 已删除
Python操作redis耗时: 0.01200413703918457 秒
2.3 开机启动Python脚本
键盘Win+r 启动运行,输入shell:startup,转到Windows“启动”目录,新建文件python_run_redis.bat(文件名自命名,扩展名是bat,此为Windows的批处理文件。和之前的vbs不同,请注意!),并保存以下内容。
python D:\pythoncode\python_run_redis.py
注意:要开机自运行,为了保证效果,在python_run_redis.py里将这行注释去掉,如下:
time.sleep(5)# 滞后5秒,等待wsl启动Ubuntu 及 redis。仅做测试,可将此行注释。
小结:至此,方案中电脑开机运行Python 写入日K数据到redis也完成了。
至于一次性将所有品种的各种周期的行情加载到redis,数据量太大,代码也贼复杂。另外,开盘后将历史行情加上实时行情即可生成当日实时日K的方法,也比较复杂。
不过这些都是实现了。篇幅有限,今天先说到这里。各位先跑起来再说!
总结
经测试,将所有股票日K写入redis耗时: 451.9708275794983 秒(这个有采集时长,如果每日盘后下载,通过本地加载应给更快。)不过无所谓,盘前9分钟而已,只要每日定时开机时间,比如9点,完全可以搞定以上操作。
另测试,将redis历史行情结合当日行情,合成生成全量股票代码当日实时日K数据并计算指标耗时: 0.3719971179962158 秒(这个神了,速度杠杠滴!)。
有人怀疑这个速度?哈哈,因为我用的行情不是文中举例的那个,其它几个也不是。又有人说了,量化软件都提供tick行情了,谁还用这个方案?那只能说谁用谁知道。每个tick都在线获取数据,那网络开销,CPU开销,估计跑上几个策略就把电脑累趴了。所以提前缓存到本地才是王道!而本地,只有内存数据库速度才是No1!
这版个人版的极速解决方案,我也是探索了很长时间。希望对大家有帮助!
边栏推荐
- 3DS MAX 批量导出文件脚本 MAXScript 带界面
- 燃炸!字节跳动成功上岸,只因刷爆LeetCode算法面试题
- 【数字IC验证进阶】SoC系统验证和IP模块验证的区别及侧重点分析
- Fragment-hide和show
- 想通这点,治好 AI 打工人的精神内耗
- Nanodlp v2.2/v3.0 light curing circuit board, connection method of mechanical switch/photoelectric switch/proximity switch and system state level setting
- 2022-08-09:以下go语言代码输出什么?A:否,会 panic;B:是,能正确运行;C:不清楚,看投票结果。 package main import ( “fmt“ “syn
- 用低代码驱动IT现代化
- M²BEV: Multi-Camera Joint 3D Detection and Segmentation with Unified Bird’s-Eye View Representation
- Fragment's show and hide
猜你喜欢
mSystems | Zhongnong Wang Jie Group Reveals the Mechanisms Affecting Soil "Plastic Interstitial" Microbial Communities
Solution for "Certificate not valid for requested usage" after Digicert EV certificate signing
MySQL面试题整理
Efficient and Robust 2D-to-BEV Representation Learning via Geometry-guided Kernel Transformer Paper Notes
【学习笔记】Redis的持久化
交换机的基础知识
浙大、阿里提出DictBERT,字典描述知识增强的预训练语言模型
LeetCode medium topic search of two-dimensional matrix
Prada, big show?In the yuan in the universe that!
Shell:数组
随机推荐
Fragment-hide和show
Twikoo腾讯云函数部署转移到私有部署
NodeJs原理 - Stream(二)
ArcMAP出现-15的问题无法访问[Provide your license server administrator with the following information:Err-15]
AtCoder Beginner Contest 077 D - Small Multiple
M²BEV: Multi-Camera Joint 3D Detection and Segmentation with Unified Bird’s-Eye View Representation
专有云ABC Stack,真正的实力派!
Nanodlp v2.2/v3.0光固化电路板,机械开关/光电开关/接近开关的接法和系统状态电平设置
Guidelines for Sending Overseas Mail (2)
11 + chrome advanced debugging skills, learn to direct efficiency increases by 666%
Efficient and Robust 2D-to-BEV Representation Learning via Geometry-guided Kernel Transformer 论文笔记
商汤自研机械臂,首款产品是AI下棋机器人:还请郭晶晶作代言
How to describe multiple paragraphs with different font settings in Open Office XML format
mSystems | Zhongnong Wang Jie Group Reveals the Mechanisms Affecting Soil "Plastic Interstitial" Microbial Communities
Nanodlp v2.2/v3.0 light curing circuit board, connection method of mechanical switch/photoelectric switch/proximity switch and system state level setting
Redis上云迁移实践
关于flask中static_folder 和 static_url_path参数理解
odps sql 不支持 unsupported feature CREATE TEMPORARY
AtCoder初学者比赛077 D -小多
Polygon zkEVM工具——PIL和CIRCOM