0%

基于python的基金定投分析

使用python可视化分析基金定投和普通投资之间的区别和优缺点。探讨基金定投的降低风险作用。
1
2
3
4
5
6
7
import requests
from bs4 import BeautifulSoup
import re
import pandas as pd
import numpy as np
import random
import matplotlib.pyplot as plt

爬取东方财富网关于基金的数据并处理数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
link="http://fund.eastmoney.com/f10/F10DataApi.aspx?type=lsjz&code=000311&page=1&sdate=2018-01-02&edate=2020-01-10&per=20"
headers={
'user-agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36",
}
r=requests.get(link,headers=headers)

s1 = requests.get(link)
s1.encoding = 'utf-8'
soup1=BeautifulSoup(s1.text,'lxml')
fund_detail=soup1.find_all('tr')

###获取总页数
pattern=re.compile(r'pages:(.*),')
html=r.text
result=re.search(pattern,html).group(1)
pages=int(result)
pages



data_list=[]
for i in range(1, pages+1):
link='http://fund.eastmoney.com/f10/F10DataApi.aspx?type=lsjz&code=000311&page='+str(i)+'&sdate=2018-01-02&edate=2020-01-10&per=20'
r=requests.get(link,headers=headers)
s1 = requests.get(link)
s1.encoding = 'utf-8'
soup1=BeautifulSoup(s1.text,'lxml')
fund_detail=soup1.find_all('tr')
for each in fund_detail:
if each.td is None:
continue
else:
date=each.td.text.strip()##only first td
unit_value=each.find('td',class_='tor bold').text.strip()##first tor bold
cum_value=each.find('td',class_='tor bold').next_sibling.text.strip()##second td
percent=each.find('td').next_sibling.next_sibling.next_sibling.text.strip()
purchase_condition=each.find('td').next_sibling.next_sibling.next_sibling.next_sibling.text.strip()
sale_condition=each.find('td').next_sibling.next_sibling.next_sibling.next_sibling.next_sibling.text.strip()
dividend=each.find('td',class_='red unbold').text.strip()
code= '000311'
name= '景顺长城沪深300增强'
data_list.append([code, name, date,unit_value, cum_value, percent,purchase_condition, sale_condition, dividend])
1
len(data_list)
497
1
2
fund_000311 = pd.DataFrame(data_list)# 设置列名
fund_000311.columns=['代码','名字','时间','单位净值','累计净值','涨跌幅','申购','赎回','分红']
1
fund_000311.to_csv("data0003111")
1
fund_000311.head()

代码 名字 时间 单位净值 累计净值 涨跌幅 申购 赎回 分红
0 000311 景顺长城沪深300增强 2020-01-10 2.2260 2.5660 0.32% 开放申购 开放赎回
1 000311 景顺长城沪深300增强 2020-01-09 2.2190 2.5590 1.46% 开放申购 开放赎回
2 000311 景顺长城沪深300增强 2020-01-08 2.1870 2.5270 -1.44% 开放申购 开放赎回
3 000311 景顺长城沪深300增强 2020-01-07 2.2190 2.5590 0.91% 开放申购 开放赎回
4 000311 景顺长城沪深300增强 2020-01-06 2.1990 2.5390 -0.36% 开放申购 开放赎回
1
2
3
4
5
6
7
8
9
10
11
12
13
##画出走势图(累计净值),共1328个交易日,累计净值=单位净值+累计分红
cum_price=fund_000311[['单位净值']]
cum_price=np.array(cum_price)
cum_price=cum_price.tolist()
cum_value=list()
t = np.arange(0.0, 497.0, 1)
for each in reversed(cum_price):##倒序 从头开始
cum_price=float(*each)
cum_value.append(cum_price)
plt.plot(t,cum_value,'r-')
plt.ylabel('value')
plt.xlabel('time')
plt.title('Fund 000311 HuSheng 300 ')
Text(0.5, 1.0, 'Fund 000311 HuSheng 300 ')

png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
##涨跌情况
percent=fund_000311[['涨跌幅']]
percent=np.array(percent)
percent=percent.tolist()
while [''] in percent:
percent.remove([''])#去除三个空白值
percent_val=[]
t = np.arange(0.0, 494.0, 1)
i=1
for each in reversed(percent):##倒序 从头开始
each=float(str(*each).strip('%'))
percent_val.append(each)
i=i+1
plt.plot(t,percent_val,'r-',linewidth=0.5)
plt.ylabel('ratio(%)')
plt.xlabel('time')
plt.title('Fund 000311 HuSheng 300 ')
##可以看到在第二百到第三百个交易日波动率明显变大,400到500明显波动率小。
Text(0.5, 1.0, 'Fund 000311 HuSheng 300 ')

png

基金定投研究

1
2
3
unit_price=fund_000311[['单位净值']]
unit_price=np.array(unit_price)
unit_price=unit_price.tolist()
1
2
3
# 查出分红情况
dividend=fund_000311.loc[fund_000311['分红'] != '']
dividend # 期间无分红

代码 名字 时间 单位净值 累计净值 涨跌幅 申购 赎回 分红

1. 简单情况一次买入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 计算年化收益

total_yearly_once = []
unit_price_new = unit_price[50:494] # 避免投资时间太短不考虑近50个交易日
dayday = 497 # 投资时长
for i in reversed(unit_price_new):
i=float(*i)
pie=1000/i ##份额
temp = pie*2.226 # 2.226 20年1月10日
total_return = (temp-1000)/1000
yearly_return = total_return/dayday*250 # 250个交易日
total_yearly_once.append(yearly_return)
dayday = dayday - 1
total_yearly_once_df=pd.DataFrame(total_yearly_once)
1
2
3
4
5
6
7
# 画图

t = np.arange(0.0, 444.0, 1)
plt.plot(t,total_yearly_once_df,'r-')
plt.ylabel('ratio(%)')
plt.xlabel('time')
plt.title('Fund 000311 normal investment ')
Text(0.5, 1.0, 'Fund 000311 normal investment ')

png

可以看到收益率的波动率在这段期间非常的大,大致从0到将近60%,并且存在负收益率。

1
plt.hist(total_yearly_once, bins=5,facecolor="red", edgecolor="black", alpha=0.7)
(array([101., 110., 124.,  78.,  31.]),
 array([-0.02019805,  0.09804444,  0.21628694,  0.33452944,  0.45277193,
         0.57101443]),
 <a list of 5 Patch objects>)

png

  1. 定投简单情况(不考虑时间价值)automatic investment plan
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 计算年化收益
total_yearly_auto = []
times= np.arange(494, 50, -1)
dayday = 497 # 投资时长
for i in times:
unit_price_new = unit_price[50:i+1] # 避免投资时间太短不考虑近50个交易日
each_pie=[]
each_amount=1000/(len(unit_price_new)) # 每笔投资多少
for each in (unit_price_new):
each=float(*each)
pie=each_amount/each
each_pie.append(pie)
total_return=(sum(each_pie)*2.226-1000)/1000
yearly_return = total_return/dayday*250
total_yearly_auto.append(yearly_return)
dayday = dayday - 1
total_yearly_auto_df=pd.DataFrame(total_yearly_auto)
1
2
3
4
5
6
7
t = np.arange(0.0, 444.0, 1)
plt.plot(t,total_yearly_auto_df,'b-', label='auto')
plt.plot(t,total_yearly_once_df,'r-', label='normal')
plt.legend(loc='upper right')
plt.ylabel('ratio(%)')
plt.xlabel('time')
plt.title('Fund 000311 auto investment')
Text(0.5, 1.0, 'Fund 000311 auto investment')

png

1
2
plt.hist(total_yearly_once, bins=10,facecolor="red", edgecolor="black", alpha=0.7)
plt.hist(total_yearly_auto, bins=10,facecolor="blue", edgecolor="black", alpha=0.7)
(array([ 52., 107., 148., 108.,   6.,  12.,   2.,   5.,   2.,   2.]),
 array([0.07401984, 0.09161269, 0.10920555, 0.1267984 , 0.14439126,
        0.16198411, 0.17957697, 0.19716982, 0.21476267, 0.23235553,
        0.24994838]),
 <a list of 10 Patch objects>)

png

通过画图可以看出,定投具有更小的收益率波动性,因此也具有更小的风险。收益率大致在10%到15%之间,没有负收益率。

总结

可以看出定投具有所谓的“削峰填谷”的作用, 可以达到随时买入而年化收益波动不大的效果。而普通投资的收益率不稳定,可能一下子“暴富”也可能“白忙活”,需要投资者掌握投资时机。定投对于想要稳定增值资产的投资者是一个相对比较好的选择。

最后项目在GitHub上网址:https://github.com/JasonVictor17/Stock-market-analysis