购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.2 进阶提高

1.2.1 批处理中切换到虚拟环境

需要每天定时执行脚本的读者通常会遇到此问题。直接运行Python实际使用的是base环境,需要提前切换环境。例如,创建 demo1.bat 文件,内容如下:

img

它会切换到 py38环境,然后执行demo.py,最后到pause暂停,等待用户单击任意键退出。注意:在Windows的计划任务中千万不要使用pause或其他等待用户输入或运行时间长的指令,否则当前控制台没有退出,计划任务不会触发第二次。

可以由另一脚本(demo2.bat)触发此脚本(demo1.bat)规避。例如:

img

1.2.2 GitHub仓库包的安装

使用pip install git+https://github.com/xx/xx.git 可能实在太慢,因为git同步的是整个仓库包括历史提交,下载zip文件安装反而更快。当然还有另一种方案,那就是使用国内的gitee拉取GitHub项目,然后执行pip install git+https://gitee.com/xx/xx.git。

1.2.3 包的引入

平时常用的import xx等能导入是因为在sys.path所指的路径下存在。这个路径分别有当前目录、site-packages等。

如果包没有安装在site-packages下,可以手工将它添加到sys.path中,也能被搜索到:

img

但这种方法只是运行时正常,在PyCharm中将显示警告,自动完成功能也会失效。可在site-packages下创建xx.pth文本文件,内容为包所在路径,PyCharm能提前识别包就能使用自动完成功能。例如,Cython编译的自定义包就推荐使用.pth文件引入。

通常使用import xx或from xx import yy引入,但遇到以下情况就需要变通了:

(1)源代码中没有直接使用包,但通过eval('xx.yy') 等方式动态地使用了某包。可能不小心在IDE中调用了移除未使用的引入功能。

(2)需要动态地引入各种包。

(3)包名不是标准的标识符,如以数字开头的文件123_abc.py,可以使用以下方法引入。

img

1.2.4 在线平台引入自定义包

随着聚宽、米筐这类在线平台的火爆,一些问题也浮出水面:如何自己安装包?如何使用自定义包?

(1)安装到自己的用户下。在Notebook中执行下列语句:

img

(2)在策略环境中使用研究环境中的自定义包。利用 sys.path 支持zip文件的特性:

img

1.2.5 pd.read_csv编码

文件内出现中文时,编码方式可能需要进行指定,中文常用编码有gbk、utf-8、utf-8-sig等。而utf-8-sig编码在文件开头有3字节的BOM头(EF BB BF),BOM头是Windows中的习惯。

Excel只能正确解析gbk和utf-8-sig编码的中文,utf-8中文会显示乱码,而金山WPS三种编码都能正常显示,建议保存时都用utf-8。

read_csv如果报错、出现格式错误,可以用各格式替换一下。engine='c' 与engine='python' 对中文的默认编码不同,建议指定encoding。

1.2.6 pd.read_csv中文路径

在Windows下,可能会遇到中文路径无法读取的问题。有多种解决方案:

(1)修改中文路径为英文路径。不光文件名,文件夹也不能用中文,或使用相对路径回避中文文件夹。

(2)使用open提前打开文件,即pd.read_csv(open('中文文件名.csv')。

(3)使用engine参数,Python引擎会慢一些,如pd.read_csv('中文文件名.csv',engine='python')。

(4)升级Pandas版本。

(5)将文件系统编码由utf-8设置成mbcs。

img

pd.read_hdf目前只能通过sys._enablelegacywindowsfsencoding() 来支持中文路径。

1.2.7 pd.read_csv示例

加载数据是数据分析的第一步,如果能灵活使用read_csv的参数,则可以大大简化代码。

在ipython环境下,可以使用问号(?)查看帮助,使用两个问号(??)查看源代码。通常问号加在后面即pd.read_csv?,也可以写在前面即?pd.read_csv。在某些情况下写在后面不生效,可以试着写在前面。探索变量还可以使用dir()、vars()、type()。

img

输出如下:

img

1.2.8 pd.read_csv高级玩法

在线平台一般可以通过 !cat demo.py直接显示代码,就算部分平台做了限制,灵活应用各种工具还是能将源代码显示出来。

img

1.2.9 pickle技巧

直接读/写pickle文件比较大,可以压缩一下,compression支持“gzip”“bz2”“zip”“xz”四种压缩算法。

可以写成以下形式:

img

但更推荐使用文件扩展名进行自动推导,这样更方便:

img

其实to_csv/read_csv也有compression参数,用法完全一样:

img

1.2.10 MultiIndex多重索引的切片

进行切片时按以下规则更易理解。

(1)df.loc[行,列],先行后列。

(2)多重索引看成tuple组成的list,切片要用tuple。

(3)tuple中无法使用冒号(:),可用slice(None)代替。

loc不是函数,而是对象。函数不能使用中括号[],对象可以使用__getitem__实现中括号的功能。

此处补充说明,本章代码部分穿插的图表,皆由运行代码后直接输出,故不做额外说明,也不进行编号。

img

复杂演示:

img
img
img
img

1.2.11 星期

不同API的定义不同:

(1)第一天是星期一还是星期日;

(2)第一天从数字0开始,还是从数字1开始。

两两组合共有4种情况。例如:QuantLib第一天是星期日,从数字1开始。所以针对不同的API,在没有提供星期枚举的情况下,一定要先测试,防止过滤星期时出错。

img
img

周还有特别的地方是跨年。一年的最后几天有可能归到第二年的第一周,一年的前几天也有可能归到前一年的最后一周。所以如果要按周进行groupby,不能直接用year*100+weekofyear,要用isocalendar() 下的year*100+week。resample(rule='WSUM') 已经正确处理了此问题。

img
img
img
img

1.2.12 魔术命令

魔术命令也是常用的功能。%表示单行命令,%%表示单元格命令。常用的命令有 %time、%%timeit、%%prun、%matplotlib等,可以通过 %lsmagic查看支持的命令。

? 和 ?? 都可用于魔术命令,但只能放在命令前,如 ?%%!、??%%html。

1.2.13 隐藏Notebook代码区

利用强大的魔术命令,我们来演示如何隐藏代码区。利用Notebook本质也是网页,可以用JavaScript进行控制的特点,将所有的代码区隐藏起来。

以下代码使用了ipython的魔术命令 %%html、jQuery的 $ 选择器:

img
img

其实通过Notebook的扩展也可以实现隐藏代码区。安装好后,选择Hide input和Hide input all扩展:

img

1.2.14 完全屏蔽Jupter Notebook源代码

这里要利用一个Jupter Notebook部署成网页应用的工具——Voila,它与Jupter Notebook一样都是网页应用服务器,只是在打开时自动执行了Jupter Notebook的内容,默认情况下只显示Out区,同时还支持ipywidgets交互控件。用它向客户提供网页展示极为便捷。

安装代码如下:

img

应用如下:

img

1.2.15 Python源代码保护

当前阶段难以破解的源代码保护方案之一是Cython。原理是,将 .py编译为 .c文件,再将 .c文件编译为 .so或者 .pyd。Cython更重要的特性是加速,缺点是针对不同的操作系统和不同的Python版本需要分别编译。

安装代码如下:

img

准备setup.py:

img

编译成 .pyd或 .so:

img

部署分发时,只复制demo.pyd或demo.so即可,复制到site-packages下,或将 .pth复制到此目录,PyCharm自动完成就正常了。

1.2.16 Python加速

(1)前面提到的Cython加速是一种方案,但编译成 .so后部署不便,想更快还是要翻译成 .pyx。需要一定的C语言功底。

(2)numba加速使用简单,只要在函数中加上 @jit或 @njit装饰器即可。但不支持class、推导式等。

(3)Pandas代码改成numpy,也能大大提速。但Pandas切片太慢,不要在循环中使用。

(4)使用多进程。

1.2.17 多进程

由于GIL的原因,Python的多线程并不能多核并行,所以Python并行一般是用多进程技术。以下演示了多进程、多参数、进度条:

img
img

1.2.18 绘图内存泄露问题

大规模计算时常常发现内存不够,无论怎样优化内存还是占用过高。测试后发现只要图片保存内存就涨了无法释放。后来发现一定要再调用一下fig.clf():

img

1.2.19 ipynb转html

之前我们学习的Notebook都是手工执行,手工转成静态报表。遇到大批量的任务时,就需要自动执行了。此时使用多个文件配合。

(1)demo.ipynb:Notebook报表模板。需要从外部传入参数,这里用环境变量来传递,并将结果保存起来。

(2)demo.py:多进程任务。读取任务列表后构造命令,并用多进程的方式触发。

(3)all.py:将生成的多个结果予以合并。

以下只展示核心部分:

img
img

上述代码主要利用了jupyter nbconvert进行转换。

• ExecutePreprocessor.timeout:大项目运行时间可能很长,但jupyter nbconvert默认超时30s,需要指定,以防止报错。

• ExecutePreprocessor.allow_errors:遇到错误后不中断,继续运行。

• execute:全文执行。

• to html:转换格式为html。

• output demo.html:指定输出文件名。

1.2.20 TA-Lib中的EMA计算

TA-Lib中的EMA算法与国内的股票软件算法不一样,可通过set_compatibility进行设置(注:TA-Lib 0.4.18版才开始有的功能):

img
img

输出如下:

img

(1)CLASSIC算法。EMA第一个有效值是前 N 个数据的平均值:

img

(2)METASTOCK算法。EMA第一个值是数据第一个值,然后迭代算出之后的值。只是显示时 N -1个值都设为了NaN:

img

MACD、STOCH内部都调用了EMA,另外CMO、RSI也受set_compatibility的影响。

1.2.21 绩效指标计算

绩效指标如夏普、最大回撤等,有工具可以直接得到结果,只要提供一条曲线即可。常用的库有ffn和empyrical。这里演示一下ffn:

img
img
img
img
img

ffn已经默认注册到了pd.DataFrame上,可以直接使用。例如:df.calc_calmar_ratio()。

dir(ffn)用于查看可用的方法。需要注意输入参数是returns还是prices,例如:ffn.calc_sharpe? 的输入参数是returns,而ffn.calc_max_drawdown? 的输入参数是prices。

1.2.22 动态图表

动态图表特别适合用于研究分析。比如支持缩放、支持显示隐藏线条、支持鼠标悬浮显示。常用的动态图表有pyecharts、bokeh、plotly。对于研究人员来说,plotly使用起来更简单,因为Pandas 1.0版后支持backend功能。

img

因为底层调用的是完全不同的对象,所以两种backend代码并不是完全兼容的。主要区别如下: 409WiSwhZWY+7P98fCIXN1xIPGrDo3gX03Vghc+Xoq/Qq282jz73kyIjgg9w390L

img
点击中间区域
呼出菜单
上一章
目录
下一章
×