说点东西
开始动手动脑
1环境准备
Linux、Mac、Windows都可以python7及以上相关第三方包:pandas、requests、re、akshare、matplotlib、dataframe-image
2获取指定日期段基金数据
基金数据可以从一些金融相关的网站获取到,比如天天基金网、新浪基金网等,可以自己写爬虫程序获取网站数据,也可以使用现成的工具包获取数据。
1回顾下akshare获取基金数据
目前akshare不支持获取指定日期范围内的基金净值数据,但是可以一次获取到基金历史净值数据,调用函数fund_em_open_fund_info获取基金历史数据,然后自己根据日期选取时间断进行分析。
import akshare as ak
fund_data = ak.fund_em_open_fund_info(fund="005827", indicator="单位净值走势")
print(fund_data)
自己调用现成数据接口
本质上akshare也是从一些金融相关的网站获取到数据,我们也可以自己写代码进行获取,通过浏览器我们很快能搜索到基金数据接口,来自东方财富的天天基金网。
根据指定参数,浏览器会返回指定参数,一段js赋值代码,包括了基金数据、总记录条数、总页数、当前页数。
格式非常规整,我们可以直接通过正则提取数据,
通过返回的数据可以发现,基金数据部分是一个由table标签包裹的html代码,那我们可以直接使用pandas的read_html来解析数据。
# 从html中解析出数据表部分 并解析成df
def parses_table(html):
# 获取基金数据表
pattern = "content:"<table(.*)</table>","
table = re.search(pattern, html).group(1)
table = "<table" + table + "</table>"
fund_data = pd.read_html(table)[0]
return fund_data
前面有提到,基金数据接口返回数据每页最多展示40条,所以要想获取所有数据,我们可能需要遍历每一页,那么我们还需要通过正则将总页数pages获取到,然后遍历调用get_html和parses_table函数解析出所有数据。
# 获取指定日期内 累计净值 等数据
def get_fund_data(code, start_date, end_date):
first_page = get_html(code, start_date, end_date)
# 获取总页数
pattern = "pages:(.*),"
pages = re.search(pattern, first_page).group(1)
# 转成int数据
try:
pages = int(pages)
except Exception as e:
r = f"【错误信息】{e}"
# print(r)
return r
# 存放每页获取到的基金数据 dataframe格式 便于后面合并
fund_df_list = []
# 循环便利所有页面
for i in range(pages):
if i == 0:
fund_data = parses_table(first_page)
else:
page_html = get_html(code, start_date, end_date, page=i+1)
fund_data = parses_table(page_html)
fund_df_list.append(fund_data)
# 将每页的数据合并到一起
fund_df = pd.concat(fund_df_list)
return fund_df
获取指定基金指定日期段净值数据
# 获取指定基金 指定日期段 净值数据
def get_fund_data(fund, start_d, end_d):
fund_df = pd.read_csv(f"./FD/DATA/{fund}_data.csv")
result_df = fund_df.query(f""{start_d}"<=净值日期<="{end_d}"")
return result_df
3返回数据呈现方式
目前先简单点,设置规则如下:
如果数据量小于等于30条,就返回原始数据
原始数据就是直接将获取到的数据转成片的方式发送给用户,这里我们使用dataframe-image这个第三方包,使用非常简单,pip安装后,直接调用export函数即可快速将datafrmae数据转成片。
# 将dtaframe表格转变成图片
def df_to_img(fund_df, fund, start_d, end_d):
if fund_df.shape[0] <=1:
dfi.export(fund_df, f"./FD/IMG/{fund}_{start_d}_{end_d}_data.png")
return
# 格式化表格 凸显最大最小值
fund_df = fund_df.style.highlight_max(subset=["单位净值"], color="red")
.highlight_min(subset=["单位净值"], color="green")
.format({"日增长率": "{:}%"})
dfi.export(fund_df, f"./FD/IMG/{fund}_{start_d}_{end_d}_data.png")
为了片数据更好看,我们还使用了df.style设置数据表格样式。
如果数据量大于30条,就返回原始数据趋势
原始数据趋势就是将数据可视化下,然后返回给用户,这里我们选择绘制数据的走势,使用matplotlib进行绘制。
# 绘制基金单位净值走势图
def draw_fund_line(fund_df, fund, start_d, end_d):
plt.rcParams["figure.figsize"] = (8.0, 4.0) # 设置figure_size尺寸
plt.rcParams["savefig.dpi"] = 300 #保存图片分辨率
# 不显示右、上边框
ax=plt.gca()
ax.spines["right"].set_color("none")
ax.spines["top"].set_color("none")
# 设置坐标网格
plt.grid(axis="y", color="gray")
# 计算最大值 最小值坐标 并标注到图中
fund_max = fund_df.loc[fund_df["单位净值"].idxmax()]
fund_min = fund_df.loc[fund_df["单位净值"].idxmin()]
ax.annotate(f"({fund_max[0]},{fund_max[1]})", xy=(fund_max[0], fund_max[1]), color="red")
ax.annotate(f"({fund_min[0]},{fund_min[1]})", xy=(fund_min[0], fund_min[1]), color="green")
# 画图
plt.plot(fund_df["净值日期"],fund_df["单位净值"], color="c")
plt.title("基金单位净值走势图")
plt.xticks(rotation=30)
plt.xlabel("净值日期")
plt.ylabel("单位净值")
plt.savefig(f"./FD/IMG/{fund}_{start_d}_{end_d}_data.png")
这里使用的是折线,有一些对片样式的设置,比如:大小、边框、最大/小值标注,但依然不是很美观,后面继续优化。
完整调用
# 返回数据
def response_data(fund, start_d, end_d):
# 本地查看 查询结果是否已存在
imgs = os.listdir("./FD/IMG/")
if f"{fund}_{start_d}_{end_d}_data.png" in imgs:
return f"./FD/IMG/{fund}_{start_d}_{end_d}_data.png"
# 获取数据
fund_df = get_fund_data(fund, start_d, end_d)
# 如果数据量小于等于30条,就返回原始数据图
if fund_df.shape[0]<= 30:
df_to_img(fund_df, fund, start_d, end_d)
else:
# 否则返回数据趋势图
fund_df = fund_df.sort_values(by=["净值日期"])
draw_fund_line(fund_df, fund, start_d, end_d)
return f"./FD/IMG/{fund}_{start_d}_{end_d}_data.png"
4对接钉钉机器人设置守护程序
钉钉群机器人主要用来汇报每天自动汇报基金数据更新情况,后面还可以加基金涨跌检测情况等。
企业机器人主要用来做基金数据查询自动回复功能,也可以拓展主动发消息给用户,后面研究研究。
5遇到问题及解决方法
1Linux上datafrmae-image转片出错
最开始是提示没有chrom,然后按网上教程安装了googlechrom。
安装后,运行代码提示SyntaxError:notaPNGfile。
看错误提示以为是Pillow和matplotlib的问题,修改到了和本地一样的版本也不行。
最后看了源码,发现可以转换方法除了使用chrom,还可以用matplotlib,修改后,确实可以正常生成片了,但是没有格式!!!
最后改回默认table_conversion,仔细看,发现有提示以下内容,大概意思linux下不能直接使用root用户权限允许谷歌chrome,最简单的方法就是创建一个普通用户。
useradd od
chown -R od /root
su od
再次运行确实能解决片生成和数据格式问题,但是有新问题:表头中文无法显示。。。
百般搜索,看源码调试、看项目仓库问题都没解决,最后我突然想到,我本地可以,两个包的版本又是一样,应该不是代码问题,会不会是因为linux里没有安装中文字体,所以无法显示中文?
mkdir -p /usr/share/fonts/my_fonts
可以通过下面指令查看中文字体是否安装成功,
fc-list :lang=zh
再次运行代码,生成的片就正常啦~开心!
2matplotlib片中文显示问题
3钉钉机器人无法直接传输片
钉钉机器人目前只支持传输:普通文本、markdown文本、连接、actionCard消息和feedCard消息类型。
如果我想要将生成的基金数据发送给用户,最好的方法是和之前一样,先将片转成链接,然后通过markdown形式传输。
如果系统仅个人使用,数据量不大,我们不必选择网络上现有的床工具,可以直接开放个http端口去共享我们的片,本身企业机器人就使用到了flask,所以我们可以更简单的实现这个功能。
app = Flask(__name__, static_folder="xxx/FD/IMG", static_url_path="/static")
然后将片链接嵌入到markdown中,即可正常返回给用户了。
6最终效果
指定查询
查看某基金某个时间段内的基金净值数据。查询格式:F基金代码起始日期结束日期,如:F0058272021-12-032022-02-10
效果
普通查询
查看某基金近10天内净值和日增长率数据+趋势查询格式:F基金代码,如:F005827
最近10天内,只有两个交易日
关于Python技术储备
学好Python不论是就业还是做副业赚钱都不错,但要学会Python还是要有一个学习规划。最后大家分享一份全套的Python学习资料,给那些想学习Python的小伙伴们一点帮助!
Python所有方向的学习路线
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
Python必备开发工具
精品Python学习书籍
当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。
Python视频合集
观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
实战案例
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
Python练习题
检查学习结果。
面试资料
我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
这份完整版的Python全套学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】
Python资料、技术、课程、解答、咨询也可以直接点击下面名片,添加官方客服斯琪↓
文章为作者独立观点,不代表 股票程序化软件自动交易接口观点