背景
今日我的Python心路历程是 基金实战可视化之根据基金代码离线获取净值并展示趋势
分析
主要逻辑及注意事项:
- 日期轴显示:因为系统是毫秒级timeStamp故此需要除以1000取秒级timeStamp,否则转换后的日期不对
- 主次轴差异化显示
- 数据整合:提取x、y1、y2轴数据并整合, pd.merge适用于Series数据类型
方案
核心代码如下:
# 根据基金代码离线获取净值, 并展示趋势
def getWorthbyJSFile(fscode):
# 获取绝对路径,funddata为当前文件夹
curpath = os.path.join(os.path.dirname(__file__), 'funddata')
fileName = fscode + 'content.js'
file_object_path = os.path.join(curpath, fileName)
f = open(file_object_path, 'r', encoding='utf-8')
content = f.read()
f.close()
jsContent = execjs.compile(content)
# 基金名称及代码
name = jsContent.eval('fS_name')
code = jsContent.eval('fS_code')
# 初始化要显示的字符串
showStr = ""
# 收益率 应用时需要加百分比
# 近一年收益率
syl_1n = jsContent.eval('syl_1n')
# 近6月收益率
syl_6y = jsContent.eval('syl_6y')
# 近三月收益率
syl_3y = jsContent.eval('syl_3y')
# 近一月收益率
syl_1y = jsContent.eval('syl_1y')
showStr += u"近一年收益率:%s" % syl_1n + '%' +"\n"
showStr += u"近6月收益率:%s" % syl_6y + '%' + "\n"
showStr += u"近3月收益率:%s" % syl_3y + '%' + "\n"
showStr += u"近1月收益率:%s" % syl_1y + '%' + "\n"
# 单位净值走势(及时的交易价值参考)
netWorthTrendData = jsContent.eval('Data_netWorthTrend')
# 累计净值走势=单位净值+累计分红
ACWorthTrendData = jsContent.eval('Data_ACWorthTrend')
# 基金规模,fluctuationScaleData
fluctuationScaleData = jsContent.eval('Data_fluctuationScale')
l = len(fluctuationScaleData['categories']) - 1
fluctuationDate = fluctuationScaleData['categories'][l]
fluctuationScale = fluctuationScaleData['series'][l]['y']
# # 平均排名Data_rateInSimilarType
#
# # 同类排名走势 var Data_rateInSimilarType
# rateInSimilarTypeData = jsContent.eval('Data_rateInSimilarType')
# l = len(rateInSimilarTypeData) - 1
# newrateInSimilarTypeX = datetime.datetime.fromtimestamp(int(rateInSimilarTypeData[l]['x'] / 1000)) #* 24 * 3600)))
# newrateInSimilarTypeX.strftime('%Y-%m-%d')
# newrateInSimilarTypeY = rateInSimilarTypeData[l]['y']
# newrateInSimilarTypeSC = rateInSimilarTypeData[l]['sc']
#
# newrateInSimilarType = str(newrateInSimilarTypeY) + ' / ' + newrateInSimilarTypeSC
#
#
#
#
# # 同类排名百分比 var Data_rateInSimilarPersent
# 现任基金经理
currentFundManager = jsContent.eval('Data_currentFundManager')
showStr += u"现任基金经理:%s" % currentFundManager[0]['name'] + "\n"
showStr += u"管理规模:%s" % currentFundManager[0]['fundSize']
# y轴, 单位净值,累计净值
netWorthTrend = [v["y"] for v in netWorthTrendData]
ACWorthTrend = [v[1] for v in ACWorthTrendData]
# x轴,日期。因为系统是毫秒级timeStamp故此需要除以1000取秒级timeStamp,否则转换后的日期不对
# vtimeStamp = [int(v["x"] / 1000) for v in netWorthTrendData] # // 算法符号的结果可以直接取整
# x轴:日期。获取年月日需要除以(1000 *24*3600),因为系统是毫秒级timeStamp。
vtimeStamp = [int(v["x"] / (1000*24*3600)) for v in netWorthTrendData] # // 算法符号的结果可以直接取整
xs = pd.to_datetime(vtimeStamp, unit='D') # , 看源码设定对应的unit,'s'类同format='%Y-%m-%dT%H:%M:%S'但其结果会出人意料的差
# 定义字段名
colSet = ['Date', 'netWorth', 'ACWorth']
# 提取x、y1、y2轴数据并整合, pd.merge适用于Series数据类型
# 设置y轴数据
snetWorthTrend = pd.Series(netWorthTrend, name=colSet[1])
sACWorthTrend = pd.Series(ACWorthTrend, name=colSet[2])
tech_df = pd.merge(snetWorthTrend, sACWorthTrend, how='outer', left_index=True,
right_index=True)
# 设置x轴数据
stimeStamp = pd.Series(xs, name=colSet[0])
tech_df.index = stimeStamp
print(tech_df.head())
# 测试基本图
# tech_df.plot()
# 主次轴差异化显示
tech_df.plot(secondary_y=colSet[2], grid=True)
ax = plt.gca() # 表明设置图片的各个轴,plt.gcf()表示图片本身
ax.xaxis.set_major_formatter(mdate.DateFormatter(
'%Y-%m-%d')) # 横坐标标签显示的日期格式;注意,如果不加语句plt.gca().xaxis.set_major_formatter(mdate.DateFormatter('%Y-%m-%d')),则横坐标只显示年份
plt.xlabel(u'日期')
plt.ylabel(u'累计净值')
plt.title(name+':'+code)
plt.text('2017-01-01', 0.65, showStr)
plt.gcf().autofmt_xdate() # 自动旋转日期标记
# plt.tight_layout()
plt.show()
# # 本基金参数信息
# jsInfo = [code, name, currentFundManager[0]['name'], currentFundManager[0]['fundSize'], syl_1y, syl_3y, syl_6y, syl_1n, fluctuationDate, fluctuationScale, newrateInSimilarType]
#
# # 替换字段名称
# # openF.rename(columns={'序号':'NO.','基金代码':'code','基金简称':'name', '日期':'date','单位净值':'unitnet','累计净值':'sumnet','日增长率':'Dailygrowth','近1周':'Rweek','近1月':'R1month','近3月':'R3months','近6月':'R6months','近1年':'R1year','近2年':'R2years','近3年':'R3years','今年来':'thisyear','成立来':'SinceFounded')
# print("基金代码 基金简称 姓名 管理规模 单位净值 累计净值 近1月 近3月 近6月 近1年 最新变动日期 本基规模(亿RMB) 最新同类排名走势")
# print(jsInfo)
return