(二)、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


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/783000.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[数仓]三、离线数仓(Hive数仓系统)

第1章 数仓分层 1.1 为什么要分层 DIM&#xff1a;dimensionality 维度 1.2 数据集市与数据仓库概念 1.3 数仓命名规范 1.3.1 表命名 ODS层命名为ods_表名DIM层命名为dim_表名DWD层命名为dwd_表名DWS层命名为dws_表名 DWT层命名为dwt_表名ADS层命名为ads_表名临时表命名为…

植物大战僵尸融合嫁接版 MAC 版本下载安装详细教程

继植物大战僵尸杂交版火了之后&#xff0c;PVZ改版可谓是百花齐放&#xff0c;最近又有一个非常好玩的模式被开发出来了&#xff0c;他们称为《植物大战僵尸融合嫁接版》 该版本并没有对植物卡牌做改动&#xff0c;而是可以将任意两种植物叠放到一起进行融合&#xff0c;产生新…

(附源码)springboot共享单车管理系统-计算机毕设 65154

springboot共享单车管理系统 摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于共享单车管理系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了共享单车管理系…

ES7210高性能四通道音频ADC转换模拟麦克风为IIS数字咪头

特征 高性能多位 Delta-Σ 音频 ADC 102 dB 信噪比 -85 分贝 THDN 24 位&#xff0c;8 至 100 kHz 采样频率 I2S/PCM 主串行数据端口或从串行数据端口 支持TDM 256/384Fs、USB 12/24 MHz 和其他非标准音频系统时钟 低功耗待机模式 应用 麦克风阵列 智能音箱 远场语音捕获 订购…

桑基气泡图 – 5个维度展示KEGG通路富集结果

2022年发表在《Nature communication》上的文章Kir2.1-mediated membrane potential promotes nutrient acquisition and inflammation through regulation of nutrient transporters fig1i使用微生信平台绘制了一张图&#xff0c;我们将其命名为“桑基气泡图”。从此&#xff…

低代码和制造企业数字化转型成功的关系是什么

针对制造企业特别繁多的应用场景、特别大量的数据以及特别复杂的业务流程等特性&#xff0c;低代码能够更贴合制造企业的应用需求&#xff0c;更符合低代码平台为企业带来的价值&#xff0c;即(低代码平台)即服务。 用低代码与平台的融合力量搭建起企业敏捷的数字底座&#xff…

14-22 剑和远方2 - 深度神经网络中的学习机制

概论 在第一部分中&#xff0c;我们深入探讨了人工智能的兴衰简史以及推动人工智能发展的努力。我们研究了一个简单的感知器&#xff0c;以了解其组件以及简单的 ANN 如何处理数据和权重层。在简单的 ANN 中&#xff0c;不会对数据执行特定操作。ANN 中的激活函数是一个线性函…

Node.js_fs模块

文件删除 文件重命名和移动&#xff08;本质都是修改路径&#xff09; 文件夹操作 创建文件夹(mkdir) 读取文件夹(readdir) &#xff08;打印出来是该文件夹下名称的数组形式&#xff09; 读取当前的文件夹(readdir) 删除文件夹 &#xff08;rmdir&#xff09; 查看资源状态…

一家虚拟电厂繁忙的一天

早晨&#xff1a;准备与监控 7:00 AM - 起床与检查 虚拟电厂&#xff08;VPP&#xff09;团队的成员早起&#xff0c;开始检查电力系统的状态和最新的市场动态。使用专用的监控软件&#xff0c;查看分布式能源资源&#xff08;DERs&#xff09;的实时数据&#xff0c;包括太阳…

【Linux】网络新手村

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 引言 今天&#xff0c;我们就开始学习Linux网络相关的内容。这篇博客作为Linux网络板块的第一篇博客看&#xff0c;我们首先要带着大家明白Linux网络的一些名词的概念&#xff0c;为之后的学习扫清障碍。然后我…

MMM(Master-Master replication manager for MySQL,MySQL主主复制管理器)

概述 MMM&#xff08;Master-Master replication manager for MySQL&#xff0c;MySQL主主复制管理器&#xff09; MMM是一套支持双主故障切换和双主日常管理的脚本程序。MMM 使用 Perl 语言开发&#xff0c;主要用来监控和管理 MySQL Master-Master &#xff08;双主&#xf…

opencv实现目标检测功能----20240704

早在 2017 年 8 月,OpenCV 3.3 正式发布,带来了高度改进的“深度神经网络”(dnn)模块。 该模块支持多种深度学习框架,包括 Caffe、TensorFlow 和 Torch/PyTorch。这次我们使用Opencv深度学习的功能实现目标检测的功能,模型选用MobileNetSSD_deploy.caffemodel。 模型加载…

GD 32中断系统实现

1.0 中断的概念 中断&#xff1a;简单来说就是打断的意思&#xff0c;在计算机系统中CPU在执行一个操作的时候&#xff0c;有一个比当前任务更为紧急的任务需要执行,cpu暂停当前任务转而去执行更为紧急任务的操作&#xff0c;执行完更为紧急任务之后再返回来执行原来未执行完的…

美股交易相关知识点 持续完善中

美股交易时间 美东时间&#xff1a;除了凌晨 03:50 ~ 04:00 这10分钟时间不可交易以外&#xff0c;其他时间都是可以交易的。 如果是在香港或者北京时间下交易要区分两种: 美东夏令时&#xff1a;除了下午 15:50 ~ 16:00 这10分钟时间不可交易以外&#xff0c;其他时间都是可…

1012-27SF 同轴连接器

型号简介 1012-27SF是Southwest Microwave的2.92 mm连接器。该连接器使用不锈钢合金外壳和镀金接触表面提供了良好的耐腐蚀性和耐磨损性&#xff0c;延长了连接器的使用寿命。适用于高频应用&#xff0c;最高可达 40 GHz&#xff0c;使其适用于微波和射频通信、雷达系统等领域。…

14-31 剑和诗人5 - 使用 AirLLM 和分层推理在单个 4GB GPU 上运行 LLama 3 70B

利用分层推理实现大模型语言(LLM) 大型语言模型 (LLM) 领域最近取得了显著进展&#xff0c;LLaMa 3 70B 等模型突破了之前认为可能实现的极限。然而&#xff0c;这些模型的庞大规模给其部署和实际使用带来了巨大挑战&#xff0c;尤其是在资源受限的设备上&#xff0c;例如内存…

pnpm介绍

PNPM 是一个 JavaScript 包管理器&#xff0c;类似于 npm 和 Yarn。它的全称是 "Performant npm"&#xff0c;主要设计目标是优化包的安装和管理过程&#xff0c;以提升速度和效率。PNPM 的主要特点包括&#xff1a; 符号链接&#xff08;Symlink&#xff09;&#x…

数据结构--二叉树相关题2(OJ)

1.比较对称二叉树&#xff08;镜像二叉树&#xff09; 二叉树相关题1中第二题的变形题。先去看1哦&#xff01; 左子树和右子树比较 bool _isSymmetric(struct TreeNode* p, struct TreeNode* q) {if (p NULL && q NULL)return true;//如果两个都为空则是相等的if …

【WEB前端】---HTML---结构---笔记

目录 1.标签---单标签和双标签 1.1单标签 1.2双标签 2.基本结构标签 2.1HTML标签 2.2文档头部标签 2.3文档标题标签 2.4文档的主题标签 3.常用的标题标签 (n∈[1,6]) 4.段落标签 5.换行标签 6.文本格式化标签 6.1粗体 6.2倾斜 6.3删除线 6.4下划线 7.div和spa…

Android:自定义View

一、简介 点击查看创建自定义视图组件中文官网 Android 提供了一个复杂而强大的组件化模型&#xff0c;用于基于基本布局类 View 和 ViewGroup 构建界面。该平台包含各种预构建的 View 和 ViewGroup 子类&#xff08;分别称为 widget 和布局&#xff09;&#xff0c;可供您用来…