【量化交易行情不够快?】一文搞定通过Win10 wsl2 +Ubuntu+redis+pickle实现股票行情极速读写(Win11+Ubuntu 22.04也适用)

本文主要是介绍【量化交易行情不够快?】一文搞定通过Win10 wsl2 +Ubuntu+redis+pickle实现股票行情极速读写(Win11+Ubuntu 22.04也适用),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一文搞定通过Win10 wsl2 +Ubuntu+redis+pickle实现股票行情极速读写

  • 前言
  • 一、准备环境分四步
    • 1.1 给Win10装wsl2
      • 硬件开启虚拟化
      • 软件开启虚拟化及安装适用于Linux系统的Windows 子系统
    • 1.2 在wsl2基础上安装Ubuntu
    • 1.3 给Ubuntu安装redis
    • 1.4 设置Win10开机后自动启动wsl2的Ubuntu
  • 二、利用Python操作redis读写行情数据
    • 2.1 环境准备(下载和安装第三方包)
    • 2.2 爬取行情数据写入redis,并进行读出和删除
    • 2.3 开机启动Python脚本
  • 总结


前言

量化交易,行情先行!

对于量化交易,行情数据很重要,可以说很关键。个人做量化,因为网络时延、本地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 设置为默认版本。打开 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.gpgecho "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.listsudo apt-get update
sudo apt-get install redis

安装完毕,将redis作为服务启动

sudo service redis-server start

执行redis-cli,输入ping,回复PONG,即标识redis正常运行。

uid@xxx:~$ redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379>

redis的命令操作,各位可以百度搜索先熟悉一下简单操作。不想学也没关系,后面用Python代码进行程序操作。

1.4 设置Win10开机后自动启动wsl2的Ubuntu

  1. 进入Ubuntu环境,输入以下命令创建init.wsl文件。这里需要输入刚才设置的密码。命令前加sudo即使用root管理员权限执行命令。
sudo nano /etc/init.wsl
  1. 将 sudo service redis-server start 粘贴到文件内
    在这里插入图片描述
    按Ctrl+x,按Y确认,回车退出即可。

  2. 赋予文件可执行权限,这步很关键,否则会提示“Permission denied”。

sudo chmod +x /etc/init.wsl
  1. 进入Windows环境,键盘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-20.04,还是Ubuntu-22.04,使用如下命令即可查看

(base) C:\Users\Administrator>wslconfig /list
适用于 Linux 的 Windows 子系统分发版:
Ubuntu-20.04 (默认)

做完以上操作,电脑重启后,会自动启动Ubuntu,并自动加载redis服务。

小结:至此,方案中先给Win10装wsl2,再在wsl2上装Ubuntu,再在Ubuntu上装redis,再让redis自动启动的步骤就算完成了。下面是Python的事儿了。


二、利用Python操作redis读写行情数据

2.1 环境准备(下载和安装第三方包)

文中数据格式都是pandas的DataFrame,建议安装Anaconda,提前准备好环境。

下面代码使用到redis和pickle两个库,redis安装命令如下,pickle在python里已自带:

pip install redis

另,本例子中采集行情数据用到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,并进行读取和删除。
注意:本文仅为演示,实操应用代码比较长,恕无法全部展示。
'''# 使用本文代码,需要提前安装redis包,并提前下载Ashare包
# pip install redisimport 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:# 提取行情并写入redisdf=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        volume2018-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        volume2018-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历史行情结合当日行情,合成生成5只股票代码当日实时日K数据并计算指标耗时: 0.3719971179962158 秒(这个神了,速度杠杠滴!)。

有人怀疑这个速度?哈哈,因为我用的行情不是文中举例的那个,其它几个也不是。又有人说了,量化软件都提供tick行情了,谁还用这个方案?那只能说谁用谁知道。每个tick都在线获取数据,那网络开销,CPU开销,估计跑上几个策略就把电脑累趴了。所以提前缓存到本地才是王道!而本地,只有内存数据库速度才是No1!

这版个人版的极速解决方案,我也是探索了很长时间。希望对大家有帮助!

笔者后来在Win11系统上安装Ubuntu 22.04版本,以上方法依然有效。

这篇关于【量化交易行情不够快?】一文搞定通过Win10 wsl2 +Ubuntu+redis+pickle实现股票行情极速读写(Win11+Ubuntu 22.04也适用)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/705358

相关文章

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

MySQL双主搭建+keepalived高可用的实现

《MySQL双主搭建+keepalived高可用的实现》本文主要介绍了MySQL双主搭建+keepalived高可用的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、测试环境准备二、主从搭建1.创建复制用户2.创建复制关系3.开启复制,确认复制是否成功4.同

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("

使用Sentinel自定义返回和实现区分来源方式

《使用Sentinel自定义返回和实现区分来源方式》:本文主要介绍使用Sentinel自定义返回和实现区分来源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Sentinel自定义返回和实现区分来源1. 自定义错误返回2. 实现区分来源总结Sentinel自定

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义

opencv图像处理之指纹验证的实现

《opencv图像处理之指纹验证的实现》本文主要介绍了opencv图像处理之指纹验证的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录一、简介二、具体案例实现1. 图像显示函数2. 指纹验证函数3. 主函数4、运行结果三、总结一、