今日指数项目之大盘指数功能实现

news2024/11/19 6:32:47

1、国内大盘指数功能

1.1国内大盘指数业务分析

1.1.1 页面原型效果

查询A股大盘最新的数据:

在这里插入图片描述

国内大盘数据包含:大盘代码、大盘名称、开盘点、最新点、前收盘点、交易量、交易金额、涨跌值、涨幅、振幅、当前日期

1.1.2 相关表结构分析

大盘指数包含国内和国外的大盘数据,目前我们先完成国内大盘信数据的展示功能;

国内股票大盘数据详情表设计如下:

在这里插入图片描述

注意事项:

数据库字段类型decimal—>java中的BigDecimal

数据库字段类型bigint—> java中的Long类型

1.1.3 A股大盘指数接口说明

功能说明:

  • 获取最新国内A股大盘信息(仅包含上证和深证大盘数据);
  • 查询时间点不在正常股票交易时间内,则显示最近时间点的交易信息;
    • 比如:当前查询时间点是周一上午8点整,因为当天尚未开盘,则显示上周五最新的数据,也就是收盘时数据;

请求路径:/api/quot/index/all
请求方式:GET
参数:无

响应数据格式:

{
    "code": 1,
    "data": [
        {
            "code": "sh000001",//大盘编码
            "name": "上证指数",//指数名称
            "openPoint": 3267.81,//开盘点
            "curPoint": 3236.70,//当前点
            "preClosePoint": 3283.43,//前收盘点
            "tradeAmt": 160591,//交易量
            "tradeVol": 1741099,//交易金额
            "upDown": -46.73,//涨跌值
            "rose": -0.01.42,//涨幅
            "amplitude": 0.0164,//振幅
            "curTime": "2022-01-02 01:32"//当前时间
        },
      	{......}
    ]
}

A股大盘开盘周期:周一至周五,每天上午9:30到11:30和下午13:00到15:00;

1.1.4 响应结果实体类封装

我们约定从数据库查询的数据如果来自多张表或者单表的部分字段,则封装到domain实体类下;

domain、pojo、entity、vo类等实体类作为公共资源都维护在stock_common工程下;

package com.itheima.stock.pojo.domain;

import lombok.Data;

import java.math.BigDecimal;

/**
 * @author by itheima
 * @Date 2022/1/9
 * @Description 定义封装多内大盘数据的实体类
 */
@Data
public class InnerMarketDomain {
    /**
     * 大盘编码
     */
    private String code;
    /**
     * 大盘名称
     */
    private String name;
    /**
     * 开盘点
     */
    private BigDecimal openPoint;
    /**
     * 当前点
     */
    private BigDecimal curPoint;
    /**
     * 前收盘点
     */
    private BigDecimal preClosePoint;
    /**
     * 交易量
     */
    private Long tradeAmt;
    /**
     * 交易金额
     */
    private Long tradeVol;
    /**
     * 涨跌值
     */
    private BigDecimal upDown;
    /**
     * 涨幅
     */
    private BigDecimal rose;

    /**
     * 振幅
     */
    private BigDecimal amplitude;
    /**
     * 当前时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
    private Date curTime;
}

注意:在stock_common工程下直接导入day02\资料\domain\InnerMarketDomain.java 即可

1.2 国内大盘功能实现准备

1.2.1 股票交易时间工具类封装

项目中经常需要查询股票最近的一次交易时间点,而大盘的开盘时间又分为不同的时间段,这给我们的逻辑判断增加了复杂度,而且项目中股票是每分钟采集一次,时间需要精确到分钟,综上,我们需要在stock_common工程下维护一个公共的时间工具类:

package com.itheima.stock.utils;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;

/**
 * @author by itheima
 * @Date 2021/12/31
 * @Description 日期时间工具类
 */
public class DateTimeUtil {
    /**
     * 获取指定日期下股票的上一个有效交易日时间
     * @return
     */
    public static DateTime getPreviousTradingDay(DateTime dateTime){
        //获取指定日期对应的工作日
        int weekNum = dateTime.dayOfWeek().get();
        //判断所属工作日
        DateTime preDateTime=null;
        //周一,那么T-1就是周五
        if (weekNum==1){
            //日期后退3天
          preDateTime=dateTime.minusDays(3);
        }
        //周末,那么T-1就是周五
        else if (weekNum==7){
            preDateTime=dateTime.minusDays(2);
        }
        else {
            preDateTime=dateTime.minusDays(1);
        }
        return getDateTimeWithoutSecond(preDateTime);
    }

    /**
     * 判断是否是工作日
     * @return true:在工作日 false:不在工作日
     */
    public static boolean isWorkDay(DateTime dateTime){
        //获取工作日
        int weekNum = dateTime.dayOfWeek().get();
        return  weekNum>=1 && weekNum<=5;
    }

    /**
     * 获取上一天日期
     * @param dateTime
     * @return
     */
    public static DateTime getPreDateTime(DateTime dateTime){
        return dateTime.minusDays(1);
    }

    /**
     * 日期转String
     * @param dateTime 日期
     * @param pattern 日期正则格式
     * @return
     */
    public static String parseToString(DateTime dateTime,String pattern){
       return  dateTime.toString(DateTimeFormat.forPattern(pattern));
    }

    /**
     * 获取股票日期格式字符串
     * @param dateTime
     * @return
     */
    public static String parseToString4Stock(DateTime dateTime){
        return parseToString(dateTime,"yyyyMMddHHmmss");
    }

    /**
     * 获取指定日期的收盘日期
     * @param dateTime
     * @return
     */
    public static DateTime getCloseDate(DateTime dateTime){
       return dateTime.withHourOfDay(14).withMinuteOfHour(58).withSecondOfMinute(0).withMillisOfSecond(0);
    }

    /**
     * 获取指定日期的开盘日期
     * @param dateTime
     * @return
     */
    public static DateTime getOpenDate(DateTime dateTime){
       return dateTime.withHourOfDay(9).withMinuteOfHour(30).withSecondOfMinute(0).withMillisOfSecond(0);
    }

    /**
     * 获取最近的股票有效时间,精确到分钟
     * @param target
     * @return
     */
    public static String getLastDateString4Stock(DateTime target){
        DateTime dateTime = getLastDate4Stock(target);
        dateTime=getDateTimeWithoutSecond(dateTime);
        return parseToString4Stock(dateTime);
    }
    /**
     * 获取最近的股票有效时间,精确到分钟
     * @param target
     * @return
     */
    public static DateTime getLastDate4Stock(DateTime target){
        //判断是否是工作日
        if (isWorkDay(target)) {
            //当前日期开盘前
            if (target.isBefore(getOpenDate(target))) {
                target=getCloseDate(getPreviousTradingDay(target));
            }else if (isMarketOffTime(target)){
                target=target.withHourOfDay(11).withMinuteOfHour(28).withSecondOfMinute(0).withMillisOfSecond(0);
            }else if (target.isAfter(getCloseDate(target))){
                //当前日期收盘后
                target=getCloseDate(target);
            }
        }else{
            //非工作日
            target=getCloseDate(getPreviousTradingDay(target));
        }
         target = getDateTimeWithoutSecond(target);
        return target;
    }

    /**
     * 判断当前时间是否在大盘的中午休盘时间段
     * @return
     */
    public static boolean isMarketOffTime(DateTime target){
        //上午休盘开始时间
        DateTime start = target.withHourOfDay(11).withMinuteOfHour(28).withSecondOfMinute(0).withMillisOfSecond(0);
        //下午开盘时间
        DateTime end = target.withHourOfDay(13).withMinuteOfHour(0).withSecondOfMinute(0).withMillisOfSecond(0);
        if (target.isAfter(start) && target.isBefore(end)) {
            return true;
        }
        return false;
    }

    /**
     * 将秒时归零
     * @param dateTime 指定日期
     * @return
     */
    public static DateTime getDateTimeWithoutSecond(DateTime dateTime){
        DateTime newDate = dateTime.withSecondOfMinute(0).withMillisOfSecond(0);
        return newDate;
    }

    /**
     * 将秒时归零
     * @param dateTime 指定日期字符串,格式必须是:yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static DateTime getDateTimeWithoutSecond(String dateTime){
        DateTime parse = DateTime.parse(dateTime, DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"));
        return getDateTimeWithoutSecond(parse);
    }
}

说明:

在stock_common下直接导入日期工具类:今日指数\day02\资料\date工具类\DateTimeUtil.java

工具类借助jode-time日期插件实现,jode-date核心方式参考:day02\资料\date工具类\TestJodeDate.java

1.2.2 常量数据封装

股票常用的公共参数非常多,我们可以在stock_common下把他们封装到一个Value Object(vo)对象下,并通过Spring为调用方动态赋值;

本小节我们把股票大盘编码信息配置到StockInfoConfig实体类下:

package com.itheima.stock.pojo.vo;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.List;

/**
 * @author by itheima
 * @Date 2021/12/30
 * @Description
 */
@ConfigurationProperties(prefix = "stock")
@Data
public class StockInfoConfig {
    //A股大盘ID集合
    private List<String> inner;
    //外盘ID集合
    private List<String> outer;
}

在调用方stock_backend工程下定义application-stock.yml文件,并配置A股大盘和外盘的编码数据:

# 配置股票相关的参数
stock:
  inner: # A股
    - sh000001 # 上证ID
    - sz399001 #  深证ID
  outer: # 外盘
    - int_dji # 道琼斯
    - int_nasdaq # 纳斯达克
    - int_hangseng # 恒生
    - int_nikkei # 日经指数
    - b_FSSTI # 新加坡

同时在主配置文件application.yml中激活该配置:

spring:
   profiles:
   		active: stock

说明:将股票相关的配置文件独立出来,方便后期维护,且避免产生臃肿的主配置文件;

在公共配置类中加载实体VO对象:

@EnableConfigurationProperties(StockInfoConfig.class)
@Configuration
public class CommonConfig {
	//省略N行
}

1.3 国内大盘指数SQL分析

业务功能:获取最新的国内大盘的数据信息

-- 功能说明:获取最新国内A股大盘信息(上证和深证)
-- 	如果不在股票交易时间,则显示最近时间点的交易信息
-- 分析:就是根据大盘的编码查询大盘的最新交易数据
-- 大盘编码:sh000001 sz399001
SELECT 
	smi.market_code AS code,
	smi.market_name AS name,
	smi.open_point AS openPoint,
	smi.cur_point AS curPoint,
	smi.pre_close_point AS preClosePoint,
	smi.trade_amount AS tradeAmt,
	smi.trade_volume AS tradeVol,
	smi.cur_point-smi.pre_close_point AS upDown,
	(smi.cur_point-smi.pre_close_point)/smi.pre_close_point AS rose,
	(smi.max_point-smi.min_point)/smi.pre_close_point AS amplitude,
	smi.cur_time AS curTime
FROM stock_market_index_info AS smi
WHERE smi.market_code IN ('sh000001','sz399001')
ORDER BY smi.cur_time DESC LIMIT 2;
# 存在的问题:1.全表查询,效率较低,如何优化?
# 一方面为了为了避免重复数据,将时间和大盘编码作为联合唯一索引,起到
-- 唯一约束的作用 另外,借助这个索引,也避免全表查询
-- 查询最新的数据,可转化成查询最新的股票交易时间点下的数据
SELECT 
	smi.market_code AS code,
	smi.market_name AS name,
	smi.open_point AS openPoint,
	smi.cur_point AS curPoint,
	smi.pre_close_point AS preClosePoint,
	smi.trade_amount AS tradeAmt,
	smi.trade_volume AS tradeVol,
	smi.cur_point-smi.pre_close_point AS upDown,
	(smi.cur_point-smi.pre_close_point)/smi.pre_close_point AS rose,
	(smi.max_point-smi.min_point)/smi.pre_close_point AS amplitude,
	smi.cur_time AS curTime
FROM stock_market_index_info AS smi
WHERE smi.market_code IN ('sh000001','sz399001')
AND smi.cur_time ='2021-12-28 09:31:00';
# 在sql查询时,尽量避免全表查询,否则随着数据量的增加,全表查询导致的查询时间成本会不断上升!

1.4 国内大盘指数功能实现

1.4.1 定义获取A股大盘数据接口
package com.itheima.stock.controller;

import com.itheima.stock.pojo.StockBusiness;
import com.itheima.stock.service.StockService;
import com.itheima.stock.vo.resp.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

/**
 * @author by itheima
 * @Date 2021/12/19
 * @Description
 */
@RestController
@RequestMapping("/api/quot")
public class StockController {

    @Autowired
    private StockService stockService;

	//其它省略.....
    /**
     * 获取国内最新大盘指数
     * @return
     */
    @GetMapping("/index/all")
    public R<List<InnerMarketDomain>> innerIndexAll(){
        return stockService.innerIndexAll();
    }
}
1.4.2 定义国内大盘数据服务

服务接口:

package com.itheima.stock.service;
import com.itheima.stock.pojo.StockBusiness;
import com.itheima.stock.vo.resp.R;

import java.util.List;
import java.util.Map;

/**
 * @author by itheima
 * @Date 2021/12/19
 * @Description 定义股票服务接口
 */
public interface StockService {
	//其它省略......
    /**
     * 获取国内大盘的实时数据
     * @return
     */
    R<List<InnerMarketDomain>> innerIndexAll();
}

服务接口实现:

package com.itheima.stock.service.impl;

import com.itheima.stock.common.domain.StockInfoConfig;
import com.itheima.stock.mapper.StockBusinessMapper;
import com.itheima.stock.mapper.StockMarketIndexInfoMapper;
import com.itheima.stock.pojo.StockBusiness;
import com.itheima.stock.service.StockService;
import com.itheima.stock.vo.resp.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;

/**
 * @author by itheima
 * @Date 2021/12/19
 * @Description
 */
@Service("stockService")
public class StockServiceImpl implements StockService {

    @Autowired
    private StockBusinessMapper stockBusinessMapper;

    @Autowired
    private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;

    @Autowired
    private StockInfoConfig stockInfoConfig;

    @Override
    public List<StockBusiness> getAllStockBusiness() {
        return stockBusinessMapper.findAll();
    }

    /**
     * 获取国内大盘的实时数据
     * @return
     */
    @Override
    public R<List<InnerMarketDomain>> innerIndexAll() {
        //1.获取国内A股大盘的id集合
        List<String> inners = stockInfoConfig.getInner();
        //2.获取最近股票交易日期
        Date lastDate = DateTimeUtil.getLastDate4Stock(DateTime.now()).toDate();
        //TODO mock测试数据,后期数据通过第三方接口动态获取实时数据 可删除
        lastDate=DateTime.parse("2022-01-02 09:32:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")).toDate();
        //3.将获取的java Date传入接口
        List<InnerMarketDomain> list= stockMarketIndexInfoMapper.getMarketInfo(inners,lastDate);
        //4.返回查询结果
        return R.ok(list);
    }
}
1.4.3 定义mapper接口方法和xml

mapper下定义接口方法和xml:

    /**
     * 根据大盘的id和时间查询大盘信息
     * @param marketIds 大盘id集合
     * @param timePoint 当前时间点(默认精确到分钟)
     * @return
     */
    List<InnerMarketDomain> getMarketInfo(@Param("marketIds") List<String> marketIds, @Param("timePoint") Date timePoint);

定义mapper接口绑定SQL:

    <select id="getMarketInfo" resultType="com.itheima.stock.pojo.domain.InnerMarketDomain">
        select
            smi.market_code as code,
            smi.market_name as name,
            smi.open_point as openPoint,
            smi.cur_point as curPoint,
            smi.pre_close_point as preClosePrice,
            smi.trade_amount as tradeAmt,
            smi.trade_volume as tradeVol,
            smi.cur_point-smi.pre_close_point as upDown,
            (smi.cur_point-smi.pre_close_point)/smi.pre_close_point as rose,
            (smi.max_point-smi.min_point)/smi.pre_close_point as amplitude,
            smi.cur_time as curTime
        from stock_market_index_info as smi
        where smi.market_code in
        <foreach collection="marketIds" item="marketId"  open="(" separator="," close=")">
            #{marketId}
        </foreach>
        and smi.cur_time=#{timePoint}
    </select>

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

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

相关文章

sprintf()函数的介绍及其用法

目录 前言 一&#xff1a;sprintf&#xff08;&#xff09;函数的介绍 二&#xff1a;sprintf&#xff08;&#xff09;函数的原型 三&#xff1a;sprintf&#xff08;&#xff09;函数的用法 1.控制输出格式 2.将数字转化成字符串 3.拼接字符串 4.当然&#xff0c;也可…

Q必达任务脚本

文章目录 1.购买服务器地址2.部署教程3. 代码如下4. 如何联系我 1.购买服务器地址 服务器购买地址 https://t.aliyun.com/U/rUHk58 若失效&#xff0c;可用地址 https://www.aliyun.com/activity/wuying/dj?source5176.29345612&userCode49hts92d 2.部署教程 2024年最…

从零开始构建后台管理系统列表:新手友好教程,全程使用 HTML+CSS+JavaScript,涵盖增删查改、导入导出、排序等功能(含完整源码)

b站视频演示效果&#xff1a; 效果图&#xff1a; 完整代码&#xff1a; <!DOCTYPE html> <html> <head><meta charset"utf-8"><title>后台管理系统</title><!-- 引入正确的 Vue.js 版本 --><script src"https:/…

鸿蒙 OS 开发零基础快速入门教程

视频课程: 东西比较多, 这里主要分享一些代码和案例. 开关灯效果案例: 开灯 开关灯效果案例: 关灯 Column 和 Row 的基本用法 Entry Component struct Index {State message: string 张三;build() {// 一行内容Row() {// 一列内容Column() {// 文本内容Text(this.mess…

27 C 语言标准库 <stdio.h> 中的两个重要字符串函数:sprintf、sscanf

目录 1 sprintf 1.1 函数原型 1.2 功能说明 1.3 案例演示 1.4 注意事项 2 sscanf 2.1 函数原型 2.2 功能说明 2.3 案例演示 2.4 注意事项 1 sprintf 1.1 函数原型 sprintf 函数是 C 语言标准库中的一个函数&#xff0c;用于将格式化的数据写入字符串。其函数原型定义…

9.24作业

将昨天的My_string类中的所有能重载的运算符全部进行重载 、[] 、>、<、、>、<、! 、&#xff08;可以加等一个字符串&#xff0c;也可以加等一个字符&#xff09;、输入输出(<< 、 >>) 代码如下 MyString.h #ifndef MYSTRING_H #define MYSTRING_…

使用Docker和cpolar在Linux服务器上搭建DashDot监控面板

使用Docker和cpolar在Linux服务器上搭建DashDot监控面板 前言环境准备安装Docker下载Dashdot镜像 部署DashDot应用本地访问DashDot服务安装cpolar内网穿透固定DashDot公网地址结语 前言 在这个数字化飞速发展的时代&#xff0c;服务器作为支撑各种应用和服务的基础设施&#xf…

C++类和对象(中)【下篇】

&#x1f31f;个人主页&#xff1a;落叶 &#x1f31f;当前专栏: C专栏 目录 赋值运算符重载 运算符重载 赋值运算符重载 日期类实现 运算符重载<和运算符重载 运算符重载进行复用 运算符重载< 运算符重载> 运算符重载> 运算符重载! 获取某年某月的天数…

大模型算法岗常见面试题100道(值得收藏)非常详细收藏我这一篇就够了

大模型应该是目前当之无愧的最有影响力的AI技术&#xff0c;它正在革新各个行业&#xff0c;包括自然语言处理、机器翻译、内容创作和客户服务等等&#xff0c;正在成为未来商业环境的重要组成部分。 截至目前大模型已经超过200个&#xff0c;在大模型纵横的时代&#xff0c;不…

在Markdown中实现内部查询

markdown实现内部查询 在想要跳转到的位置添加 <a idxxx></a> 标签&#xff0c;如下图&#xff1a; 然后按如下格式添加目录 [跳转文字](#id)&#xff1a; 如上操作即可实现markdown内部查询。 具体实现效果如下&#xff1a;

八大排序——万字长文带你剖析八大排序(C语言)

本篇文章主要介绍八大排序的思想和具体实现&#xff0c;也会分析具体的时间复杂度和空间复杂度&#xff0c;提醒一些容易出现的坑和实现一些不同版本的排序&#xff0c;以及这些不同排序之间的效率分析 目录 1.插入排序 1.1直接插入排序 1.1.1 直接插入排序的思想&#xff…

PyTorch模型转ONNX量化模型

你是否发现模型太大&#xff0c;无法部署在你想要的云服务上&#xff1f;或者你是否发现 TensorFlow 和 PyTorch 等框架对于你的云服务来说太臃肿了&#xff1f;ONNX Runtime 可能是你的救星。 如果你的模型在 PyTorch 中&#xff0c;你可以轻松地在 Python 中将其转换为 ONNX…

关于YOLOX的一些优势

YOLOX 是旷视开源的高性能检测器。旷视的研究者将解耦头、数据增强、无锚点以及标签分类等目 标检测领域的优秀进展与 YOLO 进行了巧妙的集成组合&#xff0c;提出了 YOLOX&#xff0c;不仅实现了超越 YOLOv3、 YOLOv4 和 YOLOv5 的 AP&#xff0c;而且取得了极具竞争力的推理速…

FME学习笔记

读取数据 方法一&#xff1a;add reader 通过读模块来进行数据的读取 方法二&#xff1a;FeatureReader Parameters 通过转换器来进行数据的读取 可以通过空间范围进行筛选 在FME中&#xff0c;所有数据处理都要用到的&#xff0c;绝对的重点&#xff1a;转换器&#xff…

深圳某局联想SR850服务器黄灯 不开机维修

深圳 福田区1台Lenovo Thinksystem SR850 四路服务器黄灯问题现场处理。 1&#xff1a;型号&#xff1a;联想SR850 机架式2U服务器 2&#xff1a;故障&#xff1a;能通电&#xff0c;开机按钮快闪&#xff0c;随后叹号警告灯常亮 3&#xff1a;用户自行折腾无果后找到我们tech …

【推文制作】秀米简明教程 1.0

【前言】本文内容主要是针对一些常用的秀米操作进行介绍&#xff0c;并说明一些往年的经验要求。但是&#xff0c;最重要的是&#xff0c;请发挥你的艺术创造力&#xff0c;相信你一定可以做出更好看的推文。 一、秀米页面介绍 在使用秀米之前&#xff0c;我们会有一个通过浏览…

Maya学习笔记:项目设置和快捷键

文章目录 项目设置工程文件夹 快捷键 项目设置 工程文件夹 maya需要一个文件夹存放自己的工程内容 先指定一个文件夹 文件/项目窗口 选择一个文件夹&#xff0c;然后选择创建默认工作区 然后生成文件目录 在项目窗口里&#xff0c;选择要生成的子文件夹&#xff08;保持默认…

【ASE】第二课_溶解效果

今天我们一起来学习ASE插件&#xff0c;希望各位点个关注&#xff0c;一起跟随我的步伐 今天我们来学习溶解效果&#xff0c;通过渐变纹理达到好像燃烧效果的溶解效果 今天我们的效果很简单&#xff0c;但是其中包含没有学习的节点&#xff0c;所以还是要拿出来学习一下 最终…

ESP32异常报错2

出现这种情况 一般是缺少";"分号. 或者缺少, 仔细查找代码.查看是哪儿缺少了这些代码