23.项目开发之量化交易抓取数据QuantTradeData(二)

后端业务:定时更新"A股日线行情"数据

需求说明

为了获取前一天的最新数据,我们需要每天晚上10点定时刷新daily股票列表基础信息,并将最新数据插入或更新到数据库中。

如果该内容是在当天交易日信息未更新前查询(15~16点之前),会导致一条信息都查不到, 返回:
{"msg":"","code":0,"data":{"has_more":false,"fields":["ts_code","trade_date","open","high","low","close","pre_close","change","pct_chg","vol","amount"],"items":[]},"request_id":"10449486502d11ee949207ef2f187cbe"}

这时候在测试时,可以暂时拿昨天的交易信息来测试功能。

股票日线信息表(tb_stock_daily_info)

股票日线信息实体(StockDailyInfo)

java 复制代码
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class StockDailyInfo {
   private Integer id;
   private String thcode;              //股票代码
   private String tradedate;          //交易日期
   private Float stockopen;          //开盘价
   private Float high;                   //最高价
   private Float low;                    //最低价
   private Float stockclose;          //收盘价
   private Float preclose;             //昨收价
   private Float stockchange;      //涨跌额
   private Float pctchg;               //涨跌幅
   private Float vol;                     //成交量
   private Float amount;              //成交额
}

三层搭建

StockDailyInfoMapper:

java 复制代码
import org.springframework.stereotype.Repository;

@Repository
public interface StockDailyInfoMapper {
}

StockDailyInfoMapper.xml:

java 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
       PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.quanttradedata.stock.mapper.StockDailyInfoMapper">

</mapper>

Service

java 复制代码
@Service
public class StockService {
   @Autowired
   private StockBasicInfoMapper stockBasicInfoMapper;
   @Autowired
   private TuShareAPI tuShareAPI;
   private SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
   @Autowired
   private StockDailyInfoMapper stockDailyInfoMapper;
//其他代码忽略
}

业务实现

StockDailyInfoJob

java 复制代码
import com.quanttradedata.stock.service.StockService;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;

@Component
public class StockDailyInfoJob extends QuartzJobBean {
   @Autowired
   private StockService stockService;
   @Override
   protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
       System.out.println("更新当日A股日线行情数据....");
       stockService.saveStockDailyInfoFromNet();
   }
}

QuartzConfig

注意,测试时,将时间频率改为15秒一次

java 复制代码
import com.quanttradedata.stock.job.StockBasicInfoJob;
import com.quanttradedata.stock.job.StockDailyInfoJob;
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class QuartzConfig {
   //股票基本信息的 任务详情创建 及 触发器创建
   @Bean
   public JobDetail getStockBasicInfoJob(){
       return JobBuilder.newJob(StockBasicInfoJob.class).storeDurably().build();
   }
   @Bean
   public Trigger getStockBasicInfoJobTrigger(JobDetail getStockBasicInfoJob){
       //1、编写cron表达式,指定触发的时间和周期
       //开发执行: 每个工作日的晚上22点
       CronScheduleBuilder cron = CronScheduleBuilder.cronSchedule("0 0 22 ? * MON-FRI");
       //测试执行: 每15秒执行一次
//        CronScheduleBuilder cron = CronScheduleBuilder.cronSchedule("0/15 * * * * ? ");
       //2、构建触发器,执行任务
       return TriggerBuilder.newTrigger().forJob(getStockBasicInfoJob).withSchedule(cron).build();
   }

   //A股日线行情基本信息的 任务详情创建 及 触发器创建
   @Bean
   public JobDetail getStockDailyInfoJob(){
       return JobBuilder.newJob(StockDailyInfoJob.class).storeDurably().build();
   }
   @Bean
   public Trigger getStockDailyInfoJobTrigger(JobDetail getStockDailyInfoJob){
       //1、编写cron表达式,指定触发的时间和周期
       //开发执行: 每个工作日的晚上22点
       CronScheduleBuilder cron = CronScheduleBuilder.cronSchedule("0 0 22 ? * MON-FRI");
       //测试执行: 每15秒执行一次
//        CronScheduleBuilder cron = CronScheduleBuilder.cronSchedule("0/15 * * * * ? ");
       //2、构建触发器,执行任务
       return TriggerBuilder.newTrigger().forJob(getStockDailyInfoJob).withSchedule(cron).build();
   }
}

StockService

注意:如果当天并非是工作日的15~16点之后,用指定天数据来进行测试

java 复制代码
private SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMdd");

/**
    * 更新当日的A股日线行情数据
    */
   public void saveStockDailyInfoFromNet() {
       //1、编辑传递给TuShare平台的参数
       Map<String, String> param = new HashMap<>();
       param.put("trade_date",sdf2.format(new Date()));        //当天日期
       //因为老师在写代码时,时间没有超过工作日的16:00,当天日线数据还不存在,为了测试的方便,取前面某天的数据来测试
//        param.put("trade_date","20231018");
       //2、向TuShare平台发出请求,获取json数据
       JSONObject jsonObject = tuShareAPI.get(Const.STOCK_DAILY, param, null);
       //3、解析json数据,解析为List集合
       //3.1、获取日线json数据
       JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("items");
       //3.2、创建List集合,遍历日线Json数据,每遍历一行数据,转为一个StockDailyInfo对象,存入List集合
       List<StockDailyInfo> stockDailyInfos = new ArrayList<>();
       for (int i = 0; i < jsonArray.size(); i++) {
           JSONArray array = jsonArray.getJSONArray(i);
           stockDailyInfos.add(
                   new StockDailyInfo(
                           null,
                           array.getString(0),
                           array.getString(1),
                           array.getFloat(2),
                           array.getFloat(3),
                           array.getFloat(4),
                           array.getFloat(5),
                           array.getFloat(6),
                           array.getFloat(7),
                           array.getFloat(8),
                           array.getFloat(9),
                           array.getFloat(10)
                   )
           );
       }
       /*for (StockDailyInfo sdi : stockDailyInfos) {
           System.out.println(sdi);
       }*/
       //4、直接将List集合整体插入数据库
       if(stockDailyInfos.size()>0){
           int rows = 0;
           try {
               rows = stockDailyInfoMapper.insertStockDailyInfos(stockDailyInfos);
           } catch (Exception e) {
               if(e.getCause() instanceof SQLIntegrityConstraintViolationException && e.getMessage().contains("Duplicate entry")){
                   //说明当天数据已经更新过了
                   System.out.println("当天数据已更新,无需重复更新");
               }
           }
           //5、展示结果
           System.out.println("成功向数据库插入了"+rows+"条日线数据");
       }else{
           System.out.println("当天无日线数据 或 当前时间还未更新日线数据");
       }
   }

StockDailyInfoMapper

java 复制代码
import com.quanttradedata.stock.javabean.StockDailyInfo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface StockDailyInfoMapper {
   /**
    * 向数据库插入多条日线信息
    * @param stockDailyInfos
    * @return
    */
   int insertStockDailyInfos(@Param("list") List<StockDailyInfo> stockDailyInfos);
}

StockDailyInfoMapper.xml

java 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
       PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.quanttradedata.stock.mapper.StockDailyInfoMapper">
   <insert id="insertStockDailyInfos">
       insert into tb_stock_daily_info (
           thcode,
           tradedate,
           stockopen,
           high,
           low,
           stockclose,
           preclose,
           stockchange,
           pctchg,
           vol,
           amount
       ) values
             <foreach collection="list" item="sdi" separator=",">
                 (
                     #{sdi.thcode},
                     #{sdi.tradedate},
                     #{sdi.stockopen},
                     #{sdi.high},
                     #{sdi.low},
                     #{sdi.stockclose},
                     #{sdi.preclose},
                     #{sdi.stockchange},
                     #{sdi.pctchg},
                     #{sdi.vol},
                     #{sdi.amount}
                 )
             </foreach>
   </insert>
</mapper>

后端业务:定时更新"A股日线行情"数据业务完成!!!

项目开发之量化交易抓取数据QuantTradeData(三):后端业务之分页查询股票列表基础信息---传送门

相关推荐
StickToForever3 小时前
第4章 信息系统架构(五)
经验分享·笔记·学习·职场和发展
闲猫5 小时前
go orm GORM
开发语言·后端·golang
丁卯4045 小时前
Go语言中使用viper绑定结构体和yaml文件信息时,标签的使用
服务器·后端·golang
Tirzano6 小时前
springsecurity自定义认证
spring boot·spring
leegong231117 小时前
学习PostgreSQL专家认证
数据库·学习·postgresql
Moonnnn.7 小时前
51单片机学习——动态数码管显示
笔记·嵌入式硬件·学习·51单片机
南宫生8 小时前
力扣每日一题【算法学习day.132】
java·学习·算法·leetcode
技术小齐8 小时前
网络运维学习笔记 016网工初级(HCIA-Datacom与CCNA-EI)PPP点对点协议和PPPoE以太网上的点对点协议(此处只讲华为)
运维·网络·学习
竹言笙熙8 小时前
代码审计初探
学习·web安全
日记成书9 小时前
物联网智能项目
物联网·学习