Python分析10万条基金数据,探索基金定投的奥秘

菜鸟学Python

共 8146字,需浏览 17分钟

 ·

2020-12-25 01:38

基金定投这个名词大家都不陌生,喜欢理财的朋友可能都尝试过,今天我想给大家分享是,用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[0for t in result])
    .add_yaxis(
        series_name="定投",
        y_axis=[t[2for 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[3for 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库有点逆天了,竟然能把图片,视频无损清晰放大!


点这里,获取一大波福利

浏览 23
点赞
评论
收藏
分享

手机扫一扫分享

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

手机扫一扫分享

分享
举报