40

基金定投选星期几更划算?[python统计分析]

 3 years ago
source link: https://zhuanlan.zhihu.com/p/113568323
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

基金定投选星期几更划算?[python统计分析]

上海交通大学 计算机应用技术硕士

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

(本文为学习讨论,不作为投资建议)

整体思路:选取一定的时间段,分别模拟周一至周五定投,比较最终受益情况,确定基金定投最适宜的时间。

下面开始详细介绍:

第一步:网站分析,分析数据交换url

以天天基金网为例,随便找一只基金

打开Chrome自带的开发者工具,点击下一页,从 Network 分页里找到数据传输接口(关于开发者工具的使用,可参见 Crossin:爬虫必备工具,掌握它就解决了一半的问题

点击此请求,打开响应数据

就是它没错了,接着我们看看该url的参数

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)

返回数据为

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

这样就全出来了。

第三步:构造模型,模拟定投计算最终收益

具体过程如下:

先将日期转换为星期,然后将周一至周五分类,以周五定投为例,每次定投100,将每次定投金额按当天净值转化为份额,然后与之前份额累加:

total = [0] * 5   # 到期后总份额
count = [0] * 5   # 每日定投次数
for j in result['Data']['LSJZList'][::-1]:
    if j['JZZZL']=='':
        pass
    else:
        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)]  # 到期后总收益率

效果如下:

2.然后用plt.bar画柱状图大小,第一个代表该日增长的概率,第二个为该日累计增长的收益,plt.bar内的label参数为图签,但是要用plt.legend放止图签与图像重合显示不出来,调整y轴坐标范围以便于查看,最后设置坐标轴粗细。

name_list = ['周一', '周二', '周三', '周四', '周五']
x = range(len(name_list))
minytick=int(min(total_money))-1000
maxytick=int(max(total_money))+1000
plt.bar(x, [i for i in total_money], label='该日定投最终收益', width=0.4, color='y')
# 参数 m、m2、r 用来调整高度比例
m = sum(total_money) / 5
m2 = min(profit_list)
r = 50000
plt.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) ; ###设置底部坐标轴的粗细

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")  #生成网格'''

第五步:统计分析

我们先多尝试几只不同基金不同时段的情况,画出直方图:

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

从上述的统计结果中来看,周四、五定投的收益通常要大于周一、周二定投的收益。

不过我们这里选取的数据量并不多,你也可以自己在代码中增加更多的基金代码和时间来测试。

当然咯,此演示结果仅作为参考,股市变化莫测,不可能完全预测,请大家谨慎操作。

------

欢迎搜索及关注:Crossin的编程教室

这里还有更多精彩。一起学,走得远


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK