用Python搞了个基金查询机器人,还可以拓展

今天给大家分享一个综合了数据采集、处理、分析、可视化、接口调用等技术点的项目。

一、说点东西

老早就想搞个基金监控机器人了,方便自己查看自己关注基金的各种指数涨跌情况,及时进行止损或者止盈,今天我们先建楼基,手把手带大家实现一个基金查询机器人,目前主要可以查询基金指定日期段数据和查看基金净值走势图,后面慢慢新增功能。

二、开始动手动脑

2.1 环境准备

  • Linux、Mac、Windows 都可以

  • python 3.7及以上

  • 相关第三方包:pandas(数据处理)、requests(爬取数据)、re(文本内容解析)、akshare(获取基金股票数据)、matplotlib(数据可视化)、dataframe-image(dataframe表格转成图片)

最近整理了一套编程学习资料分享给大家,全是干货内容,包含教程视频、电子书、源码笔记、学习路线图、实战项目、面试题等等,关注gzh【Python编程学习圈】就能免费获取,回复关键词【学习资料】即可,抓紧时间吧!

2.2 获取指定日期段基金数据

基金数据可以从一些金融相关的网站获取到,比如天天基金网、新浪基金网等,可以自己写爬虫程序获取网站数据,也可以使用现成的工具包获取数据,比如之前介绍过的 tushare 和akshare等库。

这里我们同时介绍下两种方法:

2.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)

2.2.2 自己调用现成数据接口

本质上akshare也是从一些金融相关的网站获取到数据,我们也可以自己写代码进行获取,通过浏览器我们很快能搜索到基金数据接口,来自东方财富的天天基金网。

f'http://fund.eastmoney.com/f10/F10DataApi.aspx?type=lsjz&code={code}&page={page}&sdate={start_date}&edate={end_date}&per={per}'

code - 基金代码
page - 基金数据页码
start_date - 数据开始日期
end_date - 数据结束日期
per - 每页展现数据量,最多40

根据指定参数,浏览器会返回指定参数,一段js赋值代码,包括了 基金数据(content)、总记录条数(records)、总页数(pages)、当前页数(curpage)。

格式非常规整,我们可以直接通过正则提取数据,

'''
获取单页面 基金数据
'''
def get_html(code, start_date, end_date, page=1, per=40):
    url = f'http://fund.eastmoney.com/f10/F10DataApi.aspx?type=lsjz&code={code}&page={page}&sdate={start_date}&edate={end_date}&per={per}'
    # print(url)
    rsp = requests.get(url)
    html = rsp.text
    
    return html

通过返回的数据可以发现,基金数据部分是一个由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_htmlparses_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

上面两种方法都可以获取到基金净值数据,最后我选择了akshare方式获取,设置一个定时任务,每天三点更新自己关注的基金所有数据,存储到本地,后面要查询的时候直接读取本地文件查询即可。

  • 定时任务:每天早上3点获取所有关注的基金历史数据,存储到本地

# 定时任务:每天早上3点获取所有关注的基金历史数据,存储到本地
def get_all():
    try:
        # 从文件读取 自己关注的基金代码列表
        with open('./FD/funds.txt') as f:
            funds = [i.strip() for i in f.readlines()]
        # 遍历 一个个更新数据
        for fund in funds:
            fund_df = ak.fund_em_open_fund_info(fund, indicator='单位净值走势')
            fund_df = fund_df.sort_values(by=['净值日期'], ascending=False)
            fund_df.to_csv(f"./FD/DATA/F{fund}_data.csv", index=False)
            # print(f"./FD/DATA/F{fund}_data.csv")
            time.sleep(random.randint(1,5))
        return '基金数据更新完成'
    except Exception as e:
        r = f"【错误信息】{e}"
        return r
  • 获取指定基金 指定日期段 净值数据

# 获取指定基金 指定日期段 净值数据
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

2.3 返回数据呈现方式

目前先简单点,设置规则如下:

  • 1)如果数据量小于等于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设置数据表格样式(单位净值最大值、最小值高亮和日增长率添加百分号)。

  • 2)如果数据量大于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'

2.4 对接钉钉机器人设置守护程序

目前项目对接了两种机器人:钉钉群机器人和企业机器人,相关配置方法因篇幅原因这里不展开介绍。

钉钉群机器人主要用来汇报每天自动汇报基金数据更新情况,后面还可以加基金涨跌检测情况等。

企业机器人主要用来做基金数据查询自动回复功能,也可以拓展主动发消息给用户。

2.5 最终效果图

  • 指定查询

查看某基金某个时间段内的基金净值数据。(30条以内数据,表格展示;大于30条,趋势图展示)

查询格式: F基金代码 起始日期 结束日期,如:F005827 2021-12-03 2022-02-10

效果图

  • 普通查询

查看某基金近10天内净值和日增长率数据+趋势图

查询格式: F基金代码,如:F005827

最近10天内,只有两个交易日

三、后言后语

这项目说大不大,说小也不小,百行代码。目前基金监测机器人还比较简陋,甚至都没有监测功能(目前只支持数据查询和更新),但是这个楼基很稳、很深,后面添加其他功能会简单、便捷许多,欢迎大家评论区留言,说说你想为这个机器人添加的功能。完整代码在下个版本文章发布时一起分享出来,还请耐心等待。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
追踪印度共同基金的铬扩展。 不再需要为您的金融投资组合中的所有共同基金添加书签!此扩展程序可用于一键跟踪您的所有共同基金。可以通过精美的用户界面通过此扩展程序跟踪“当前资产净值”,“百分比变化”等详细信息 =============版本4.3.3 ==============添加了更新电子邮件按钮==============版本4.3.2 ==============固定3年和5年颜色===============版本4.3.1 ======== ======基于过滤器的固定图表持续时间文本==============版本4.3.0 ===============提供了多个持续时间过滤器图表,例如1个月,3个月,6个月,1年,3年和5年 =============版本4.2.0 ================================================== =======版本4.1.1 ==============共同基金列表已升级 =============版本4.1.0 =============添加了Instamojo捐赠按钮! =============版本4.0.3 ==========================================================================================================================================================================================================================================================================================> =============版本4.0.0 ==============现在,详细信息页面添加了漂亮的图表,显示了过去10天的趋势 =============版本3.0.0 ==============此版本包含“详细信息”页面的主要版本。在此更新之前,单击用于重定向到Zerodha网站的基金名称。现在,详细信息显示在扩展本身中 =============版本2.1.7 ==============在获取数据之前添加了加载显示功能 ============= 2.1.1版==============现在添加了“功能请求”按钮。您可以请求在扩展中看到的新功能,其余的我们将处理! =============版本2.1.0 ==============已启用Chrome同步。在Chrome浏览器中登录到Google帐户后,您就可以在其他计算机上访问您的资金了 ==========版本2 ===========版本2具有许多UI更改,其中新字体和颜色在浏览器上看起来很漂亮。预计很快就会在即将发布的版本中推出新功能,例如完整的共同基金详细信息(弹出窗口),图表(一段时间内的基金业绩)等。继续等待。干杯! ==========版本1 ===========基本功能支持搜索和跟踪共同基金。注意:目前,该扩展程序仅支持印度共同基金。如果您有任何建议/反馈,请给我发送电子邮件[mail@sunilkumarc.in] 支持语言:English (United States)
好的,让我们通过 Python 编写一个简单的机器人来回答你的问题。 你可以使用 Python 的聊天机器人库 chatterbot 来实现这个机器人,首先需要安装 chatterbot 库,可以通过 pip 命令来安装: ``` pip install chatterbot ``` 接下来,我们可以创建一个 Python 文件,并编写以下代码: ```python from chatterbot import ChatBot from chatterbot.trainers import ListTrainer # 创建一个 chatbot 对象 chatbot = ChatBot('MyBot') # 使用 ListTrainer 对象进行训练 trainer = ListTrainer(chatbot) # 训练 chatbot 对象 trainer.train([ '你好', '你好,有什么我可以帮助你的吗?', '什么是人工智能?', '人工智能是模拟人类智能的计算机系统,包括学习、推理、感知和自然语言处理。', '谢谢', '不用谢,有需要随时联系我哦!' ]) # 与 chatbot 对象进行交互 while True: user_input = input('你:') bot_response = chatbot.get_response(user_input) print('机器人:', bot_response) ``` 这个机器人会回答一些简单的问题,例如问候、人工智能的定义等。你可以通过修改训练集列表来训练机器人回答更多的问题。运行脚本后,你可以和机器人进行交互,在输入问题后,它会给出相应的回答。 需要注意的是,这个机器人只是一个简单的示例,它的应用场景非常有限。如果你想要构建更复杂和实用的机器人,需要深入学习自然语言处理和机器学习等领域的知识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值