Python分析:基金定投 选星期几收益更大?

裸睡的猪

共 4027字,需浏览 9分钟

 ·

2020-03-15 23:27

982fb823e3ee12f88bce4720f613efb7.webp

作者 | 锅g头
来源 | Crossin的编程教室



基金定投常见的一种方式是定期定额投资,即每周或每月固定的时间段,向基金公司申购固定份额的基金。基金定投可以平均成本、分散风险,实现自动投资,所以基金定投又称为“懒人投资术”。今天主要用python带大家分析一下,从统计数据上来看,到底什么时候定投获得收益的概率最大。

(本文为学习讨论,不作为投资建议)
整体思路:选取一定的时间段,分别模拟周一至周五定投,比较最终受益情况,确定基金定投最适宜的时间。
下面开始详细介绍:

第一步:网站分析,分析数据交换url
以天天基金网为例,随便找一只基金39544db78ca2e95aad16d80edc0eec7a.webp
打开Chrome自带的开发者工具,点击下一页,从 Network 分页里找到数据传输接口bdb469e1a3197a504d56f0be4d4da129.webp
点击此请求,打开响应数据a8cdb914ef543105f671e9dd63d1a54e.webp 就是它没错了,接着我们看看该url的参数22c51faec3f40de05629bac8a659fa10.webp Callback可以忽略,fundcode为该基金代码,pageIndex为当前页码,pageSize为返回数据条数,这里一次返回20条,startData和endData分别为起始时间和终止时间,但是都为空值,最后一个参数也不用管。

第二步:requests模拟请求,得到数据
正常情况,应该是for循环,一页一页的取数据,但是我们从第一步可以看到,该url参数中含有起始、截止时间,那我们可以试试,能不能忽略页码信息,以时间为截点得到返回数据,改一下url结构,开始模拟请求:
startDate = '2018-01-13'  #起始时间endDate = '2020-02-28'   #截止时间header = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0','Referer': 'http://fundf10.eastmoney.com/jjjz_{0}.html'.format(fundCode)}url = 'http://api.fund.eastmoney.com/f10/lsjz?fundCode={0}&pageIndex={1}&pageSize=5000&startDate={2}&endDate={3}&_=1555586870418?'.format(fundCode, pageIndex, startDate, endDate)response = requests.get(url, headers=header)result=json.loads(response.text)print(result)for j in result['Data']['LSJZList']:print(j)

返回数据为b6720797bde15bf439c18ddd6be5ccbe.webp
确实能按此url结构返回数据,但是貌似只有20条,起初还以为是网站接口限制问题,最后发现是pageSize没有设置,索性直接设置为5000,再来一次 a2e54895daf32abc52430bb10f2ee937.webp这样就全出来了。



第三步:构造模型,模拟定投计算最终收益
具体过程如下:
先将日期转换为星期,然后将周一至周五分类,以周五定投为例,每次定投100,将每次定投金额按当天净值转化为份额,然后与之前份额累加:
total = [0] * 5   # 到期后总份额count = [0] * 5   # 每日定投次数for j in result['Data']['LSJZList'][::-1]:if j['JZZZL']=='':        passelse:        weekday = int(datetime.strptime(j['FSRQ'], '%Y-%m-%d').weekday())        DWJZ = float(j['DWJZ'])   # 净值                total[weekday] = total[weekday]+money/DWJZ        count[weekday] += 1
最后根据最后的净值将份额转化为金额:
total_money=[]   #根据份额算出总金额for t, i in enumerate(total):    total_money.append(i*DWJZ)print("周{0}定投最终金额{1}".format(t+1, i*DWJZ), "定投{0}次".format(count[t]))
返回结果:
周1定投最终金额10702.031523199748 定投87次周2定投最终金额10916.721436831616 定投89次周3定投最终金额10762.509365370352 定投87次周4定投最终金额10880.683965470516 定投88次周5定投最终金额10375.517539233546 定投84次



第四步:用matplotlib画柱状图

1.首先设置正常显示中文标签,SimHei为中文字体,用plt.figure建1个15x8的画布,设置标题内容、字体颜色、字体粗细及大小
plt.rcParams['font.sans-serif'] = ['SimHei']  # windows 用来正常显示中文标签# plt.rcParams["font.family"] = 'Arial Unicode MS'  # mac 用来正常显示中文标签plt.figure(figsize=(15, 10), dpi=80)plt.title('{0}基金模拟定投收益图'.format(fundCode), color='blue', fontweight=800, size=50)profit_list = [round((i-100*j)/(100*j), 4) for i, j in zip(total_money, count)]  # 到期后总收益率

效果如下:

c4a2df1918682ca2002db3cc1dff3188.webp 


2.然后用plt.bar画柱状图大小,第一个代表该日增长的概率,第二个为该日累计增长的收益,plt.bar内的label参数为图签,但是要用plt.legend防止图签与图像重合显示不出来,调整y轴坐标范围以便于查看,最后设置坐标轴粗细。
name_list = ['周一', '周二', '周三', '周四', '周五']x = range(len(name_list))minytick=int(min(total_money))-1000maxytick=int(max(total_money))+1000plt.bar(x, [i for i in total_money], label='该日定投最终收益', width=0.4, color='y')# 参数 m、m2、r 用来调整高度比例m = sum(total_money) / 5m2 = min(profit_list)r = 50000plt.bar([i+0.4 for i in x], [(i-m2)*r + m for i in profit_list], label='该日定投收益率', width=0.4, color='r')plt.legend(loc="upper left")  # 防止label和图像重合显示不出来plt.xticks(x, name_list, size=20)   # x坐标plt.ylim(minytick, maxytick)plt.yticks(range(minytick, maxytick, 200), size=20) # y坐标ax = plt.gca();#获得坐标轴的句柄ax.spines['left'].set_linewidth(3) ; ####设置左边坐标轴的粗细ax.spines['bottom'].set_linewidth(3) ; ###设置底部坐标轴的粗细

a8b0859daf255e9cb9bc5f6c42e676d3.webp


3.完善标签、网格、文字等设置
for a, b, c in zip(x, total_money, count):    plt.text(a, b+0.05, '%.1f' % b, ha='center', va='bottom', fontsize=15)    plt.text(a, b+100, '定投{}次'.format(c), ha='center', va='bottom', fontsize=15, color='r')for a, b in zip(x, profit_list):    plt.text(a+0.4, (b-m2)*r + m, '%.4f' % b, ha='center', va='bottom', fontsize=15)
plt.text(2, maxytick+300, '时间:{0}至{1}'.format(startDate, endDate), fontsize=20)plt.grid(axis="y") #生成网格'''

c73e29ec89a9568911941c0388806ccb.webp



第五步:统计分析
我们先多尝试几只不同基金不同时段的情况,画出直方图:

56ec79312342164b6f9d00956cdda7bb.webp

0b13803fa82724b1341d9f563e35d8f4.webp

f76b1b021d223c92e88e32784fa03262.webp

8add9083fea76fc2bc0b73e2a37cd595.webp

仅从几个个例很难看出什么规律。所以进一步的,我们随机选10支基金,再随机选10个时间段,画出收益分布的散点图,并计算出平均值:

b177d2bd47bf251c9573d20e3aef5861.webp



第六步:得出结论
从上述的统计结果中来看,周四、五定投的收益通常要大于周一、周二定投的收益。
不过我们这里选取的数据量并不多,你也可以自己在代码中增加更多的基金代码和时间来测试。另外建议大家可以选择自己定投的鸡来分析,这样也许可将自己的收益最大化!
当然咯,此演示结果仅作为参考,股市变化莫测,不可能完全预测,请大家谨慎操作。

源码地址(或阅读原文):https://gitee.com/crossin/snippet/tree/master/fund_week





浏览 55
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报