Python分析10万条基金数据,探索基金定投的奥秘
基金定投这个名词大家都不陌生,喜欢理财的朋友可能都尝试过,今天我想给大家分享是,用python模拟基金定投和普通投的过程,并进行简单比较,探索基金定投的奥秘。
1.分析单支基金定投收益情况
基金数据已经给大家准备好了,首先用pandas读取:
import pandas as pd
data=pd.read_csv('基金数据.csv',encoding='gbk')
data
总共92390条
以‘161724’基金为例,起投100,从2020年1月2日到2020年12月18日,工作日每日定投100,计算收益并可视化展示。
首先选出该基金在上述时间段内的数据,代码如下:
import datetime
s_date = datetime.datetime.strptime('2020-01-01', '%Y-%m-%d').date()
data['日期']=[datetime.datetime.strptime(i.replace('/','-'), '%Y-%m-%d').date() for i in list(data['日期'])]
data1=data[(data['代码']==161724) & (data['日期'] >= s_date)]
data1
就算定投和普通投收益并可视化展示(计算方式参考注释):
#定投收益率计算
portion1=0 #总份额
for i in list(data1['日期'])[::-1]:
dwjz=data1[data1['日期']==i]['单位净值'].values[0]
portion1+=float(100/dwjz)
capital=100*len(list(data1['日期'])) #本金=100*天数
profit1=int(portion1*data1[data1['日期']==i]['单位净值'].values[0]) #本金+收益=份额*单位净值
#正常投资收益率计算
profit2=(capital/(data1['单位净值'].values[-1]))*data1['单位净值'].values[0] #本金+收益=份额*单位净值
可视化展示:
from pyecharts import options as opts
from pyecharts.charts import Bar
from pyecharts.globals import ThemeType
kind=['定投','普投']
l1=[capital,capital]
l2=[profit1,int(profit2)]
bar = (
Bar(init_opts=opts.InitOpts(theme=ThemeType.VINTAGE))
.add_xaxis(kind)
.add_yaxis("本金", l1)
.add_yaxis("收益", l2)
.set_global_opts(title_opts=opts.TitleOpts(title="定投与普投收益比较", subtitle="2020-161724"),
toolbox_opts=opts.BrushOpts(),)
)
bar.render_notebook()
通过上图可以看出,本年23400固定的情况下,2020年一年的时间,定投比普投多收入1千元,差别不是很大。
2.设置随机时间段
有的朋友会说,仅靠一个时间段,局限性和偶然性太大,下面我们随机设置30个时间段,并用折线图来比较最终结果:
首先,我们将30个时间段的收益结果存入列表中,代码如下:
import random
result=[]
for i in range(30):
s=random.choice(list(data1['日期']))
e=random.choice(list(data1['日期']))
if s>e:
t=s
s=e
e=t
portion1=0 #总份额
for j in list(data1['日期'])[list(data1['日期'])[::-1].index(s):list(data1['日期'])[::-1].index(e)]:
dwjz=data1[data1['日期']==j]['单位净值'].values[0]
portion1+=float(100/dwjz)
capital=100*len(list(data1['日期'])[list(data1['日期'])[::-1].index(s):list(data1['日期'])[::-1].index(e)]) #本金
profit1=int(portion1*data1[data1['日期']==j]['单位净值'].values[0]) #定投本金+收益
profit2=(capital/(data1['单位净值'].values[-1]))*data1['单位净值'].values[0]
result.append(['第{}次'.format(i+1),capital,profit1,int(profit2)])
result
[['第1次', 15300, 13557, 18520],
['第2次', 3200, 3422, 3873],
['第3次', 17100, 18548, 20699],
['第4次', 12100, 12441, 14646],
['第5次', 18800, 20094, 22757],
['第6次', 4000, 3595, 4841],
['第7次', 13900, 12782, 16825],
['第8次', 7400, 7021, 8957],
['第9次', 700, 687, 847],
['第10次', 7600, 7508, 9199],
['第11次', 10600, 10705, 12831],
['第12次', 1600, 1598, 1936],
['第13次', 900, 902, 1089],
['第14次', 12200, 12551, 14767],
['第15次', 5200, 4452, 6294],
['第16次', 1400, 1282, 1694],
['第17次', 3100, 2942, 3752],
['第18次', 15300, 16436, 18520],
['第19次', 15300, 14039, 18520],
['第20次', 8100, 7218, 9804],
['第21次', 100, 100, 121],
['第22次', 13600, 11708, 16462],
['第23次', 3900, 3656, 4720],
['第24次', 1300, 1291, 1573],
['第25次', 11100, 12648, 13436],
['第26次', 15100, 13296, 18278],
['第27次', 17700, 17189, 21425],
['第28次', 3500, 3485, 4236],
['第29次', 18900, 20274, 22878],
['第30次', 13400, 12638, 16220]]
对结果进行可视化:
import pyecharts.options as opts
from pyecharts.charts import Line
line=(
Line(init_opts=opts.InitOpts(theme=ThemeType.VINTAGE))
.add_xaxis(xaxis_data=[t[0] for t in result])
.add_yaxis(
series_name="定投",
y_axis=[t[2] for t in result],
symbol="triangle",
symbol_size=10,
linestyle_opts=opts.LineStyleOpts(color="red", width=2, type_="dashed"),
label_opts=opts.LabelOpts(is_show=False),
itemstyle_opts=opts.ItemStyleOpts(
border_width=3, border_color="yellow", color="red"
),
markline_opts=opts.MarkLineOpts(data=[opts.MarkLineItem(type_="average")]),
)
.add_yaxis(
series_name="普投",
y_axis=[t[3] for t in result],
symbol="circle",
symbol_size=10,
linestyle_opts=opts.LineStyleOpts(color="blue", width=2, type_="dashed"),
label_opts=opts.LabelOpts(is_show=False),
itemstyle_opts=opts.ItemStyleOpts(
border_width=3, border_color="yellow", color="blue"
),
markline_opts=opts.MarkLineOpts(data=[opts.MarkLineItem(type_="average")]),
)
.set_global_opts(
xaxis_opts=opts.AxisOpts(type_="category"),
yaxis_opts=opts.AxisOpts(
type_="value",
axistick_opts=opts.AxisTickOpts(is_show=True),
splitline_opts=opts.SplitLineOpts(is_show=True),
),
tooltip_opts=opts.TooltipOpts(is_show=False),
)
)
line.render_notebook()
根据上图,30个时间段内,普投的最终平均值为10990元,定投为8935.5,普投的总体情况较好。
3.设置随机基金
为做进一步探索,继续扩大数据范围,随机选择20支基金,计算在30个随机时间段内的平均收益情况:
首先各时间段内的总收益,存入字典中:
import numpy as np
codes=random.sample(list(data['代码']),20)
results={}
for i in range(1,31):
results['第{}次'.format(i)]=np.array([0,0,0])
for code in codes[1:2]:
data2=data[(data['代码']==code)]
result=[]
capital=0
profit1=0
profit2=0
for i in range(1,31):
s=random.choice(list(data1['日期']))
e=random.choice(list(data1['日期']))
if s>e:
t=s
s=e
e=t
portion1=0 #总份额
for j in list(data1['日期'])[list(data1['日期'])[::-1].index(s):list(data1['日期'])[::-1].index(e)]:
dwjz=data1[data1['日期']==j]['单位净值'].values[0]
portion1+=float(100/dwjz)
capital=100*len(list(data1['日期'])[list(data1['日期'])[::-1].index(s):list(data1['日期'])[::-1].index(e)]) #本金
profit1=int(portion1*data1[data1['日期']==j]['单位净值'].values[0]) #定投本金+收益
profit2=(capital/(data1['单位净值'].values[-1]))*data1['单位净值'].values[0]
results['第{}次'.format(i)]+=np.array([capital,profit1,int(profit2)])
将结果可视化:
import pyecharts.options as opts
from pyecharts.charts import Line
fina=[results[i].tolist() for i in list(results.keys())]
line1=(
Line(init_opts=opts.InitOpts(theme=ThemeType.ROMANTIC))
.add_xaxis(xaxis_data=list(results.keys()))
.add_yaxis(
series_name="本金",
y_axis=[t[0]/20 for t in fina],
symbol="triangle",
symbol_size=10,
linestyle_opts=opts.LineStyleOpts(color="yellow", width=2, type_="dashed"),
label_opts=opts.LabelOpts(is_show=False),
itemstyle_opts=opts.ItemStyleOpts(
border_width=3, border_color="yellow", color="yellow"
),
markline_opts=opts.MarkLineOpts(data=[opts.MarkLineItem(type_="average")]),
)
.add_yaxis(
series_name="定投",
y_axis=[t[1]/20 for t in fina],
symbol="triangle",
symbol_size=10,
linestyle_opts=opts.LineStyleOpts(color="red", width=2, type_="dashed"),
label_opts=opts.LabelOpts(is_show=False),
itemstyle_opts=opts.ItemStyleOpts(
border_width=3, border_color="red", color="red"
),
markline_opts=opts.MarkLineOpts(data=[opts.MarkLineItem(type_="average")]),
)
.add_yaxis(
series_name="普投",
y_axis=[t[2]/20 for t in fina],
symbol="circle",
symbol_size=10,
linestyle_opts=opts.LineStyleOpts(color="blue", width=2, type_="dashed"),
label_opts=opts.LabelOpts(is_show=False),
itemstyle_opts=opts.ItemStyleOpts(
border_width=3, border_color="blue", color="blue"
),
markline_opts=opts.MarkLineOpts(data=[opts.MarkLineItem(type_="average")]),
)
.set_global_opts(
xaxis_opts=opts.AxisOpts(type_="category"),
yaxis_opts=opts.AxisOpts(
type_="value",
axistick_opts=opts.AxisTickOpts(is_show=True),
splitline_opts=opts.SplitLineOpts(is_show=True),
),
tooltip_opts=opts.TooltipOpts(is_show=False),
)
)
line1.render_notebook()
从上图可以看出,普投的收益情况要高于定投。
说明:本文模型比较简单,仅作为学习pyhton数据分析的素材,不作为投资依据,感兴趣的朋友可以继续深入探索。另外,若对本文有疑问,请在留言区评论。
程序员GitHub,现已正式上线! 接下来我们将会在该公众号上,专注为大家分享GitHub上有趣的开源库包括Python,Java,Go,前端开发等优质的学习资源和技术,分享一些程序员圈的新鲜趣事。
推荐阅读:
这个GitHub 1400星的Git魔法书火了,斯坦福校友出品丨有中文版 贼 TM 好用的 Java 工具类库 超全Python IDE武器库大总结,优缺点一目了然! 秋招来袭!GitHub28.5颗星!这个汇聚阿里,腾讯,百度,美团,头条的面试题库必须安利! 收获10400颗星!这个Python库有点黑科技,竟然可以伪造很多'假'的数据! 牛掰了!这个Python库有点逆天了,竟然能把图片,视频无损清晰放大!
点这里,获取一大波福利
评论