Python进阶量化交易专栏场外篇7- 装饰器计算代码时间
欢迎大家订阅《教你用 Python 进阶量化交易》专栏!为了能够提供给大家更轻松的学习过程,笔者在专栏内容之外已陆续推出一些手记来辅助同学们学习本专栏内容,目前已推出如下扩展篇:
在第一篇《管理概率==理性交易》中笔者结合一个简单的市场模型介绍了为什么在没有概率优势的前提下参与交易会亏钱,其实股票交易和玩一个游戏、做一个项目理念是相通的,需要章法、需要制定策略,否则就和抛硬币赌博一样一样的,用量化交易可以帮助我们管理好概率,更理性的去下单。
在第二篇《线性回归拟合股价沉浮》中笔者在专栏《股票交易策略开发:走势线性回归选股策略》小节的基础上对线性回归方法的策略应用做进一步的扩展介绍。由于线性回归作用于股票收盘价的整个周期,前后两段完全相反的周期会彼此作用,最终影响拟合的角度值,于是笔者设定窗口期用移动窗口的方式拟合股价的走势,寻找角度曲线的拐点以预示新一轮的反转走势,给大家提供一个衍生的策略思路。
在第三篇《最大回撤评价策略风险》中笔者在专栏
《股票交易数据可视化:买卖区间下策略收益绘制》的基础上对策略的最大回撤指标做一定的扩展介绍。投资是有风险的,那么如何去衡量这个风险呢?最大回撤率就是一种直观的将风险切实量化的指标,它描述了买入股票后,在策略出现最糟糕的情况下会损失多少钱,这也直接关系到了风险策略中止损因子的设定。
在第四篇《寻找最优化策略参数》中笔者在专栏
《股票交易策略开发:趋势突破择时策略》的基础上对寻找最优化策略参数的方法做一些扩展介绍。对于寻找最优化参数的方法可以选择枚举法或者蒙特卡洛法。枚举法适用于解决效率要求不高,样本规模小的问题。蒙特卡洛法得到的结果并不一定是最优的,但是在大规模样品的场合下可以更快地找到近似最优结果。
在第五篇《标记A股市场涨跌周期》中笔者在专栏
《股票交易数据的自动下载》的基础上对matplotlib绘图工具的使用方法做一些扩展介绍,在A股历史走势图中标记出市场涨跌周期。
在第六篇《Tushare Pro接口介绍》中笔者在《股票交易数据的自动下载》的基础上扩展介绍使用Tushare Pro版本获取财经和股票交易数据的方法。
本次场外篇笔者在《用装饰器注册股票池》的基础上对装饰器的进行扩展介绍,通过装饰器方式实现timeit测试函数执行时间功能。
当我们对一个函数或若干语句的执行时间要求较高时,希望能够测试得到该代码的开销时间是多少。比如遍历计算每个交易日股票数据的价格波动,如下所示:
df_sh['diff_price'] = df_sh.apply(lambda row: (row['high']-row['low']), axis =1)
"""
date open close ... volume code diff_price
0 2018-01-02 3314.03 3348.33 ... 202278860.0 sh 35.02
1 2018-01-03 3347.74 3369.11 ... 213836149.0 sh 34.63
2 2018-01-04 3371.00 3385.71 ... 206955288.0 sh 27.53
3 2018-01-05 3386.46 3391.75 ... 213060681.0 sh 21.82
4 2018-01-08 3391.55 3409.48 ... 236165106.0 sh 28.17
"""
最先想到的是采用Python内置time模块来测试代码运行时间,使用时导入模块,如下所示:
import time
其中time.perf_counter()和time.process_time() 可以实现我们的需求。
time.perf_counter():返回计时器的精准时间(系统的运行时间),包含整个系统的睡眠时间。由于返回值的基准点是未定义的,所以,只有连续调用的结果之间的差才是有效的。
time.process_time() :返回当前进程执行 CPU 的时间总和,不包含睡眠时间。由于返回值的基准点是未定义的,所以,只有连续调用的结果之间的差才是有效的。
此处使用time.perf_counter()方法实现,如下所示:
start = time.perf_counter()
#运行的程序
df_sh['diff_price'] = df_sh.apply(lambda row: (row['high']-row['low']), axis =1)
#运行的程序
elapsed = (time.perf_counter() - start)
print("Time used:",elapsed)
# Time used: 0.00546605699999958
另外可以使用Python更强大的计时库timeit测试执行时间,使用时导入timeit,如下所示:
from timeit import timeit
用timeit()测试一个函数的执行时间可按timeit(函数名_字符串,运行环境_字符串,number=运行次数)这个方式来实现,如下所示:
elapsed = timeit('func()', 'from __main__ import func', number=1)
print("Time used:",elapsed)
#Time used: 0.005263746999999985
由于电脑永远都有其他程序也在占用着资源,因此我们的程序不可能最高效地执行该函数。所以一般会进行多次试验,取最少的执行时间为真正的执行时间。此时可以使用repeat方法,使用时需要导入repeat ,如下所示:
from timeit import repeat
使用repeat方法和timeit用法相似,多了一个repeat参数,表示重复测试的次数(默认值为3),返回值为一个时间的列表,如下所示:
t_elapsed = repeat('func()', 'from __main__ import func', number=1, repeat=5)
print("Time used:",t_elapsed)
print("Time of min used:",min(t_elapsed))
#Time used: [0.005254602999999136, 0.005191876999999678, 0.00529747400000069, 0.005051099999999309, 0.005246075000000516]
#Time of min used: 0.005051099999999309
回到本篇的主题内容——装饰器,装饰器顾名思义就是“装饰”其他函数,为其他函数添加附加功能,原则上不能修改被装饰的函数的代码,也不能修改被装饰的函数的调用方式,这也是装饰器“厉害”的地方。
以上无论使用time,还是timeit,都需要对被测函数添加实现的代码,那么尝试使用装饰器来解决这个痛点,如下所示:
def timeit(func):
def wrapper(*args, **kwargs):
start = time.perf_counter()
func(*args, **kwargs)
elapsed = (time.perf_counter() - start)
print("Time used: %s ", elapsed)
return wrapper
@timeit
def func_diff():
df_sh['diff_price'] = df_sh.apply(lambda row: (row['high']-row['low']), axis =1)
# timeit(func_diff)()
func_diff()#Time used: %s 0.005055395000000074
关于装饰器的基础原理介绍,大家可以参阅专栏中的讲解,此处再次提炼下其关键点。执行func_diff()等价于执行timeit(func_diff)(),把函数作为一个变量传递给timeit函数, 此处timeit为二层嵌套的高阶函数。电动叉车
假如要像timeit模块那样有repeat、number参数扩展测试的需求,可以再进一步升级下装饰器,如下所示:
# use decorator method with parameter
def timer_para(number = 3, repeat = 3):
def decorator(func):
def wrapper(*args, **kwargs):
for i in range(repeat):
start = time.perf_counter()
for _ in range(number):
func(*args, **kwargs)
elapsed = (time.perf_counter() - start)
print("Time of %s used: %s ", i, elapsed)
return wrapper
return decorator
@timer_para(number = 2, repeat = 2)
def func_diff_par():
df_sh['diff_price'] = df_sh.apply(lambda row: (row['high']-row['low']), axis =1)
# timer_para(number = 2, repeat = 2)(func_diff_par)()
func_diff_par()
#Time of %s used: %s 0 0.01577713199999997
#Time of %s used: %s 1 0.015201944999999939
执行func_diff_par ()等价于执行timer_para(number = 2)(func_diff_par)(),此处timeit为三层嵌套的高阶函数,第1层是timer_para(number = 2),返回第2层decorator函数,第2层函数decorator接受func_diff_par函数作为参数进行调用,返回第三层函数wrapper。如此一来只需要使用@xxxx就可以一劳永逸地对所有函数测试执行时间了!!!
Python进阶量化交易专栏场外篇7- 装饰器计算代码时间的更多相关文章
- Python进阶量化交易场外篇5——标记A股市场涨跌周期
新年伊始,很荣幸笔者的<教你用 Python 进阶量化交易>专栏在慕课专栏板块上线了,欢迎大家订阅!为了能够提供给大家更轻松的学习过程,笔者在专栏内容之外会陆续推出一些手记来辅助同学们学习 ...
- Python进阶量化交易场外篇4——寻找最优化策略参数
新年伊始,很荣幸笔者的<教你用 Python 进阶量化交易>专栏在慕课专栏板块上线了,欢迎大家订阅!为了能够提供给大家更轻松的学习过程,笔者在专栏内容之外会陆续推出一些手记来辅助同学们学习 ...
- Python进阶量化交易场外篇3——最大回撤评价策略风险
新年伊始,很荣幸笔者的<教你用 Python 进阶量化交易>专栏在慕课专栏板块上线了,欢迎大家订阅!为了能够提供给大家更轻松的学习过程,笔者在专栏内容之外会陆续推出一些手记来辅助同学们学习 ...
- Python开发【第十四篇】装饰器
装饰器 什么是装饰器? 装饰器是一个函数,主要作用是用来给包装另一个函数或者类 包装的目的是不改变原函数名(或类名)的情况下改变或添加被包装对象的功能 函数装饰器 是指装饰器是一个函数,传入的是一 ...
- Noah的学习笔记之Python篇:装饰器
Noah的学习笔记之Python篇: 1.装饰器 2.函数“可变长参数” 3.命令行解析 注:本文全原创,作者:Noah Zhang (http://www.cnblogs.com/noahzn/) ...
- 使用python装饰器计算函数运行时间的实例
使用python装饰器计算函数运行时间的实例 装饰器在python里面有很重要的作用, 如果能够熟练使用,将会大大的提高工作效率 今天就来见识一下 python 装饰器,到底是怎么工作的. 本文主要是 ...
- python语法生成器、迭代器、闭包、装饰器总结
1.生成器 生成器的创建方法: (1)通过列表生成式创建 可以通过将列表生成式的[]改成() eg: # 列表生成式 L = [ x*2 for x in range(5)] # L = [0, 2, ...
- Python自动化面试必备 之 你真明白装饰器么?
Python自动化面试必备 之 你真明白装饰器么? 装饰器是程序开发中经常会用到的一个功能,用好了装饰器,开发效率如虎添翼,所以这也是Python面试中必问的问题,但对于好多小白来讲,这个功能 有点绕 ...
- python中“生成器”、“迭代器”、“闭包”、“装饰器”的深入理解
python中"生成器"."迭代器"."闭包"."装饰器"的深入理解 一.生成器 1.生成器定义:在python中,一边 ...
随机推荐
- Ubuntu关闭(重启)网络服务命令
Ubuntu关闭网络服务命令: service network-manager stop 重启网络服务命令: service network-manager restart
- k-vim安装及The ycmd server SHUT DOWN (restart with ':YcmRestartServer')这种错误的解决方法
vim配置 下载地址:https://github.com/wklken/k-vim 安装步骤: 1. clone 到本地 git clone https://github.com/wklken/k- ...
- Kubernetes 核心概念
什么是Kubernetes? Kubernetes(k8s)是自动化容器操作的开源平台,这些操作包括部署,调度和节点集群间扩展.如果你曾经用过Docker容器技术部署容器,那么可以将Docker看成K ...
- 在同一个服务器(同一个IP)为不同域名绑定的免费SSL证书
越来越多的浏览器不在支持http协议了,这就要求你为你的网站必须绑定SSL证书.谷歌浏览器也将要在今年取消对http协议的支持,申请CA证书迫在眉睫.我购买有两个域名,一个虚拟机,没事鼓捣鼓捣,图个乐 ...
- jQuery插件slider实现图片轮播
1:引入相应的js文件 jquery.SuperSilder.js 2:HTML: 结构 注:此地加载图片的代码也可以从后台库中读取图片的集合列表,然后通过循环的方式显示出来 3:CSS 样式定义左 ...
- centos 上安装phpstorm
phpstorm在centos上运行依赖JDK,所以先安装JDK环境. 假如是centos自带的openjdk,直接卸载,不支持phpstorm. 下载jdk-7u45-linux-i586.tar. ...
- [NOIP 2015]运输计划-[树上差分+二分答案]-解题报告
[NOIP 2015]运输计划 题面: A[NOIP2015 Day2]运输计划 时间限制 : 20000 MS 空间限制 : 262144 KB 问题描述 公元 2044 年,人类进入了宇宙纪元. ...
- 使用k8s cronjob ,清除应用生成的日志文件
目前应用日志,tomcat日志 统一输出到 /data/logs/pod名字/ 目录下,并且/data/logs 目录挂载到cephfs上, tomcat 日志使用 cronolog进行日志切割 使用 ...
- 使用python制作时间戳转换工具
使用python制作时间戳转换工具 python 时间戳转日期 日期转时间戳 前言:作为一个程序员一般情况下,json和时间戳是常用的两个工具,我咨询过很多个朋友,他们一般都是通过在线工具对json进 ...
- 转 一个web项目web.xml的配置中<context-param>配置作用
一个web项目web.xml的配置中<context-param>配置作用 <context-param>的作用:web.xml的配置中<context-param& ...