(二)、python程序--基金看板

一、绪论

获取基金数据并展示。

已实现功能:

1、获取基金名称以列表的方式展示,可按照类型筛选,也可以直接搜索;

2、点击左侧基金名称展示日线,移动鼠标竖线跟着移动,并且显示对应日期的基金数据;

3、右上角显示基金的基本信息。

二、代码分享

包含两个.py文件,一个负责展示、一个负责数据获取

JJ_Windows.py

import tkinter as tk
from tkinter import ttk
from tkinter import *
import JJ_InterFace
import pandas as pd
import time


class JJ_Windows:

    def __init__(self, jj_interface):
        self.window = tk.Tk()
        self.window.title('基金看板')
        self.window_width = self.window.winfo_screenwidth()
        self.window_height = self.window.winfo_screenheight()
        self.window.geometry(str(self.window_width) + 'x' + str(self.window_height))
        # 基金数据接口类
        self.columns = ['基金编号', '基金名称', '基金类型']
        self.columns_width = [2, 5, 3]
        self.table_width = 300
        self.search_height = 90
        self.logging_height = 90

        self.jj_interface = jj_interface
        self.jj_codes, self.jj_types, self.jj_names = self.jj_interface.GetCodes()
        self.jj_types_set = set(self.jj_types)
        self.jjs_infor = zip(*[self.jj_codes, self.jj_names, self.jj_types])
        self.jjs_y_infor = pd.DataFrame(self.jjs_infor, columns=self.columns)
        self.jjs_infor = self.jjs_y_infor

        self.jj_code = ''
        self.net_x = []
        self.net_y = []
        self.rate_x = 0
        self.rate_y = 0
        
        self.InitWindows()
        self.window.mainloop()


    def InitWindows(self):
        """初始化界面"""
        ##### 最左侧的表格,并在表格内插入数据
        # 创建表格头和摆放位置
        self.table = ttk.Treeview(master=self.window, height=40, columns=self.columns, show='headings')
        for index, column in enumerate(self.columns):
            self.table.heading(column=column, text=column, anchor=CENTER)
            self.table.column(column=column, width=int(self.table_width*self.columns_width[index]/10), minwidth=5, anchor=CENTER)
        self.table.place(x=0, y=self.search_height)
        # 插入表格数据
        for index, row in self.jjs_infor.iterrows():
            jj_code = row['基金编号']
            jj_name = row['基金名称']
            jj_type = row['基金类型']
            self.table.insert('', END, values=[jj_code, jj_name, jj_type])
        self.table.bind('<ButtonRelease-1>', self.TableViewClick)
        ##### 筛选框
        ttk.Label(self.window, text="类型筛选:").place(x=0, y=10)

        s_jj_type = tk.StringVar()
        self.jj_type_chose_c = ttk.Combobox(self.window, width=15, textvariable=s_jj_type)
        self.jj_type_chose_c['values'] = tuple(self.jj_types_set)
        self.jj_type_chose_c.place(x=60, y=10)

        jj_type_chose_b = tk.Button(self.window, text ="筛选")
        jj_type_chose_b.bind('<ButtonRelease-1>', self.TypeChose)
        jj_type_chose_b.place(x=200, y=8)
        ##### 搜索框
        ttk.Label(self.window, text="名称搜索:").place(x=0, y=50)

        s_jj_name = tk.StringVar()
        self.jj_name_search_c = ttk.Entry(self.window, width=15, textvariable=s_jj_name)
        self.jj_name_search_c.place(x=60, y=50)

        jj_name_search_b = tk.Button(self.window, text ="搜索")
        jj_name_search_b.bind('<ButtonRelease-1>', self.NameSearch)
        jj_name_search_b.place(x=200, y=48)
        ##### 右侧画布
        self.canvas = Canvas(self.window, width=self.window_width-self.table_width, height=self.window_height, bg="black")
        self.canvas.place(x=self.table_width, y=0)
        self.canvas.bind('<Motion>', self.XYMotion)
        ##### 画布上的控件
        self.jj_name_c = self.canvas.create_text(self.window_width-self.table_width-100, 10, text='', font = "time 10", fill='white')
        self.jj_code_c = self.canvas.create_text(self.window_width-self.table_width-100, 25, text='', font = "time 10", fill='white')
        self.syl_1n_c = self.canvas.create_text(self.window_width-self.table_width-100, 40, text='', font = "time 10", fill='white')
        self.syl_6y_c = self.canvas.create_text(self.window_width-self.table_width-100, 55, text='', font = "time 10", fill='white')
        self.syl_3y_c = self.canvas.create_text(self.window_width-self.table_width-100, 70, text='', font = "time 10", fill='white')
        self.syl_1y_c = self.canvas.create_text(self.window_width-self.table_width-100, 85, text='', font = "time 10", fill='white')
        self.jj_line_c = []
        self.jj_x_c = self.canvas.create_line(0, 0, 0, self.window_height, fill='white')
        # self.jj_y_c = self.canvas.create_line(0, 0, self.window_width-self.table_width, 0, fill='white')
        self.jj_xtext_c = self.canvas.create_text(0, 0, text='', font = "time 10", fill='white')
        self.jj_ytext_c = self.canvas.create_text(0, 0, text='', font = "time 10", fill='white')


    def TypeChose(self, event):
        """按照类型进行筛选基金"""
        jj_type = self.jj_type_chose_c.get()
        if jj_type != '':
            self.jjs_infor = self.jjs_y_infor[self.jjs_y_infor['基金类型'] == jj_type]
        self.UpdateTable()


    def NameSearch(self, event):
        """按照名称搜索基金"""
        jj_name = self.jj_name_search_c.get()
        if jj_name != '':
            self.jjs_infor = self.jjs_y_infor[self.jjs_y_infor['基金名称'].str.contains(jj_name)]
        self.UpdateTable()


    def UpdateTable(self):
        """更新表格数据"""
        # 先删除表格数据
        ch_table = self.table.get_children()
        for value in ch_table:
            self.table.delete(value)
        # 插入表格数据
        for index, row in self.jjs_infor.iterrows():
            jj_code = row['基金编号']
            jj_name = row['基金名称']
            jj_type = row['基金类型']
            self.table.insert('', END, values=[jj_code, jj_name, jj_type])


    def XYMotion(self, event):
        """鼠标在画布上滑动,显示竖线,曲线与竖线交叉位置的数据"""
        x, y = event.x, event.y
        self.canvas.coords(self.jj_x_c, x, 0, x, self.window_height)
        # self.canvas.coords(self.jj_y_c, 0, y, self.window_width-self.table_width, y)
        index = int(x/self.rate_x)
        if index >=0 and index <= len(self.net_y):
            x1, y1 = x, self.window_height/2 - (self.net_y[index]-self.net_y_min)*self.rate_y-50
            x2, y2 = x, self.window_height/2 - (self.net_y[index]-self.net_y_min)*self.rate_y-70
            if y2 < 10:
                y1, y2 = 30, 10
            self.canvas.coords(self.jj_xtext_c, x1, y1)
            self.canvas.coords(self.jj_ytext_c, x2, y2)
            self.canvas.itemconfig(self.jj_xtext_c, text=time.strftime("%Y/%m/%d %H:%M:%S", time.localtime(int(self.net_x[index]/1000))))
            self.canvas.itemconfig(self.jj_ytext_c, text=str(self.net_y[index]))


    def TableViewClick(self, event):
        """获得表格里面选择基金的代码,通过基金代码获得数据,并展示数据"""
        # 获得选取的行数据
        for item in self.table.selection():
            item_text = self.table.item(item,"values")
            self.jj_code = item_text[0]
            self.jj_name = item_text[1]
        # 通过基金代码,获得数据
        self.net_x, self.net_y, ACWorth, syl_1n, syl_6y, syl_3y, syl_1y = self.jj_interface.GetWorth(self.jj_code)
        # 展示数据
        self.canvas.itemconfig(self.jj_name_c, text='基金名称:'+self.jj_name)
        self.canvas.itemconfig(self.jj_code_c, text='基金编码:'+self.jj_code)
        self.canvas.itemconfig(self.syl_1n_c, text='近1年收益率:'+str(syl_1n))
        self.canvas.itemconfig(self.syl_6y_c, text='近6个月收益率:'+str(syl_6y))
        self.canvas.itemconfig(self.syl_3y_c, text='近3个月收益率:'+str(syl_3y))
        self.canvas.itemconfig(self.syl_1y_c, text='近1个月收益率:'+str(syl_1y))
        self.clear_jj_line()
        self.draw_jj_line('green')


    def clear_jj_line(self):
        """先删除之前的曲线"""
        for index in self.jj_line_c:
            self.canvas.delete(index)
        self.jj_line_c.clear()


    def draw_jj_line(self, color):
        """画曲线"""
        # 整个曲线的宽度
        x_edging = 10
        y_edging = 10
        jj_line_width = self.window_width - self.table_width - 2*x_edging
        # 整个曲线的高度
        jj_lin_height = self.window_height/2 - 2*y_edging
        # 整个曲线数据中y数据的最小值
        self.net_y_min = min(self.net_y)
        # 整个曲线数据中y数据的最大值
        net_y_max = max(self.net_y)
        # 整个曲线数据中y数据的个数
        net_y_len = len(self.net_y)
        # 相邻x数据之间的像素距离
        self.rate_x = jj_line_width/net_y_len
        # 相邻y数据之间的像素距离
        self.rate_y = jj_lin_height/(net_y_max - self.net_y_min)
        # 开始画曲线
        for index, value in enumerate(self.net_y):
            if index == 0:
                x2, y2 = index*self.rate_x + x_edging, jj_lin_height - value*self.rate_y + y_edging
            else:
                x1, y1, x2, y2 = x2, y2, index*self.rate_x + x_edging, jj_lin_height - (value-self.net_y_min)*self.rate_y + y_edging
                self.jj_line_c.append(self.canvas.create_line(x1, y1, x2, y2, fill=color))
        # 画两条坐标线
        x1, y1, x2, y2 = x_edging, y_edging, x_edging + jj_line_width, y_edging + jj_lin_height
        self.jj_line_c.append(self.canvas.create_line(x1, y1, x1, y2, fill='white'))
        self.jj_line_c.append(self.canvas.create_line(x1, y2, x2, y2, fill='white'))
        pass

 
jj_interface = JJ_InterFace.JJ_InterFace()
jj_windows = JJ_Windows(jj_interface)

JJ_InterFace.py

注意:由于基金的数据从网上获取的js文件,分享可能有风险,这里未给出,需要的请私信我。

import requests
import time
import execjs

class JJ_InterFace:

    def __init__(self) -> None:
        pass


    def GetUrl(self, jj_code):
        """
        函数功能:获得单个基金数据的URL
        参数说明:jj_code->单个基金的代码,类似"001794"
        """
        head = 'xxxx'
        tail = '.js?v='+ time.strftime("%Y%m%d%H%M%S",time.localtime())
        return head+jj_code+tail


    def GetCodes(self):
        """
        函数功能:获得所有基金的代码
        参数说明:
        jj_codes->所有基金的代码,类似["001794", "001794"]
        jj_types->所有基金的类型,类似["混合型-灵活", "货币型"]
        url返回的数据:
        var r = [["000001","HXCZHH","华夏成长混合","混合型-偏股","HUAXIACHENGZHANGHUNHE"]]
        """
        url = 'xxxxx'
        content = requests.get(url)
        jscontent = execjs.compile(content.text)
        rawdata = jscontent.eval('r')
        jj_codes = []
        jj_types = []
        jj_names = []
        for code in rawdata:
            jj_codes.append(code[0])
            jj_types.append(code[3])
            jj_names.append(code[2])
        return jj_codes, jj_types, jj_names


    def GetWorth(self, jj_code):
        """
        函数功能:根据基金代码获取净值
        参数说明:
        jj_code->单个基金的代码,类似"001794"
        url返回的数据:
        var fS_name = "华夏成长混合";
        var fS_code = "000001";
        var Data_netWorthTrend = [{"x":1245945600000,"y":1.399,"equityReturn":0.7925,"unitMoney":""},];
        var Data_ACWorthTrend = [[1008604800000,1.0],]
        url xxxxx
        """
        url = self.GetUrl(jj_code)
        print(url)
        content = requests.get(url)
        jsContent = execjs.compile(content.text)
        name = jsContent.eval('fS_name')
        code = jsContent.eval('fS_code')
        #单位净值走势
        netWorthTrend = jsContent.eval('Data_netWorthTrend')
        #累计净值走势
        ACWorthTrend = jsContent.eval('Data_ACWorthTrend')

        syl_1n = jsContent.eval('syl_1n')
        syl_6y = jsContent.eval('syl_6y')
        syl_3y = jsContent.eval('syl_3y')
        syl_1y = jsContent.eval('syl_1y')
        net_x = []
        net_y = []
        ACWorth = []
        for dayWorth in netWorthTrend[::-1]:
            net_x.append(dayWorth['x'])
            net_y.append(dayWorth['y'])
        for dayACWorth in ACWorthTrend[::-1]:
            ACWorth.append(dayACWorth[1])
        return net_x, net_y, ACWorth, syl_1n, syl_6y, syl_3y, syl_1y


相关推荐

  1. 工具清单 - 工具

    2024-07-10 01:28:01       28 阅读
  2. Python基础语法(

    2024-07-10 01:28:01       43 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-10 01:28:01       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-10 01:28:01       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-10 01:28:01       57 阅读
  4. Python语言-面向对象

    2024-07-10 01:28:01       68 阅读

热门阅读

  1. ARM汇编的基础语法

    2024-07-10 01:28:01       24 阅读
  2. postman

    postman

    2024-07-10 01:28:01      20 阅读
  3. Redis

    Redis

    2024-07-10 01:28:01      20 阅读
  4. [Linux安全运维] Linux命令相关

    2024-07-10 01:28:01       26 阅读
  5. PCL 点云最小外接球形包围盒

    2024-07-10 01:28:01       20 阅读
  6. Pytest单元测试系列[v1.0.0][高级技巧]

    2024-07-10 01:28:01       19 阅读
  7. CLIP-EBC:通过增强的逐块分类,CLIP能够准确计数

    2024-07-10 01:28:01       24 阅读
  8. #pragma 指令

    2024-07-10 01:28:01       24 阅读
  9. C++休眠的方法

    2024-07-10 01:28:01       24 阅读
  10. Spring容器加载Bean和JVM加载类

    2024-07-10 01:28:01       21 阅读
  11. word 使用手册

    2024-07-10 01:28:01       30 阅读
  12. winform4

    winform4

    2024-07-10 01:28:01      25 阅读