【金融数据分析】计算2023年沪深300成分股涨跌排行榜

news2024/11/17 1:50:58

前言

之前的文章中我们已经获取了沪深300成分股的详细个股数据,本文我们来计算一下2023年成分股的涨跌排行榜。

首先看一下效果

详细代码

首先说一下后端的代码,涨跌幅的计算公式如下:

(2023年最后一天的收盘价-2023年第一天的收盘价)/ 2023年第一天的收盘价

计算完所有股票的涨跌幅后,再进行排序即可。

主要的函数如下

    // 将查询的数据缓存到内存中
    private List<CSI300RankVO> cache = new ArrayList<>();

    // 查询沪深300成分股2023年涨跌排行榜
    public synchronized List<CSI300RankVO> query2023rank(int type, int limit) {
        // 首先将所有的股票查出来
        List<StockOptionVO> allCode = getAllCode();
        List<CSI300RankVO> csi300RankVOList = new ArrayList<>();
        if (cache.size() == 0) {
            log.info("需要重新计算数据");
            // 根据股票代码查询所有股票的涨跌幅
            for (int i = 0; i < allCode.size(); i++) {
                // 去除掉沪深300指数本身
                if (allCode.get(i).getCode().equals("399300")) {
                    continue;
                }
                List<StockEntity> stockEntities = sqLiteStockDao.queryAllByCodeAndYear(allCode.get(i).getCode(), "2023");
                CSI300RankVO csi300RankVO = new CSI300RankVO();
                csi300RankVO.setCode(allCode.get(i).getCode());
                csi300RankVO.setName(allCode.get(i).getName());
                Double rise = (stockEntities.get(0).getClose_price() - stockEntities.get(stockEntities.size() - 1).getClose_price()) / stockEntities.get(stockEntities.size() - 1).getClose_price();
                rise = rise * 100;
                String str = String.format("%.2f", rise);
                rise = Double.parseDouble(str);
                csi300RankVO.setRise(rise);
                csi300RankVOList.add(csi300RankVO);
            }
            log.info("填充数据");
            // 将数据填充到缓存中
            for (int i=0; i<csi300RankVOList.size(); i++) {
                cache.add(csi300RankVOList.get(i));
            }
        } else {
            log.info("缓存中已存在数据,不需要重新计算");
            for (int i=0; i<cache.size(); i++) {
                csi300RankVOList.add(cache.get(i));
            }
        }
        // type==1查询涨幅
        if (type == 1) {
            // 按照涨幅升序排序
            Collections.sort(csi300RankVOList, new Comparator<CSI300RankVO>() {
                @Override
                public int compare(CSI300RankVO o1, CSI300RankVO o2) {
                    if (o1.getRise() > o2.getRise()) {
                        return -1;
                    } else if (o1.getRise() == o2.getRise()) {
                        return 0;
                    } else {
                        return 1;
                    }
                }
            });
        } else if (type == 2) { // type==2查询跌幅
            Collections.sort(csi300RankVOList, new Comparator<CSI300RankVO>() {
                @Override
                public int compare(CSI300RankVO o1, CSI300RankVO o2) {
                    if (o1.getRise() > o2.getRise()) {
                        return 1;
                    } else if (o1.getRise() == o2.getRise()) {
                        return 0;
                    } else {
                        return -1;
                    }
                }
            });
        }
        // 最后取limit个数据返回
        List<CSI300RankVO> result = new ArrayList<>();
        for (int i=0; i<limit; i++) {
            if (i > csi300RankVOList.size()-1) {
                return result;
            }
            if (type == 1 && csi300RankVOList.get(i).getRise()<0) { // 查询涨幅
                return result;
            }
            if (type == 2 && csi300RankVOList.get(i).getRise()>0) { // 查询跌幅
                return result;
            }
            result.add(csi300RankVOList.get(i));
        }
        return result;
    }

由于计算的时候很慢,所以当第一次算完后就将结果保存在内存中,下一次再查询就不需要重复计算了。

接着是前端的代码,就是两张表格还有一个现实echarts图表的div

<template>
  <div>
    <el-row class="container">
      <div class="left-grid">
        <el-card class="box-card">
          <template #header>
            <div class="card-header">
              <span>涨幅排行榜</span>
            </div>
          </template>
          <el-table
            v-loading="loading1"
            :data="rise_data"
            :show-header="true"
            :max-height="500"
            stripe
          >
            <el-table-column
              type="index"
              label="排名"
              width="65%"
            ></el-table-column>
            <el-table-column
              prop="name"
              label="公司简称"
              width="85%"
            ></el-table-column>
            <el-table-column
              prop="rise"
              label="涨幅"
              width="85%"
              :formatter="formatter"
            ></el-table-column>
            <el-table-column prop="industry" label="操作">
              <template #default="scope">
                <el-button
                  type="primary"
                  size="small"
                  @click="queryData(scope.row)"
                  >查看</el-button
                >
              </template>
            </el-table-column>
          </el-table>
        </el-card>
        <el-card>
          <template #header>
            <div class="card-header">
              <span>跌幅排行榜</span>
            </div>
          </template>
          <el-table
            v-loading="loading2"
            :data="fall_data"
            :show-header="true"
            :max-height="500"
            stripe
          >
            <el-table-column
              type="index"
              label="排名"
              width="65%"
            ></el-table-column>
            <el-table-column
              prop="name"
              label="公司简称"
              width="85%"
            ></el-table-column>
            <el-table-column
              prop="rise"
              label="跌幅"
              width="85%"
              :formatter="formatter"
            ></el-table-column>
            <el-table-column prop="industry" label="操作">
              <template #default="scope">
                <el-button
                  type="primary"
                  size="small"
                  @click="queryData(scope.row)"
                  >查看</el-button
                >
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </div>

      <div class="right-grid" ref="myChart"></div>
    </el-row>
  </div>
</template>

<script>
import axios from "axios";
import { ElMessage } from "element-plus";
import { getCurrentInstance } from "vue";
export default {
  data() {
    return {
      // 涨幅排行榜
      rise_data: [],
      loading1: true,
      // 跌幅排行榜
      fall_data: [],
      // 个股详细数据
      stock_data: [],
      loading2: true,
      table_title: "",
      echarts: getCurrentInstance().appContext.config.globalProperties.$echarts,
    };
  },
  mounted() {
    this.init();
  },
  methods: {
    init() {
      var url1 = "http://localhost:9001/stock/query2023rank/1/10";
      axios
        .get(url1)
        .then((response) => {
          this.rise_data = response.data;
          console.log(response);
          this.loading1 = false;
        })
        .catch((error) => {
          console.log(error);
          this.loading1 = false;
        });
      var url2 = "http://localhost:9001/stock/query2023rank/2/10";
      axios
        .get(url2)
        .then((response) => {
          this.fall_data = response.data;
          console.log(response);
          this.loading2 = false;
        })
        .catch((error) => {
          console.log(error);
          this.loading2 = false;
        });
    },
    // 绘制折线图
    create_axis() {
      //3.初始化实例对象 echarts.init(dom容器)
      var data_xAxis = [];
      var data_yAxis = [];
      for (var i = this.stock_data.length - 1; i >= 0; i--) {
        data_xAxis.push(this.stock_data[i].record_date);
        data_yAxis.push(this.stock_data[i].close_price);
      }
      console.log(data_xAxis);
      console.log(data_yAxis);
      var dom = this.$refs["myChart"]; // 获取dom节点
      var myChart = this.echarts.init(dom);
      //4.指定配置项和数据
      var option = {
        tooltip: {
          trigger: "axis",
          position: function (pt) {
            return [pt[0], "10%"];
          },
        },
        title: {
          left: "center",
          text: this.table_title,
        },
        toolbox: {
          feature: {
            dataZoom: {
              yAxisIndex: "none",
            },
            restore: {},
            saveAsImage: {},
          },
        },
        xAxis: {
          type: "category",
          boundaryGap: false,
          data: data_xAxis,
        },
        yAxis: {
          type: "value",
          boundaryGap: [0, "100%"],
        },
        dataZoom: [
          {
            type: "inside",
            start: 0,
            end: 10,
          },
          {
            start: 0,
            end: 10,
          },
        ],
        series: [
          {
            name: this.table_title,
            type: "line",
            symbol: "none",
            sampling: "lttb",
            itemStyle: {
              color: "rgb(135,206,235)",
            },
            areaStyle: {
              color: new this.echarts.graphic.LinearGradient(0, 0, 0, 1, [
                {
                  offset: 0,
                  color: "rgb(135,206,250)",
                },
                {
                  offset: 1,
                  color: "rgb(135,206,235)",
                },
              ]),
            },
            data: data_yAxis,
          },
        ],
      };
      //5.将配置项设置给echarts实例对象,使用刚指定的配置项和数据显示图表。
      myChart.setOption(option);
    },
    // 查询数据
    queryData(row) {
      var url = "http://localhost:9001/stock/querinfo2023/" + row.code;
      this.table_title = row.code + " " + row.name;
      ElMessage("开始查询 " + row.name + " 的数据");
      axios
        .get(url)
        .then((response) => {
          this.stock_data = response.data;
          console.log(response);
          this.loading = false;
          ElMessage({
            message: "查询 " + row.name + " 的数据成功",
            type: "success",
          });
          // 绘制数据
          this.create_axis();
        })
        .catch((error) => {
          console.log(error);
          this.loading = false;
          ElMessage.error("查询 " + row.name + " 的数据失败");
        });
    },
    formatter(row) {
      return row.rise + "%";
    },
  },
};
</script>

<style scoped>
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.container {
  display: grid;
  grid-template-columns: 35% 65%;
  width: 100%;
  height: 80vh;
}
.left-grid {
  background-color: #f0f0f0;
  border-radius: 2%;
  padding: 10px;
  height: 95%;
}
.right-grid {
  background-color: #f9ecc3;
  border-radius: 2%;
  padding: 10px;
  height: 650px;
}
</style>

数据分析

介绍完代码后,我们来看一下数据分析的结果,首先是涨幅排行榜

下面是排行榜上10只股票的走势图(顺序是根据文件名排的) 

接着是跌幅排行榜

下面是排行榜上10只股票的走势图(顺序是根据文件名排的) 

结语

本文介绍了获取计算涨跌排行榜的方法,以及进行涨幅排行榜前10名和跌幅排行榜前10名的股票数据展示,希望对你有所帮助。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IMS基本架构

IP Multimedia Core Network Subsystem (IMS)商用已久&#xff0c;相对于CS domain的语音方案&#xff0c;IMS则是基于IETF定义的会话控制功能与多媒体传输功能通过IP-CAN实现的 全IP完整语音解决方案。 IMS能为无线和有线用户实现语音、视频、消息、数据等服务。便于运营商通过…

【C++】深入了解构造函数之初始化列表

目录 一、再谈构造函数 1、引入 1&#xff09;构造函数体赋值 2&#xff09;不同成员变量赋值 2、初始化列表 一、再谈构造函数 1、引入 1&#xff09;构造函数体赋值 在创建对象时&#xff0c;编译器通过调用构造函数&#xff0c;给对象中各个成员变量一个合适的初始值…

【小沐学C++】C++ 实现鼠标键盘钩子HOOK

文章目录 1、简介2、相关函数2.1 SetWindowsHookEx2.2 UnhookWindowsHookEx2.3 CallNextHookEx 3、相关结构体3.1 KBDLLHOOKSTRUCT3.2 MSLLHOOKSTRUCT 4、挂钩过程5、代码测试5.1 代码1 结语 1、简介 https://learn.microsoft.com/zh-cn/windows/win32/winmsg/about-hooks 挂…

Kali Linux——获取root权限

目录 一、设置root密码 【操作命令】 【操作实例】 二、临时获取root权限 【操作命令】 【操作实例】 三、提升用户到root 1、获取root权限 2、进入/etc/passwd 3、查看root账号ID 4、找到需要修改的用户 5、输入i&#xff0c;进入编辑模式 6、把用户的ID改成跟r…

专为Mac用户设计的思维导图软件MindNode 2023 for Mac助您激发创意!

在现代快节奏的生活中&#xff0c;我们经常需要整理思绪、规划项目、记录灵感。而思维导图作为一种高效的思维工具&#xff0c;能够帮助我们更好地整理和展现思维。现在&#xff0c;我们介绍一款强大而直观的思维导图软件——MindNode 2023 for Mac&#xff0c;助您拓展思维边界…

SqueezeNet:通过紧凑架构彻底改变深度学习

一、介绍 在深度学习领域&#xff0c;对效率和性能的追求往往会带来创新的架构。SqueezeNet 是神经网络设计的一项突破&#xff0c;体现了这种追求。本文深入研究了 SqueezeNet 的复杂性&#xff0c;探讨其独特的架构、设计背后的基本原理、应用及其对深度学习领域的影响。 在创…

第九节HarmonyOS 常用基础组件11-TextPicker

1、描述 滑动选择文本内容的组件。 2、接口 TextPicker(options?: {range: string[]|Resource, selected?: number, value?: string}) 3、参数 参数名称 参数类型 必填 描述 range string[]|Resource 是 选择器的数据。 selected number 否 设置默认选中项在…

2024.1.7周报

目录 摘要 ABSTRACT 一、文献阅读 1、题目 2、摘要 3、模型架构 4、文献解读 一、Introduction 二、创新点 三、实验过程 四、结论 二、深度学习知识 一、从Encoder-Decoder框架中理解为什么要有Attention机制 二、Attention思想 三、Seq2Seq Attention代码逐…

7-35 有理数均值 分数 20

每日一言 我们把世界看错&#xff0c;反说它欺骗了我们。 --飞鸟集 题目 本题要求编写程序&#xff0c;计算N个有理数的平均值。 输入格式&#xff1a; 输入第一行给出正整数N&#xff08;≤100&#xff09;&#xff1b;第二行中按照a1/b1 a2/b2 …的格式给出N个分数形式的…

Python的核心知识点整理大全66(已完结撒花)

目录 D.3 忽略文件 .gitignore 注意 D.4 初始化仓库 D.5 检查状态 D.6 将文件加入到仓库中 D.7 执行提交 D.8 查看提交历史 D.9 第二次提交 hello_world.py D.10 撤销修改 hello_world.py 注意 D.11 检出以前的提交 往期快速传送门&#x1f446;&#xff08;在文…

openssl3.2 - 编译

文章目录 openssl3.2 - 编译概述OpenSSL源码下载编译目标如何编译前置环境 - perl前置环境 - VS前置环境 - NASM快速编译步骤编译 - Quick startInstall PerlInstall NASMUse Visual Studio Developer Command Prompt with administrative privilegesFrom the root of the Open…

Windows安装部署nginx

1、官网下载安装包&#xff1a; 官网地址&#xff1a;https://nginx.org/en/download.html 下载好后&#xff0c;解压即可&#xff1a; 在nginx的配置文件是conf目录下的nginx.conf&#xff0c;默认配置的nginx监听的端口为80&#xff0c;如果本地80端口已经被使用则修改成其…

分析抖音直播弹幕评论和礼物的websocket数据流信息,通过proto协议解析消息内容思路

现在定位到一个解析的大概位置&#xff1a; e.decode function(e, t) {e instanceof o || (e o.create(e));for (var n, i, s void 0 t ? e.len : e.pos t, u new r.webcast.im.MemberMessage(r.webcast. 通过请求找到发送请求的js代码位置&#xff0c;然后通过跟踪这…

ASP.NET Core中实现个人资料上传图片功能

当用户需要在ASP.NET Core中实现修改个人资料的功能时&#xff0c;其中一个常见的需求就是允许上传个人头像图片。下面将详细介绍如何在ASP.NET Core中实现修改个人资料上传图片的功能。 步骤一&#xff1a;控制器中添加一个HttpPost方法 首先&#xff0c;我们在控制器中添加…

基于JavaWeb+SSM+Vue基于微信小程序的消防隐患在线举报系统的设计与实现

基于JavaWebSSMVue基于微信小程序的消防隐患在线举报系统的设计与实现 源码获取入口KaiTi 报告Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 KaiTi 报告 1.1 题目背景 随着信息化飞速发展&#xff0c;互联网不…

【gRPC学习】使用go学习gRPC

个人博客:Sekyoro的博客小屋 个人网站:Proanimer的个人网站 RPC是远程调用,而google实现了grpc比较方便地实现了远程调用,gRPC是一个现代的开源远程过程调用(RPC)框架 概念介绍 在gRPC中&#xff0c;客户端应用程序可以直接调用另一台计算机上的服务器应用程序上的方法&#…

PyTorch 进阶指南,这个宝典太棒了

最新写了很多关于 Pytorch 的文章&#xff0c;主要针对刚刚接触 Pytorch 的同学&#xff0c;文章我给大家列出来了&#xff0c;喜欢可以从0开始学习&#xff1a; 小白学 PyTorch 系列&#xff1a;这一次&#xff0c;我准备了 20节 PyTorch 中文课程小白学 PyTorch 系列&#x…

【视频图像篇】模糊图像处理之运动模糊造成的车牌号码图像模糊还原

【视频图像篇】模糊图像处理之运动模糊造成的车牌号码图像模糊还原 处理车辆运动过程中造成车牌号码的视频图像模糊—【蘇小沐】 0、目录 1、实验环境 2、路径 3、测量工具&#xff1a;测量模糊角度及距离 4、运动模糊滤波器 5、结果展示 1、实验环境 系统环境Windows…

YOLOv5训练损失、精度、mAP绘图功能 | 支持多结果对比,多结果绘在一个图片(消融实验、科研必备)

一、本文介绍 本文给大家带来的是YOLOv5系列的绘图功能,我将向大家介绍YOLO系列的绘图功能。我们在进行实验时,经常需要比较多个结果,针对这一问题,我写了点代码来解决这个问题,它可以根据训练结果绘制损失(loss)和mAP(平均精度均值)的对比图。这个工具不仅支持多个文件…

P12 音视频复合流——TS流讲解

前言 从本章开始我们将要学习嵌入式音视频的学习了 &#xff0c;使用的瑞芯微的开发板 &#x1f3ac; 个人主页&#xff1a;ChenPi &#x1f43b;推荐专栏1: 《C_ChenPi的博客-CSDN博客》✨✨✨ &#x1f525; 推荐专栏2: 《Linux C应用编程&#xff08;概念类&#xff09;_C…