2022/7/27 算力-价格明细
一.统计数据接口


controller层
/**
* 根据ProductSpec和date查询
* 查询条件: 地区,ProductSpec,date
* @param renduiPriceDailyDTO
* @return
*/
@PostMapping(value = "/daily/getByProductSpecAndDate")
public Result<?> getByProductSpecAndDate(@RequestBody RenduiPriceDailyDTO renduiPriceDailyDTO){
if(StringUtils.isBlank(renduiPriceDailyDTO.getSiteId())){
return Result.error("地区不能为空!");
}
if(StringUtils.isBlank(renduiPriceDailyDTO.getProductSpec())){
return Result.error("productSpec不能为空!");
}
if(renduiPriceDailyDTO.getDate() == null){
return Result.error("日期不能为空,日期格式为:yyyy-MM-dd!");
}
return renduiPriceDailyService.getByProductSpecAndDate(renduiPriceDailyDTO);
}
在校验一个String类型的变量是否为空时,可以使用StringUtils.isBlank方法,它可以校验三种情况:是否为null、是否为""、是否为空字符串(引号中间有空格)" "、制表符、换行符、换页符和回车。
StringUtils.isEmpty("yyy") = false
StringUtils.isEmpty("") = true
StringUtils.isEmpty(" ") = false
StringUtils.isBlank("yyy") = false
StringUtils.isBlank("") = true
StringUtils.isBlank(" ") = true
service层
/**
* 根据ProductSpec和date查询
* 查询条件: 地区,ProductSpec,date
* @param renduiPriceDailyDTO
* @return
*/
Result<?> getByProductSpecAndDate(RenduiPriceDailyDTO renduiPriceDailyDTO);
}
serviceImpl层
@Override
public Result<?> getByProductSpecAndDate(RenduiPriceDailyDTO renduiPriceDailyDTO) {
//1.获取该日期的每日统计结果
long date = renduiPriceDailyDTO.getDate().atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli();
Document daily = renduiPriceDailyManager.queryByProductSpec(renduiPriceDailyDTO.getSiteId(), renduiPriceDailyDTO.getProductSpec(), date);
if(daily == null){
return Result.error("当前没有报价,暂无统计");
}
//今开
if (daily.get("openingPrice") != null) {
daily.put("openingPrice",daily.get("openingPrice"));
daily.put("openingPriceTax",daily.get("openingPriceTax"));
}else {
daily.put("openingPrice",0);
daily.put("openingPriceTax",0);
}
//2.查询该日期前一天的每日统计结果
long yesterday = renduiPriceDailyDTO.getDate().minusDays(1).atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli();
Document yesterdayDaily = renduiPriceDailyManager.queryByProductSpec(renduiPriceDailyDTO.getSiteId(), renduiPriceDailyDTO.getProductSpec(), yesterday);
if(yesterdayDaily == null){
daily.put("closePrice",0);
daily.put("closePriceTax",0);
daily.put("riseAndFall",0);
daily.put("riseAndFallTax",0);
daily.put("riseRange",0.00);
daily.put("riseRangeTax",0.00);
return Result.OK(daily);
}
//3.计算
//涨跌 当前价 - 昨天均价
Float riseAndFall = Float.valueOf(daily.get("lastprice").toString()) - Float.valueOf(yesterdayDaily.get("price").toString());
Float riseAndFallTax = Float.valueOf(daily.get("lastpriceTax").toString()) - Float.valueOf(yesterdayDaily.get("priceTax").toString());
//涨幅 涨跌 / 昨天均价
Float riseRange = Double.valueOf(AccurateCalculation.div(riseAndFall,Double.valueOf(yesterdayDaily.get("price").toString()),2)).floatValue() * 100;
Float riseRangeTax = Double.valueOf(AccurateCalculation.div(riseAndFallTax,Double.valueOf(yesterdayDaily.get("priceTax").toString()),2)).floatValue() * 100;
daily.put("riseAndFall",riseAndFall);
daily.put("riseAndFallTax",riseAndFallTax);
daily.put("riseRange",riseRange);
daily.put("riseRangeTax",riseRangeTax);
//昨收
daily.put("closePrice",yesterdayDaily.get("closePrice"));
daily.put("closePriceTax",yesterdayDaily.get("closePriceTax"));
return Result.OK(daily);
}
atStartOfDay()
long date = renduiPriceDailyDTO.getDate().atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli();
java.time.LocalDate.atStartOfDay()方法将此日期与午夜时间组合在一起,以便在此日期开始时创建LocalDateTime。
声明
public LocalDateTime atStartOfDay()
返回值
此日期开始时的午夜的本地日期时间,不为null。
示例
package com.yiibai;
import java.time.LocalDate;
import java.time.LocalDateTime;
public class LocalDateDemo {
public static void main(String[] args) {
LocalDate date = LocalDate.parse("2017-02-03");
System.out.println(date);
LocalDateTime date1 = date.atStartOfDay();
System.out.println(date1);
}
}
结果
2017-02-03
2017-02-03T00:00
toInstant()
Java8出现的 Instant 类似于 Date ,LocalDateTime 类似于 Calendar,DateTimeFormatter 类似于 SimpleDateFormat,由于 SimpleDateFormat 是线程不安全的(一般使用 SimpleDateFormat 的时会把它定义成静态变量,从而避免频繁地创建它的对象实例,但 SimpleDateFormat 内部使用 Calendar 去完成日期的转换,多线程情况下可能会出现线程不安全情况),推荐使用 Instant代替 Date,LocalDateTime 代替 Calendar,DateTimeFormatter 代替 SimpleDateFormat
localDateTime
// 输出当前时间:2019-04-24T19:41:21.858
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
// 格式化时间,输出:2019年04月24日 19:49:25
LocalDateTime time = LocalDateTime.now();
String timeStr = time.format(DateTimeFormatter.ofPattern("yyyy年年MM月dd日 HH:mm:ss"));
System.out.println(timeStr);
// 当前时间增加20分钟
LocalDateTime afterPlusTime = LocalDateTime.now().plus(20, ChronoUnit.MINUTES);
System.out.println(afterPlusTime);
// 创建开始和结束时间,并计算中间差值
LocalDateTime start = LocalDateTime.of(1992, 8, 13, 0, 0, 0);
LocalDateTime end = LocalDateTime.of(2019, 4, 25, 0, 0);
long diff = LocalDateTimeUtils.betweenTwoTime(start, end, ChronoUnit.YEARS);
System.out.println(diff+"年"); // 26
boolean b = start.isAfter(end);
System.out.println(b); // false
//获取秒数 (东8区,也就是北京时间)
Long second = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
//获取毫秒数(东8区,也就是北京时间)
Long milliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
instant
Instant now = Instant.now(); // 2019-04-24T12:30:34.349Z
long currentSecond = now.getEpochSecond(); // 秒数:1556109034
long currentMilli = now.toEpochMilli(); // 毫秒数:1556109034349
Instant afterPlusSecondInstant = now.plusSeconds(1000); // 秒数增加1000
boolean b = now.isBefore(afterPlusSecondInstant); // 比较
DateTimeFormatter
// 输出:2019年04月24日 20:53:23
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
LocalDateTime time = LocalDateTime.now();
String formatResult = time.format(df);
// 输出:20190424
LocalDateTime time = LocalDateTime.now();
String formatResult = time.format(DateTimeFormatter.BASIC_ISO_DATE);
ISO_DATE --> 2019-04-24
ISO_LOCAL_DATE --> 2019-04-24
ISO_LOCAL_TIME --> 20:59:48.42
ISO_TIME --> 21:00:38.256
ISO_LOCAL_DATE_TIME --> 2019-04-24T21:01:11.083
.......
格式转化
Instant instant = Instant.now();
Date date = Date.from(instant); // Instant转换为Date
Instant instant2 = date.toInstant(); // Date转换为Instant
// Date 与 LocalDateTime 的转换是通过 Instant 中间的转换来进行的
Date date = new Date();
LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(),ZoneId.systemDefault()); // Date转换为LocalDateTime
LocalDateTime localDateTime = LocalDateTime.now();
Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
Date date = Date.from(instant); // LocalDateTime转换为Date
二.根据维度查询 区间均价加折线图 当天不显示区间均价


controller层
/**
* 查询分钟维度价格统计(曲线图的数据接口)
* @param
* @return
*/
@AutoLog(value = "/prices/statistics")
@ApiOperation(value = "/prices/statistics", notes = "/prices/statistics")
@GetMapping(value = "/prices/statistics")
public Result<?> statisticsPrice(@RequestParam(value = "productSpec") String productSpec, @RequestParam(value = "siteId")String siteId, @RequestParam(value = "from")String from, @RequestParam(value = "to")String to) {
boolean fromBeforeTo = DateCommonUtil.getDateFromStr(from).before(DateCommonUtil.getDateFromStr(to));
if(!fromBeforeTo){
return Result.error("开始时间不能大于结束时间");
}
return service.statisticsPrice(productSpec, siteId, from, to);
}
service层
Result<?> statisticsPrice(String productSpec, String siteId, String from, String to);
serviceImpl层
@Override
public Result<?> statisticsPrice(String productSpec, String siteId, String from, String to) {
long dateDiff = DateUtil.betweenDay(DateCommonUtil.getDateFromStr(from), DateCommonUtil.getDateFromStr(to), false);
boolean isSameDay = DateUtil.isSameDay(DateCommonUtil.getDateFromStr(from), DateCommonUtil.getDateFromStr(to));
if (dateDiff <= 0 && isSameDay) {
return Result.OK(statisticsMinutely2(productSpec, siteId, from, to));
} else {
return Result.OK(statisticsDaily(productSpec, siteId, from, to, dateDiff));
}
}
private Map<String,Object> statisticsMinutely2(String productSpec, String siteId, String from, String to) {
Map<String,Object> map = new HashMap<>();
map.put("rangeAvgPrice",0);
long FIVE_MINUTES = 5 * 60000;
long fromTime = DateCommonUtil.getTimeFromStr(from);
long toTime = DateCommonUtil.getTimeFromStr(to);
List<Document> minutely = renduiPriceMinutelyManager.queryByProductSpec(productSpec, siteId, fromTime, toTime);
List<PriceStatisticsVO> results = new ArrayList<>();
long minuteDiff = DateUtil.between(DateCommonUtil.getDateFromStr(from), DateCommonUtil.getDateFromStr(to), DateUnit.MINUTE);
int window = (int) minuteDiff / 5;
// 如果为空
if (minutely.size() == 0) {
PriceStatisticsVO lastPrice = getLastPrice(productSpec, siteId, fromTime);
long t = fromTime;
while (t <= toTime) {
PriceStatisticsVO p = new PriceStatisticsVO();
BeanUtil.copyProperties(lastPrice, p);
p.setTimestamp(t);
results.add(lastPrice);
t += 5 * 60000;
}
map.put("list",results);
return map;
}
PriceStatisticsVO firstPrice = new PriceStatisticsVO();
BeanUtil.copyProperties(minutely.get(0), firstPrice);
// 补充左边的数据
long fistTime = firstPrice.getTimestamp();
PriceStatisticsVO formerPrice = null;
if (fistTime > fromTime) {
PriceStatisticsVO latestPrice = getLastPrice(productSpec, siteId, fromTime);
long t = fromTime;
int i = 0;
while (t < fistTime) {
PriceStatisticsVO p = new PriceStatisticsVO();
BeanUtil.copyProperties(latestPrice, p);
p.setTimestamp(t);
results.add(p);
formerPrice = p;
i ++;
t += FIVE_MINUTES;
}
}
// 补充中间数据
for (int i = 0; i < minutely.size(); i ++) {
Document m = minutely.get(i);
PriceStatisticsVO price = new PriceStatisticsVO();
BeanUtil.copyProperties(m, price);
// 补充中间数据
if (formerPrice != null && price.getTimestamp() - formerPrice.getTimestamp() > FIVE_MINUTES) {
long t = formerPrice.getTimestamp() + FIVE_MINUTES;
while ( t < price.getTimestamp()) {
PriceStatisticsVO p = new PriceStatisticsVO();
BeanUtil.copyProperties(formerPrice, p);
p.setTimestamp(t);
results.add(p);
t += FIVE_MINUTES;
}
}
results.add(price);
formerPrice = price;
}
if (formerPrice != null && formerPrice.getTimestamp() < toTime) {
long t = formerPrice.getTimestamp() + FIVE_MINUTES;
while ( t < toTime) {
PriceStatisticsVO p = new PriceStatisticsVO();
BeanUtil.copyProperties(formerPrice, p);
p.setTimestamp(t);
results.add(p);
t += FIVE_MINUTES;
}
}
map.put("list",results);
return map;
}
DateUtil.betweenDay()
需求
求出 当前天, 与指定日期之间相差的天数, 指定日期一定在 当前天之前即 当前天为 01-23 , 指定日期应该为 01-22
解决方案
使用hutools工具包中提供的计算两个日期之间相差天数的方法
betweenDay()
三个参数: betweenDay(Date,Date,Boolean)
// 使用方式
// cn.hutool.core.date.DateUtil.betweenDay(currentDate, targetTime, true);
// 源码
/**
* 判断两个日期相差的天数<br>
*
* <pre>
* 有时候我们计算相差天数的时候需要忽略时分秒。
* 比如:2016-02-01 23:59:59和2016-02-02 00:00:00相差一秒
* 如果isReset为<code>false</code>相差天数为0。
* 如果isReset为<code>true</code>相差天数将被计算为1
* </pre>
*
* @param beginDate 起始日期
* @param endDate 结束日期
* @param isReset 是否重置时间为起始时间
* @return 日期差
* @since 3.0.1
*/
public static long betweenDay(Date beginDate, Date endDate, boolean isReset) {
if (isReset) {
beginDate = beginOfDay(beginDate);
endDate = beginOfDay(endDate);
}
return between(beginDate, endDate, DateUnit.DAY);
}
private Map<String,Object> statisticsDaily(String productSpec, String siteId, String from, String to, long dateDiff) {
List<PriceStatisticsVO> result = new ArrayList<>();
//按天统计
long fromTime = 0;
List<Float> avgList = new ArrayList<>();
Map<String,Object> map = new HashMap<>();
for (int i = 0; i < dateDiff + 1; i++) {
if (i == 0) {
fromTime = DateCommonUtil.getTimeFromStr(from);
}
long toTime = DateCommonUtil.dayAfterInterval(DateCommonUtil.dateFromTimestamp(fromTime), 1).getTime();
List<Document> daily = renduiPriceDailyManager.queryByProductSpec(productSpec, siteId, fromTime, toTime);
Float avgPrice = daily.stream().map(document -> document.get("price") == null ? 0 : Float.parseFloat(document.get("price").toString()))
.collect(Collectors.averagingDouble(price -> price)).floatValue();
//当avgPrice > 0
if(avgPrice.compareTo(new Float(0.00f)) == 1 ){
avgList.add(avgPrice);
}
PriceStatisticsVO statisticsVO = new PriceStatisticsVO();
statisticsVO.setProductSpec(productSpec);
statisticsVO.setPrice(Float.valueOf("0.00"));
statisticsVO.setPriceTax(Float.valueOf("0.00"));
statisticsVO.setSatisticsTime(DateCommonUtil.strFromTimestamp(fromTime));
if (CollectionUtil.isEmpty(daily)) {
setDailyEmptyVal(productSpec, siteId, fromTime, i, statisticsVO);
} else {
BeanUtil.copyProperties(daily.get(daily.size() - 1), statisticsVO);
}
fromTime = toTime;
result.add(statisticsVO);
}
for (int i = 0; i < result.size(); i++) {
//将空值替换为上个周期的数据 ,因为前面保证了第一条数据一定有值所以不会出现数组越界问题
if (result.get(i).getProductSpec() != null && result.get(i).getProductSpec().equals(EMPTY_MARK)) {
PriceStatisticsVO statisticsVO = getNotEmptyOne(i - 1, result);
String statisticTime = result.get(i).getSatisticsTime();
BeanUtil.copyProperties(statisticsVO, result.get(i));
result.get(i).setSatisticsTime(statisticTime);
}
}
Float rangeAvgPrice = avgList.stream().collect(Collectors.averagingDouble(avg -> avg)).floatValue();
map.put("rangeAvgPrice",rangeAvgPrice);
map.put("list",result);
return map;
}
三.大盘价曲线图
controller层
/**
* 大盘价曲线图
* 根据范围查询
* 查询条件 productSpec,siteId,from,to
* @param bigDishPriceDTO
* @return
*/
@PostMapping(value = "/bigDishPrice/rangeQueryBigDishPrice")
public Result<?> rangeQueryBigDishPrice(@RequestBody BigDishPriceDTO bigDishPriceDTO){
if(StringUtils.isBlank(bigDishPriceDTO.getProductSpec())){
return Result.error("查询条件不能为空!");
}
if(StringUtils.isBlank(bigDishPriceDTO.getSiteId())){
return Result.error("地区不能为空!");
}
if(bigDishPriceDTO.getTo().compareTo(LocalDateTime.now().plusMinutes(1)) == 1){
return Result.error("结束时间需小于当前时间!");
}
if(bigDishPriceDTO.getFrom().compareTo(bigDishPriceDTO.getTo()) >= 0){
return Result.error("开始时间需小于结束时间!");
}
return bigDishPriceService.rangeQueryBigDishPrice(bigDishPriceDTO);
}
service层
/**
* 大盘价曲线图
* 根据范围查询
* 查询条件 productSpec,siteId,from,to
* @param bigDishPriceDTO
* @return
*/
Result<?> rangeQueryBigDishPrice(BigDishPriceDTO bigDishPriceDTO);
serviceImpl层
@Override
public Result<?> rangeQueryBigDishPrice(BigDishPriceDTO bigDishPriceDTO) {
Duration duration = Duration.between(bigDishPriceDTO.getFrom(),bigDishPriceDTO.getTo());
//当前查询范围大于1天
if(duration.toDays() > 1){
return Result.OK(replenishDayData(bigDishPriceDTO.getProductSpec(),bigDishPriceDTO.getSiteId(),bigDishPriceDTO.getFrom(),bigDishPriceDTO.getTo(),duration.toDays()));
}
//1.查询范围内大盘价
long fromTime = bigDishPriceDTO.getFrom().toInstant(ZoneOffset.of("+8")).toEpochMilli();
long toTime = bigDishPriceDTO.getTo().toInstant(ZoneOffset.of("+8")).toEpochMilli();
List<Document> priceList = renduiPriceMinutelyManager.queryByProductSpec(bigDishPriceDTO.getProductSpec(), bigDishPriceDTO.getSiteId(), fromTime, toTime);
List<PriceStatisticsVO> result = new ArrayList<>();
// 如果为空取之前的最后一条大盘价
if (priceList.size() == 0 || priceList == null) {
Document doc = renduiPriceMinutelyManager.queryLastDataBy(bigDishPriceDTO.getProductSpec(), bigDishPriceDTO.getSiteId(), fromTime);
if(doc == null){
return Result.OK();
}
doc.put("price",Float.parseFloat(doc.get("price").toString()));
doc.put("priceTax",Float.parseFloat(doc.get("priceTax").toString()));
PriceStatisticsVO lastPrice = JSONObject.parseObject(JSON.toJSONString(doc), PriceStatisticsVO.class);
long from = fromTime;
while (from <= toTime) {
PriceStatisticsVO p = new PriceStatisticsVO();
BeanUtil.copyProperties(lastPrice, p);
p.setTimestamp(from);
p.setSatisticsTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(from),ZoneOffset.of("+8")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
result.add(p);
from = from + 5 * 60 * 1000;
}
return Result.OK(result);
}
//2.补充左边的数据
Document firstDoc = priceList.get(0);
firstDoc.put("price",Float.parseFloat(firstDoc.get("price").toString()));
firstDoc.put("priceTax",Float.parseFloat(firstDoc.get("priceTax").toString()));
PriceStatisticsVO firstPrice = JSONObject.parseObject(JSON.toJSONString(firstDoc), PriceStatisticsVO.class);
PriceStatisticsVO flagPrice = null;
if(firstPrice.getTimestamp() > fromTime){
Document doc = renduiPriceMinutelyManager.queryLastDataBy(bigDishPriceDTO.getProductSpec(), bigDishPriceDTO.getSiteId(), fromTime);
//如果之前没有数据则
PriceStatisticsVO lastPrice;
if(doc == null){
lastPrice = firstPrice;
}else {
doc.put("price",Float.parseFloat(doc.get("price").toString()));
doc.put("priceTax",Float.parseFloat(doc.get("priceTax").toString()));
lastPrice = JSONObject.parseObject(JSON.toJSONString(doc), PriceStatisticsVO.class);
}
long from = fromTime;
while (from < firstPrice.getTimestamp()) {
PriceStatisticsVO p = new PriceStatisticsVO();
BeanUtil.copyProperties(lastPrice, p);
p.setTimestamp(from);
p.setSatisticsTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(from),ZoneOffset.of("+8")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
result.add(p);
from = from + 5 * 60 * 1000;
flagPrice = p;
}
}
//3.补充中间的数据
for (Document document : priceList) {
document.put("price",Float.parseFloat(document.get("price").toString()));
document.put("priceTax",Float.parseFloat(document.get("priceTax").toString()));
PriceStatisticsVO price = JSONObject.parseObject(JSON.toJSONString(document), PriceStatisticsVO.class);
if(flagPrice != null && price.getTimestamp() - flagPrice.getTimestamp() >= 5 * 60 * 1000){
//+ 5 分钟
long from = flagPrice.getTimestamp() + 5 * 60 * 1000;
while (from < price.getTimestamp()){
PriceStatisticsVO p = new PriceStatisticsVO();
BeanUtil.copyProperties(price, p);
p.setTimestamp(from);
p.setSatisticsTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(from),ZoneOffset.of("+8")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
result.add(p);
from = from + 5 * 60 * 1000;
}
}
price.setSatisticsTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(price.getTimestamp()),ZoneOffset.of("+8")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
result.add(price);
flagPrice = price;
}
//4.补充右边的数据
if(flagPrice != null && flagPrice.getTimestamp() < toTime){
//+ 5 分钟
long from = flagPrice.getTimestamp() + 5 * 60 * 1000;
while (from < toTime){
PriceStatisticsVO p = new PriceStatisticsVO();
BeanUtil.copyProperties(flagPrice, p);
p.setTimestamp(from);
p.setSatisticsTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(from),ZoneOffset.of("+8")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
result.add(p);
from = from + 5 * 60 * 1000;
}
}
return Result.OK(result);
}
四.计算基差 根据范围
controller层
/**
* 根据范围计算基差
* 计算规则:市场价 - 大盘价
* @param bigDishPriceDTO
* @return
*/
@PostMapping(value = "/bigDishPrice/rangeQueryBasicDiff")
public Result<?> rangeQueryBasicDiff(@RequestBody BigDishPriceDTO bigDishPriceDTO){
if(StringUtils.isBlank(bigDishPriceDTO.getProductSpec()) || StringUtils.isBlank(bigDishPriceDTO.getBigDishProductSpec())){
return Result.error("查询条件不能为空!");
}
if(StringUtils.isBlank(bigDishPriceDTO.getSiteId()) || StringUtils.isBlank(bigDishPriceDTO.getBigDishSiteId())){
return Result.error("地区不能为空!");
}
if(bigDishPriceDTO.getTo().compareTo(LocalDateTime.now().plusMinutes(1)) == 1){
return Result.error("结束时间需小于当前时间!");
}
if(bigDishPriceDTO.getFrom().compareTo(bigDishPriceDTO.getTo()) >= 0){
return Result.error("开始时间需小于结束时间!");
}
return bigDishPriceService.rangeQueryBasicDiff(bigDishPriceDTO);
}
service层
/**
* 根据范围查询基差
* 计算规则:市场价 - 大盘价
* @param bigDishPriceDTO
* @return
*/
Result<?> rangeQueryBasicDiff(BigDishPriceDTO bigDishPriceDTO);
serviceImpl层
@Override
public Result<?> rangeQueryBasicDiff(BigDishPriceDTO bigDishPriceDTO) {
//计算公式 市场价 - 大盘价
//1.存储结果
List<PriceStatisticsVO> result = new ArrayList<>();
Duration duration = Duration.between(bigDishPriceDTO.getFrom(),bigDishPriceDTO.getTo());
//当前查询范围大于1天
if(duration.toDays() > 1){
//2.根据时间补齐市场价的数据
List<PriceStatisticsVO> priceList = replenishDayData(bigDishPriceDTO.getProductSpec(), bigDishPriceDTO.getSiteId(), bigDishPriceDTO.getFrom(), bigDishPriceDTO.getTo(),duration.toDays());
//3.根据时间补齐大盘价的数据
List<PriceStatisticsVO> bigDishPriceList = replenishDayData(bigDishPriceDTO.getBigDishProductSpec(), bigDishPriceDTO.getBigDishSiteId(), bigDishPriceDTO.getFrom(), bigDishPriceDTO.getTo(),duration.toDays());
Map<String, Float> bigDishPriceMap = bigDishPriceList.stream().collect(Collectors.toMap(priceStatisticsVO -> priceStatisticsVO.getSatisticsTime(), o -> o.getPrice()));
//4.计算存储结果
priceList.forEach(p -> {
PriceStatisticsVO priceStatisticsVO = new PriceStatisticsVO();
//基差 = 市场价 - 大盘价
Float basicDiff = p.getPrice() - bigDishPriceMap.get(p.getSatisticsTime());
basicDiff = new BigDecimal(basicDiff).setScale(2,RoundingMode.HALF_UP).floatValue();
priceStatisticsVO.setPrice(basicDiff);
priceStatisticsVO.setSatisticsTime(p.getSatisticsTime());
priceStatisticsVO.setTimestamp(p.getTimestamp());
result.add(priceStatisticsVO);
});
return Result.OK(result);
}
//2.根据时间补齐市场价的数据
List<PriceStatisticsVO> priceList = replenishData(bigDishPriceDTO.getProductSpec(), bigDishPriceDTO.getSiteId(), bigDishPriceDTO.getFrom(), bigDishPriceDTO.getTo());
if(priceList == null || priceList.size() == 0){
return Result.OK();
}
//3.根据时间补齐大盘价的数据
List<PriceStatisticsVO> bigDishPriceList = replenishData(bigDishPriceDTO.getBigDishProductSpec(), bigDishPriceDTO.getBigDishSiteId(), bigDishPriceDTO.getFrom(), bigDishPriceDTO.getTo());
if(bigDishPriceList == null || bigDishPriceList.size() == 0){
return Result.OK();
}
Map<String, Float> bigDishPriceMap = bigDishPriceList.stream().collect(Collectors.toMap(priceStatisticsVO -> priceStatisticsVO.getSatisticsTime(), o -> o.getPrice()));
//4.计算存储结果
priceList.forEach(p -> {
PriceStatisticsVO priceStatisticsVO = new PriceStatisticsVO();
//基差 = 市场价 - 大盘价
Float basicDiff = p.getPrice() - bigDishPriceMap.get(p.getSatisticsTime());
basicDiff = new BigDecimal(basicDiff).setScale(2,RoundingMode.HALF_UP).floatValue();
priceStatisticsVO.setPrice(basicDiff);
priceStatisticsVO.setSatisticsTime(p.getSatisticsTime());
priceStatisticsVO.setTimestamp(p.getTimestamp());
result.add(priceStatisticsVO);
});
return Result.OK(result);
}
更多推荐



所有评论(0)