欢迎大家订阅《教你用 Python 进阶量化交易》专栏!为了能够提供给大家更轻松的学习过程,笔者在专栏内容之外已陆续推出一些手记来辅助同学们学习本专栏内容,目前已推出如下扩展篇:
在第一篇《管理概率==理性交易》中笔者结合一个简单的市场模型介绍了为什么在没有概率优势的前提下参与交易会亏钱,其实股票交易和玩一个游戏、做一个项目理念是相通的,需要章法、需要制定策略,否则就和抛硬币赌博一样一样的,用量化交易可以帮助我们管理好概率,更理性的去下单。
在第二篇《线性回归拟合股价沉浮》中笔者在专栏《股票交易策略开发:走势线性回归选股策略》小节的基础上对线性回归方法的策略应用做进一步的扩展介绍。由于线性回归作用于股票收盘价的整个周期,前后两段完全相反的周期会彼此作用,最终影响拟合的角度值,于是笔者设定窗口期用移动窗口的方式拟合股价的走势,寻找角度曲线的拐点以预示新一轮的反转走势,给大家提供一个衍生的策略思路。
在第三篇《最大回撤评价策略风险》中笔者在专栏
《股票交易数据可视化:买卖区间下策略收益绘制》的基础上对策略的最大回撤指标做一定的扩展介绍。投资是有风险的,那么如何去衡量这个风险呢?最大回撤率就是一种直观的将风险切实量化的指标,它描述了买入股票后,在策略出现最糟糕的情况下会损失多少钱,这也直接关系到了风险策略中止损因子的设定。
在第四篇《寻找最优化策略参数》中笔者在专栏
《股票交易策略开发:趋势突破择时策略》的基础上对寻找最优化策略参数的方法做一些扩展介绍。对于寻找最优化参数的方法可以选择枚举法或者蒙特卡洛法。枚举法适用于解决效率要求不高,样本规模小的问题。蒙特卡洛法得到的结果并不一定是最优的,但是在大规模样品的场合下可以更快地找到近似最优结果。
在第五篇《标记A股市场涨跌周期》中笔者在专栏
《股票交易数据的自动下载》的基础上对matplotlib绘图工具的使用方法做一些扩展介绍,在A股历史走势图中标记出市场涨跌周期。
在第六篇《Tushare Pro接口介绍》中笔者在《股票交易数据的自动下载》的基础上扩展介绍使用Tushare Pro版本获取财经和股票交易数据的方法。
在第七篇《装饰器计算代码时间》中笔者在《用装饰器注册股票池》的基础上对装饰器的进行扩展介绍,通过装饰器方式实现timeit测试函数执行时间功能。
在第八篇《矢量化计算KDJ指标》中笔者在《技术分析常用指标绘制》的基础上对KDJ指标的计算进行扩展介绍,由之前for…in循环遍历方式升级为矢量化方式,并且用自制的@timeit装饰器对比两种方式的效率。
为了将专栏中分散的知识点贯穿起来,笔者在专栏的末尾小节《制作自己的量化交易工具》中分享了早期制作的一个简易版量化交易小工具,希望大家能够通过调试代码的方式掌握相关的知识。由于此部分代码基于Python2.7.5版本编写,发现部分读者在移植到Python3.7x版本上遇到了问题,比如:
那么本次场外篇笔者介绍下如何在Python3.7版本上运行量化交易小工具。
首先建议大家安装Anaconda来管理Python环境,Anaconda具有跨平台、包管理、环境管理的特点,无论在平台兼容性还是库版本兼容性上都会更有保证。大家可以参考笔者在慕课网手记板块的文章《Python基础系列讲解-安装步骤》搭建开发环境。
接下来让我们一步一步将代码移植到与Python3.7x版本上。
(1)在Python2中print无需加括号(语法结构),在Python3中print为内置函数,必须加括号。
(2)提示ModuleNotFoundError: No module named ‘wx’,缺少wxpython库,可通过conda install wxpython或者pip install wxpython进行安装。其他库的安装也相同。不过conda在安装packages时下载的速度经常很慢,建议使用pip。
conda下载几次非常慢:
pip下载比较顺畅:
(3)提示ModuleNotFoundError: No module named ‘matplotlib.finance’。原因是从matplotlib 2.2.0版本开始,matplotlib.finance已经从matplotlib中剥离了,需要单独安装mpl_finance这个库(pip install mpl_finance)。相应的代码上作如下更改:
import mpl_finance as mpf #替换 import matplotlib.finance as mpf
(4)提示AttributeError: module ‘wx’ has no attribute ‘DatePickerCtrl’。当前与Python3.7x版本匹配的wxPython版本为4.0.4,日历控件DatePickerCtrl与旧版本存在差异,新版本中已经迁徙至wx.adv模块中。代码上作如下更改:
import wx.adv
#日历控件选择数据周期
#self.dpcEndTime = wx.DatePickerCtrl(self.ParaPanel, -1,style = wx.DP_DROPDOWN|wx.DP_SHOWCENTURY|wx.DP_ALLOWNONE)#结束时间
#self.dpcStartTime = wx.DatePickerCtrl(self.ParaPanel, -1,style = wx.DP_DROPDOWN|wx.DP_SHOWCENTURY|wx.DP_ALLOWNONE)#起始时间
self.dpcEndTime = wx.adv.DatePickerCtrl(self.ParaPanel, -1,style = wx.adv.DP_DROPDOWN|wx.adv.DP_SHOWCENTURY|wx.adv.DP_ALLOWNONE)#结束时间
self.dpcStartTime = wx.adv.DatePickerCtrl(self.ParaPanel, -1,style = wx.adv.DP_DROPDOWN|wx.adv.DP_SHOWCENTURY|wx.adv.DP_ALLOWNONE)#起始时间
(5)提示:DateTimeNow.SetYear(DateTimeNow.Year-1) TypeError: unsupported operand type(s) for -: ‘sip.enumtype’ and ‘int’。DateTimeNow.Year-1表示取上一年的年份,但在新版本中DateTimeNow.Year并非年份值,而是<class ‘wx._core.DateTime.Year’>对象。在新版本中年份属性为小写的year,相应的month、day等都为小写,代码上作如下更改:
#DateTimeNow.SetYear(DateTimeNow.Year-1)
DateTimeNow.SetYear(DateTimeNow.year - 1)
(5)与Python3.7x版本匹配的Pandas中求移动平均线的代码需要相应作出调整,如下所示:
在StockDataMod文件中:
#处理移动平均线
stockPro['Ma20'] = stockPro.Close.rolling(window=20).mean() #pd.rolling_mean(stockPro.Close,window=20)
stockPro['Ma60'] = stockPro.Close.rolling(window=60).mean() #pd.rolling_mean(stockPro.Close,window=60)
stockPro['Ma120'] = stockPro.Close.rolling(window=120).mean() #pd.rolling_mean(stockPro.Close,window=120)
在IndicatStrateMod文件中:
#stock_df['N1_High'] = pd.rolling_max(stock_df.High,window=N1)#计算最近N1个交易日最高价
stock_df['N1_High'] = stock_df.High.rolling(window=N1).max() #计算最近N1个交易日最高价
#expan_max = pd.expanding_max(stock_df.Close)
expan_max = stock_df.Close.expanding().max()
#stock_df['N2_Low'] = pd.rolling_min(stock_df.Low,window=N2)#计算最近N2个交易日最低价
stock_df['N2_Low'] = stock_df.Low.rolling(window=N2).min() # 计算最近N2个交易日最低价
#expan_min = pd.expanding_min(stock_df.Close)
expan_min = stock_df.Close.expanding().min()
(6)提示:AttributeError: module ‘mpl_finance’ has no attribute ‘candlestick’。可参考《技术分析常用指标绘制》K线图可视化部分的介绍,代码上作如下更改:
#mpf.candlestick(self.am, ohlc, width=0.5, colorup='r', colordown='g')#绘制K线走势
mpf.candlestick_ochl(self.am, ohlc, width=0.5, colorup='r', colordown='g')#绘制K线走势 py3.7
到这一步,可以显示小工具的界面了,如下所示:
光是显示界面还不够,还需要试下小工具行情、选股和回测等按钮功能是否完整,结果是我们仍然需要做些代码移植。
(7)提示:TypeError: Sizer.Remove(): arguments did not match any overloaded call:
overload 1: argument 1 has unexpected type 'MPL_Panel_Base’
overload 2: argument 1 has unexpected type 'MPL_Panel_Base’
在切换行情和回测页面时会出现这种情况,该部分代码的作用是页面替换,Replace()函数已实现该需求,可将Remove()函数去除。
Remove:Removes a sizer child from the sizer and destroys it.
Replace:Detaches the given oldwin from the sizer and replaces it with the given newwin.
另外,使用 GetItemCount和GetChildren打印验证下去除Remove()函数后,是否在sizer中的child会越来越多,结果是令人满意的,如下所示:
print(self.HBoxPanel.GetItemCount())
print(self.HBoxPanel.GetChildren())
# 3
# SizerItemList: [<wx._core.SizerItem object at 0x1c228c7678>, <wx._core.SizerItem object at 0x1c228c7708>, <wx._core.SizerItem object at 0x1c228c7798>]
self.HBoxPanel.Hide(self.DispPanel)
self.HBoxPanel.Replace(self.DispPanel,self.BackPanel)
self.HBoxPanel.Show(self.BackPanel)
print(self.HBoxPanel.GetItemCount())
print(self.HBoxPanel.GetChildren())
#3
#SizerItemList: [<wx._core.SizerItem object at 0x1c228c7708>, <wx._core.SizerItem object at 0x1c228c7798>, <wx._core.SizerItem object at 0x1c228c70d8>]
GetItemCount:Returns the number of items in the sizer.
GetChildren:Returns the list of the items in this sizer.
到这一步,可以来回切换页面了,如下所示:
另外需要提一下的是在StockDataMod文件中数据存储的路径,mac的用户可将数据存储在py程序当前路径下,即path = ‘.’
#path = 'C:\programPY\GUI_Inter_StoMPL\StockData'
path = '.'
关于完整代码可以加入专栏交流群获取。更多的量化交易内容欢迎大家订阅专栏阅读!!
热门评论
能给个现在python版本能直接运行的代码吗?比较报错千千万,修复所有报错代价太大。。。
ヾ(´A`)ノ゚你是实战课程怎么还没出.......