package com.yami.trading.huobi.hobi.internal;
|
|
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.util.StrUtil;
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.google.common.collect.Lists;
|
import com.yami.trading.bean.data.domain.Kline;
|
import com.yami.trading.bean.etf.domain.EtfMinuteKLine;
|
import com.yami.trading.bean.item.domain.Item;
|
import com.yami.trading.huobi.data.internal.KlineConstant;
|
import com.yami.trading.huobi.data.internal.KlineService;
|
import com.yami.trading.huobi.hobi.http.HttpHelper;
|
import com.yami.trading.service.etf.EtfMinuteKLineService;
|
import com.yami.trading.service.item.ItemService;
|
import org.checkerframework.checker.units.qual.K;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
|
import java.math.BigDecimal;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
@Service
|
public class FakeKlineInitService {
|
@Autowired
|
private KlineService klineService;
|
@Autowired
|
private EtfMinuteKLineService etfMinuteKLineService;
|
|
public final void saveInit(String symbol) {
|
Item bySymbol = itemService.findBySymbol(symbol);
|
// 非机器人的价格,无需初始化
|
if("0".equalsIgnoreCase(bySymbol.getFake())){
|
return;
|
}
|
QueryWrapper<EtfMinuteKLine> queryWrapper = new QueryWrapper<>();
|
queryWrapper.eq("symbol", symbol);
|
queryWrapper.lt("ts", System.currentTimeMillis());
|
queryWrapper.orderByAsc("ts");
|
List<EtfMinuteKLine> list = etfMinuteKLineService.list(queryWrapper);
|
List<Kline> klineList = list.stream().map(e -> {
|
Kline kline = BeanUtil.copyProperties(e, Kline.class);
|
kline.setPeriod(Kline.PERIOD_1MIN);
|
return kline;
|
}).collect(Collectors.toList());
|
Map<String, List<Kline>> dailyWeekMonthHistoryMap = getDailyWeekMonthHistory(symbol, klineList);
|
Map<String, List<Kline>> hourlyAndMinuteHistoryMap = getHourlyAndMinuteHistory(symbol, klineList);
|
klineService.saveInit(symbol, dailyWeekMonthHistoryMap, hourlyAndMinuteHistoryMap);
|
}
|
|
@Autowired
|
private ItemService itemService;
|
|
/**
|
* 获取分钟数据
|
*/
|
public Map<String, List<Kline>> getHourlyAndMinuteHistory(String symbol , List<Kline> klineList) {
|
Map<String, List<Kline>> map = new HashMap<>();
|
|
List<Kline> fourHourlyList = getTimeseriesForFourHourly(symbol, klineList);
|
map.put(KlineConstant.PERIOD_4HOUR, fourHourlyList);
|
|
List<Kline> twoHourlyList = getTimeseriesForTwoHourly(symbol, klineList);
|
map.put(KlineConstant.PERIOD_2HOUR, twoHourlyList);
|
|
List<Kline> oneHourlyList = getTimeseriesForOneHourly(symbol, klineList);
|
map.put(KlineConstant.PERIOD_60MIN, oneHourlyList);
|
|
List<Kline> thirtyMinuteList = getTimeseriesThirtyMinute(symbol, klineList);
|
map.put(KlineConstant.PERIOD_30MIN, thirtyMinuteList);
|
|
List<Kline> fifteenMinuteList = getTimeseriesFifteenMinute(symbol, klineList);
|
map.put(KlineConstant.PERIOD_15MIN, fifteenMinuteList);
|
|
List<Kline> fiveMinuteList = getTimeseriesFiveMinute(symbol, klineList);
|
map.put(KlineConstant.PERIOD_5MIN, fiveMinuteList);
|
|
List<Kline> oneMinuteList = klineList;
|
map.put(KlineConstant.PERIOD_1MIN, oneMinuteList);
|
return map;
|
}
|
|
|
/**
|
* 1day 历史数据 : 周期 1年
|
* 1week,1mon 历史数据 : 周期 5年
|
* 请求 350次
|
*/
|
public Map<String, List<Kline>> getDailyWeekMonthHistory(String symbol , List<Kline> klineList) {
|
Map<String, List<Kline>> map = new HashMap<>();
|
map.put(Kline.PERIOD_1WEEK, buildOneWeekPeriod(symbol, klineList));
|
map.put(Kline.PERIOD_1MON, buildOneMonthPeriod(symbol, klineList));
|
map.put(Kline.PERIOD_1DAY, buildOneDayPeriod(symbol, klineList));
|
map.put(Kline.PERIOD_5DAY, buildFiveDayPeriod(symbol, klineList));
|
map.put(Kline.PERIOD_QUARTER, buildOneQuarterPeriod(symbol, klineList));
|
map.put(Kline.PERIOD_YEAR, buildOneYearPeriod(symbol, klineList));
|
|
return map;
|
}
|
|
public List<Kline> buildOneDayPeriod(String currency, List<Kline> klineList) {
|
return getTimeseriesByMinute(currency, 390, Kline.PERIOD_1DAY , klineList);
|
|
}
|
|
|
public List<Kline> buildOneWeekPeriod(String currency, List<Kline> klineList) {
|
return getTimeseriesByMinute(currency, 390*7, Kline.PERIOD_1WEEK , klineList);
|
|
}
|
|
public List<Kline> buildOneMonthPeriod(String currency, List<Kline> klineList) {
|
return getTimeseriesByMinute(currency, 390*22, Kline.PERIOD_1MON , klineList);
|
}
|
|
public List<Kline> buildOneQuarterPeriod(String currency, List<Kline> klineList) {
|
return getTimeseriesByMinute(currency, 390*66, Kline.PERIOD_QUARTER , klineList);
|
}
|
|
public List<Kline> buildOneYearPeriod(String currency, List<Kline> klineList) {
|
return getTimeseriesByMinute(currency, 390*220, Kline.PERIOD_YEAR , klineList);
|
}
|
|
/**
|
* 雪球支持120分钟的,讲120分钟的,
|
* Hourly
|
* 4hourly 3月
|
*/
|
public List<Kline> buildFiveDayPeriod(String currency, List<Kline> klineList) {
|
return getTimeseriesByMinute(currency, 390*5, Kline.PERIOD_5DAY , klineList);
|
|
|
}
|
|
|
/**
|
* 雪球支持120分钟的,讲120分钟的,
|
* Hourly
|
* 4hourly 3月
|
*/
|
public List<Kline> getTimeseriesForFourHourly(String currency, List<Kline> klineList) {
|
return getTimeseriesByMinute(currency, 240, Kline.PERIOD_4HOUR , klineList);
|
|
|
}
|
|
/**
|
* Hourly
|
* 1hourly 2个小时
|
*/
|
public List<Kline> getTimeseriesForTwoHourly(String currency, List<Kline> klineList) {
|
return getTimeseriesByMinute(currency, 120, Kline.PERIOD_2HOUR , klineList);
|
}
|
|
/**
|
* Hourly
|
* 1hourly 1月
|
*/
|
public List<Kline> getTimeseriesForOneHourly(String currency, List<Kline> klineList) {
|
return getTimeseriesByMinute(currency, 60, Kline.PERIOD_60MIN, klineList);
|
}
|
|
/**
|
* Minute
|
* 30minute 10天
|
* 15minute 5天
|
* 5minute 2天
|
* 1minute 1天
|
*/
|
public List<Kline> getTimeseriesOneMinute(String currency, List<Kline> klineList) {
|
return klineList;
|
|
}
|
|
/**
|
* Minute
|
* 30minute 10天
|
* 15minute 5天
|
* 5minute 2天
|
* 1minute 1天
|
*/
|
public List<Kline> getTimeseriesFiveMinute(String currency, List<Kline> klineList) {
|
return getTimeseriesByMinute(currency, 5, Kline.PERIOD_5MIN, klineList);
|
|
}
|
|
/**
|
* Minute
|
* 30minute 10天
|
* 15minute 5天
|
* 5minute 2天
|
* 1minute 1天
|
*/
|
public List<Kline> getTimeseriesFifteenMinute(String currency, List<Kline> klineList) {
|
return getTimeseriesByMinute(currency, 15, Kline.PERIOD_15MIN, klineList);
|
}
|
|
/**
|
* Minute
|
* 30minute 15
|
* 15minute 15
|
* 5minute 15
|
* 1minute 15
|
*/
|
public List<Kline> getTimeseriesThirtyMinute(String currency, List<Kline> klineList) {
|
return getTimeseriesByMinute(currency, 30, Kline.PERIOD_30MIN, klineList);
|
}
|
|
|
/**
|
* 按多少分钟进行partition聚合
|
* @param symbol
|
* @param minute
|
* @param klineList
|
* @return
|
*/
|
public List<Kline> getTimeseriesByMinute(String symbol, int minute, String period, List<Kline> klineList) {
|
int decimal = itemService.getDecimal(symbol);
|
List<Kline> result = new ArrayList<>();
|
// 抽象成minute分钟图,方便前端显示
|
List<List<Kline>> partition = Lists.partition(klineList, minute);
|
for (List<Kline> list1Min : partition) {
|
Double high = list1Min.get(0).getHigh().doubleValue();
|
Double low = list1Min.get(0).getLow().doubleValue();
|
for (Kline kline : list1Min) {
|
if (high <= kline.getHigh().doubleValue()) {
|
high = kline.getHigh().doubleValue();
|
}
|
if (low >= kline.getLow().doubleValue()) {
|
low = kline.getLow().doubleValue();
|
}
|
}
|
int lastIndex = list1Min.size() - 1;
|
Kline kline = new Kline();
|
kline.setSymbol(symbol);
|
kline.setTs(list1Min.get(lastIndex).getTs());
|
kline.setOpen(list1Min.get(0).getOpen().setScale(decimal, BigDecimal.ROUND_DOWN));
|
kline.setHigh(new BigDecimal(high).setScale(decimal, BigDecimal.ROUND_DOWN));
|
kline.setLow(new BigDecimal(low).setScale(decimal, BigDecimal.ROUND_DOWN));
|
kline.setClose(list1Min.get(lastIndex).getClose().setScale(decimal, BigDecimal.ROUND_DOWN));
|
kline.setPeriod(period);
|
// 格式化小数点位
|
// klineOneTop.formatPoint(kline);
|
BigDecimal sumAmount = klineList.stream()
|
.map(Kline::getAmount)
|
.filter(Objects::nonNull)
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
BigDecimal sumVolume = klineList.stream()
|
.map(Kline::getVolume)
|
.filter(Objects::nonNull)
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
kline.setAmount(sumAmount);
|
kline.setVolume(sumVolume);
|
result.add(kline);
|
}
|
return result;
|
}
|
}
|