股票价格预测窗体

股票评价系统


一、目的意义

本文介绍了一个基于Tkinter的股票数据处理应用程序,它提供了抓取、清洗和评估股票数据的功能。该应用程序通过网络抓取股票数据,并将数据保存到CSV文件中。然后,它执行数据清洗操作,包括移除空数据行、替换市盈率为负的值为最大市盈率,并过滤特定股票代码和名称的股票。最后,用户可以输入权重值,对清洗后的数据进行评估,计算每只股票的评价分数。评价分数基于股票的最新价、涨跌幅、成交量、市盈率和振幅等指标计算得出。应用程序将排名靠前的股票代码和评分结果显示给用户,并通过弹窗展示结果。

二、主要功能

1. 抓取数据

通过点击"抓取数据"按钮,应用程序会从指定的网址抓取股票数据,并将数据保存到名为"stock_data.csv"的CSV文件中。

def clean_stock_data():
    with open('stock_data.csv', 'r', newline='', encoding='utf-8') as file:
        reader = csv.DictReader(file)
        pe_ratios = [float(row['市盈率']) for row in reader if row['市盈率'] != '-' and row['市盈率'] != '']
        max_pe_ratio = 150

        # 重新打开CSV文件以重置读取器
        file.seek(0)
        next(reader)  # 跳过标题行

        cleaned_rows = [row for row in reader if clean_data(row, max_pe_ratio) and all(value != '' and value != '-' for value in row.values())]

2. 清洗数据

点击"清洗数据"按钮,应用程序会读取"stock_data.csv"文件中的数据,并进行数据清洗。清洗的过程包括移除包含空数据的行,替换市盈率为负的值为市盈率的最大值,以及移除股票代码以600、00或8开头的股票和股票名称中包含"ST"的股票。清洗后的数据将被保存到名为"cleaned_stock_data.csv"的新CSV文件中。

    # 将清洗后的数据写入新的CSV文件
    cleaned_filename = 'cleaned_stock_data.csv'
    with open(cleaned_filename, 'w', newline='', encoding='utf-8') as file:
        writer = csv.DictWriter(file, fieldnames=reader.fieldnames)
        writer.writeheader()
        writer.writerows(cleaned_rows)

3. 评估股票

用户可以在界面上输入权重值,然后点击"评估股票"按钮进行股票评估。应用程序会读取"cleaned_stock_data.csv"文件中的数据,并根据用户输入的权重计算每只股票的评价分数。评价分数是根据股票的最新价、涨跌幅、成交量、市盈率和振幅等指标计算得出的。计算完成后,应用程序会将评分排名靠前的股票代码和评分结果显示在界面上,并通过messagebox.showinfo弹窗显示结果。

def evaluate_stocks():
    # 用户自定义的权重
    user_weights = {
        '最新价': float(weights_entry['最新价'].get()),
        '涨跌幅': float(weights_entry['涨跌幅'].get()),
        '成交量': float(weights_entry['成交量'].get()),
        '市盈率': float(weights_entry['市盈率'].get()),
        '振幅': float(weights_entry['振幅'].get())
    }

    # 存储股票评价指数的字典
    stock_scores = {}

    # 读取CSV文件
    with open('cleaned_stock_data.csv', 'r', newline='', encoding='utf-8') as file:
        reader = csv.DictReader(file)
        for row in reader:
            # 计算每只股票的评价分数
            stock_score = calculate_score(row, user_weights)

            # 将评价指数存储到字典中
            stock_scores[row['股票代码']] = stock_score

    # 按评价指数从高到低排序股票
    sorted_stocks = sorted(stock_scores.items(), key=lambda x: x[1], reverse=True)

    # 输出排序后的股票列表
    for stock_code, score in sorted_stocks:
        print(f"股票代码: {stock_code}, 评分: {score}")
    result_text = ""
    for stock_code, score in sorted_stocks[:20]:
        result_text += f"股票代码: {stock_code}, 评分: {score}\n"

    # 使用messagebox.showinfo显示结果
    messagebox.showinfo("排名靠前的股票信息", result_text)

4. 用户界面

应用程序使用Tkinter库创建了一个简单的GUI界面,包含几个输入框和按钮,用于输入股票代码、开始日期和结束日期,以及触发相应的操作。

window = tk.Tk()
window.title("股票数据处理")
window.geometry("600x300")

# 创建控件
fetch_data_button = tk.Button(window, text="抓取数据", command=fetch_stock_all_data)
fetch_data_button.pack(pady=10)

clean_data_button = tk.Button(window, text="清洗数据", command=clean_stock_data)
clean_data_button.pack(pady=10)

weights_label = tk.Label(window, text="请输入权重:")
weights_label.pack(pady=10)

weights_entry = {}
weight_labels = ['最新价', '涨跌幅', '成交量', '市盈率', '振幅']
for label in weight_labels:
    frame = tk.Frame(window)
    frame.pack()
    label_widget = tk.Label(frame, text=label)
    label_widget.pack(side=tk.LEFT)
    entry_widget = tk.Entry(frame)
    entry_widget.pack(side=tk.LEFT)
    weights_entry[label] = entry_widget

evaluate_stocks_button = tk.Button(window, text="评估股票", command=evaluate_stocks)
evaluate_stocks_button.pack(pady=10)

# 运行主窗口的消息循环
window.mainloop()

三、完整代码

import requests
import json
import os
import csv
from sklearn.preprocessing import StandardScaler
import tkinter as tk
from tkinter import messagebox

def fetch_stock_all_data():
    json_url = "http://48.push2.eastmoney.com/api/qt/clist/get?cb=jQuery112402508937289440778_1658838703304&pn={page}&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&wbp2u=|0|0|0|web&fid=f3&fs=m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048&fields=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152&_=1658838703305"
    filename = "stock_data.csv"

    if not os.path.exists(filename):
        with open(filename, "w", encoding="utf-8") as f:
            f.write("股票代码,股票名称,最新价,涨跌幅,涨跌额,成交量(手),成交额,振幅,换手率,市盈率,量比,最高,最低,今开,昨收,市净率\n")

    for i in range(1, 300):
        print("抓取网页%s" % str(i))
        res = requests.get(json_url.format(page=str(i)))
        result = res.text.split("jQuery112402508937289440778_1658838703304")[1].split("(")[1].split(");")[0]
        result_json = json.loads(result)
        try:
            stock_data = result_json['data']['diff']
        except:
            print('over')
            break
        with open(filename, "a", encoding="utf-8") as f:
            for j in stock_data:
                Code = j["f12"]
                Name = j["f14"]
                Close = j['f2']
                ChangePercent = j["f3"]
                Change = j['f4']
                Volume = j['f5']
                Amount = j['f6']
                Amplitude = j['f7']
                TurnoverRate = j['f8']
                PERation = j['f9']
                VolumeRate = j['f10']
                Hign = j['f15']
                Low = j['f16']
                Open = j['f17']
                PreviousClose = j['f18']
                PB = j['f22']
                row = '{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}\n'.format(
                    Code, Name, Close, ChangePercent, Change, Volume, Amount, Amplitude,
                    TurnoverRate, PERation, VolumeRate, Hign, Low, Open, PreviousClose, PB)
                f.write(row)

def clean_data(row, max_pe_ratio):
    # 检查数据行中是否存在空数据
    for value in row.values():
        if value == '' or value == '-':
            return False

    # 将市盈率为负的值替换为市盈率的最大值
    pe_ratio = float(row['市盈率'])
    if pe_ratio < 0:
        row['市盈率'] = str(max_pe_ratio)

    # 检查股票代码是否以600、00或8开头,如果是则返回False
    stock_code = row['股票代码']
    if stock_code.startswith(('600', '00', '8')):
        return False

    # 检查股票名称是否包含'ST',如果是则返回False
    stock_name = row['股票名称']
    if 'ST' in stock_name:
        return False

    return True

def clean_stock_data():
    # 读取CSV文件
    with open('stock_data.csv', 'r', newline='', encoding='utf-8') as file:
        reader = csv.DictReader(file)
        pe_ratios = [float(row['市盈率']) for row in reader if row['市盈率'] != '-' and row['市盈率'] != '']
        max_pe_ratio = 150

        # 重新打开CSV文件以重置读取器
        file.seek(0)
        next(reader)  # 跳过标题行

        cleaned_rows = [row for row in reader if clean_data(row, max_pe_ratio) and all(value != '' and value != '-' for value in row.values())]

    # 将清洗后的数据写入新的CSV文件
    cleaned_filename = 'cleaned_stock_data.csv'
    with open(cleaned_filename, 'w', newline='', encoding='utf-8') as file:
        writer = csv.DictWriter(file, fieldnames=reader.fieldnames)
        writer.writeheader()
        writer.writerows(cleaned_rows)

def calculate_score(data, weights):
    # 从数据中提取所需的字段
    latest_price = float(data['最新价'])
    change_percent = float(data['涨跌幅'].replace('%', ''))
    volume = int(data['成交量(手)'].replace(',', ''))
    pe_ratio = float(data['市盈率'])
    shock = float(data['振幅'].replace('%', ''))

    # 标准化处理
    scaler = StandardScaler()
    scaler.fit([[latest_price], [change_percent], [volume], [1 / pe_ratio], [shock]])  # 使用 pe_ratio
    scaled_price = scaler.transform([[latest_price]])[0][0]
    scaled_change = scaler.transform([[change_percent]])[0][0]
    scaled_volume = scaler.transform([[volume]])[0][0]
    scaled_pe_ratio = scaler.transform([[1 / pe_ratio]])[0][0]
    scaled_shock = scaler.transform([[shock]])[0][0]

    # 根据权重计算评价分数
    score = (scaled_price * weights['最新价'] +
             scaled_change * weights['涨跌幅'] +
             scaled_volume * weights['成交量'] +
             scaled_pe_ratio * weights['市盈率'] +
             scaled_shock * weights['振幅'])

    return score

def evaluate_stocks():
    # 用户自定义的权重
    user_weights = {
        '最新价': float(weights_entry['最新价'].get()),
        '涨跌幅': float(weights_entry['涨跌幅'].get()),
        '成交量': float(weights_entry['成交量'].get()),
        '市盈率': float(weights_entry['市盈率'].get()),
        '振幅': float(weights_entry['振幅'].get())
    }

    # 存储股票评价指数的字典
    stock_scores = {}

    # 读取CSV文件
    with open('cleaned_stock_data.csv', 'r', newline='', encoding='utf-8') as file:
        reader = csv.DictReader(file)
        for row in reader:
            # 计算每只股票的评价分数
            stock_score = calculate_score(row, user_weights)

            # 将评价指数存储到字典中
            stock_scores[row['股票代码']] = stock_score

    # 按评价指数从高到低排序股票
    sorted_stocks = sorted(stock_scores.items(), key=lambda x: x[1], reverse=True)

    # 输出排序后的股票列表
    for stock_code, score in sorted_stocks:
        print(f"股票代码: {stock_code}, 评分: {score}")
    result_text = ""
    for stock_code, score in sorted_stocks[:20]:
        result_text += f"股票代码: {stock_code}, 评分: {score}\n"

    # 使用messagebox.showinfo显示结果
    messagebox.showinfo("排名靠前的股票信息", result_text)

window = tk.Tk()
window.title("股票数据处理")
window.geometry("600x300")

# 创建控件
fetch_data_button = tk.Button(window, text="抓取数据", command=fetch_stock_all_data)
fetch_data_button.pack(pady=10)

clean_data_button = tk.Button(window, text="清洗数据", command=clean_stock_data)
clean_data_button.pack(pady=10)

weights_label = tk.Label(window, text="请输入权重:")
weights_label.pack(pady=10)

weights_entry = {}
weight_labels = ['最新价', '涨跌幅', '成交量', '市盈率', '振幅']
for label in weight_labels:
    frame = tk.Frame(window)
    frame.pack()
    label_widget = tk.Label(frame, text=label)
    label_widget.pack(side=tk.LEFT)
    entry_widget = tk.Entry(frame)
    entry_widget.pack(side=tk.LEFT)
    weights_entry[label] = entry_widget

evaluate_stocks_button = tk.Button(window, text="评估股票", command=evaluate_stocks)
evaluate_stocks_button.pack(pady=10)

# 运行主窗口的消息循环
window.mainloop()

这个应用程序的目的是帮助用户方便地抓取、清洗和评估股票数据。通过使用这个应用程序,用户可以获取最新的股票数据,并通过自定义权重对股票进行评估,以辅助他们做出更明智的投资决策。

如有共同爱好或者交流,可以加Q:2388627579

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jony..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值