调试zipline相关包
- 有些包是需要赛博穿越万里长城才能下载的,记得提前开好clash,zipline也是这类包之一;
- zipline很早就不再对该项目进行维护,因此“ pip install zipline ”是无效的只能手动操作(报错如下图);
- 安装之前需要使用“ import os ”和“ os.path ”确定一下应该到哪个路径下把下载好的包复粘过去,不然python那么多,真的有可能装错地方还一直跟报错鏖战。
平滑操作的Ubuntu指令
因为没有对根目录的一些位置开放修改权限,直接在文件夹使用光标移动是没办法执行的,只能使用命令行操作,接连遇到几个坑,比如直接用“ cp -f +路径1 +路径2 ”命令会返回报错,其实是因为缺少权限,并且移动的是文件夹所以得用“ -r ”命令。在这之前最好对之后要安装的文件或文件夹“target_package”进行命名规范,比如把“ - ”换成“ _ ”之类的,避免后续出问题。
'''先切入到文件夹所在的目录下,这里target_package就在“小黑子系统”这个目录下'''
cd /home/cxk/小黑子系统
'''因为复制过去的是 “一个文件夹”,所以要用 -r 命令'''
sudo cp -r target_package /lib/python3.10
'''记得给这个文件(包括文件夹下的所有内容)加入权限,不然啥也干不了,import时会锁死'''
#sudo chmod +x /lib/python3.10/target_package 这个命令好像没啥用
cd /lib/python3.10
sudo chmod -R 777 target_package
直接在python环境中调用这个包的子包会告诉你没有该子包,这个错误的原因就是这个包在文件夹UI界面下是上了锁的(有一个红色“叉叉”),需要执行如上的代码加入权限,避免锁死:
具体一些的模块(module)使用规范请参考文章「python 中的import、模块和包」,
不过就算完成了上述的平滑操作,还是一堆bug,一方面是python的架构发生了变化,比如print函数的调用方式( "print xxx" -> "print( xxx )" )等,造成了代码不规范的报错,另一方面是包自身有一些缺陷,不是少了这个就是丢了那个,因此给相应的文件添加完权限以后,还是会报错:这里自查了一下,确实没有“ logbook ”文件。
改弦更张:聚宽平台
需要使用一段时间去适应这个平台上研究环境和回测环境的交互方式,以及整一套策略执行的「因子构建」、「下单流程」、「回测流程」 。
对于聚宽文档提供的新手入门中,还暂时不涉及多因子等框架,因此入门示例仅介绍了“应该在哪个界面直接进行策略模拟 ”,因此这部分还不需要使用其“ 研究环境 (Jupyter Notebook) ”,参考聚宽新手指引的文章「量化交易策略基本框架」。
回测环境/模拟:
研究环境:
聚宽的“ g ”和“ context ”对象
首先需要理解它们工作的模式,在「聚宽文档-对象」中可以见到官方对它们的定义,标准的解释是“内部存储着被序列化信息的载体”,
序列化的目的:参考文章「序列化含义/如何实现(反)序列化/序列化的应用」
- 序列化最终的目的是为了对象可以跨平台存储,和进行网络传输 (也可以在分布式应用系统中传递数据)
- 也可以是将对象以二进制字节序列的方式存储在硬盘上。
类似的使用方式其实在调用statsmodels包里的OLS函数以及sklearn包里的相关模型时见到过:
附注:文档中对“ g ”的标准文字解释
全局对象 g (或context) 用来存储用户的各类可被pickle.dumps函数序列化的全局数据。在模拟盘中,如果中途进程中断,我们会使用[pickle.dumps]序列化所有的g下面的变量内容, 保存到磁盘中,再启动的时候模拟盘就不会有任何数据影响。如果没有用g声明,会出现模拟盘重启后,变量数据丢失的问题。
如果不想 g 中的某个变量被序列化, 可以让变量以 '__' 开头, 这时它在序列化时就会被忽略。
附注:文档中对“ context ”属性初始模板进行刻画的图片解释
这两个对象在官方的说法里基本是等价的,只不过context是出于方便用户把策略从旧有的聚宽版本迁移过来而设立的g的替代品,另外“ log.info( g.xxx ) ”函数的功能跟print函数完全一样,在“回测环境/模拟”中打印context返回的是对象的地址信息,另外context对象不能用运算符“ () ”进行调用,会返回报错“TypeError: 'StrategyContext' object is not callable”。
研究环境(Jupyter Notebook):因子测试
另外根据目前的研究环境版本,其内部载入的一些包跟官方指引中的写法有差异,比如这篇官方指引文档里「聚宽技术支持:从单因子到策略」,Jupyter Notebook部分的代码里为了得到因子统计特性的回测报告,导入了“ jqdatasdk包中的technical_analysis函数 ”,而这是一个氪金功能...参见文档「JQData本地量化数据说明书」。
- 破解尝试一:修改jqdatasdk.client.py中的JQDataClient(object)函数,也即规避向聚宽的端口发送请求,需要了解自己的端口,参考文章「4种方法来在Linux系统中查看IP地址」,其中最好的命令还是“ hostname -I ”。
这种修改会使得上图中的try和except部分同时报错,从而造成实际的报错,因为没有jqdata包就算了(氪金可得),jqdatasdk也是要氪金以后才能有认证从而在后续过程中不报错的(氪金者的双重保险罢了)。
观察上图的报错返回,通过最下面的一块报错信息可知错误出现在调用“ JQDataClient() ”这个函数上,这很明显就是聚宽要实现令用户氪金使用其回测模板的核心代码了,因此首先想办法破解这块端口,连接到本地端口,因此反查JQDataClient函数的封装文件所在路径( from .client import JQDataClient:也就是上一级路径jqdatasdk文件夹下的client.py文件 ),找到函数定义位置并尝试修改。结果还是不行,只能说这个破解逻辑太简单了。
- 破解尝试二:根据最下面一块报错信息,在utils中修改调用JQDataClient函数的代码。
修改完成后报错变为上图内容,这说明不止一处使用了“ JQDataClient.instance() ”这个函数属性对象,并且很多地方都有对象勾稽关系,如果不知道该对象的具体构造,简单写个while True也是白搭(不然就可以根据一个具体构造全造True例就扎不多徳勒)。
附注:" **local() "参数的一点注释说明
'''如果是两个星号,它表示的方法如下:''' test(**kwargs)** '''此时,两个星号的作用就是把我们字典当中的kwargs作为一个关键字参数进行传递,像上面的代码,假设我们使用的kwargs值为:''' {‘A’:1,‘B’:2,‘C’:3} '''这个代码就和下面的这段代码是实现功能相等:''' test(A=1,B=2,C=3)
身为一个强迫症,还是觉得要加个下划线,顺便记录一下用了近三天时间写成本文的新路历程。也算正式开学了,希望这个学期可以兼顾实习面试等琐碎和自我提升的学习,同学推荐了一个更简单的小平台「海矿网」,毕竟还是naive了些。
另外这两天看到了cq老总2010、2011年个人自制投研策略然后2013年单飞的小故事,还看到了姚总挂在论文库跟xk老师做的毕业论文(大佬的菜鸡态嘻嘻),大概感觉还是世事纷杂,但“不积珪步,无以致千里”不改其理,继续浪并快乐着地努力吧。