diff --git a/src/main/java/cn/stock/market/dto/TwelveStockData.java b/src/main/java/cn/stock/market/dto/TwelveStockData.java new file mode 100644 index 0000000..fd46097 --- /dev/null +++ b/src/main/java/cn/stock/market/dto/TwelveStockData.java @@ -0,0 +1,22 @@ +package cn.stock.market.dto; + +import lombok.Data; + +@Data +public class TwelveStockData { + + private String symbol; + + private String name; + + private String currency; + + private String exchange; + + private String mic_code; + + private String country; + + private String type; +} + diff --git a/src/main/java/cn/stock/market/dto/TwelveStockInfo.java b/src/main/java/cn/stock/market/dto/TwelveStockInfo.java new file mode 100644 index 0000000..0301655 --- /dev/null +++ b/src/main/java/cn/stock/market/dto/TwelveStockInfo.java @@ -0,0 +1,61 @@ +package cn.stock.market.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +/** + * TwelveStockInfo类用于存储股票信息。 + * 该类包含了股票的基本信息和交易数据。 + */ +@ApiModel("TwelveStockInfo") +public class TwelveStockInfo { + @ApiModelProperty("股票代码") + private String stockCode; + + @ApiModelProperty("交易代码") + private String symbol; + + @ApiModelProperty("股票名称") + private String stockName; + + @ApiModelProperty("股票类型") + private String stockType; + + @ApiModelProperty("当前价格") + private String lastPrice; + + @ApiModelProperty("变动百分比") + private String perchg; + @ApiModelProperty("变动值") + private String change; + + @ApiModelProperty("开盘价格") + private String openPrice; + + @ApiModelProperty("昨日收盘价格") + private String previousPrice; + + @ApiModelProperty("成交量") + private String volume; + + @ApiModelProperty("最高价格") + private String highPrice; + + @ApiModelProperty("最低价格") + private String lowPrice; + + @ApiModelProperty("52周最高价格") + private String week52HighPrice; + + @ApiModelProperty("52周最低价格") + private String week52LowPrice; + + @ApiModelProperty("股票当前的交易状态: 1-表示退市Closed, 2-Opening Auction, 3-Continuous Trading, 15-Intra-day Close (scheduled)") + private String status; + + @ApiModelProperty("股票id") + private Integer id; +} + diff --git a/src/main/java/cn/stock/market/infrastructure/job/TwelvedataTask.java b/src/main/java/cn/stock/market/infrastructure/job/TwelvedataTask.java new file mode 100644 index 0000000..74918bf --- /dev/null +++ b/src/main/java/cn/stock/market/infrastructure/job/TwelvedataTask.java @@ -0,0 +1,102 @@ +package cn.stock.market.infrastructure.job; + +import lombok.extern.slf4j.Slf4j; + +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.google.common.base.Stopwatch; +import com.google.common.collect.Lists; + +import cn.stock.market.domain.basic.entity.TwelveStock; +import cn.stock.market.domain.basic.service.TwelveStockService; +import cn.stock.market.dto.TwelveStockData; +import cn.stock.market.utils.HttpRequest; + +@Slf4j +@Component +@RestController +public class TwelvedataTask { + + @Autowired + private TwelveStockService twelveStockService; + + @GetMapping("/task/syncStockData") + @Scheduled(cron = "0 0 18 * * ?") + public void syncStockData() { + log.info("每天18点定时同步Twelvedata股票数据开始"); + Stopwatch stopwatch = Stopwatch.createStarted(); + // 获取股票symbol列表 + List stockList = getStockList(); + // 查询出数据库中所有股票 + List allStocks = twelveStockService.repository().findAll(); + List savedSymbols = allStocks.stream().map(p-> p.getStockCode() + "#" + p.getStockType()).distinct().collect(Collectors.toList()); + // 去除数据库中已经存在的股票 + // 使用Iterator安全地移除元素 + if(stockList!=null && stockList.size()>0) { + Iterator iterator = stockList.iterator(); + while (iterator.hasNext()) { + TwelveStockData stockData = iterator.next(); + if (savedSymbols.contains(stockData.getSymbol() + "#" + stockData.getExchange())) { // 根据条件移除元素 + iterator.remove(); + } + } + } + //剩余数据入库 + List addList = Lists.newArrayList(); + if(stockList!=null && stockList.size()>0) { + for(TwelveStockData stockData:stockList) { + addList.add(cover(stockData)); + } + twelveStockService.repository().saveAll(addList); + } + log.info("syncStockData执行, 受影响数{}, 耗时:{}毫秒", addList.size(), stopwatch.elapsed(TimeUnit.MILLISECONDS)); + } + + private TwelveStock cover(TwelveStockData data) { + TwelveStock stock = new TwelveStock(); + stock.setStockCode(data.getSymbol()); + stock.setStockName(data.getName()); + stock.setStockType(data.getExchange()); + stock.setSaveTime(new Date()); + return stock; + } + + private List getStockList() { + try { + String source = "docs"; + String country = "India"; + List list = Lists.newArrayList(); + long start = System.currentTimeMillis(); + String url = String.format("https://api.twelvedata.com/stocks?source=%s&country=%s&apikey=%s",source,country,"4098a6fc2c3245a88c7da804f10223c2"); + String result = HttpRequest.doTwelveGet(url); + log.info("getStockList:获取 {} {} 的股票全量列表结束,耗时: {} ms ",source,country,(System.currentTimeMillis()-start)); + JSONObject jsonObject = JSONObject.parseObject(result); + if (jsonObject != null && !jsonObject.isEmpty()) { + JSONArray jsonArray = jsonObject.getJSONArray("data"); + if(jsonArray!=null && jsonArray.size()>0) { + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject item = jsonArray.getJSONObject(i); + TwelveStockData stock = JSONObject.toJavaObject(item, TwelveStockData.class); + list.add(stock); + } + } + } + return list; + } catch (Exception e) { + // TODO Auto-generated catch block + log.error("getStockList同步twelvedata股票数据异常,Exception:{}", e); + } + return null; + } +}