量化学交易习笔记#寻找稳定收益的股票,可能吗?

本文目的:寻找近年来稳定收益的股票

利用python,通过数据分析,进行的一次小型课题研究。会涉及之前文章里邢老师教的回测框架模块。具体相关邢老师的文章,可以看《Python量化入门》的课程,我的相关笔记传送门:

量化交易学习笔记#Python量化入门课程(第零课)零基础的预备课

最近有个刚开始学习研究股票的朋友问我,有没有什么3-5年来,收益稳定的股票,只要买着不动就可以安心睡觉?

这句话一听,我就笑了。心里想,哥们你来错地方了。天堂(固定收益)在左,地狱(股市)在右。

追求稳定收益就不应该来股市,股权市场天生流通性强,波动性大。单靠个股是很难做到稳定收益的,不然那些金融大咖们,也不需要尝试各种策略,每天做各种研究,使用各种金融衍生品工具了。

但是本着严谨的态度,我觉得还是用该历史数据说话,随手写了个小程序。

运行状态:

量化学交易习笔记#寻找稳定收益的股票,可能吗?_第1张图片

20140101-20170930的测试结果:

量化学交易习笔记#寻找稳定收益的股票,可能吗?_第2张图片

从上面的结果看,是不是出乎意料的好~!

2014年时有股票2526个,如果在20140101买入并持有的话有2027个股票年化收益率大于了4%,超过了余额宝。

如果我们调整下参数

量化学交易习笔记#寻找稳定收益的股票,可能吗?_第3张图片

天哪噜,超过年化10%的股票还有1386只,刚才谁说股票是地狱来着的?

大家快去冲冲冲。。。。客观且慢,如果仅仅因为上面的数据就觉得股权投资好于固定收益类产品,是非常危险的。因为股票有这天然不可避免的风险:

第一点:波动性。 我们引入一个指标max_drawdown,最大回撤,就是买入持有期间,收益最大的回撤幅度。

我们把回撤最小的股票找出来看看

量化学交易习笔记#寻找稳定收益的股票,可能吗?_第4张图片

过去3年里回撤最小的股票,也有22%,最大能搞达到90%。当你亏了22%的时候,你真的还能坚持持有吗?有的人说我能。。。毕竟在巨大的收益面前,总是有勇士的。那如果是90%呢?

第二点,买入时间点。看一下,为什么2014年买入的时候,股票收益还是不错的。

量化学交易习笔记#寻找稳定收益的股票,可能吗?_第5张图片

看一下上证指数就知道了,2014年的时候是非常接近历史低点的。如果我们把买入时间切换到20150101看看。

量化学交易习笔记#寻找稳定收益的股票,可能吗?_第6张图片

居然还有1432个股票跑赢了支付宝。

年化收益超过10%的居然还有868个~whoops

期间最小回撤还是22%

量化学交易习笔记#寻找稳定收益的股票,可能吗?_第7张图片

最大回撤90%

量化学交易习笔记#寻找稳定收益的股票,可能吗?_第8张图片

好吧,那我们再尝试下从20150512开始,这次就比较惨了

量化学交易习笔记#寻找稳定收益的股票,可能吗?_第9张图片

年化收益率大于4%的445个,大于10%的只有251个了。

我们再看下上证最悲惨的3年 20110101-20140101

量化学交易习笔记#寻找稳定收益的股票,可能吗?_第10张图片

战胜余额宝的只有410个了,而年化收益率超过10%的只有213个了。

量化学交易习笔记#寻找稳定收益的股票,可能吗?_第11张图片

收益率排名靠前的股票:

量化学交易习笔记#寻找稳定收益的股票,可能吗?_第12张图片

其中,除了600460华夏幸福,经久不衰。

量化学交易习笔记#寻找稳定收益的股票,可能吗?_第13张图片

其他更多的是走出了不同程度的反转

000156 华数传媒

量化学交易习笔记#寻找稳定收益的股票,可能吗?_第14张图片

000750 国海证券

量化学交易习笔记#寻找稳定收益的股票,可能吗?_第15张图片

600705 中航资本

量化学交易习笔记#寻找稳定收益的股票,可能吗?_第16张图片

结论:

1. 可以看出无论何时,只要找到有潜力的股票,总能帮你扛过熊市,获得丰厚的收益,但是找到他们谈何容易。

2. 对于大盘的择时,会提高我们选股的成功率。

3. 历史是否可能重复,更像是薛定谔的猫。

4. 长期持有才是稳定收益的根基。

5. 长期来看,股权投资的收益跑赢固定收益的可能性还是很高的。但是需要你花时间和经历去研究。

实验思路和源代码:

1、获得全量的股票交易数据,如股票代码,名称,高,开,低,收,涨跌幅,交易量等

如果你之前学过邢老师的《Python量化交易入门》系列课程,那你应该已经拿到了一套很完备的A股数据。

如果没有,你也可以通过万得导出数据。

本实验使用过的就是万得数据。

# 从指定文件夹中获取所有股票代码,组成一个list,这里我直接使用了《Python量化交易入门里的框架》stock_list = Functions.get_stock_code_list_in_one_dir_wande()

2、定义一个函数,获取每个股票,在某一段时间内,收益情况分析的表格

获取每个股票,在某一段时间内,收益情况分析的表格

def get_result(start_date='20140101', end_date='20180101', stock_list=[]):

    """

    :param start_date: 策略开始日期

    :param end_date: 策略结束日期

    :param stock_list: 需要模拟的股票列表

    :return: 带有股票代码,策略开始时间,策略结束时间,策略期间总收益,策略的年化收益,策略的最大回撤幅度,策略的波动性,策略的sharp比率。

    """

    # 定义一张空表,含有需要返回的字段名(列名)

    output = pd.DataFrame(columns=['stock_code', 'start_date', 'end_date', 'total_return', 'annual_return', 'max_drawdown', 'volatility', 'sharp_ratio'])

    # 利用《Python量化入门》的框架,获取上证指数数据,为了填补非交易日

    index_data = Functions.import_index_data_wande()

    # 计数器i,初始值为0

    i = 0

    # 对于在全部股票代码列表里的股票进行遍历

    for stock in stock_list:

        # 利用《Python量化入门》的框架读取每个股票的数据

        df = Functions.import_stock_data_wande(stock)

        # 个股数据和指数数据合并,填补非交易日

        df = Functions.merge_with_index_data(df, index_data)

        # 剔除上市交易日小于3年的(250*3)的,或者起始日期大于最终日期,跳过

        if (df.shape[0] < 750) or (df['date'].iloc[0] > pd.to_datetime(end_date)):

            continue

        # 截取所需要的时间段的股票交易数据

        df = df.loc[(df['date'] >= start_date) & (df['date'] <= end_date)]

        # 重置index

        df.reset_index(drop=True, inplace=True)

        # 个股数据的第一天买入

        df.loc[0, 'signal'] = 1

        # 个股数据的最有一天卖出

        df['signal'].iloc[-1] = 0

        # 计算仓位

        df = equity_cal.position(df)

        # 计算资金曲线的简单方法,因为使用buy_hold的策略,交易频率几乎没有,手续费和印花税的交易结果的影响不显著

        df = equity_cal.equity_curve_simple(df)

        # 输出表格的代码

        output.loc[i, 'stock_code'] = stock

        # 输出表格的起始日期

        output.loc[i, 'start_date'] = start_date

        # 输出表格的结束日期

        output.loc[i, 'end_date'] = end_date

        # 输出表格的期间总收益

        output.loc[i, 'total_return'] = df['equity'].iloc[-1] / df['equity'].iloc[0] - 1

        # 输出表格的年化收益

        output.loc[i, 'annual_return'] = pf_analysis.annual_return(df)

        # 输出表格的最大回撤

        output.loc[i, 'max_drawdown'] = pf_analysis.max_drawdown(df)[0]

        # 输出表格的波动性

        output.loc[i, 'volatility'] = pf_analysis.volatility(df)

        # 输出表格的夏普比率

        output.loc[i, 'sharp_ratio'] = pf_analysis.sharp_ratio(df)

        # 计数器+1,下次指向输出表格的下一行

        i += 1

        # 记录当前的进度

        print str(stock) + " is finished, and process is in " + str(stock_list.index(stock)/len(stock_list) * 100.00)

    # 将输出表格,保存为output.csv

    output.to_csv('D:/all_trading_data/data/output_data/Going_Merry/test_20180103/output.csv', index=False)

    # 输出结束

    print "finished"

    # 返回输出表格

    return output

3. 对结果数据进行数据分析,得到全部的股票数据量,收益为正的股票个数,年化收益率大于4%的股票个数

对结果数据进行数据分析,得到全部的股票数据量,收益为正的股票个数,年化收益率大于4%的股票个数

def pf_return(df):

    # 根据total_return进行排序

    df.sort_values(by='total_return', ascending=False, inplace=True)

    # 全部股票数量

    print "全部股票数量: " + str(df.shape[0])

    # 只选取收益为正的股票

    df = df.loc[df['total_return'] > 0 ]

    # 重置index

    df.reset_index(drop=True, inplace=True)

    # 打印结果

    print "收益率大于0的股票个数:"+ str(df.shape[0])

    df = df.loc[df['annual_return'] > 0.04]

    # 重置index

    df.reset_index(drop=True, inplace=True)

    # 打印结果

    print "年化收益率大于4%的股票个数:"+ str(df.shape[0])

    # 返回重新排序后的表格

    return df

4. 利用上面写好的函数运行

# 获取全部股票数据

stock_list = Functions.get_stock_code_list_in_one_dir_wande()

# 打印结果

print "测试股票数量:" + str(len(stock_list))

# 获得某段时间内所有股票的收益情况

get_result(start_date='20140101', stock_list=stock_list)

可能对于初学者而言,即使有上述源代码,可能还是会觉得较难理解。那么,建议各位想学习python并研究交易的朋友们可以考虑《Python量化入门》课程系列,非常适合零基础的朋友们,获得所有的股票历史数据,并建立自己的交易策略,建议购买课程后深入学习。

课程评价

优点:这套课程特别适合对Python,pandas都没掌握的同学,和“入门”二字很贴切。虽然价要收取一定的费用,但是对于零基础的同学还是墙裂推荐。当然我的笔记是完全免费的,但这个只能作为点心,毕竟正餐才是最有营养的~而且还有大量的源代码A股所有的股票历史交易数据。

缺点:只能用微信访问学习,PC端的话要通过微信客户端访问。

系列总课时约12多个小时,会获得课程讲解的所有源代码。如要深入熟练掌握,课外练习可能需要100小时+。

课程传送门:

量化学交易习笔记#寻找稳定收益的股票,可能吗?_第17张图片

你可能感兴趣的:(量化学交易习笔记#寻找稳定收益的股票,可能吗?)