对于一个量化交易平台,它主要包含如下功能模块:
而整个模块基本都是基于后端来开发的,只有图表可视化是用一个可视化库来打造,并未涉及到前端的功能,核心主要是来学习业务逻辑:
在咱们的工程中新建一个Readme文件用来进行功能的描述:
而其它模块会随着学习的不断深入再慢慢填充,其实对于这些数据的获取在上一次咱们已经都试验过了,只是没有将其封装成一个通用的API,所以接下来则会基于咱们上次实现的代码进行一个抽取,来实现这里所列出的具体API。
这个在之前咱们实现的代码为:
咱们直接基于它来改一下:
先看一下咱们之前实现的:
定义一下:
原来咱们在获取股票财务指标时用过:
咱们来封装一下:
先来看一下之前咱们使用的:
下面基于它来封装一下:
之前的代码:
封装一下:
封装为:
接下来咱们则来调用一下咱们重新封装的stock。
1、新建一个测试模块:
2、获取股票行情数据并导入csv:
控制台输出:
看一下表格文件有木有生成?
但是!!!你会发现表格中表头部分少了一个日期:
这个时候是需要咱们来处理一下的,如果不处理在未来的cvs的读取数据时是会有问题的,这个问题是啥呢?下面在stock中先增加一个cvs的读取函数,读出来自然就明白了:
咱们来调用读取一下:
接下来就来修复它,需要在导出函数那块进行处理了,如何处理呢,此时则需要对数据的索引进行重命名了,如下:
再重新导出,再获取:
先来计算一下每日的涨跌幅,看是否准确,先来明确一下涨跌幅的计算公式:“(当期收盘价-前期收盘价)/前期收盘价”,
其中的当期可以是当天、当分钟、当秒钟、当周、当月,具体实现如下:
其中shift(1)表示上一行的数据,而shift(2)表示上两行的数据,shift(-1)表示下一行的数据。
下面来调用验证一下是否准确,这里还是以平安银行的日K数据为例:
运行看一下:
/Users/xiongwei/opt/anaconda3/bin/python3.8/Users/xiongwei/Documents/workspace/python/QuantitativeTrading/studycode/example/stock.pyauthsuccessopenclosehighlowvolumemoney2021-09-0117.4817.8817.9217.01231689409.04.046284e+092021-09-0218.0018.4018.7817.80242260354.04.454545e+092021-09-0318.5018.0418.5017.70139481871.02.523273e+092021-09-0617.9318.4518.6017.78151522556.02.780281e+092021-09-0718.6019.2419.5618.35162234416.03.067366e+09openclosehighlowvolumemoneyclose_pct2021-09-0117.4817.8817.9217.01231689409.04.046284e+09NaN2021-09-0218.0018.4018.7817.80242260354.04.454545e+090.0290832021-09-0318.5018.0418.5017.70139481871.02.523273e+09-0.0195652021-09-0617.9318.4518.6017.78151522556.02.780281e+090.0227272021-09-0718.6019.2419.5618.35162234416.03.067366e+090.042818Processfinishedwithexitcode0接下来就要来验证咱们计算涨幅的正确性了,咱们这里来挑两天的验证一下既可,比如我们挑这两天的:
回到交易平台中咱们来看一下:
完成正确。
为了进一步验证准确性,这里再来看一下周K的涨跌幅,那首先咱们需要将日K的数据转换为周K的数据对吧,该功能我们已经封装好了,直接调用既可:
好,获取了三周的数据,回到同花顺软件里确认一下准确性:
为啥咱们打印的日期是显示的2021-09-05呢?
其实我们打印的是一周的最后一天:
而股票软件里是算到工作日的最后一天,关于这个细节就不过多较真的,总之涨幅结果对相同的,再来看一天的:
对于股票操作最频繁的就是买入和卖出操作对吧,所以接下来会以一个简单的策略来对股票生成买卖信息,注意:由于这阶段还在打基础,还没有学习各种选股策略的应用这块,所以这里的策略是很呆板的,比如可能就是定就是周一卖,周四买之类的,重点是能让我们程序按预期来生成买卖信号。
1、新建Strategy模块:
由于未来会有很多的一些策略,所以这里新建一个包名:
2、创建周期选股策略:
好,接下来则来创建一个非常简单按周期选股的策略:周四买入、周一卖出【有过炒股经历的应该也能感受到这个规则,也有点用吧,因为基本上到了周四就开始阴了,而周一作为一周的开始往往势头比较旺~~】
"""用来创建交易策略、生成交易信号"""importdata.stockasstimportnumpyasnpdefweek_peroid_strategy(code,time_freq,start_date,end_date):data=st.get_single_price(code,time_freq,start_date,end_date)#新建周期字段,周一是从0开始data['weekday']=data['date'].weekday#周四买入,下面代码的意思是如果是周四,则是1表示买,0表示不买data['buy_signal']=np.where((data['weekday']==3),1,0)#周一卖出,下面代码的意思是如果是周一,则是-1表示卖,0表示不卖data['sell_signal']=np.where((data['weekday']==0),-1,0)returndataif__name__=='__main__':data=week_peroid_strategy(code='000001.XSHE',time_freq='daily',start_date='2021-08-25',end_date='2021-09-08')print(data)下面运行看一下,报错了:
原因是咱们的索引列木有给它重命名,没有date这一列,当时我们重命名只是在导出函数中加了:
好,那修改一下程序:
为了打印看得更加清楚,这里将字段过滤一下:
3、信号整合:
接下来想一个场景,就是有可能周四你买入,周五又有可能买入对吧,那连续两天买入,在实际做策略时会经常碰到这种重复的信号的,所以这里针对这样的场景模拟一下:
那针对这样的数据,咱们得想办法只让第一天买入为1,其它的买入都变为0,其实也很简单,如下:
好,此时咱们把整合的那句代码又打开注释,再运行,你会发现:
这里需要改一下条件了,如下:
当然对于卖出信号也需要整合一下,因为也有可能出现重复卖出的情况,如下:
4、最终生成买卖信号:
目前buy_signal和sell_singal,在同一天只可能有一种signal,要么是买,要么是卖对么?所以这里再加一个字段,用来做买卖的直观判断,不然我看两个字段有点晕,如下:
先来看一下股票软件中持仓收益一般包含的数据内容:
其中咱们需要了解的有如下几个计算公式:
1、总盈亏=(市价-成本价)*股数;
也就是表格中这一列的值:
2、浮动盈亏比=(市价-成本价)/成本价;
也就是表格中的这一列的值,我们平常最关心的收益率:
比如7.377,通常也叫挣了7.3个点,其实还有一个更加简便的计算方法,比如盈利的情况下,直接拿市价/成本价,然后肉眼就可以看到收益率了,比如表格中的新城股份:
咱们来除一下:
然后用它再减去1,此时就可以看到百分收益率就是7.377啦,如果对于亏损的情况也类似,用价格高的除以价格低的就成。
3、成本价=买入金额/持有股数
因为有可能在实际会分仓进行买入,所以成本价计算就是如上公式了。
4、股数=累计买入股数
这个就比较简单了,通常一手是100股。
实现:
1、收益率计算:
接下来咱们基于上面的买卖信号数据来计算一下每次的收益率,先分析一下咱们的数据:
发现在买和卖之间的天数肯定是不一定的,短线的周期短,中长线的周期长,而对于计算收益率来说,只关心买入和卖出那两天的价格对吧?所以,我们可以为了方便计算的收益率,把买和卖中间持股的记录都给删掉,只保留买和卖那两天的数据,这样计算的话就比较方便了,所以基于这样的思路咱们来写一下逻辑:
接下来计算收益率为:
其中发现,对于买的情况很显然是不需要显示收益率的,所以这里再过滤一下:
2、获取上市以来所有数据:
那上官网查一下:
好,咱们来改一下:
此时咱们在调用时就可以传None了:
其中需要导一下datetime:
3、重构week_peroid_strategy函数:
目前对于week_peroid_strategy可以稍加优化一下代码,因为看着有点乱,就是把这俩逻辑抽离出去:
说不定未来还能在其它的功能上使用上,如下:
这样,整个逻辑就变得清爽了:
这个思想不管是用啥语言写程序都是应该我们来进行考虑的,因为可以大大增加代码的可读性。
另外目前咱们代码这有个报警:
是因为在main中也是用的data:
这里将它改一下名称既可:
4、打印一下数据的均值:describe()
对于平安银行自上市至今的数据太多了,可以用下面来查看一下均值,对整体数据有一个大概的了解:
关于各参数的函数可以参考:
3、将其可视化输出:plot()
接下来咱们也可以使用plot()函数来将整个的收益率情况可视化一下,如下:
现在我们已经能计算出一支股票的单次的收益率对吧?那如何根据单次收益率来计算出一个累计收益率呢?比如你支付宝中的基金【关于基金的学习,也是今年的一个计划,将来得实际行动起来】,通常在这个页面会展示累计收益率:
那你有没有搞清楚这个值是如何计算出来的呢?这里正好可以弥补一下这个知识,假如你买的一个基金,整体的收益情况如下:
那累计收益的计算,咱们口算一下,算完之后你就会发现公式出来了,公式有了那们咱们的程序就有戏了:
这个比较简单对吧,也就是原来100块钱,经过一天之后的收益利息,挣了3块钱,总金额变成了103了,好,接着算第二天的累计收益了:
接下来再把剩下的两天算出来,你就会发现公式了:
其中“(1+当天收益率)的累积乘积”,其实就是一个通用计算累计收益率的公式【一定要注意累计收益和累计收益率,累计收益是有本金在里面,而累计收益率是不包含本金的,就是一个比例嘛,这一点必须要搞清楚】,但是!!!它还是有问题的,为啥呢?那咱们以这个公式来算一下图中第一天的累积收益就知道了,很明显第一天的累计收益率就是3%,因为只有一天嘛,但是如果以"(1+3%)"来算,很明显它的收益率就为103%,需要将本金去掉,也就是累计收益率的公式为“(1+当天收益率)的累积乘积-1”,(1+3%)-1是不是收益率就是3%了?
接下来则回到python的世界,来计算一下平安银行的累计收益率:
接下来咱们来调用一下:
而看一下可视化的累积收益率的图:
从这个收益曲线图来看,貌似周四买入,周一卖出的简单策略,收益率还是蛮不错的嘛,当然啦,不可能按这么简单的规则来炒股的,纯学习。
最后在写python时有一个小的细节这里提一下,就是在计算累计收益率不是用到了这个函数嘛:
但是!!!你这个函数完全得要你手动敲全,不能智能的提示对吧?其实不提示的原因也很简单,原因是由于:
不知道它加出来的是DataFrame,所以当然也就不知道给你提示它里面的函数喽,要想解决这个提示问题,咱们可以显示的指定这数据是DataFrame既可,如下: