1 前言
2022年1月末,正值年前,股票市场持续大幅下跌,与之相应的基金市场也出现了近一周的持续跌势。作为一个资深的投资者,我承认自己曾是一名“韭菜”,在2021年12月初购买了中欧医疗健康混合C基金。这只基金由医疗板块的佼佼者葛兰担任基金经理。尽管我听闻葛兰是医疗板块最杰出的基金经理之一,而医疗行业又是民生大计,当时我对这次投资有着极高的期望,期待着获得可观的收益。
然而,我购买这只基金后,却经历了一个月的持续下跌,导致我的投资亏损接近15%。为了改变这一局面,我不断学习有关基金的知识,希望通过数据分析的方法来量化我的购买决策,以科学的方式获取更多的收益。
2 数据采集/清洗
数据来源与所需数据
为了进行准确的数据分析,我们将从天天基金网获取必要的数据。以下是我们需要收集的数据:
- 中欧医疗健康混合C基金的历史净值和日涨幅数据。
- 同类型基金(医疗行业)的历史净值均值和日涨幅数据。
- 沪深300指数基金的历史净值和日涨幅数据。
- 中欧医疗健康混合C基金的用户评论数据。
针对中欧医疗健康混合C的历史净值以及日涨幅、同类型基金(医疗)的历史净值的均值以及日涨幅、沪深300指数基金历史净值以及日涨幅数据利用Python的requests库对天天基金网进行爬取。点击“基金档案”并搜索“中欧医疗健康混合C”可以看到基金净值的表格,网站截图如下所示:
并且通过天天基金网的板块检索选择与中欧医疗相似的七只基金,基金代码分别是007613、001563、003581、005043、007111、005044、110023。具体操作如下图所示:
2.1 数据采集
#导入相应的包
import requests
import re
import json
import pandas as pd
#爬取中欧医疗数据
df_list = []
for i in range(1,65):
url = "http://api.fund.eastmoney.com/f10/lsjz?callback=jQuery18304159015262110892_1643544350831&fundCode=003096&pageIndex={}&pageSize=20&startDate=&endDate=&_=1643545365216".format(i)
headers = {
"Referer":"http://fundf10.eastmoney.com/jjjz_003096.html",
"User-Agent":'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0',
}
resp = requests.get(url,headers=headers)
html = resp.text
res = re.findall('\((.*?)\)',html)
datas = json.loads(res[0])["Data"]["LSJZList"]
df = pd.DataFrame(datas)
df_list.append(df)
df_data = pd.concat(df_list)
df_data.to_csv('中欧医疗健康混合C (003096).csv',index=False,encoding="utf_8_sig")
#爬取同医疗类型基金数据并计算净值均值方便以后对比
same_type = ["007613","001563","003581","005043","007111","005044","110023"]
pages = [25,64,62,50,34,50,64]
df_list = []
for index in range(1,65):
lis = []
for i in range(0,7):
if pages[i] >= index:
lis.append(same_type[i])
else:
pass
df1 = []
for i in lis:
url = "http://api.fund.eastmoney.com/f10/lsjz?callback=jQuery18304159015262110892_1643544350831&fundCode={}&pageIndex={}&pageSize=20&startDate=&endDate=&_=1643545365216".format(i,index)
headers = {
"Referer":"http://fundf10.eastmoney.com/jjjz_{}.html".format(i),
"User-Agent":'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0',
}
resp = requests.get(url,headers=headers)
html = resp.text
res = re.findall('\((.*?)\)',html)
datas = json.loads(res[0])["Data"]["LSJZList"]
df = pd.DataFrame(datas)
df1.append(df)
df_new = pd.concat(df1,keys=lis)
df_list.append(df_new)
df_data = pd.concat(df_list)
df_data.to_csv('同类基金.csv',index=True,encoding="utf_8_sig")
#爬取沪深300指数净值
df_list = []
for i in range(1,65):
url = "http://api.fund.eastmoney.com/f10/lsjz?callback=jQuery18304159015262110892_1643544350831&fundCode=050002&pageIndex={}&pageSize=20&startDate=&endDate=&_=1643545365216".format(i)
headers = {
"Referer":"http://fundf10.eastmoney.com/jjjz_050002.html",
"User-Agent":'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0',
}
resp = requests.get(url,headers=headers)
html = resp.text
res = re.findall('\((.*?)\)',html)
datas = json.loads(res[0])["Data"]["LSJZList"]
df = pd.DataFrame(datas)
df_list.append(df)
df_data = pd.concat(df_list)
df_data.to_csv('博时沪深300指数A (050002).csv',index=False,encoding="utf_8_sig")
2.2 数据清洗
import os
import re
import math
import pandas as pd
df_base = pd.read_csv('中欧医疗健康混合C (003096).csv')
df_avg = pd.read_csv('同类医疗基金均值.csv')
df_300 = pd.read_csv('博时沪深300指数A (050002).csv')
def data_extraction(df,col): #df_avg的col=3,其余为6
df_flashback = df.reindex(index=df.index[::-1])
cumulative_growth = []
sum_up = 0
for i in range(0,1280):
cod = float(df_flashback.iloc[i,col])
sum_up += cod
cumulative_growth.append(sum_up)
data = {
"FSRQ":pd.Series(df_flashback["FSRQ"].values),
"DWJZ":pd.Series(df_flashback["DWJZ"].values),
"JZZZL":pd.Series(df_flashback["JZZZL"].values),
"DWZZL":pd.Series(cumulative_growth)
}
new_df = pd.DataFrame(data)
return new_df
3 净值可视化
为了更好地理解中欧医疗基金的历史走势和业绩表现,我们将利用 pyecharts 结合 DataFrame 进行数据可视化。pyecharts 提供了强大的绘图方法,而 DataFrame 则作为数据的基础,让我们可以更方便地呈现分析结果。
(1)使用 DataFrame 进行图像绘制
在进行数据分析时,数据通常存储在 DataFrame 中,为了更好地使用这些数据进行图像绘制,我们可以结合 pyecharts 库,使用 DataFrame 的 plot 方法来进行图像绘制。通过这种方式,我们可以轻松地生成交互式图表,以及更好地展示数据之间的关系和变化。
(2)图表多样性
pyecharts 提供了各种图表类型,例如折线图、柱状图、散点图等,可以根据数据的性质和分析的需求选择合适的图表类型。同时,这些图表也支持交互功能,例如鼠标悬停、放大缩小等,使数据可视化更加生动和有趣。
通过净值可视化,我们可以更直观地观察中欧医疗基金的历史净值走势,与同类基金以及市场指数的对比情况。这将有助于我们更深入地了解基金的表现,从而为投资决策提供更多的依据。
中欧医疗健康混合C历史净值数据可视化
from eplot import eplot
df1 = pd.Series(data_extraction(df_base,6)['DWJZ'].values.tolist(),
index= data_extraction(df_base,6)['FSRQ'].values.tolist())
df1.eplot()
从可视化结果中可以明显看出,自2016年11月8日中欧医疗健康混合C基金成立之初,该基金在短时间内获得了显著的上涨,一直持续到2021年5月左右,净值达到了约4.5。然而,自2021年开始,该基金的净值开始连续下跌,这也是导致我亏损的主要原因之一。
中欧医疗健康混合C与其他基金对比
(1)中欧医疗成立以来涨幅对比
from pyecharts.charts import Line #导入折线图
from pyecharts import options as opts
line=(
Line()
.set_global_opts(
tooltip_opts=opts.TooltipOpts(is_show=False),
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),
),
)
.add_xaxis(xaxis_data=data_extraction(df_base,6)["FSRQ"].values.tolist())
.add_yaxis(
series_name="中欧医疗",
y_axis=data_extraction(df_base,6)["DWZZL"].values.tolist(),
symbol="emptyCircle",
is_symbol_show=True,
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis(
series_name="沪深300",
y_axis=data_extraction(df_300,6)["DWZZL"].values.tolist(),
symbol="emptyCircle",
is_symbol_show=True,
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis(
series_name="同类均值",
y_axis=data_extraction(df_avg,3)["DWZZL"].values.tolist(),
symbol="emptyCircle",
is_symbol_show=True,
label_opts=opts.LabelOpts(is_show=False),
)
)
line.render_notebook()
根据我们的数据可视化结果,可以清晰地看出中欧医疗基金的涨幅已经远远超过了同类基金的均值以及沪深300指数。这样的表现令人印象深刻,表明中欧医疗基金在过去的一段时间里取得了非常可观的业绩。
(2)近一年的涨幅对比
def data_extraction_year(df,col): #df_avg的col=3,其余为6
df = df[0:366]
df_flashback = df.reindex(index=df.index[::-1])
cumulative_growth = []
sum_up = 0
for i in range(0,366):
cod = float(df_flashback.iloc[i,col])
cumulative_growth.append(sum_up)
sum_up += cod
data = {
"FSRQ":pd.Series(df_flashback["FSRQ"].values),
"DWJZ":pd.Series(df_flashback["DWJZ"].values),
"JZZZL":pd.Series(df_flashback["JZZZL"].values),
"DWZZL":pd.Series(cumulative_growth)
}
new_df = pd.DataFrame(data)
return new_df
from pyecharts.charts import Line #导入折线图
x = data_extraction_year(df_base,6)["FSRQ"].values.tolist()
y1 = data_extraction_year(df_base,6)["DWZZL"].values.tolist()
y2 = data_extraction_year(df_300,6)["DWZZL"].values.tolist()
y3 = data_extraction_year(df_avg,3)["DWZZL"].values.tolist()
line=(
Line()
.set_global_opts(
tooltip_opts=opts.TooltipOpts(is_show=False),
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),
),
)
.add_xaxis(xaxis_data=x)
.add_yaxis(
series_name="中欧医疗",
y_axis=y1,
symbol="emptyCircle",
is_symbol_show=True,
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis(
series_name="沪深300",
y_axis=y2,
symbol="emptyCircle",
is_symbol_show=True,
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis(
series_name="同类均值",
y_axis=y3,
symbol="emptyCircle",
is_symbol_show=True,
label_opts=opts.LabelOpts(is_show=False),
)
)
line.render_notebook()
我们可以看出中欧医疗基金的涨跌幅度已经趋近于同类基金的均值以及市场指数的均值。这表明在近一年的时间里,中欧医疗基金的表现已经不如之前几年。虽然总体上来看,中欧医疗基金的涨幅仍然是可观的,超过了同类基金的均值以及市场指数的均值,但业绩下滑确实是不可忽视的事实。
(3)近三个月的涨幅对比
def data_extraction_month3(df,col): #df_avg的col=3,其余为6
df = df[0:80]
df_flashback = df.reindex(index=df.index[::-1])
cumulative_growth = []
sum_up = 0
for i in range(0,80):
cod = float(df_flashback.iloc[i,col])
cumulative_growth.append(sum_up)
sum_up += cod
data = {
"FSRQ":pd.Series(df_flashback["FSRQ"].values),
"DWJZ":pd.Series(df_flashback["DWJZ"].values),
"JZZZL":pd.Series(df_flashback["JZZZL"].values),
"DWZZL":pd.Series(cumulative_growth)
}
new_df = pd.DataFrame(data)
return new_df
from pyecharts.charts import Line #导入折线图
x = data_extraction_month3(df_base,6)["FSRQ"].values.tolist()
y1 = data_extraction_month3(df_base,6)["DWZZL"].values.tolist()
y2 = data_extraction_month3(df_300,6)["DWZZL"].values.tolist()
y3 = data_extraction_month3(df_avg,3)["DWZZL"].values.tolist()
line=(
Line()
.set_global_opts(
tooltip_opts=opts.TooltipOpts(is_show=False),
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),
),
)
.add_xaxis(xaxis_data=x)
.add_yaxis(
series_name="中欧医疗",
y_axis=y1,
symbol="emptyCircle",
is_symbol_show=True,
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis(
series_name="沪深300",
y_axis=y2,
symbol="emptyCircle",
is_symbol_show=True,
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis(
series_name="同类均值",
y_axis=y3,
symbol="emptyCircle",
is_symbol_show=True,
label_opts=opts.LabelOpts(is_show=False),
)
)
line.render_notebook()
从图可见中欧医疗的业绩已经远远不如同类均值以及市场均值,与此同时中欧医疗的基金规模不断的扩大。说明散户都认为这时是底部,大家都进行了抄底,但是由于美联储加息政策的出台,造成了情绪恐慌,市场下跌严重。而中欧医疗抗跌能力远远不及同类均值,造成了大量用户损失,这也是我损失的原因。
(4)近一个月的涨幅对比
def data_extraction_month(df,col): #df_avg的col=3,其余为6
df = df[0:32]
df_flashback = df.reindex(index=df.index[::-1])
cumulative_growth = []
sum_up = 0
for i in range(0,32):
cod = float(df_flashback.iloc[i,col])
cumulative_growth.append(sum_up)
sum_up += cod
data = {
"FSRQ":pd.Series(df_flashback["FSRQ"].values),
"DWJZ":pd.Series(df_flashback["DWJZ"].values),
"JZZZL":pd.Series(df_flashback["JZZZL"].values),
"DWZZL":pd.Series(cumulative_growth)
}
new_df = pd.DataFrame(data)
return new_df
from pyecharts.charts import Line #导入折线图
x = data_extraction_month(df_base,6)["FSRQ"].values.tolist()
y1 = data_extraction_month(df_base,6)["DWZZL"].values.tolist()
y2 = data_extraction_month(df_300,6)["DWZZL"].values.tolist()
y3 = data_extraction_month(df_avg,3)["DWZZL"].values.tolist()
line=(
Line()
.set_global_opts(
tooltip_opts=opts.TooltipOpts(is_show=False),
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),
),
)
.add_xaxis(xaxis_data=x)
.add_yaxis(
series_name="中欧医疗",
y_axis=y1,
symbol="emptyCircle",
is_symbol_show=True,
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis(
series_name="沪深300",
y_axis=y2,
symbol="emptyCircle",
is_symbol_show=True,
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis(
series_name="同类均值",
y_axis=y3,
symbol="emptyCircle",
is_symbol_show=True,
label_opts=opts.LabelOpts(is_show=False),
)
)
line.render_notebook()
从图可见医疗板块在本次市场下跌中是下跌比较严重的板块,并且中欧医疗的抗跌能力非常差,由此可以推出这只基金最大回撤率非常的高。这是股票型基金的特点——大涨大跌。根据我稳健型的投资风格,我可能会放弃这只基金,转站债券、指数基金等具有相对稳定收益的理财产品。
4 结语
通过本次数据分析,我们深入了解了中欧医疗基金的历史表现、市场对比以及投资者评价。投资是一个复杂的过程,涵盖了众多因素和风险。在投资决策中,我们需要综合考虑基金的历史业绩、市场动态、用户评价等因素,制定合理的投资策略。
无论是基金的业绩表现还是市场的波动,都需要我们保持冷静、理性的态度。过去的表现并不能完全预测未来,市场也可能受到各种因素的影响而产生波动。因此,在投资决策中,我们应该保持警惕,随时准备应对市场的变化。
投资需要谨慎,也需要积极的学习和分析。通过数据的深入挖掘,我们能更好地了解基金的特点和市场的变化。在未来的投资征程中,让我们坚持谨慎乐观的态度,保持灵活性,不断优化投资计划,以期获得更稳健的投资回报。
注意:本文的分析仅供参考,投资决策需谨慎。投资者应根据自身情况和市场风险,做出明智的选择。